* gcc.pot: Regenerate.
[official-gcc.git] / gcc / builtins.c
blob726fcef611876f35ef1c2eb4fb2bf7a88bad8b8c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
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_int_roundingfn (tree, rtx, rtx);
98 static rtx expand_builtin_args_info (tree);
99 static rtx expand_builtin_next_arg (void);
100 static rtx expand_builtin_va_start (tree);
101 static rtx expand_builtin_va_end (tree);
102 static rtx expand_builtin_va_copy (tree);
103 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
113 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
114 static rtx expand_builtin_bcopy (tree);
115 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
116 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_strlen (tree);
140 static tree fold_builtin_inf (tree, int);
141 static tree fold_builtin_nan (tree, tree, int);
142 static int validate_arglist (tree, ...);
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_sin (tree);
153 static tree fold_builtin_cos (tree, tree, tree);
154 static tree fold_builtin_tan (tree);
155 static tree fold_builtin_atan (tree, tree);
156 static tree fold_builtin_trunc (tree, tree);
157 static tree fold_builtin_floor (tree, tree);
158 static tree fold_builtin_ceil (tree, tree);
159 static tree fold_builtin_round (tree, tree);
160 static tree fold_builtin_int_roundingfn (tree, tree);
161 static tree fold_builtin_bitop (tree, tree);
162 static tree fold_builtin_memory_op (tree, tree, bool, int);
163 static tree fold_builtin_strchr (tree, tree);
164 static tree fold_builtin_memcmp (tree);
165 static tree fold_builtin_strcmp (tree);
166 static tree fold_builtin_strncmp (tree);
167 static tree fold_builtin_signbit (tree, tree);
168 static tree fold_builtin_copysign (tree, tree, tree);
169 static tree fold_builtin_isascii (tree);
170 static tree fold_builtin_toascii (tree);
171 static tree fold_builtin_isdigit (tree);
172 static tree fold_builtin_fabs (tree, tree);
173 static tree fold_builtin_abs (tree, tree);
174 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
175 enum tree_code);
176 static tree fold_builtin_1 (tree, tree, bool);
178 static tree fold_builtin_strpbrk (tree, tree);
179 static tree fold_builtin_strstr (tree, tree);
180 static tree fold_builtin_strrchr (tree, tree);
181 static tree fold_builtin_strcat (tree);
182 static tree fold_builtin_strncat (tree);
183 static tree fold_builtin_strspn (tree);
184 static tree fold_builtin_strcspn (tree);
185 static tree fold_builtin_sprintf (tree, int);
187 static rtx expand_builtin_object_size (tree);
188 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
189 enum built_in_function);
190 static void maybe_emit_chk_warning (tree, enum built_in_function);
191 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
192 static tree fold_builtin_object_size (tree);
193 static tree fold_builtin_strcat_chk (tree, tree);
194 static tree fold_builtin_strncat_chk (tree, tree);
195 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
196 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
197 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
198 static bool init_target_chars (void);
200 static unsigned HOST_WIDE_INT target_newline;
201 static unsigned HOST_WIDE_INT target_percent;
202 static unsigned HOST_WIDE_INT target_c;
203 static unsigned HOST_WIDE_INT target_s;
204 static char target_percent_c[3];
205 static char target_percent_s[3];
206 static char target_percent_s_newline[4];
208 /* Return true if NODE should be considered for inline expansion regardless
209 of the optimization level. This means whenever a function is invoked with
210 its "internal" name, which normally contains the prefix "__builtin". */
212 static bool called_as_built_in (tree node)
214 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
215 if (strncmp (name, "__builtin_", 10) == 0)
216 return true;
217 if (strncmp (name, "__sync_", 7) == 0)
218 return true;
219 return false;
222 /* Return the alignment in bits of EXP, a pointer valued expression.
223 But don't return more than MAX_ALIGN no matter what.
224 The alignment returned is, by default, the alignment of the thing that
225 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
227 Otherwise, look at the expression to see if we can do better, i.e., if the
228 expression is actually pointing at an object whose alignment is tighter. */
230 static int
231 get_pointer_alignment (tree exp, unsigned int max_align)
233 unsigned int align, inner;
235 /* We rely on TER to compute accurate alignment information. */
236 if (!(optimize && flag_tree_ter))
237 return 0;
239 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
240 return 0;
242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243 align = MIN (align, max_align);
245 while (1)
247 switch (TREE_CODE (exp))
249 case NOP_EXPR:
250 case CONVERT_EXPR:
251 case NON_LVALUE_EXPR:
252 exp = TREE_OPERAND (exp, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254 return align;
256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257 align = MIN (inner, max_align);
258 break;
260 case PLUS_EXPR:
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
263 ALIGN. */
264 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265 return align;
267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268 & (max_align / BITS_PER_UNIT - 1))
269 != 0)
270 max_align >>= 1;
272 exp = TREE_OPERAND (exp, 0);
273 break;
275 case ADDR_EXPR:
276 /* See what we are pointing at and look at its alignment. */
277 exp = TREE_OPERAND (exp, 0);
278 inner = max_align;
279 if (handled_component_p (exp))
281 HOST_WIDE_INT bitsize, bitpos;
282 tree offset;
283 enum machine_mode mode;
284 int unsignedp, volatilep;
286 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
287 &mode, &unsignedp, &volatilep, true);
288 if (bitpos)
289 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
290 if (offset && TREE_CODE (offset) == PLUS_EXPR
291 && host_integerp (TREE_OPERAND (offset, 1), 1))
293 /* Any overflow in calculating offset_bits won't change
294 the alignment. */
295 unsigned offset_bits
296 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
297 * BITS_PER_UNIT);
299 if (offset_bits)
300 inner = MIN (inner, (offset_bits & -offset_bits));
301 offset = TREE_OPERAND (offset, 0);
303 if (offset && TREE_CODE (offset) == MULT_EXPR
304 && host_integerp (TREE_OPERAND (offset, 1), 1))
306 /* Any overflow in calculating offset_factor won't change
307 the alignment. */
308 unsigned offset_factor
309 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
310 * BITS_PER_UNIT);
312 if (offset_factor)
313 inner = MIN (inner, (offset_factor & -offset_factor));
315 else if (offset)
316 inner = MIN (inner, BITS_PER_UNIT);
318 if (TREE_CODE (exp) == FUNCTION_DECL)
319 align = FUNCTION_BOUNDARY;
320 else if (DECL_P (exp))
321 align = MIN (inner, DECL_ALIGN (exp));
322 #ifdef CONSTANT_ALIGNMENT
323 else if (CONSTANT_CLASS_P (exp))
324 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
325 #endif
326 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
327 || TREE_CODE (exp) == INDIRECT_REF)
328 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
329 else
330 align = MIN (align, inner);
331 return MIN (align, max_align);
333 default:
334 return align;
339 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
340 way, because it could contain a zero byte in the middle.
341 TREE_STRING_LENGTH is the size of the character array, not the string.
343 ONLY_VALUE should be nonzero if the result is not going to be emitted
344 into the instruction stream and zero if it is going to be expanded.
345 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
346 is returned, otherwise NULL, since
347 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
348 evaluate the side-effects.
350 The value returned is of type `ssizetype'.
352 Unfortunately, string_constant can't access the values of const char
353 arrays with initializers, so neither can we do so here. */
355 tree
356 c_strlen (tree src, int only_value)
358 tree offset_node;
359 HOST_WIDE_INT offset;
360 int max;
361 const char *ptr;
363 STRIP_NOPS (src);
364 if (TREE_CODE (src) == COND_EXPR
365 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
367 tree len1, len2;
369 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
370 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
371 if (tree_int_cst_equal (len1, len2))
372 return len1;
375 if (TREE_CODE (src) == COMPOUND_EXPR
376 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
377 return c_strlen (TREE_OPERAND (src, 1), only_value);
379 src = string_constant (src, &offset_node);
380 if (src == 0)
381 return 0;
383 max = TREE_STRING_LENGTH (src) - 1;
384 ptr = TREE_STRING_POINTER (src);
386 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
388 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
389 compute the offset to the following null if we don't know where to
390 start searching for it. */
391 int i;
393 for (i = 0; i < max; i++)
394 if (ptr[i] == 0)
395 return 0;
397 /* We don't know the starting offset, but we do know that the string
398 has no internal zero bytes. We can assume that the offset falls
399 within the bounds of the string; otherwise, the programmer deserves
400 what he gets. Subtract the offset from the length of the string,
401 and return that. This would perhaps not be valid if we were dealing
402 with named arrays in addition to literal string constants. */
404 return size_diffop (size_int (max), offset_node);
407 /* We have a known offset into the string. Start searching there for
408 a null character if we can represent it as a single HOST_WIDE_INT. */
409 if (offset_node == 0)
410 offset = 0;
411 else if (! host_integerp (offset_node, 0))
412 offset = -1;
413 else
414 offset = tree_low_cst (offset_node, 0);
416 /* If the offset is known to be out of bounds, warn, and call strlen at
417 runtime. */
418 if (offset < 0 || offset > max)
420 warning (0, "offset outside bounds of constant string");
421 return 0;
424 /* Use strlen to search for the first zero byte. Since any strings
425 constructed with build_string will have nulls appended, we win even
426 if we get handed something like (char[4])"abcd".
428 Since OFFSET is our starting index into the string, no further
429 calculation is needed. */
430 return ssize_int (strlen (ptr + offset));
433 /* Return a char pointer for a C string if it is a string constant
434 or sum of string constant and integer constant. */
436 static const char *
437 c_getstr (tree src)
439 tree offset_node;
441 src = string_constant (src, &offset_node);
442 if (src == 0)
443 return 0;
445 if (offset_node == 0)
446 return TREE_STRING_POINTER (src);
447 else if (!host_integerp (offset_node, 1)
448 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
449 return 0;
451 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
454 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
455 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
457 static rtx
458 c_readstr (const char *str, enum machine_mode mode)
460 HOST_WIDE_INT c[2];
461 HOST_WIDE_INT ch;
462 unsigned int i, j;
464 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
466 c[0] = 0;
467 c[1] = 0;
468 ch = 1;
469 for (i = 0; i < GET_MODE_SIZE (mode); i++)
471 j = i;
472 if (WORDS_BIG_ENDIAN)
473 j = GET_MODE_SIZE (mode) - i - 1;
474 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
475 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
476 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
477 j *= BITS_PER_UNIT;
478 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
480 if (ch)
481 ch = (unsigned char) str[i];
482 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
484 return immed_double_const (c[0], c[1], mode);
487 /* Cast a target constant CST to target CHAR and if that value fits into
488 host char type, return zero and put that value into variable pointed to by
489 P. */
491 static int
492 target_char_cast (tree cst, char *p)
494 unsigned HOST_WIDE_INT val, hostval;
496 if (!host_integerp (cst, 1)
497 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
498 return 1;
500 val = tree_low_cst (cst, 1);
501 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
502 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
504 hostval = val;
505 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
506 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
508 if (val != hostval)
509 return 1;
511 *p = hostval;
512 return 0;
515 /* Similar to save_expr, but assumes that arbitrary code is not executed
516 in between the multiple evaluations. In particular, we assume that a
517 non-addressable local variable will not be modified. */
519 static tree
520 builtin_save_expr (tree exp)
522 if (TREE_ADDRESSABLE (exp) == 0
523 && (TREE_CODE (exp) == PARM_DECL
524 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
525 return exp;
527 return save_expr (exp);
530 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
531 times to get the address of either a higher stack frame, or a return
532 address located within it (depending on FNDECL_CODE). */
534 static rtx
535 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
537 int i;
539 #ifdef INITIAL_FRAME_ADDRESS_RTX
540 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
541 #else
542 rtx tem;
544 /* For a zero count with __builtin_return_address, we don't care what
545 frame address we return, because target-specific definitions will
546 override us. Therefore frame pointer elimination is OK, and using
547 the soft frame pointer is OK.
549 For a non-zero count, or a zero count with __builtin_frame_address,
550 we require a stable offset from the current frame pointer to the
551 previous one, so we must use the hard frame pointer, and
552 we must disable frame pointer elimination. */
553 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
554 tem = frame_pointer_rtx;
555 else
557 tem = hard_frame_pointer_rtx;
559 /* Tell reload not to eliminate the frame pointer. */
560 current_function_accesses_prior_frames = 1;
562 #endif
564 /* Some machines need special handling before we can access
565 arbitrary frames. For example, on the SPARC, we must first flush
566 all register windows to the stack. */
567 #ifdef SETUP_FRAME_ADDRESSES
568 if (count > 0)
569 SETUP_FRAME_ADDRESSES ();
570 #endif
572 /* On the SPARC, the return address is not in the frame, it is in a
573 register. There is no way to access it off of the current frame
574 pointer, but it can be accessed off the previous frame pointer by
575 reading the value from the register window save area. */
576 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
577 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
578 count--;
579 #endif
581 /* Scan back COUNT frames to the specified frame. */
582 for (i = 0; i < count; i++)
584 /* Assume the dynamic chain pointer is in the word that the
585 frame address points to, unless otherwise specified. */
586 #ifdef DYNAMIC_CHAIN_ADDRESS
587 tem = DYNAMIC_CHAIN_ADDRESS (tem);
588 #endif
589 tem = memory_address (Pmode, tem);
590 tem = gen_frame_mem (Pmode, tem);
591 tem = copy_to_reg (tem);
594 /* For __builtin_frame_address, return what we've got. But, on
595 the SPARC for example, we may have to add a bias. */
596 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
597 #ifdef FRAME_ADDR_RTX
598 return FRAME_ADDR_RTX (tem);
599 #else
600 return tem;
601 #endif
603 /* For __builtin_return_address, get the return address from that frame. */
604 #ifdef RETURN_ADDR_RTX
605 tem = RETURN_ADDR_RTX (count, tem);
606 #else
607 tem = memory_address (Pmode,
608 plus_constant (tem, GET_MODE_SIZE (Pmode)));
609 tem = gen_frame_mem (Pmode, tem);
610 #endif
611 return tem;
614 /* Alias set used for setjmp buffer. */
615 static HOST_WIDE_INT setjmp_alias_set = -1;
617 /* Construct the leading half of a __builtin_setjmp call. Control will
618 return to RECEIVER_LABEL. This is also called directly by the SJLJ
619 exception handling code. */
621 void
622 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
624 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
625 rtx stack_save;
626 rtx mem;
628 if (setjmp_alias_set == -1)
629 setjmp_alias_set = new_alias_set ();
631 buf_addr = convert_memory_address (Pmode, buf_addr);
633 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
635 /* We store the frame pointer and the address of receiver_label in
636 the buffer and use the rest of it for the stack save area, which
637 is machine-dependent. */
639 mem = gen_rtx_MEM (Pmode, buf_addr);
640 set_mem_alias_set (mem, setjmp_alias_set);
641 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
643 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
644 set_mem_alias_set (mem, setjmp_alias_set);
646 emit_move_insn (validize_mem (mem),
647 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
649 stack_save = gen_rtx_MEM (sa_mode,
650 plus_constant (buf_addr,
651 2 * GET_MODE_SIZE (Pmode)));
652 set_mem_alias_set (stack_save, setjmp_alias_set);
653 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
655 /* If there is further processing to do, do it. */
656 #ifdef HAVE_builtin_setjmp_setup
657 if (HAVE_builtin_setjmp_setup)
658 emit_insn (gen_builtin_setjmp_setup (buf_addr));
659 #endif
661 /* Tell optimize_save_area_alloca that extra work is going to
662 need to go on during alloca. */
663 current_function_calls_setjmp = 1;
665 /* Set this so all the registers get saved in our frame; we need to be
666 able to copy the saved values for any registers from frames we unwind. */
667 current_function_has_nonlocal_label = 1;
670 /* Construct the trailing part of a __builtin_setjmp call. This is
671 also called directly by the SJLJ exception handling code. */
673 void
674 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
676 /* Clobber the FP when we get here, so we have to make sure it's
677 marked as used by this function. */
678 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
680 /* Mark the static chain as clobbered here so life information
681 doesn't get messed up for it. */
682 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
684 /* Now put in the code to restore the frame pointer, and argument
685 pointer, if needed. */
686 #ifdef HAVE_nonlocal_goto
687 if (! HAVE_nonlocal_goto)
688 #endif
690 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
691 /* This might change the hard frame pointer in ways that aren't
692 apparent to early optimization passes, so force a clobber. */
693 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
696 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
697 if (fixed_regs[ARG_POINTER_REGNUM])
699 #ifdef ELIMINABLE_REGS
700 size_t i;
701 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
703 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
704 if (elim_regs[i].from == ARG_POINTER_REGNUM
705 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
706 break;
708 if (i == ARRAY_SIZE (elim_regs))
709 #endif
711 /* Now restore our arg pointer from the address at which it
712 was saved in our stack frame. */
713 emit_move_insn (virtual_incoming_args_rtx,
714 copy_to_reg (get_arg_pointer_save_area (cfun)));
717 #endif
719 #ifdef HAVE_builtin_setjmp_receiver
720 if (HAVE_builtin_setjmp_receiver)
721 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
722 else
723 #endif
724 #ifdef HAVE_nonlocal_goto_receiver
725 if (HAVE_nonlocal_goto_receiver)
726 emit_insn (gen_nonlocal_goto_receiver ());
727 else
728 #endif
729 { /* Nothing */ }
731 /* @@@ This is a kludge. Not all machine descriptions define a blockage
732 insn, but we must not allow the code we just generated to be reordered
733 by scheduling. Specifically, the update of the frame pointer must
734 happen immediately, not later. So emit an ASM_INPUT to act as blockage
735 insn. */
736 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
739 /* __builtin_longjmp is passed a pointer to an array of five words (not
740 all will be used on all machines). It operates similarly to the C
741 library function of the same name, but is more efficient. Much of
742 the code below is copied from the handling of non-local gotos. */
744 static void
745 expand_builtin_longjmp (rtx buf_addr, rtx value)
747 rtx fp, lab, stack, insn, last;
748 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
750 if (setjmp_alias_set == -1)
751 setjmp_alias_set = new_alias_set ();
753 buf_addr = convert_memory_address (Pmode, buf_addr);
755 buf_addr = force_reg (Pmode, buf_addr);
757 /* We used to store value in static_chain_rtx, but that fails if pointers
758 are smaller than integers. We instead require that the user must pass
759 a second argument of 1, because that is what builtin_setjmp will
760 return. This also makes EH slightly more efficient, since we are no
761 longer copying around a value that we don't care about. */
762 gcc_assert (value == const1_rtx);
764 last = get_last_insn ();
765 #ifdef HAVE_builtin_longjmp
766 if (HAVE_builtin_longjmp)
767 emit_insn (gen_builtin_longjmp (buf_addr));
768 else
769 #endif
771 fp = gen_rtx_MEM (Pmode, buf_addr);
772 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
773 GET_MODE_SIZE (Pmode)));
775 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
776 2 * GET_MODE_SIZE (Pmode)));
777 set_mem_alias_set (fp, setjmp_alias_set);
778 set_mem_alias_set (lab, setjmp_alias_set);
779 set_mem_alias_set (stack, setjmp_alias_set);
781 /* Pick up FP, label, and SP from the block and jump. This code is
782 from expand_goto in stmt.c; see there for detailed comments. */
783 #ifdef HAVE_nonlocal_goto
784 if (HAVE_nonlocal_goto)
785 /* We have to pass a value to the nonlocal_goto pattern that will
786 get copied into the static_chain pointer, but it does not matter
787 what that value is, because builtin_setjmp does not use it. */
788 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
789 else
790 #endif
792 lab = copy_to_reg (lab);
794 emit_insn (gen_rtx_CLOBBER (VOIDmode,
795 gen_rtx_MEM (BLKmode,
796 gen_rtx_SCRATCH (VOIDmode))));
797 emit_insn (gen_rtx_CLOBBER (VOIDmode,
798 gen_rtx_MEM (BLKmode,
799 hard_frame_pointer_rtx)));
801 emit_move_insn (hard_frame_pointer_rtx, fp);
802 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
804 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
805 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
806 emit_indirect_jump (lab);
810 /* Search backwards and mark the jump insn as a non-local goto.
811 Note that this precludes the use of __builtin_longjmp to a
812 __builtin_setjmp target in the same function. However, we've
813 already cautioned the user that these functions are for
814 internal exception handling use only. */
815 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
817 gcc_assert (insn != last);
819 if (JUMP_P (insn))
821 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
822 REG_NOTES (insn));
823 break;
825 else if (CALL_P (insn))
826 break;
830 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
831 and the address of the save area. */
833 static rtx
834 expand_builtin_nonlocal_goto (tree arglist)
836 tree t_label, t_save_area;
837 rtx r_label, r_save_area, r_fp, r_sp, insn;
839 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
840 return NULL_RTX;
842 t_label = TREE_VALUE (arglist);
843 arglist = TREE_CHAIN (arglist);
844 t_save_area = TREE_VALUE (arglist);
846 r_label = expand_normal (t_label);
847 r_label = convert_memory_address (Pmode, r_label);
848 r_save_area = expand_normal (t_save_area);
849 r_save_area = convert_memory_address (Pmode, r_save_area);
850 r_fp = gen_rtx_MEM (Pmode, r_save_area);
851 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
852 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
854 current_function_has_nonlocal_goto = 1;
856 #ifdef HAVE_nonlocal_goto
857 /* ??? We no longer need to pass the static chain value, afaik. */
858 if (HAVE_nonlocal_goto)
859 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
860 else
861 #endif
863 r_label = copy_to_reg (r_label);
865 emit_insn (gen_rtx_CLOBBER (VOIDmode,
866 gen_rtx_MEM (BLKmode,
867 gen_rtx_SCRATCH (VOIDmode))));
869 emit_insn (gen_rtx_CLOBBER (VOIDmode,
870 gen_rtx_MEM (BLKmode,
871 hard_frame_pointer_rtx)));
873 /* Restore frame pointer for containing function.
874 This sets the actual hard register used for the frame pointer
875 to the location of the function's incoming static chain info.
876 The non-local goto handler will then adjust it to contain the
877 proper value and reload the argument pointer, if needed. */
878 emit_move_insn (hard_frame_pointer_rtx, r_fp);
879 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
881 /* USE of hard_frame_pointer_rtx added for consistency;
882 not clear if really needed. */
883 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
884 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
885 emit_indirect_jump (r_label);
888 /* Search backwards to the jump insn and mark it as a
889 non-local goto. */
890 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
892 if (JUMP_P (insn))
894 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
895 const0_rtx, REG_NOTES (insn));
896 break;
898 else if (CALL_P (insn))
899 break;
902 return const0_rtx;
905 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
906 (not all will be used on all machines) that was passed to __builtin_setjmp.
907 It updates the stack pointer in that block to correspond to the current
908 stack pointer. */
910 static void
911 expand_builtin_update_setjmp_buf (rtx buf_addr)
913 enum machine_mode sa_mode = Pmode;
914 rtx stack_save;
917 #ifdef HAVE_save_stack_nonlocal
918 if (HAVE_save_stack_nonlocal)
919 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
920 #endif
921 #ifdef STACK_SAVEAREA_MODE
922 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
923 #endif
925 stack_save
926 = gen_rtx_MEM (sa_mode,
927 memory_address
928 (sa_mode,
929 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
931 #ifdef HAVE_setjmp
932 if (HAVE_setjmp)
933 emit_insn (gen_setjmp ());
934 #endif
936 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
939 /* Expand a call to __builtin_prefetch. For a target that does not support
940 data prefetch, evaluate the memory address argument in case it has side
941 effects. */
943 static void
944 expand_builtin_prefetch (tree arglist)
946 tree arg0, arg1, arg2;
947 rtx op0, op1, op2;
949 if (!validate_arglist (arglist, POINTER_TYPE, 0))
950 return;
952 arg0 = TREE_VALUE (arglist);
953 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
954 zero (read) and argument 2 (locality) defaults to 3 (high degree of
955 locality). */
956 if (TREE_CHAIN (arglist))
958 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
959 if (TREE_CHAIN (TREE_CHAIN (arglist)))
960 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
961 else
962 arg2 = build_int_cst (NULL_TREE, 3);
964 else
966 arg1 = integer_zero_node;
967 arg2 = build_int_cst (NULL_TREE, 3);
970 /* Argument 0 is an address. */
971 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
973 /* Argument 1 (read/write flag) must be a compile-time constant int. */
974 if (TREE_CODE (arg1) != INTEGER_CST)
976 error ("second argument to %<__builtin_prefetch%> must be a constant");
977 arg1 = integer_zero_node;
979 op1 = expand_normal (arg1);
980 /* Argument 1 must be either zero or one. */
981 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
983 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
984 " using zero");
985 op1 = const0_rtx;
988 /* Argument 2 (locality) must be a compile-time constant int. */
989 if (TREE_CODE (arg2) != INTEGER_CST)
991 error ("third argument to %<__builtin_prefetch%> must be a constant");
992 arg2 = integer_zero_node;
994 op2 = expand_normal (arg2);
995 /* Argument 2 must be 0, 1, 2, or 3. */
996 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
998 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
999 op2 = const0_rtx;
1002 #ifdef HAVE_prefetch
1003 if (HAVE_prefetch)
1005 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1006 (op0,
1007 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1008 || (GET_MODE (op0) != Pmode))
1010 op0 = convert_memory_address (Pmode, op0);
1011 op0 = force_reg (Pmode, op0);
1013 emit_insn (gen_prefetch (op0, op1, op2));
1015 #endif
1017 /* Don't do anything with direct references to volatile memory, but
1018 generate code to handle other side effects. */
1019 if (!MEM_P (op0) && side_effects_p (op0))
1020 emit_insn (op0);
1023 /* Get a MEM rtx for expression EXP which is the address of an operand
1024 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1025 the maximum length of the block of memory that might be accessed or
1026 NULL if unknown. */
1028 static rtx
1029 get_memory_rtx (tree exp, tree len)
1031 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1032 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1034 /* Get an expression we can use to find the attributes to assign to MEM.
1035 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1036 we can. First remove any nops. */
1037 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1038 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1039 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1040 exp = TREE_OPERAND (exp, 0);
1042 if (TREE_CODE (exp) == ADDR_EXPR)
1043 exp = TREE_OPERAND (exp, 0);
1044 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1045 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1046 else
1047 exp = NULL;
1049 /* Honor attributes derived from exp, except for the alias set
1050 (as builtin stringops may alias with anything) and the size
1051 (as stringops may access multiple array elements). */
1052 if (exp)
1054 set_mem_attributes (mem, exp, 0);
1056 /* Allow the string and memory builtins to overflow from one
1057 field into another, see http://gcc.gnu.org/PR23561.
1058 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1059 memory accessed by the string or memory builtin will fit
1060 within the field. */
1061 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1063 tree mem_expr = MEM_EXPR (mem);
1064 HOST_WIDE_INT offset = -1, length = -1;
1065 tree inner = exp;
1067 while (TREE_CODE (inner) == ARRAY_REF
1068 || TREE_CODE (inner) == NOP_EXPR
1069 || TREE_CODE (inner) == CONVERT_EXPR
1070 || TREE_CODE (inner) == NON_LVALUE_EXPR
1071 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1072 || TREE_CODE (inner) == SAVE_EXPR)
1073 inner = TREE_OPERAND (inner, 0);
1075 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1077 if (MEM_OFFSET (mem)
1078 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1079 offset = INTVAL (MEM_OFFSET (mem));
1081 if (offset >= 0 && len && host_integerp (len, 0))
1082 length = tree_low_cst (len, 0);
1084 while (TREE_CODE (inner) == COMPONENT_REF)
1086 tree field = TREE_OPERAND (inner, 1);
1087 gcc_assert (! DECL_BIT_FIELD (field));
1088 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1089 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1091 if (length >= 0
1092 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1093 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1095 HOST_WIDE_INT size
1096 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1097 /* If we can prove the memory starting at XEXP (mem, 0)
1098 and ending at XEXP (mem, 0) + LENGTH will fit into
1099 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1100 if (offset <= size
1101 && length <= size
1102 && offset + length <= size)
1103 break;
1106 if (offset >= 0
1107 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1108 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1109 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1110 / BITS_PER_UNIT;
1111 else
1113 offset = -1;
1114 length = -1;
1117 mem_expr = TREE_OPERAND (mem_expr, 0);
1118 inner = TREE_OPERAND (inner, 0);
1121 if (mem_expr == NULL)
1122 offset = -1;
1123 if (mem_expr != MEM_EXPR (mem))
1125 set_mem_expr (mem, mem_expr);
1126 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1129 set_mem_alias_set (mem, 0);
1130 set_mem_size (mem, NULL_RTX);
1133 return mem;
1136 /* Built-in functions to perform an untyped call and return. */
1138 /* For each register that may be used for calling a function, this
1139 gives a mode used to copy the register's value. VOIDmode indicates
1140 the register is not used for calling a function. If the machine
1141 has register windows, this gives only the outbound registers.
1142 INCOMING_REGNO gives the corresponding inbound register. */
1143 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1145 /* For each register that may be used for returning values, this gives
1146 a mode used to copy the register's value. VOIDmode indicates the
1147 register is not used for returning values. If the machine has
1148 register windows, this gives only the outbound registers.
1149 INCOMING_REGNO gives the corresponding inbound register. */
1150 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1152 /* For each register that may be used for calling a function, this
1153 gives the offset of that register into the block returned by
1154 __builtin_apply_args. 0 indicates that the register is not
1155 used for calling a function. */
1156 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1158 /* Return the size required for the block returned by __builtin_apply_args,
1159 and initialize apply_args_mode. */
1161 static int
1162 apply_args_size (void)
1164 static int size = -1;
1165 int align;
1166 unsigned int regno;
1167 enum machine_mode mode;
1169 /* The values computed by this function never change. */
1170 if (size < 0)
1172 /* The first value is the incoming arg-pointer. */
1173 size = GET_MODE_SIZE (Pmode);
1175 /* The second value is the structure value address unless this is
1176 passed as an "invisible" first argument. */
1177 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1178 size += GET_MODE_SIZE (Pmode);
1180 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1181 if (FUNCTION_ARG_REGNO_P (regno))
1183 mode = reg_raw_mode[regno];
1185 gcc_assert (mode != VOIDmode);
1187 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1188 if (size % align != 0)
1189 size = CEIL (size, align) * align;
1190 apply_args_reg_offset[regno] = size;
1191 size += GET_MODE_SIZE (mode);
1192 apply_args_mode[regno] = mode;
1194 else
1196 apply_args_mode[regno] = VOIDmode;
1197 apply_args_reg_offset[regno] = 0;
1200 return size;
1203 /* Return the size required for the block returned by __builtin_apply,
1204 and initialize apply_result_mode. */
1206 static int
1207 apply_result_size (void)
1209 static int size = -1;
1210 int align, regno;
1211 enum machine_mode mode;
1213 /* The values computed by this function never change. */
1214 if (size < 0)
1216 size = 0;
1218 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1219 if (FUNCTION_VALUE_REGNO_P (regno))
1221 mode = reg_raw_mode[regno];
1223 gcc_assert (mode != VOIDmode);
1225 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1226 if (size % align != 0)
1227 size = CEIL (size, align) * align;
1228 size += GET_MODE_SIZE (mode);
1229 apply_result_mode[regno] = mode;
1231 else
1232 apply_result_mode[regno] = VOIDmode;
1234 /* Allow targets that use untyped_call and untyped_return to override
1235 the size so that machine-specific information can be stored here. */
1236 #ifdef APPLY_RESULT_SIZE
1237 size = APPLY_RESULT_SIZE;
1238 #endif
1240 return size;
1243 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1244 /* Create a vector describing the result block RESULT. If SAVEP is true,
1245 the result block is used to save the values; otherwise it is used to
1246 restore the values. */
1248 static rtx
1249 result_vector (int savep, rtx result)
1251 int regno, size, align, nelts;
1252 enum machine_mode mode;
1253 rtx reg, mem;
1254 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1256 size = nelts = 0;
1257 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1258 if ((mode = apply_result_mode[regno]) != VOIDmode)
1260 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1261 if (size % align != 0)
1262 size = CEIL (size, align) * align;
1263 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1264 mem = adjust_address (result, mode, size);
1265 savevec[nelts++] = (savep
1266 ? gen_rtx_SET (VOIDmode, mem, reg)
1267 : gen_rtx_SET (VOIDmode, reg, mem));
1268 size += GET_MODE_SIZE (mode);
1270 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1272 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1274 /* Save the state required to perform an untyped call with the same
1275 arguments as were passed to the current function. */
1277 static rtx
1278 expand_builtin_apply_args_1 (void)
1280 rtx registers, tem;
1281 int size, align, regno;
1282 enum machine_mode mode;
1283 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1285 /* Create a block where the arg-pointer, structure value address,
1286 and argument registers can be saved. */
1287 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1289 /* Walk past the arg-pointer and structure value address. */
1290 size = GET_MODE_SIZE (Pmode);
1291 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1292 size += GET_MODE_SIZE (Pmode);
1294 /* Save each register used in calling a function to the block. */
1295 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1296 if ((mode = apply_args_mode[regno]) != VOIDmode)
1298 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1299 if (size % align != 0)
1300 size = CEIL (size, align) * align;
1302 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1304 emit_move_insn (adjust_address (registers, mode, size), tem);
1305 size += GET_MODE_SIZE (mode);
1308 /* Save the arg pointer to the block. */
1309 tem = copy_to_reg (virtual_incoming_args_rtx);
1310 #ifdef STACK_GROWS_DOWNWARD
1311 /* We need the pointer as the caller actually passed them to us, not
1312 as we might have pretended they were passed. Make sure it's a valid
1313 operand, as emit_move_insn isn't expected to handle a PLUS. */
1315 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1316 NULL_RTX);
1317 #endif
1318 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1320 size = GET_MODE_SIZE (Pmode);
1322 /* Save the structure value address unless this is passed as an
1323 "invisible" first argument. */
1324 if (struct_incoming_value)
1326 emit_move_insn (adjust_address (registers, Pmode, size),
1327 copy_to_reg (struct_incoming_value));
1328 size += GET_MODE_SIZE (Pmode);
1331 /* Return the address of the block. */
1332 return copy_addr_to_reg (XEXP (registers, 0));
1335 /* __builtin_apply_args returns block of memory allocated on
1336 the stack into which is stored the arg pointer, structure
1337 value address, static chain, and all the registers that might
1338 possibly be used in performing a function call. The code is
1339 moved to the start of the function so the incoming values are
1340 saved. */
1342 static rtx
1343 expand_builtin_apply_args (void)
1345 /* Don't do __builtin_apply_args more than once in a function.
1346 Save the result of the first call and reuse it. */
1347 if (apply_args_value != 0)
1348 return apply_args_value;
1350 /* When this function is called, it means that registers must be
1351 saved on entry to this function. So we migrate the
1352 call to the first insn of this function. */
1353 rtx temp;
1354 rtx seq;
1356 start_sequence ();
1357 temp = expand_builtin_apply_args_1 ();
1358 seq = get_insns ();
1359 end_sequence ();
1361 apply_args_value = temp;
1363 /* Put the insns after the NOTE that starts the function.
1364 If this is inside a start_sequence, make the outer-level insn
1365 chain current, so the code is placed at the start of the
1366 function. */
1367 push_topmost_sequence ();
1368 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1369 pop_topmost_sequence ();
1370 return temp;
1374 /* Perform an untyped call and save the state required to perform an
1375 untyped return of whatever value was returned by the given function. */
1377 static rtx
1378 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1380 int size, align, regno;
1381 enum machine_mode mode;
1382 rtx incoming_args, result, reg, dest, src, call_insn;
1383 rtx old_stack_level = 0;
1384 rtx call_fusage = 0;
1385 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1387 arguments = convert_memory_address (Pmode, arguments);
1389 /* Create a block where the return registers can be saved. */
1390 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1392 /* Fetch the arg pointer from the ARGUMENTS block. */
1393 incoming_args = gen_reg_rtx (Pmode);
1394 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1395 #ifndef STACK_GROWS_DOWNWARD
1396 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1397 incoming_args, 0, OPTAB_LIB_WIDEN);
1398 #endif
1400 /* Push a new argument block and copy the arguments. Do not allow
1401 the (potential) memcpy call below to interfere with our stack
1402 manipulations. */
1403 do_pending_stack_adjust ();
1404 NO_DEFER_POP;
1406 /* Save the stack with nonlocal if available. */
1407 #ifdef HAVE_save_stack_nonlocal
1408 if (HAVE_save_stack_nonlocal)
1409 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1410 else
1411 #endif
1412 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1414 /* Allocate a block of memory onto the stack and copy the memory
1415 arguments to the outgoing arguments address. */
1416 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1417 dest = virtual_outgoing_args_rtx;
1418 #ifndef STACK_GROWS_DOWNWARD
1419 if (GET_CODE (argsize) == CONST_INT)
1420 dest = plus_constant (dest, -INTVAL (argsize));
1421 else
1422 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1423 #endif
1424 dest = gen_rtx_MEM (BLKmode, dest);
1425 set_mem_align (dest, PARM_BOUNDARY);
1426 src = gen_rtx_MEM (BLKmode, incoming_args);
1427 set_mem_align (src, PARM_BOUNDARY);
1428 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1430 /* Refer to the argument block. */
1431 apply_args_size ();
1432 arguments = gen_rtx_MEM (BLKmode, arguments);
1433 set_mem_align (arguments, PARM_BOUNDARY);
1435 /* Walk past the arg-pointer and structure value address. */
1436 size = GET_MODE_SIZE (Pmode);
1437 if (struct_value)
1438 size += GET_MODE_SIZE (Pmode);
1440 /* Restore each of the registers previously saved. Make USE insns
1441 for each of these registers for use in making the call. */
1442 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1443 if ((mode = apply_args_mode[regno]) != VOIDmode)
1445 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1446 if (size % align != 0)
1447 size = CEIL (size, align) * align;
1448 reg = gen_rtx_REG (mode, regno);
1449 emit_move_insn (reg, adjust_address (arguments, mode, size));
1450 use_reg (&call_fusage, reg);
1451 size += GET_MODE_SIZE (mode);
1454 /* Restore the structure value address unless this is passed as an
1455 "invisible" first argument. */
1456 size = GET_MODE_SIZE (Pmode);
1457 if (struct_value)
1459 rtx value = gen_reg_rtx (Pmode);
1460 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1461 emit_move_insn (struct_value, value);
1462 if (REG_P (struct_value))
1463 use_reg (&call_fusage, struct_value);
1464 size += GET_MODE_SIZE (Pmode);
1467 /* All arguments and registers used for the call are set up by now! */
1468 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1470 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1471 and we don't want to load it into a register as an optimization,
1472 because prepare_call_address already did it if it should be done. */
1473 if (GET_CODE (function) != SYMBOL_REF)
1474 function = memory_address (FUNCTION_MODE, function);
1476 /* Generate the actual call instruction and save the return value. */
1477 #ifdef HAVE_untyped_call
1478 if (HAVE_untyped_call)
1479 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1480 result, result_vector (1, result)));
1481 else
1482 #endif
1483 #ifdef HAVE_call_value
1484 if (HAVE_call_value)
1486 rtx valreg = 0;
1488 /* Locate the unique return register. It is not possible to
1489 express a call that sets more than one return register using
1490 call_value; use untyped_call for that. In fact, untyped_call
1491 only needs to save the return registers in the given block. */
1492 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1493 if ((mode = apply_result_mode[regno]) != VOIDmode)
1495 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1497 valreg = gen_rtx_REG (mode, regno);
1500 emit_call_insn (GEN_CALL_VALUE (valreg,
1501 gen_rtx_MEM (FUNCTION_MODE, function),
1502 const0_rtx, NULL_RTX, const0_rtx));
1504 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1506 else
1507 #endif
1508 gcc_unreachable ();
1510 /* Find the CALL insn we just emitted, and attach the register usage
1511 information. */
1512 call_insn = last_call_insn ();
1513 add_function_usage_to (call_insn, call_fusage);
1515 /* Restore the stack. */
1516 #ifdef HAVE_save_stack_nonlocal
1517 if (HAVE_save_stack_nonlocal)
1518 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1519 else
1520 #endif
1521 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1523 OK_DEFER_POP;
1525 /* Return the address of the result block. */
1526 result = copy_addr_to_reg (XEXP (result, 0));
1527 return convert_memory_address (ptr_mode, result);
1530 /* Perform an untyped return. */
1532 static void
1533 expand_builtin_return (rtx result)
1535 int size, align, regno;
1536 enum machine_mode mode;
1537 rtx reg;
1538 rtx call_fusage = 0;
1540 result = convert_memory_address (Pmode, result);
1542 apply_result_size ();
1543 result = gen_rtx_MEM (BLKmode, result);
1545 #ifdef HAVE_untyped_return
1546 if (HAVE_untyped_return)
1548 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1549 emit_barrier ();
1550 return;
1552 #endif
1554 /* Restore the return value and note that each value is used. */
1555 size = 0;
1556 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1557 if ((mode = apply_result_mode[regno]) != VOIDmode)
1559 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1560 if (size % align != 0)
1561 size = CEIL (size, align) * align;
1562 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1563 emit_move_insn (reg, adjust_address (result, mode, size));
1565 push_to_sequence (call_fusage);
1566 emit_insn (gen_rtx_USE (VOIDmode, reg));
1567 call_fusage = get_insns ();
1568 end_sequence ();
1569 size += GET_MODE_SIZE (mode);
1572 /* Put the USE insns before the return. */
1573 emit_insn (call_fusage);
1575 /* Return whatever values was restored by jumping directly to the end
1576 of the function. */
1577 expand_naked_return ();
1580 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1582 static enum type_class
1583 type_to_class (tree type)
1585 switch (TREE_CODE (type))
1587 case VOID_TYPE: return void_type_class;
1588 case INTEGER_TYPE: return integer_type_class;
1589 case ENUMERAL_TYPE: return enumeral_type_class;
1590 case BOOLEAN_TYPE: return boolean_type_class;
1591 case POINTER_TYPE: return pointer_type_class;
1592 case REFERENCE_TYPE: return reference_type_class;
1593 case OFFSET_TYPE: return offset_type_class;
1594 case REAL_TYPE: return real_type_class;
1595 case COMPLEX_TYPE: return complex_type_class;
1596 case FUNCTION_TYPE: return function_type_class;
1597 case METHOD_TYPE: return method_type_class;
1598 case RECORD_TYPE: return record_type_class;
1599 case UNION_TYPE:
1600 case QUAL_UNION_TYPE: return union_type_class;
1601 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1602 ? string_type_class : array_type_class);
1603 case LANG_TYPE: return lang_type_class;
1604 default: return no_type_class;
1608 /* Expand a call to __builtin_classify_type with arguments found in
1609 ARGLIST. */
1611 static rtx
1612 expand_builtin_classify_type (tree arglist)
1614 if (arglist != 0)
1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1616 return GEN_INT (no_type_class);
1619 /* This helper macro, meant to be used in mathfn_built_in below,
1620 determines which among a set of three builtin math functions is
1621 appropriate for a given type mode. The `F' and `L' cases are
1622 automatically generated from the `double' case. */
1623 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626 fcodel = BUILT_IN_MATHFN##L ; break;
1628 /* Return mathematic function equivalent to FN but operating directly
1629 on TYPE, if available. If we can't do the conversion, return zero. */
1630 tree
1631 mathfn_built_in (tree type, enum built_in_function fn)
1633 enum built_in_function fcode, fcodef, fcodel;
1635 switch (fn)
1637 CASE_MATHFN (BUILT_IN_ACOS)
1638 CASE_MATHFN (BUILT_IN_ACOSH)
1639 CASE_MATHFN (BUILT_IN_ASIN)
1640 CASE_MATHFN (BUILT_IN_ASINH)
1641 CASE_MATHFN (BUILT_IN_ATAN)
1642 CASE_MATHFN (BUILT_IN_ATAN2)
1643 CASE_MATHFN (BUILT_IN_ATANH)
1644 CASE_MATHFN (BUILT_IN_CBRT)
1645 CASE_MATHFN (BUILT_IN_CEIL)
1646 CASE_MATHFN (BUILT_IN_COPYSIGN)
1647 CASE_MATHFN (BUILT_IN_COS)
1648 CASE_MATHFN (BUILT_IN_COSH)
1649 CASE_MATHFN (BUILT_IN_DREM)
1650 CASE_MATHFN (BUILT_IN_ERF)
1651 CASE_MATHFN (BUILT_IN_ERFC)
1652 CASE_MATHFN (BUILT_IN_EXP)
1653 CASE_MATHFN (BUILT_IN_EXP10)
1654 CASE_MATHFN (BUILT_IN_EXP2)
1655 CASE_MATHFN (BUILT_IN_EXPM1)
1656 CASE_MATHFN (BUILT_IN_FABS)
1657 CASE_MATHFN (BUILT_IN_FDIM)
1658 CASE_MATHFN (BUILT_IN_FLOOR)
1659 CASE_MATHFN (BUILT_IN_FMA)
1660 CASE_MATHFN (BUILT_IN_FMAX)
1661 CASE_MATHFN (BUILT_IN_FMIN)
1662 CASE_MATHFN (BUILT_IN_FMOD)
1663 CASE_MATHFN (BUILT_IN_FREXP)
1664 CASE_MATHFN (BUILT_IN_GAMMA)
1665 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1666 CASE_MATHFN (BUILT_IN_HYPOT)
1667 CASE_MATHFN (BUILT_IN_ILOGB)
1668 CASE_MATHFN (BUILT_IN_INF)
1669 CASE_MATHFN (BUILT_IN_J0)
1670 CASE_MATHFN (BUILT_IN_J1)
1671 CASE_MATHFN (BUILT_IN_JN)
1672 CASE_MATHFN (BUILT_IN_LCEIL)
1673 CASE_MATHFN (BUILT_IN_LDEXP)
1674 CASE_MATHFN (BUILT_IN_LFLOOR)
1675 CASE_MATHFN (BUILT_IN_LGAMMA)
1676 CASE_MATHFN (BUILT_IN_LLCEIL)
1677 CASE_MATHFN (BUILT_IN_LLFLOOR)
1678 CASE_MATHFN (BUILT_IN_LLRINT)
1679 CASE_MATHFN (BUILT_IN_LLROUND)
1680 CASE_MATHFN (BUILT_IN_LOG)
1681 CASE_MATHFN (BUILT_IN_LOG10)
1682 CASE_MATHFN (BUILT_IN_LOG1P)
1683 CASE_MATHFN (BUILT_IN_LOG2)
1684 CASE_MATHFN (BUILT_IN_LOGB)
1685 CASE_MATHFN (BUILT_IN_LRINT)
1686 CASE_MATHFN (BUILT_IN_LROUND)
1687 CASE_MATHFN (BUILT_IN_MODF)
1688 CASE_MATHFN (BUILT_IN_NAN)
1689 CASE_MATHFN (BUILT_IN_NANS)
1690 CASE_MATHFN (BUILT_IN_NEARBYINT)
1691 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1693 CASE_MATHFN (BUILT_IN_POW)
1694 CASE_MATHFN (BUILT_IN_POWI)
1695 CASE_MATHFN (BUILT_IN_POW10)
1696 CASE_MATHFN (BUILT_IN_REMAINDER)
1697 CASE_MATHFN (BUILT_IN_REMQUO)
1698 CASE_MATHFN (BUILT_IN_RINT)
1699 CASE_MATHFN (BUILT_IN_ROUND)
1700 CASE_MATHFN (BUILT_IN_SCALB)
1701 CASE_MATHFN (BUILT_IN_SCALBLN)
1702 CASE_MATHFN (BUILT_IN_SCALBN)
1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1704 CASE_MATHFN (BUILT_IN_SIN)
1705 CASE_MATHFN (BUILT_IN_SINCOS)
1706 CASE_MATHFN (BUILT_IN_SINH)
1707 CASE_MATHFN (BUILT_IN_SQRT)
1708 CASE_MATHFN (BUILT_IN_TAN)
1709 CASE_MATHFN (BUILT_IN_TANH)
1710 CASE_MATHFN (BUILT_IN_TGAMMA)
1711 CASE_MATHFN (BUILT_IN_TRUNC)
1712 CASE_MATHFN (BUILT_IN_Y0)
1713 CASE_MATHFN (BUILT_IN_Y1)
1714 CASE_MATHFN (BUILT_IN_YN)
1716 default:
1717 return 0;
1720 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1721 return implicit_built_in_decls[fcode];
1722 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1723 return implicit_built_in_decls[fcodef];
1724 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1725 return implicit_built_in_decls[fcodel];
1726 else
1727 return 0;
1730 /* If errno must be maintained, expand the RTL to check if the result,
1731 TARGET, of a built-in function call, EXP, is NaN, and if so set
1732 errno to EDOM. */
1734 static void
1735 expand_errno_check (tree exp, rtx target)
1737 rtx lab = gen_label_rtx ();
1739 /* Test the result; if it is NaN, set errno=EDOM because
1740 the argument was not in the domain. */
1741 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1742 0, lab);
1744 #ifdef TARGET_EDOM
1745 /* If this built-in doesn't throw an exception, set errno directly. */
1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1748 #ifdef GEN_ERRNO_RTX
1749 rtx errno_rtx = GEN_ERRNO_RTX;
1750 #else
1751 rtx errno_rtx
1752 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1753 #endif
1754 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1755 emit_label (lab);
1756 return;
1758 #endif
1760 /* We can't set errno=EDOM directly; let the library call do it.
1761 Pop the arguments right away in case the call gets deleted. */
1762 NO_DEFER_POP;
1763 expand_call (exp, target, 0);
1764 OK_DEFER_POP;
1765 emit_label (lab);
1769 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770 Return 0 if a normal call should be emitted rather than expanding the
1771 function in-line. EXP is the expression that is a call to the builtin
1772 function; if convenient, the result should be placed in TARGET.
1773 SUBTARGET may be used as the target for computing one of EXP's operands. */
1775 static rtx
1776 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1778 optab builtin_optab;
1779 rtx op0, insns, before_call;
1780 tree fndecl = get_callee_fndecl (exp);
1781 tree arglist = TREE_OPERAND (exp, 1);
1782 enum machine_mode mode;
1783 bool errno_set = false;
1784 tree arg, narg;
1786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1787 return 0;
1789 arg = TREE_VALUE (arglist);
1791 switch (DECL_FUNCTION_CODE (fndecl))
1793 CASE_FLT_FN (BUILT_IN_SQRT):
1794 errno_set = ! tree_expr_nonnegative_p (arg);
1795 builtin_optab = sqrt_optab;
1796 break;
1797 CASE_FLT_FN (BUILT_IN_EXP):
1798 errno_set = true; builtin_optab = exp_optab; break;
1799 CASE_FLT_FN (BUILT_IN_EXP10):
1800 CASE_FLT_FN (BUILT_IN_POW10):
1801 errno_set = true; builtin_optab = exp10_optab; break;
1802 CASE_FLT_FN (BUILT_IN_EXP2):
1803 errno_set = true; builtin_optab = exp2_optab; break;
1804 CASE_FLT_FN (BUILT_IN_EXPM1):
1805 errno_set = true; builtin_optab = expm1_optab; break;
1806 CASE_FLT_FN (BUILT_IN_LOGB):
1807 errno_set = true; builtin_optab = logb_optab; break;
1808 CASE_FLT_FN (BUILT_IN_ILOGB):
1809 errno_set = true; builtin_optab = ilogb_optab; break;
1810 CASE_FLT_FN (BUILT_IN_LOG):
1811 errno_set = true; builtin_optab = log_optab; break;
1812 CASE_FLT_FN (BUILT_IN_LOG10):
1813 errno_set = true; builtin_optab = log10_optab; break;
1814 CASE_FLT_FN (BUILT_IN_LOG2):
1815 errno_set = true; builtin_optab = log2_optab; break;
1816 CASE_FLT_FN (BUILT_IN_LOG1P):
1817 errno_set = true; builtin_optab = log1p_optab; break;
1818 CASE_FLT_FN (BUILT_IN_ASIN):
1819 builtin_optab = asin_optab; break;
1820 CASE_FLT_FN (BUILT_IN_ACOS):
1821 builtin_optab = acos_optab; break;
1822 CASE_FLT_FN (BUILT_IN_TAN):
1823 builtin_optab = tan_optab; break;
1824 CASE_FLT_FN (BUILT_IN_ATAN):
1825 builtin_optab = atan_optab; break;
1826 CASE_FLT_FN (BUILT_IN_FLOOR):
1827 builtin_optab = floor_optab; break;
1828 CASE_FLT_FN (BUILT_IN_CEIL):
1829 builtin_optab = ceil_optab; break;
1830 CASE_FLT_FN (BUILT_IN_TRUNC):
1831 builtin_optab = btrunc_optab; break;
1832 CASE_FLT_FN (BUILT_IN_ROUND):
1833 builtin_optab = round_optab; break;
1834 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1835 builtin_optab = nearbyint_optab; break;
1836 CASE_FLT_FN (BUILT_IN_RINT):
1837 builtin_optab = rint_optab; break;
1838 CASE_FLT_FN (BUILT_IN_LRINT):
1839 CASE_FLT_FN (BUILT_IN_LLRINT):
1840 builtin_optab = lrint_optab; break;
1841 default:
1842 gcc_unreachable ();
1845 /* Make a suitable register to place result in. */
1846 mode = TYPE_MODE (TREE_TYPE (exp));
1848 if (! flag_errno_math || ! HONOR_NANS (mode))
1849 errno_set = false;
1851 /* Before working hard, check whether the instruction is available. */
1852 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1854 target = gen_reg_rtx (mode);
1856 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1857 need to expand the argument again. This way, we will not perform
1858 side-effects more the once. */
1859 narg = builtin_save_expr (arg);
1860 if (narg != arg)
1862 arg = narg;
1863 arglist = build_tree_list (NULL_TREE, arg);
1864 exp = build_function_call_expr (fndecl, arglist);
1867 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1869 start_sequence ();
1871 /* Compute into TARGET.
1872 Set TARGET to wherever the result comes back. */
1873 target = expand_unop (mode, builtin_optab, op0, target, 0);
1875 if (target != 0)
1877 if (errno_set)
1878 expand_errno_check (exp, target);
1880 /* Output the entire sequence. */
1881 insns = get_insns ();
1882 end_sequence ();
1883 emit_insn (insns);
1884 return target;
1887 /* If we were unable to expand via the builtin, stop the sequence
1888 (without outputting the insns) and call to the library function
1889 with the stabilized argument list. */
1890 end_sequence ();
1893 before_call = get_last_insn ();
1895 target = expand_call (exp, target, target == const0_rtx);
1897 /* If this is a sqrt operation and we don't care about errno, try to
1898 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1899 This allows the semantics of the libcall to be visible to the RTL
1900 optimizers. */
1901 if (builtin_optab == sqrt_optab && !errno_set)
1903 /* Search backwards through the insns emitted by expand_call looking
1904 for the instruction with the REG_RETVAL note. */
1905 rtx last = get_last_insn ();
1906 while (last != before_call)
1908 if (find_reg_note (last, REG_RETVAL, NULL))
1910 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1911 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1912 two elements, i.e. symbol_ref(sqrt) and the operand. */
1913 if (note
1914 && GET_CODE (note) == EXPR_LIST
1915 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1916 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1917 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1919 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1920 /* Check operand is a register with expected mode. */
1921 if (operand
1922 && REG_P (operand)
1923 && GET_MODE (operand) == mode)
1925 /* Replace the REG_EQUAL note with a SQRT rtx. */
1926 rtx equiv = gen_rtx_SQRT (mode, operand);
1927 set_unique_reg_note (last, REG_EQUAL, equiv);
1930 break;
1932 last = PREV_INSN (last);
1936 return target;
1939 /* Expand a call to the builtin binary math functions (pow and atan2).
1940 Return 0 if a normal call should be emitted rather than expanding the
1941 function in-line. EXP is the expression that is a call to the builtin
1942 function; if convenient, the result should be placed in TARGET.
1943 SUBTARGET may be used as the target for computing one of EXP's
1944 operands. */
1946 static rtx
1947 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1949 optab builtin_optab;
1950 rtx op0, op1, insns;
1951 int op1_type = REAL_TYPE;
1952 tree fndecl = get_callee_fndecl (exp);
1953 tree arglist = TREE_OPERAND (exp, 1);
1954 tree arg0, arg1, temp, narg;
1955 enum machine_mode mode;
1956 bool errno_set = true;
1957 bool stable = true;
1959 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1960 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1961 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1962 op1_type = INTEGER_TYPE;
1964 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1965 return 0;
1967 arg0 = TREE_VALUE (arglist);
1968 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1970 switch (DECL_FUNCTION_CODE (fndecl))
1972 CASE_FLT_FN (BUILT_IN_POW):
1973 builtin_optab = pow_optab; break;
1974 CASE_FLT_FN (BUILT_IN_ATAN2):
1975 builtin_optab = atan2_optab; break;
1976 CASE_FLT_FN (BUILT_IN_LDEXP):
1977 builtin_optab = ldexp_optab; break;
1978 CASE_FLT_FN (BUILT_IN_FMOD):
1979 builtin_optab = fmod_optab; break;
1980 CASE_FLT_FN (BUILT_IN_DREM):
1981 builtin_optab = drem_optab; break;
1982 default:
1983 gcc_unreachable ();
1986 /* Make a suitable register to place result in. */
1987 mode = TYPE_MODE (TREE_TYPE (exp));
1989 /* Before working hard, check whether the instruction is available. */
1990 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1991 return 0;
1993 target = gen_reg_rtx (mode);
1995 if (! flag_errno_math || ! HONOR_NANS (mode))
1996 errno_set = false;
1998 /* Always stabilize the argument list. */
1999 narg = builtin_save_expr (arg1);
2000 if (narg != arg1)
2002 arg1 = narg;
2003 temp = build_tree_list (NULL_TREE, narg);
2004 stable = false;
2006 else
2007 temp = TREE_CHAIN (arglist);
2009 narg = builtin_save_expr (arg0);
2010 if (narg != arg0)
2012 arg0 = narg;
2013 arglist = tree_cons (NULL_TREE, narg, temp);
2014 stable = false;
2016 else if (! stable)
2017 arglist = tree_cons (NULL_TREE, arg0, temp);
2019 if (! stable)
2020 exp = build_function_call_expr (fndecl, arglist);
2022 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2023 op1 = expand_normal (arg1);
2025 start_sequence ();
2027 /* Compute into TARGET.
2028 Set TARGET to wherever the result comes back. */
2029 target = expand_binop (mode, builtin_optab, op0, op1,
2030 target, 0, OPTAB_DIRECT);
2032 /* If we were unable to expand via the builtin, stop the sequence
2033 (without outputting the insns) and call to the library function
2034 with the stabilized argument list. */
2035 if (target == 0)
2037 end_sequence ();
2038 return expand_call (exp, target, target == const0_rtx);
2041 if (errno_set)
2042 expand_errno_check (exp, target);
2044 /* Output the entire sequence. */
2045 insns = get_insns ();
2046 end_sequence ();
2047 emit_insn (insns);
2049 return target;
2052 /* Expand a call to the builtin sin and cos math functions.
2053 Return 0 if a normal call should be emitted rather than expanding the
2054 function in-line. EXP is the expression that is a call to the builtin
2055 function; if convenient, the result should be placed in TARGET.
2056 SUBTARGET may be used as the target for computing one of EXP's
2057 operands. */
2059 static rtx
2060 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2062 optab builtin_optab;
2063 rtx op0, insns;
2064 tree fndecl = get_callee_fndecl (exp);
2065 tree arglist = TREE_OPERAND (exp, 1);
2066 enum machine_mode mode;
2067 tree arg, narg;
2069 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2070 return 0;
2072 arg = TREE_VALUE (arglist);
2074 switch (DECL_FUNCTION_CODE (fndecl))
2076 CASE_FLT_FN (BUILT_IN_SIN):
2077 CASE_FLT_FN (BUILT_IN_COS):
2078 builtin_optab = sincos_optab; break;
2079 default:
2080 gcc_unreachable ();
2083 /* Make a suitable register to place result in. */
2084 mode = TYPE_MODE (TREE_TYPE (exp));
2086 /* Check if sincos insn is available, otherwise fallback
2087 to sin or cos insn. */
2088 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2089 switch (DECL_FUNCTION_CODE (fndecl))
2091 CASE_FLT_FN (BUILT_IN_SIN):
2092 builtin_optab = sin_optab; break;
2093 CASE_FLT_FN (BUILT_IN_COS):
2094 builtin_optab = cos_optab; break;
2095 default:
2096 gcc_unreachable ();
2100 /* Before working hard, check whether the instruction is available. */
2101 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2103 target = gen_reg_rtx (mode);
2105 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2106 need to expand the argument again. This way, we will not perform
2107 side-effects more the once. */
2108 narg = save_expr (arg);
2109 if (narg != arg)
2111 arg = narg;
2112 arglist = build_tree_list (NULL_TREE, arg);
2113 exp = build_function_call_expr (fndecl, arglist);
2116 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2118 start_sequence ();
2120 /* Compute into TARGET.
2121 Set TARGET to wherever the result comes back. */
2122 if (builtin_optab == sincos_optab)
2124 int result;
2126 switch (DECL_FUNCTION_CODE (fndecl))
2128 CASE_FLT_FN (BUILT_IN_SIN):
2129 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2130 break;
2131 CASE_FLT_FN (BUILT_IN_COS):
2132 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2133 break;
2134 default:
2135 gcc_unreachable ();
2137 gcc_assert (result);
2139 else
2141 target = expand_unop (mode, builtin_optab, op0, target, 0);
2144 if (target != 0)
2146 /* Output the entire sequence. */
2147 insns = get_insns ();
2148 end_sequence ();
2149 emit_insn (insns);
2150 return target;
2153 /* If we were unable to expand via the builtin, stop the sequence
2154 (without outputting the insns) and call to the library function
2155 with the stabilized argument list. */
2156 end_sequence ();
2159 target = expand_call (exp, target, target == const0_rtx);
2161 return target;
2164 /* Expand a call to the builtin sincos math function.
2165 Return 0 if a normal call should be emitted rather than expanding the
2166 function in-line. EXP is the expression that is a call to the builtin
2167 function. */
2169 static rtx
2170 expand_builtin_sincos (tree exp)
2172 rtx op0, op1, op2, target1, target2;
2173 tree arglist = TREE_OPERAND (exp, 1);
2174 enum machine_mode mode;
2175 tree arg, sinp, cosp;
2176 int result;
2178 if (!validate_arglist (arglist, REAL_TYPE,
2179 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2180 return 0;
2182 arg = TREE_VALUE (arglist);
2183 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2184 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2186 /* Make a suitable register to place result in. */
2187 mode = TYPE_MODE (TREE_TYPE (arg));
2189 /* Check if sincos insn is available, otherwise emit the call. */
2190 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2191 return NULL_RTX;
2193 target1 = gen_reg_rtx (mode);
2194 target2 = gen_reg_rtx (mode);
2196 op0 = expand_normal (arg);
2197 op1 = expand_normal (build_fold_indirect_ref (sinp));
2198 op2 = expand_normal (build_fold_indirect_ref (cosp));
2200 /* Compute into target1 and target2.
2201 Set TARGET to wherever the result comes back. */
2202 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2203 gcc_assert (result);
2205 /* Move target1 and target2 to the memory locations indicated
2206 by op1 and op2. */
2207 emit_move_insn (op1, target1);
2208 emit_move_insn (op2, target2);
2210 return const0_rtx;
2213 /* Expand a call to one of the builtin rounding functions (lfloor).
2214 If expanding via optab fails, lower expression to (int)(floor(x)).
2215 EXP is the expression that is a call to the builtin function;
2216 if convenient, the result should be placed in TARGET. SUBTARGET may
2217 be used as the target for computing one of EXP's operands. */
2219 static rtx
2220 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2222 optab builtin_optab;
2223 rtx op0, insns, tmp;
2224 tree fndecl = get_callee_fndecl (exp);
2225 tree arglist = TREE_OPERAND (exp, 1);
2226 enum built_in_function fallback_fn;
2227 tree fallback_fndecl;
2228 enum machine_mode mode;
2229 tree arg, narg;
2231 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2232 gcc_unreachable ();
2234 arg = TREE_VALUE (arglist);
2236 switch (DECL_FUNCTION_CODE (fndecl))
2238 CASE_FLT_FN (BUILT_IN_LCEIL):
2239 CASE_FLT_FN (BUILT_IN_LLCEIL):
2240 builtin_optab = lceil_optab;
2241 fallback_fn = BUILT_IN_CEIL;
2242 break;
2244 CASE_FLT_FN (BUILT_IN_LFLOOR):
2245 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2246 builtin_optab = lfloor_optab;
2247 fallback_fn = BUILT_IN_FLOOR;
2248 break;
2250 default:
2251 gcc_unreachable ();
2254 /* Make a suitable register to place result in. */
2255 mode = TYPE_MODE (TREE_TYPE (exp));
2257 /* Before working hard, check whether the instruction is available. */
2258 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2260 target = gen_reg_rtx (mode);
2262 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2263 need to expand the argument again. This way, we will not perform
2264 side-effects more the once. */
2265 narg = builtin_save_expr (arg);
2266 if (narg != arg)
2268 arg = narg;
2269 arglist = build_tree_list (NULL_TREE, arg);
2270 exp = build_function_call_expr (fndecl, arglist);
2273 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2275 start_sequence ();
2277 /* Compute into TARGET.
2278 Set TARGET to wherever the result comes back. */
2279 target = expand_unop (mode, builtin_optab, op0, target, 0);
2281 if (target != 0)
2283 /* Output the entire sequence. */
2284 insns = get_insns ();
2285 end_sequence ();
2286 emit_insn (insns);
2287 return target;
2290 /* If we were unable to expand via the builtin, stop the sequence
2291 (without outputting the insns). */
2292 end_sequence ();
2295 /* Fall back to floating point rounding optab. */
2296 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2297 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2298 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2299 gcc_assert (fallback_fndecl != NULL_TREE);
2300 exp = build_function_call_expr (fallback_fndecl, arglist);
2302 tmp = expand_normal (exp);
2304 /* Truncate the result of floating point optab to integer
2305 via expand_fix (). */
2306 target = gen_reg_rtx (mode);
2307 expand_fix (target, tmp, 0);
2309 return target;
2312 /* To evaluate powi(x,n), the floating point value x raised to the
2313 constant integer exponent n, we use a hybrid algorithm that
2314 combines the "window method" with look-up tables. For an
2315 introduction to exponentiation algorithms and "addition chains",
2316 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2317 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2318 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2319 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2321 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2322 multiplications to inline before calling the system library's pow
2323 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2324 so this default never requires calling pow, powf or powl. */
2326 #ifndef POWI_MAX_MULTS
2327 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2328 #endif
2330 /* The size of the "optimal power tree" lookup table. All
2331 exponents less than this value are simply looked up in the
2332 powi_table below. This threshold is also used to size the
2333 cache of pseudo registers that hold intermediate results. */
2334 #define POWI_TABLE_SIZE 256
2336 /* The size, in bits of the window, used in the "window method"
2337 exponentiation algorithm. This is equivalent to a radix of
2338 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2339 #define POWI_WINDOW_SIZE 3
2341 /* The following table is an efficient representation of an
2342 "optimal power tree". For each value, i, the corresponding
2343 value, j, in the table states than an optimal evaluation
2344 sequence for calculating pow(x,i) can be found by evaluating
2345 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2346 100 integers is given in Knuth's "Seminumerical algorithms". */
2348 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2350 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2351 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2352 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2353 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2354 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2355 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2356 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2357 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2358 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2359 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2360 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2361 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2362 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2363 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2364 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2365 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2366 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2367 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2368 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2369 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2370 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2371 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2372 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2373 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2374 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2375 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2376 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2377 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2378 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2379 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2380 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2381 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2385 /* Return the number of multiplications required to calculate
2386 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2387 subroutine of powi_cost. CACHE is an array indicating
2388 which exponents have already been calculated. */
2390 static int
2391 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2393 /* If we've already calculated this exponent, then this evaluation
2394 doesn't require any additional multiplications. */
2395 if (cache[n])
2396 return 0;
2398 cache[n] = true;
2399 return powi_lookup_cost (n - powi_table[n], cache)
2400 + powi_lookup_cost (powi_table[n], cache) + 1;
2403 /* Return the number of multiplications required to calculate
2404 powi(x,n) for an arbitrary x, given the exponent N. This
2405 function needs to be kept in sync with expand_powi below. */
2407 static int
2408 powi_cost (HOST_WIDE_INT n)
2410 bool cache[POWI_TABLE_SIZE];
2411 unsigned HOST_WIDE_INT digit;
2412 unsigned HOST_WIDE_INT val;
2413 int result;
2415 if (n == 0)
2416 return 0;
2418 /* Ignore the reciprocal when calculating the cost. */
2419 val = (n < 0) ? -n : n;
2421 /* Initialize the exponent cache. */
2422 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2423 cache[1] = true;
2425 result = 0;
2427 while (val >= POWI_TABLE_SIZE)
2429 if (val & 1)
2431 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2432 result += powi_lookup_cost (digit, cache)
2433 + POWI_WINDOW_SIZE + 1;
2434 val >>= POWI_WINDOW_SIZE;
2436 else
2438 val >>= 1;
2439 result++;
2443 return result + powi_lookup_cost (val, cache);
2446 /* Recursive subroutine of expand_powi. This function takes the array,
2447 CACHE, of already calculated exponents and an exponent N and returns
2448 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2450 static rtx
2451 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2453 unsigned HOST_WIDE_INT digit;
2454 rtx target, result;
2455 rtx op0, op1;
2457 if (n < POWI_TABLE_SIZE)
2459 if (cache[n])
2460 return cache[n];
2462 target = gen_reg_rtx (mode);
2463 cache[n] = target;
2465 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2466 op1 = expand_powi_1 (mode, powi_table[n], cache);
2468 else if (n & 1)
2470 target = gen_reg_rtx (mode);
2471 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2472 op0 = expand_powi_1 (mode, n - digit, cache);
2473 op1 = expand_powi_1 (mode, digit, cache);
2475 else
2477 target = gen_reg_rtx (mode);
2478 op0 = expand_powi_1 (mode, n >> 1, cache);
2479 op1 = op0;
2482 result = expand_mult (mode, op0, op1, target, 0);
2483 if (result != target)
2484 emit_move_insn (target, result);
2485 return target;
2488 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2489 floating point operand in mode MODE, and N is the exponent. This
2490 function needs to be kept in sync with powi_cost above. */
2492 static rtx
2493 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2495 unsigned HOST_WIDE_INT val;
2496 rtx cache[POWI_TABLE_SIZE];
2497 rtx result;
2499 if (n == 0)
2500 return CONST1_RTX (mode);
2502 val = (n < 0) ? -n : n;
2504 memset (cache, 0, sizeof (cache));
2505 cache[1] = x;
2507 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2509 /* If the original exponent was negative, reciprocate the result. */
2510 if (n < 0)
2511 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2512 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2514 return result;
2517 /* Expand a call to the pow built-in mathematical function. Return 0 if
2518 a normal call should be emitted rather than expanding the function
2519 in-line. EXP is the expression that is a call to the builtin
2520 function; if convenient, the result should be placed in TARGET. */
2522 static rtx
2523 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2525 tree arglist = TREE_OPERAND (exp, 1);
2526 tree arg0, arg1;
2528 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2529 return 0;
2531 arg0 = TREE_VALUE (arglist);
2532 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2534 if (TREE_CODE (arg1) == REAL_CST
2535 && ! TREE_CONSTANT_OVERFLOW (arg1))
2537 REAL_VALUE_TYPE cint;
2538 REAL_VALUE_TYPE c;
2539 HOST_WIDE_INT n;
2541 c = TREE_REAL_CST (arg1);
2542 n = real_to_integer (&c);
2543 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2544 if (real_identical (&c, &cint))
2546 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2547 Otherwise, check the number of multiplications required.
2548 Note that pow never sets errno for an integer exponent. */
2549 if ((n >= -1 && n <= 2)
2550 || (flag_unsafe_math_optimizations
2551 && ! optimize_size
2552 && powi_cost (n) <= POWI_MAX_MULTS))
2554 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2555 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2556 op = force_reg (mode, op);
2557 return expand_powi (op, mode, n);
2562 if (! flag_unsafe_math_optimizations)
2563 return NULL_RTX;
2564 return expand_builtin_mathfn_2 (exp, target, subtarget);
2567 /* Expand a call to the powi built-in mathematical function. Return 0 if
2568 a normal call should be emitted rather than expanding the function
2569 in-line. EXP is the expression that is a call to the builtin
2570 function; if convenient, the result should be placed in TARGET. */
2572 static rtx
2573 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2575 tree arglist = TREE_OPERAND (exp, 1);
2576 tree arg0, arg1;
2577 rtx op0, op1;
2578 enum machine_mode mode;
2579 enum machine_mode mode2;
2581 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2582 return 0;
2584 arg0 = TREE_VALUE (arglist);
2585 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2586 mode = TYPE_MODE (TREE_TYPE (exp));
2588 /* Handle constant power. */
2590 if (TREE_CODE (arg1) == INTEGER_CST
2591 && ! TREE_CONSTANT_OVERFLOW (arg1))
2593 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2595 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2596 Otherwise, check the number of multiplications required. */
2597 if ((TREE_INT_CST_HIGH (arg1) == 0
2598 || TREE_INT_CST_HIGH (arg1) == -1)
2599 && ((n >= -1 && n <= 2)
2600 || (! optimize_size
2601 && powi_cost (n) <= POWI_MAX_MULTS)))
2603 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2604 op0 = force_reg (mode, op0);
2605 return expand_powi (op0, mode, n);
2609 /* Emit a libcall to libgcc. */
2611 /* Mode of the 2nd argument must match that of an int. */
2612 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2614 if (target == NULL_RTX)
2615 target = gen_reg_rtx (mode);
2617 op0 = expand_expr (arg0, subtarget, mode, 0);
2618 if (GET_MODE (op0) != mode)
2619 op0 = convert_to_mode (mode, op0, 0);
2620 op1 = expand_expr (arg1, 0, mode2, 0);
2621 if (GET_MODE (op1) != mode2)
2622 op1 = convert_to_mode (mode2, op1, 0);
2624 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2625 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2626 op0, mode, op1, mode2);
2628 return target;
2631 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2632 if we failed the caller should emit a normal call, otherwise
2633 try to get the result in TARGET, if convenient. */
2635 static rtx
2636 expand_builtin_strlen (tree arglist, rtx target,
2637 enum machine_mode target_mode)
2639 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2640 return 0;
2641 else
2643 rtx pat;
2644 tree len, src = TREE_VALUE (arglist);
2645 rtx result, src_reg, char_rtx, before_strlen;
2646 enum machine_mode insn_mode = target_mode, char_mode;
2647 enum insn_code icode = CODE_FOR_nothing;
2648 int align;
2650 /* If the length can be computed at compile-time, return it. */
2651 len = c_strlen (src, 0);
2652 if (len)
2653 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2655 /* If the length can be computed at compile-time and is constant
2656 integer, but there are side-effects in src, evaluate
2657 src for side-effects, then return len.
2658 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2659 can be optimized into: i++; x = 3; */
2660 len = c_strlen (src, 1);
2661 if (len && TREE_CODE (len) == INTEGER_CST)
2663 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2664 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2667 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2669 /* If SRC is not a pointer type, don't do this operation inline. */
2670 if (align == 0)
2671 return 0;
2673 /* Bail out if we can't compute strlen in the right mode. */
2674 while (insn_mode != VOIDmode)
2676 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2677 if (icode != CODE_FOR_nothing)
2678 break;
2680 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2682 if (insn_mode == VOIDmode)
2683 return 0;
2685 /* Make a place to write the result of the instruction. */
2686 result = target;
2687 if (! (result != 0
2688 && REG_P (result)
2689 && GET_MODE (result) == insn_mode
2690 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2691 result = gen_reg_rtx (insn_mode);
2693 /* Make a place to hold the source address. We will not expand
2694 the actual source until we are sure that the expansion will
2695 not fail -- there are trees that cannot be expanded twice. */
2696 src_reg = gen_reg_rtx (Pmode);
2698 /* Mark the beginning of the strlen sequence so we can emit the
2699 source operand later. */
2700 before_strlen = get_last_insn ();
2702 char_rtx = const0_rtx;
2703 char_mode = insn_data[(int) icode].operand[2].mode;
2704 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2705 char_mode))
2706 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2708 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2709 char_rtx, GEN_INT (align));
2710 if (! pat)
2711 return 0;
2712 emit_insn (pat);
2714 /* Now that we are assured of success, expand the source. */
2715 start_sequence ();
2716 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2717 if (pat != src_reg)
2718 emit_move_insn (src_reg, pat);
2719 pat = get_insns ();
2720 end_sequence ();
2722 if (before_strlen)
2723 emit_insn_after (pat, before_strlen);
2724 else
2725 emit_insn_before (pat, get_insns ());
2727 /* Return the value in the proper mode for this function. */
2728 if (GET_MODE (result) == target_mode)
2729 target = result;
2730 else if (target != 0)
2731 convert_move (target, result, 0);
2732 else
2733 target = convert_to_mode (target_mode, result, 0);
2735 return target;
2739 /* Expand a call to the strstr builtin. Return 0 if we failed the
2740 caller should emit a normal call, otherwise try to get the result
2741 in TARGET, if convenient (and in mode MODE if that's convenient). */
2743 static rtx
2744 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2746 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2748 tree result = fold_builtin_strstr (arglist, type);
2749 if (result)
2750 return expand_expr (result, target, mode, EXPAND_NORMAL);
2752 return 0;
2755 /* Expand a call to the strchr builtin. Return 0 if we failed the
2756 caller should emit a normal call, otherwise try to get the result
2757 in TARGET, if convenient (and in mode MODE if that's convenient). */
2759 static rtx
2760 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2762 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2764 tree result = fold_builtin_strchr (arglist, type);
2765 if (result)
2766 return expand_expr (result, target, mode, EXPAND_NORMAL);
2768 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2770 return 0;
2773 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2774 caller should emit a normal call, otherwise try to get the result
2775 in TARGET, if convenient (and in mode MODE if that's convenient). */
2777 static rtx
2778 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2780 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2782 tree result = fold_builtin_strrchr (arglist, type);
2783 if (result)
2784 return expand_expr (result, target, mode, EXPAND_NORMAL);
2786 return 0;
2789 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2790 caller should emit a normal call, otherwise try to get the result
2791 in TARGET, if convenient (and in mode MODE if that's convenient). */
2793 static rtx
2794 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2796 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2798 tree result = fold_builtin_strpbrk (arglist, type);
2799 if (result)
2800 return expand_expr (result, target, mode, EXPAND_NORMAL);
2802 return 0;
2805 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2806 bytes from constant string DATA + OFFSET and return it as target
2807 constant. */
2809 static rtx
2810 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2811 enum machine_mode mode)
2813 const char *str = (const char *) data;
2815 gcc_assert (offset >= 0
2816 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2817 <= strlen (str) + 1));
2819 return c_readstr (str + offset, mode);
2822 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2823 Return 0 if we failed, the caller should emit a normal call,
2824 otherwise try to get the result in TARGET, if convenient (and in
2825 mode MODE if that's convenient). */
2826 static rtx
2827 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2829 tree fndecl = get_callee_fndecl (exp);
2830 tree arglist = TREE_OPERAND (exp, 1);
2831 if (!validate_arglist (arglist,
2832 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2833 return 0;
2834 else
2836 tree dest = TREE_VALUE (arglist);
2837 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2838 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2839 const char *src_str;
2840 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2841 unsigned int dest_align
2842 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2843 rtx dest_mem, src_mem, dest_addr, len_rtx;
2844 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2845 false, /*endp=*/0);
2847 if (result)
2849 while (TREE_CODE (result) == COMPOUND_EXPR)
2851 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2852 EXPAND_NORMAL);
2853 result = TREE_OPERAND (result, 1);
2855 return expand_expr (result, target, mode, EXPAND_NORMAL);
2858 /* If DEST is not a pointer type, call the normal function. */
2859 if (dest_align == 0)
2860 return 0;
2862 /* If either SRC is not a pointer type, don't do this
2863 operation in-line. */
2864 if (src_align == 0)
2865 return 0;
2867 dest_mem = get_memory_rtx (dest, len);
2868 set_mem_align (dest_mem, dest_align);
2869 len_rtx = expand_normal (len);
2870 src_str = c_getstr (src);
2872 /* If SRC is a string constant and block move would be done
2873 by pieces, we can avoid loading the string from memory
2874 and only stored the computed constants. */
2875 if (src_str
2876 && GET_CODE (len_rtx) == CONST_INT
2877 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2878 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2879 (void *) src_str, dest_align))
2881 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2882 builtin_memcpy_read_str,
2883 (void *) src_str, dest_align, 0);
2884 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2885 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2886 return dest_mem;
2889 src_mem = get_memory_rtx (src, len);
2890 set_mem_align (src_mem, src_align);
2892 /* Copy word part most expediently. */
2893 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2894 CALL_EXPR_TAILCALL (exp)
2895 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2897 if (dest_addr == 0)
2899 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2900 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2902 return dest_addr;
2906 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2907 Return 0 if we failed; the caller should emit a normal call,
2908 otherwise try to get the result in TARGET, if convenient (and in
2909 mode MODE if that's convenient). If ENDP is 0 return the
2910 destination pointer, if ENDP is 1 return the end pointer ala
2911 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2912 stpcpy. */
2914 static rtx
2915 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2916 int endp)
2918 if (!validate_arglist (arglist,
2919 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2920 return 0;
2921 /* If return value is ignored, transform mempcpy into memcpy. */
2922 else if (target == const0_rtx)
2924 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2926 if (!fn)
2927 return 0;
2929 return expand_expr (build_function_call_expr (fn, arglist),
2930 target, mode, EXPAND_NORMAL);
2932 else
2934 tree dest = TREE_VALUE (arglist);
2935 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2936 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2937 const char *src_str;
2938 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2939 unsigned int dest_align
2940 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2941 rtx dest_mem, src_mem, len_rtx;
2942 tree result = fold_builtin_memory_op (arglist, type, false, endp);
2944 if (result)
2946 while (TREE_CODE (result) == COMPOUND_EXPR)
2948 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2949 EXPAND_NORMAL);
2950 result = TREE_OPERAND (result, 1);
2952 return expand_expr (result, target, mode, EXPAND_NORMAL);
2955 /* If either SRC or DEST is not a pointer type, don't do this
2956 operation in-line. */
2957 if (dest_align == 0 || src_align == 0)
2958 return 0;
2960 /* If LEN is not constant, call the normal function. */
2961 if (! host_integerp (len, 1))
2962 return 0;
2964 len_rtx = expand_normal (len);
2965 src_str = c_getstr (src);
2967 /* If SRC is a string constant and block move would be done
2968 by pieces, we can avoid loading the string from memory
2969 and only stored the computed constants. */
2970 if (src_str
2971 && GET_CODE (len_rtx) == CONST_INT
2972 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2973 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2974 (void *) src_str, dest_align))
2976 dest_mem = get_memory_rtx (dest, len);
2977 set_mem_align (dest_mem, dest_align);
2978 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2979 builtin_memcpy_read_str,
2980 (void *) src_str, dest_align, endp);
2981 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2982 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2983 return dest_mem;
2986 if (GET_CODE (len_rtx) == CONST_INT
2987 && can_move_by_pieces (INTVAL (len_rtx),
2988 MIN (dest_align, src_align)))
2990 dest_mem = get_memory_rtx (dest, len);
2991 set_mem_align (dest_mem, dest_align);
2992 src_mem = get_memory_rtx (src, len);
2993 set_mem_align (src_mem, src_align);
2994 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2995 MIN (dest_align, src_align), endp);
2996 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2997 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2998 return dest_mem;
3001 return 0;
3005 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3006 if we failed; the caller should emit a normal call. */
3008 static rtx
3009 expand_builtin_memmove (tree arglist, tree type, rtx target,
3010 enum machine_mode mode, tree orig_exp)
3012 if (!validate_arglist (arglist,
3013 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3014 return 0;
3015 else
3017 tree dest = TREE_VALUE (arglist);
3018 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3019 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3021 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3022 unsigned int dest_align
3023 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3024 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3026 if (result)
3028 while (TREE_CODE (result) == COMPOUND_EXPR)
3030 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3031 EXPAND_NORMAL);
3032 result = TREE_OPERAND (result, 1);
3034 return expand_expr (result, target, mode, EXPAND_NORMAL);
3037 /* If DEST is not a pointer type, call the normal function. */
3038 if (dest_align == 0)
3039 return 0;
3041 /* If either SRC is not a pointer type, don't do this
3042 operation in-line. */
3043 if (src_align == 0)
3044 return 0;
3046 /* If src is categorized for a readonly section we can use
3047 normal memcpy. */
3048 if (readonly_data_expr (src))
3050 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3051 if (!fn)
3052 return 0;
3053 fn = build_function_call_expr (fn, arglist);
3054 if (TREE_CODE (fn) == CALL_EXPR)
3055 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3056 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3059 /* If length is 1 and we can expand memcpy call inline,
3060 it is ok to use memcpy as well. */
3061 if (integer_onep (len))
3063 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3064 /*endp=*/0);
3065 if (ret)
3066 return ret;
3069 /* Otherwise, call the normal function. */
3070 return 0;
3074 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3075 if we failed the caller should emit a normal call. */
3077 static rtx
3078 expand_builtin_bcopy (tree exp)
3080 tree arglist = TREE_OPERAND (exp, 1);
3081 tree type = TREE_TYPE (exp);
3082 tree src, dest, size, newarglist;
3084 if (!validate_arglist (arglist,
3085 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3086 return NULL_RTX;
3088 src = TREE_VALUE (arglist);
3089 dest = TREE_VALUE (TREE_CHAIN (arglist));
3090 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3092 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3093 memmove(ptr y, ptr x, size_t z). This is done this way
3094 so that if it isn't expanded inline, we fallback to
3095 calling bcopy instead of memmove. */
3097 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3098 newarglist = tree_cons (NULL_TREE, src, newarglist);
3099 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3101 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3104 #ifndef HAVE_movstr
3105 # define HAVE_movstr 0
3106 # define CODE_FOR_movstr CODE_FOR_nothing
3107 #endif
3109 /* Expand into a movstr instruction, if one is available. Return 0 if
3110 we failed, the caller should emit a normal call, otherwise try to
3111 get the result in TARGET, if convenient. If ENDP is 0 return the
3112 destination pointer, if ENDP is 1 return the end pointer ala
3113 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3114 stpcpy. */
3116 static rtx
3117 expand_movstr (tree dest, tree src, rtx target, int endp)
3119 rtx end;
3120 rtx dest_mem;
3121 rtx src_mem;
3122 rtx insn;
3123 const struct insn_data * data;
3125 if (!HAVE_movstr)
3126 return 0;
3128 dest_mem = get_memory_rtx (dest, NULL);
3129 src_mem = get_memory_rtx (src, NULL);
3130 if (!endp)
3132 target = force_reg (Pmode, XEXP (dest_mem, 0));
3133 dest_mem = replace_equiv_address (dest_mem, target);
3134 end = gen_reg_rtx (Pmode);
3136 else
3138 if (target == 0 || target == const0_rtx)
3140 end = gen_reg_rtx (Pmode);
3141 if (target == 0)
3142 target = end;
3144 else
3145 end = target;
3148 data = insn_data + CODE_FOR_movstr;
3150 if (data->operand[0].mode != VOIDmode)
3151 end = gen_lowpart (data->operand[0].mode, end);
3153 insn = data->genfun (end, dest_mem, src_mem);
3155 gcc_assert (insn);
3157 emit_insn (insn);
3159 /* movstr is supposed to set end to the address of the NUL
3160 terminator. If the caller requested a mempcpy-like return value,
3161 adjust it. */
3162 if (endp == 1 && target != const0_rtx)
3164 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3165 emit_move_insn (target, force_operand (tem, NULL_RTX));
3168 return target;
3171 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3172 if we failed the caller should emit a normal call, otherwise try to get
3173 the result in TARGET, if convenient (and in mode MODE if that's
3174 convenient). */
3176 static rtx
3177 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3179 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3181 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3182 if (result)
3184 while (TREE_CODE (result) == COMPOUND_EXPR)
3186 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3187 EXPAND_NORMAL);
3188 result = TREE_OPERAND (result, 1);
3190 return expand_expr (result, target, mode, EXPAND_NORMAL);
3193 return expand_movstr (TREE_VALUE (arglist),
3194 TREE_VALUE (TREE_CHAIN (arglist)),
3195 target, /*endp=*/0);
3197 return 0;
3200 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3201 Return 0 if we failed the caller should emit a normal call,
3202 otherwise try to get the result in TARGET, if convenient (and in
3203 mode MODE if that's convenient). */
3205 static rtx
3206 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3208 tree arglist = TREE_OPERAND (exp, 1);
3209 /* If return value is ignored, transform stpcpy into strcpy. */
3210 if (target == const0_rtx)
3212 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3213 if (!fn)
3214 return 0;
3216 return expand_expr (build_function_call_expr (fn, arglist),
3217 target, mode, EXPAND_NORMAL);
3220 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3221 return 0;
3222 else
3224 tree dst, src, len, lenp1;
3225 tree narglist;
3226 rtx ret;
3228 /* Ensure we get an actual string whose length can be evaluated at
3229 compile-time, not an expression containing a string. This is
3230 because the latter will potentially produce pessimized code
3231 when used to produce the return value. */
3232 src = TREE_VALUE (TREE_CHAIN (arglist));
3233 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3234 return expand_movstr (TREE_VALUE (arglist),
3235 TREE_VALUE (TREE_CHAIN (arglist)),
3236 target, /*endp=*/2);
3238 dst = TREE_VALUE (arglist);
3239 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3240 narglist = build_tree_list (NULL_TREE, lenp1);
3241 narglist = tree_cons (NULL_TREE, src, narglist);
3242 narglist = tree_cons (NULL_TREE, dst, narglist);
3243 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3244 target, mode, /*endp=*/2);
3246 if (ret)
3247 return ret;
3249 if (TREE_CODE (len) == INTEGER_CST)
3251 rtx len_rtx = expand_normal (len);
3253 if (GET_CODE (len_rtx) == CONST_INT)
3255 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3256 arglist, target, mode);
3258 if (ret)
3260 if (! target)
3262 if (mode != VOIDmode)
3263 target = gen_reg_rtx (mode);
3264 else
3265 target = gen_reg_rtx (GET_MODE (ret));
3267 if (GET_MODE (target) != GET_MODE (ret))
3268 ret = gen_lowpart (GET_MODE (target), ret);
3270 ret = plus_constant (ret, INTVAL (len_rtx));
3271 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3272 gcc_assert (ret);
3274 return target;
3279 return expand_movstr (TREE_VALUE (arglist),
3280 TREE_VALUE (TREE_CHAIN (arglist)),
3281 target, /*endp=*/2);
3285 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3286 bytes from constant string DATA + OFFSET and return it as target
3287 constant. */
3289 static rtx
3290 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3291 enum machine_mode mode)
3293 const char *str = (const char *) data;
3295 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3296 return const0_rtx;
3298 return c_readstr (str + offset, mode);
3301 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3302 if we failed the caller should emit a normal call. */
3304 static rtx
3305 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3307 tree fndecl = get_callee_fndecl (exp);
3308 tree arglist = TREE_OPERAND (exp, 1);
3309 if (validate_arglist (arglist,
3310 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3312 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3313 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3314 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3316 if (result)
3318 while (TREE_CODE (result) == COMPOUND_EXPR)
3320 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3321 EXPAND_NORMAL);
3322 result = TREE_OPERAND (result, 1);
3324 return expand_expr (result, target, mode, EXPAND_NORMAL);
3327 /* We must be passed a constant len and src parameter. */
3328 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3329 return 0;
3331 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3333 /* We're required to pad with trailing zeros if the requested
3334 len is greater than strlen(s2)+1. In that case try to
3335 use store_by_pieces, if it fails, punt. */
3336 if (tree_int_cst_lt (slen, len))
3338 tree dest = TREE_VALUE (arglist);
3339 unsigned int dest_align
3340 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3341 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3342 rtx dest_mem;
3344 if (!p || dest_align == 0 || !host_integerp (len, 1)
3345 || !can_store_by_pieces (tree_low_cst (len, 1),
3346 builtin_strncpy_read_str,
3347 (void *) p, dest_align))
3348 return 0;
3350 dest_mem = get_memory_rtx (dest, len);
3351 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3352 builtin_strncpy_read_str,
3353 (void *) p, dest_align, 0);
3354 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3355 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3356 return dest_mem;
3359 return 0;
3362 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3363 bytes from constant string DATA + OFFSET and return it as target
3364 constant. */
3366 static rtx
3367 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3368 enum machine_mode mode)
3370 const char *c = (const char *) data;
3371 char *p = alloca (GET_MODE_SIZE (mode));
3373 memset (p, *c, GET_MODE_SIZE (mode));
3375 return c_readstr (p, mode);
3378 /* Callback routine for store_by_pieces. Return the RTL of a register
3379 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3380 char value given in the RTL register data. For example, if mode is
3381 4 bytes wide, return the RTL for 0x01010101*data. */
3383 static rtx
3384 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3385 enum machine_mode mode)
3387 rtx target, coeff;
3388 size_t size;
3389 char *p;
3391 size = GET_MODE_SIZE (mode);
3392 if (size == 1)
3393 return (rtx) data;
3395 p = alloca (size);
3396 memset (p, 1, size);
3397 coeff = c_readstr (p, mode);
3399 target = convert_to_mode (mode, (rtx) data, 1);
3400 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3401 return force_reg (mode, target);
3404 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3405 if we failed the caller should emit a normal call, otherwise try to get
3406 the result in TARGET, if convenient (and in mode MODE if that's
3407 convenient). */
3409 static rtx
3410 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3411 tree orig_exp)
3413 if (!validate_arglist (arglist,
3414 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3415 return 0;
3416 else
3418 tree dest = TREE_VALUE (arglist);
3419 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3420 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3421 tree fndecl, fn;
3422 enum built_in_function fcode;
3423 char c;
3424 unsigned int dest_align;
3425 rtx dest_mem, dest_addr, len_rtx;
3427 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3429 /* If DEST is not a pointer type, don't do this
3430 operation in-line. */
3431 if (dest_align == 0)
3432 return 0;
3434 /* If the LEN parameter is zero, return DEST. */
3435 if (integer_zerop (len))
3437 /* Evaluate and ignore VAL in case it has side-effects. */
3438 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3439 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3442 /* Stabilize the arguments in case we fail. */
3443 dest = builtin_save_expr (dest);
3444 val = builtin_save_expr (val);
3445 len = builtin_save_expr (len);
3447 len_rtx = expand_normal (len);
3448 dest_mem = get_memory_rtx (dest, len);
3450 if (TREE_CODE (val) != INTEGER_CST)
3452 rtx val_rtx;
3454 val_rtx = expand_normal (val);
3455 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3456 val_rtx, 0);
3458 /* Assume that we can memset by pieces if we can store the
3459 * the coefficients by pieces (in the required modes).
3460 * We can't pass builtin_memset_gen_str as that emits RTL. */
3461 c = 1;
3462 if (host_integerp (len, 1)
3463 && !(optimize_size && tree_low_cst (len, 1) > 1)
3464 && can_store_by_pieces (tree_low_cst (len, 1),
3465 builtin_memset_read_str, &c, dest_align))
3467 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3468 val_rtx);
3469 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3470 builtin_memset_gen_str, val_rtx, dest_align, 0);
3472 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3473 dest_align))
3474 goto do_libcall;
3476 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3477 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3478 return dest_mem;
3481 if (target_char_cast (val, &c))
3482 goto do_libcall;
3484 if (c)
3486 if (host_integerp (len, 1)
3487 && !(optimize_size && tree_low_cst (len, 1) > 1)
3488 && can_store_by_pieces (tree_low_cst (len, 1),
3489 builtin_memset_read_str, &c, dest_align))
3490 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3491 builtin_memset_read_str, &c, dest_align, 0);
3492 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3493 dest_align))
3494 goto do_libcall;
3496 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3497 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3498 return dest_mem;
3501 set_mem_align (dest_mem, dest_align);
3502 dest_addr = clear_storage (dest_mem, len_rtx,
3503 CALL_EXPR_TAILCALL (orig_exp)
3504 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3506 if (dest_addr == 0)
3508 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3509 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3512 return dest_addr;
3514 do_libcall:
3515 fndecl = get_callee_fndecl (orig_exp);
3516 fcode = DECL_FUNCTION_CODE (fndecl);
3517 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3518 arglist = build_tree_list (NULL_TREE, len);
3519 if (fcode == BUILT_IN_MEMSET)
3520 arglist = tree_cons (NULL_TREE, val, arglist);
3521 arglist = tree_cons (NULL_TREE, dest, arglist);
3522 fn = build_function_call_expr (fndecl, arglist);
3523 if (TREE_CODE (fn) == CALL_EXPR)
3524 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3525 return expand_call (fn, target, target == const0_rtx);
3529 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3530 if we failed the caller should emit a normal call. */
3532 static rtx
3533 expand_builtin_bzero (tree exp)
3535 tree arglist = TREE_OPERAND (exp, 1);
3536 tree dest, size, newarglist;
3538 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3539 return NULL_RTX;
3541 dest = TREE_VALUE (arglist);
3542 size = TREE_VALUE (TREE_CHAIN (arglist));
3544 /* New argument list transforming bzero(ptr x, int y) to
3545 memset(ptr x, int 0, size_t y). This is done this way
3546 so that if it isn't expanded inline, we fallback to
3547 calling bzero instead of memset. */
3549 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3550 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3551 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3553 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3556 /* Expand expression EXP, which is a call to the memcmp built-in function.
3557 ARGLIST is the argument list for this call. Return 0 if we failed and the
3558 caller should emit a normal call, otherwise try to get the result in
3559 TARGET, if convenient (and in mode MODE, if that's convenient). */
3561 static rtx
3562 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3563 enum machine_mode mode)
3565 if (!validate_arglist (arglist,
3566 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3567 return 0;
3568 else
3570 tree result = fold_builtin_memcmp (arglist);
3571 if (result)
3572 return expand_expr (result, target, mode, EXPAND_NORMAL);
3575 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3577 tree arg1 = TREE_VALUE (arglist);
3578 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3579 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3580 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3581 rtx result;
3582 rtx insn;
3584 int arg1_align
3585 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3586 int arg2_align
3587 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3588 enum machine_mode insn_mode;
3590 #ifdef HAVE_cmpmemsi
3591 if (HAVE_cmpmemsi)
3592 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3593 else
3594 #endif
3595 #ifdef HAVE_cmpstrnsi
3596 if (HAVE_cmpstrnsi)
3597 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3598 else
3599 #endif
3600 return 0;
3602 /* If we don't have POINTER_TYPE, call the function. */
3603 if (arg1_align == 0 || arg2_align == 0)
3604 return 0;
3606 /* Make a place to write the result of the instruction. */
3607 result = target;
3608 if (! (result != 0
3609 && REG_P (result) && GET_MODE (result) == insn_mode
3610 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3611 result = gen_reg_rtx (insn_mode);
3613 arg1_rtx = get_memory_rtx (arg1, len);
3614 arg2_rtx = get_memory_rtx (arg2, len);
3615 arg3_rtx = expand_normal (len);
3617 /* Set MEM_SIZE as appropriate. */
3618 if (GET_CODE (arg3_rtx) == CONST_INT)
3620 set_mem_size (arg1_rtx, arg3_rtx);
3621 set_mem_size (arg2_rtx, arg3_rtx);
3624 #ifdef HAVE_cmpmemsi
3625 if (HAVE_cmpmemsi)
3626 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3627 GEN_INT (MIN (arg1_align, arg2_align)));
3628 else
3629 #endif
3630 #ifdef HAVE_cmpstrnsi
3631 if (HAVE_cmpstrnsi)
3632 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3633 GEN_INT (MIN (arg1_align, arg2_align)));
3634 else
3635 #endif
3636 gcc_unreachable ();
3638 if (insn)
3639 emit_insn (insn);
3640 else
3641 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3642 TYPE_MODE (integer_type_node), 3,
3643 XEXP (arg1_rtx, 0), Pmode,
3644 XEXP (arg2_rtx, 0), Pmode,
3645 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3646 TYPE_UNSIGNED (sizetype)),
3647 TYPE_MODE (sizetype));
3649 /* Return the value in the proper mode for this function. */
3650 mode = TYPE_MODE (TREE_TYPE (exp));
3651 if (GET_MODE (result) == mode)
3652 return result;
3653 else if (target != 0)
3655 convert_move (target, result, 0);
3656 return target;
3658 else
3659 return convert_to_mode (mode, result, 0);
3661 #endif
3663 return 0;
3666 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3667 if we failed the caller should emit a normal call, otherwise try to get
3668 the result in TARGET, if convenient. */
3670 static rtx
3671 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3673 tree arglist = TREE_OPERAND (exp, 1);
3675 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3676 return 0;
3677 else
3679 tree result = fold_builtin_strcmp (arglist);
3680 if (result)
3681 return expand_expr (result, target, mode, EXPAND_NORMAL);
3684 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3685 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3686 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3688 rtx arg1_rtx, arg2_rtx;
3689 rtx result, insn = NULL_RTX;
3690 tree fndecl, fn;
3692 tree arg1 = TREE_VALUE (arglist);
3693 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3694 int arg1_align
3695 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3696 int arg2_align
3697 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3699 /* If we don't have POINTER_TYPE, call the function. */
3700 if (arg1_align == 0 || arg2_align == 0)
3701 return 0;
3703 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3704 arg1 = builtin_save_expr (arg1);
3705 arg2 = builtin_save_expr (arg2);
3707 arg1_rtx = get_memory_rtx (arg1, NULL);
3708 arg2_rtx = get_memory_rtx (arg2, NULL);
3710 #ifdef HAVE_cmpstrsi
3711 /* Try to call cmpstrsi. */
3712 if (HAVE_cmpstrsi)
3714 enum machine_mode insn_mode
3715 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3717 /* Make a place to write the result of the instruction. */
3718 result = target;
3719 if (! (result != 0
3720 && REG_P (result) && GET_MODE (result) == insn_mode
3721 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3722 result = gen_reg_rtx (insn_mode);
3724 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3725 GEN_INT (MIN (arg1_align, arg2_align)));
3727 #endif
3728 #ifdef HAVE_cmpstrnsi
3729 /* Try to determine at least one length and call cmpstrnsi. */
3730 if (!insn && HAVE_cmpstrnsi)
3732 tree len;
3733 rtx arg3_rtx;
3735 enum machine_mode insn_mode
3736 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3737 tree len1 = c_strlen (arg1, 1);
3738 tree len2 = c_strlen (arg2, 1);
3740 if (len1)
3741 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3742 if (len2)
3743 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3745 /* If we don't have a constant length for the first, use the length
3746 of the second, if we know it. We don't require a constant for
3747 this case; some cost analysis could be done if both are available
3748 but neither is constant. For now, assume they're equally cheap,
3749 unless one has side effects. If both strings have constant lengths,
3750 use the smaller. */
3752 if (!len1)
3753 len = len2;
3754 else if (!len2)
3755 len = len1;
3756 else if (TREE_SIDE_EFFECTS (len1))
3757 len = len2;
3758 else if (TREE_SIDE_EFFECTS (len2))
3759 len = len1;
3760 else if (TREE_CODE (len1) != INTEGER_CST)
3761 len = len2;
3762 else if (TREE_CODE (len2) != INTEGER_CST)
3763 len = len1;
3764 else if (tree_int_cst_lt (len1, len2))
3765 len = len1;
3766 else
3767 len = len2;
3769 /* If both arguments have side effects, we cannot optimize. */
3770 if (!len || TREE_SIDE_EFFECTS (len))
3771 goto do_libcall;
3773 arg3_rtx = expand_normal (len);
3775 /* Make a place to write the result of the instruction. */
3776 result = target;
3777 if (! (result != 0
3778 && REG_P (result) && GET_MODE (result) == insn_mode
3779 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3780 result = gen_reg_rtx (insn_mode);
3782 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3783 GEN_INT (MIN (arg1_align, arg2_align)));
3785 #endif
3787 if (insn)
3789 emit_insn (insn);
3791 /* Return the value in the proper mode for this function. */
3792 mode = TYPE_MODE (TREE_TYPE (exp));
3793 if (GET_MODE (result) == mode)
3794 return result;
3795 if (target == 0)
3796 return convert_to_mode (mode, result, 0);
3797 convert_move (target, result, 0);
3798 return target;
3801 /* Expand the library call ourselves using a stabilized argument
3802 list to avoid re-evaluating the function's arguments twice. */
3803 #ifdef HAVE_cmpstrnsi
3804 do_libcall:
3805 #endif
3806 arglist = build_tree_list (NULL_TREE, arg2);
3807 arglist = tree_cons (NULL_TREE, arg1, arglist);
3808 fndecl = get_callee_fndecl (exp);
3809 fn = build_function_call_expr (fndecl, arglist);
3810 if (TREE_CODE (fn) == CALL_EXPR)
3811 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3812 return expand_call (fn, target, target == const0_rtx);
3814 #endif
3815 return 0;
3818 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3819 if we failed the caller should emit a normal call, otherwise try to get
3820 the result in TARGET, if convenient. */
3822 static rtx
3823 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3825 tree arglist = TREE_OPERAND (exp, 1);
3827 if (!validate_arglist (arglist,
3828 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3829 return 0;
3830 else
3832 tree result = fold_builtin_strncmp (arglist);
3833 if (result)
3834 return expand_expr (result, target, mode, EXPAND_NORMAL);
3837 /* If c_strlen can determine an expression for one of the string
3838 lengths, and it doesn't have side effects, then emit cmpstrnsi
3839 using length MIN(strlen(string)+1, arg3). */
3840 #ifdef HAVE_cmpstrnsi
3841 if (HAVE_cmpstrnsi)
3843 tree arg1 = TREE_VALUE (arglist);
3844 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3845 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3846 tree len, len1, len2;
3847 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3848 rtx result, insn;
3849 tree fndecl, fn;
3851 int arg1_align
3852 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3853 int arg2_align
3854 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3855 enum machine_mode insn_mode
3856 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3858 len1 = c_strlen (arg1, 1);
3859 len2 = c_strlen (arg2, 1);
3861 if (len1)
3862 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3863 if (len2)
3864 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3866 /* If we don't have a constant length for the first, use the length
3867 of the second, if we know it. We don't require a constant for
3868 this case; some cost analysis could be done if both are available
3869 but neither is constant. For now, assume they're equally cheap,
3870 unless one has side effects. If both strings have constant lengths,
3871 use the smaller. */
3873 if (!len1)
3874 len = len2;
3875 else if (!len2)
3876 len = len1;
3877 else if (TREE_SIDE_EFFECTS (len1))
3878 len = len2;
3879 else if (TREE_SIDE_EFFECTS (len2))
3880 len = len1;
3881 else if (TREE_CODE (len1) != INTEGER_CST)
3882 len = len2;
3883 else if (TREE_CODE (len2) != INTEGER_CST)
3884 len = len1;
3885 else if (tree_int_cst_lt (len1, len2))
3886 len = len1;
3887 else
3888 len = len2;
3890 /* If both arguments have side effects, we cannot optimize. */
3891 if (!len || TREE_SIDE_EFFECTS (len))
3892 return 0;
3894 /* The actual new length parameter is MIN(len,arg3). */
3895 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3896 fold_convert (TREE_TYPE (len), arg3));
3898 /* If we don't have POINTER_TYPE, call the function. */
3899 if (arg1_align == 0 || arg2_align == 0)
3900 return 0;
3902 /* Make a place to write the result of the instruction. */
3903 result = target;
3904 if (! (result != 0
3905 && REG_P (result) && GET_MODE (result) == insn_mode
3906 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3907 result = gen_reg_rtx (insn_mode);
3909 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3910 arg1 = builtin_save_expr (arg1);
3911 arg2 = builtin_save_expr (arg2);
3912 len = builtin_save_expr (len);
3914 arg1_rtx = get_memory_rtx (arg1, len);
3915 arg2_rtx = get_memory_rtx (arg2, len);
3916 arg3_rtx = expand_normal (len);
3917 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3918 GEN_INT (MIN (arg1_align, arg2_align)));
3919 if (insn)
3921 emit_insn (insn);
3923 /* Return the value in the proper mode for this function. */
3924 mode = TYPE_MODE (TREE_TYPE (exp));
3925 if (GET_MODE (result) == mode)
3926 return result;
3927 if (target == 0)
3928 return convert_to_mode (mode, result, 0);
3929 convert_move (target, result, 0);
3930 return target;
3933 /* Expand the library call ourselves using a stabilized argument
3934 list to avoid re-evaluating the function's arguments twice. */
3935 arglist = build_tree_list (NULL_TREE, len);
3936 arglist = tree_cons (NULL_TREE, arg2, arglist);
3937 arglist = tree_cons (NULL_TREE, arg1, arglist);
3938 fndecl = get_callee_fndecl (exp);
3939 fn = build_function_call_expr (fndecl, arglist);
3940 if (TREE_CODE (fn) == CALL_EXPR)
3941 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3942 return expand_call (fn, target, target == const0_rtx);
3944 #endif
3945 return 0;
3948 /* Expand expression EXP, which is a call to the strcat builtin.
3949 Return 0 if we failed the caller should emit a normal call,
3950 otherwise try to get the result in TARGET, if convenient. */
3952 static rtx
3953 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3955 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3956 return 0;
3957 else
3959 tree dst = TREE_VALUE (arglist),
3960 src = TREE_VALUE (TREE_CHAIN (arglist));
3961 const char *p = c_getstr (src);
3963 /* If the string length is zero, return the dst parameter. */
3964 if (p && *p == '\0')
3965 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3967 if (!optimize_size)
3969 /* See if we can store by pieces into (dst + strlen(dst)). */
3970 tree newsrc, newdst,
3971 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3972 rtx insns;
3974 /* Stabilize the argument list. */
3975 newsrc = builtin_save_expr (src);
3976 if (newsrc != src)
3977 arglist = build_tree_list (NULL_TREE, newsrc);
3978 else
3979 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3981 dst = builtin_save_expr (dst);
3983 start_sequence ();
3985 /* Create strlen (dst). */
3986 newdst =
3987 build_function_call_expr (strlen_fn,
3988 build_tree_list (NULL_TREE, dst));
3989 /* Create (dst + (cast) strlen (dst)). */
3990 newdst = fold_convert (TREE_TYPE (dst), newdst);
3991 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3993 newdst = builtin_save_expr (newdst);
3994 arglist = tree_cons (NULL_TREE, newdst, arglist);
3996 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3998 end_sequence (); /* Stop sequence. */
3999 return 0;
4002 /* Output the entire sequence. */
4003 insns = get_insns ();
4004 end_sequence ();
4005 emit_insn (insns);
4007 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4010 return 0;
4014 /* Expand expression EXP, which is a call to the strncat builtin.
4015 Return 0 if we failed the caller should emit a normal call,
4016 otherwise try to get the result in TARGET, if convenient. */
4018 static rtx
4019 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4021 if (validate_arglist (arglist,
4022 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4024 tree result = fold_builtin_strncat (arglist);
4025 if (result)
4026 return expand_expr (result, target, mode, EXPAND_NORMAL);
4028 return 0;
4031 /* Expand expression EXP, which is a call to the strspn builtin.
4032 Return 0 if we failed the caller should emit a normal call,
4033 otherwise try to get the result in TARGET, if convenient. */
4035 static rtx
4036 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4038 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4040 tree result = fold_builtin_strspn (arglist);
4041 if (result)
4042 return expand_expr (result, target, mode, EXPAND_NORMAL);
4044 return 0;
4047 /* Expand expression EXP, which is a call to the strcspn builtin.
4048 Return 0 if we failed the caller should emit a normal call,
4049 otherwise try to get the result in TARGET, if convenient. */
4051 static rtx
4052 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4054 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4056 tree result = fold_builtin_strcspn (arglist);
4057 if (result)
4058 return expand_expr (result, target, mode, EXPAND_NORMAL);
4060 return 0;
4063 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4064 if that's convenient. */
4067 expand_builtin_saveregs (void)
4069 rtx val, seq;
4071 /* Don't do __builtin_saveregs more than once in a function.
4072 Save the result of the first call and reuse it. */
4073 if (saveregs_value != 0)
4074 return saveregs_value;
4076 /* When this function is called, it means that registers must be
4077 saved on entry to this function. So we migrate the call to the
4078 first insn of this function. */
4080 start_sequence ();
4082 /* Do whatever the machine needs done in this case. */
4083 val = targetm.calls.expand_builtin_saveregs ();
4085 seq = get_insns ();
4086 end_sequence ();
4088 saveregs_value = val;
4090 /* Put the insns after the NOTE that starts the function. If this
4091 is inside a start_sequence, make the outer-level insn chain current, so
4092 the code is placed at the start of the function. */
4093 push_topmost_sequence ();
4094 emit_insn_after (seq, entry_of_function ());
4095 pop_topmost_sequence ();
4097 return val;
4100 /* __builtin_args_info (N) returns word N of the arg space info
4101 for the current function. The number and meanings of words
4102 is controlled by the definition of CUMULATIVE_ARGS. */
4104 static rtx
4105 expand_builtin_args_info (tree arglist)
4107 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4108 int *word_ptr = (int *) &current_function_args_info;
4110 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4112 if (arglist != 0)
4114 if (!host_integerp (TREE_VALUE (arglist), 0))
4115 error ("argument of %<__builtin_args_info%> must be constant");
4116 else
4118 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4120 if (wordnum < 0 || wordnum >= nwords)
4121 error ("argument of %<__builtin_args_info%> out of range");
4122 else
4123 return GEN_INT (word_ptr[wordnum]);
4126 else
4127 error ("missing argument in %<__builtin_args_info%>");
4129 return const0_rtx;
4132 /* Expand a call to __builtin_next_arg. */
4134 static rtx
4135 expand_builtin_next_arg (void)
4137 /* Checking arguments is already done in fold_builtin_next_arg
4138 that must be called before this function. */
4139 return expand_binop (Pmode, add_optab,
4140 current_function_internal_arg_pointer,
4141 current_function_arg_offset_rtx,
4142 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4145 /* Make it easier for the backends by protecting the valist argument
4146 from multiple evaluations. */
4148 static tree
4149 stabilize_va_list (tree valist, int needs_lvalue)
4151 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4153 if (TREE_SIDE_EFFECTS (valist))
4154 valist = save_expr (valist);
4156 /* For this case, the backends will be expecting a pointer to
4157 TREE_TYPE (va_list_type_node), but it's possible we've
4158 actually been given an array (an actual va_list_type_node).
4159 So fix it. */
4160 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4162 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4163 valist = build_fold_addr_expr_with_type (valist, p1);
4166 else
4168 tree pt;
4170 if (! needs_lvalue)
4172 if (! TREE_SIDE_EFFECTS (valist))
4173 return valist;
4175 pt = build_pointer_type (va_list_type_node);
4176 valist = fold_build1 (ADDR_EXPR, pt, valist);
4177 TREE_SIDE_EFFECTS (valist) = 1;
4180 if (TREE_SIDE_EFFECTS (valist))
4181 valist = save_expr (valist);
4182 valist = build_fold_indirect_ref (valist);
4185 return valist;
4188 /* The "standard" definition of va_list is void*. */
4190 tree
4191 std_build_builtin_va_list (void)
4193 return ptr_type_node;
4196 /* The "standard" implementation of va_start: just assign `nextarg' to
4197 the variable. */
4199 void
4200 std_expand_builtin_va_start (tree valist, rtx nextarg)
4202 tree t;
4204 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4205 make_tree (ptr_type_node, nextarg));
4206 TREE_SIDE_EFFECTS (t) = 1;
4208 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4211 /* Expand ARGLIST, from a call to __builtin_va_start. */
4213 static rtx
4214 expand_builtin_va_start (tree arglist)
4216 rtx nextarg;
4217 tree chain, valist;
4219 chain = TREE_CHAIN (arglist);
4221 if (!chain)
4223 error ("too few arguments to function %<va_start%>");
4224 return const0_rtx;
4227 if (fold_builtin_next_arg (chain))
4228 return const0_rtx;
4230 nextarg = expand_builtin_next_arg ();
4231 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4233 #ifdef EXPAND_BUILTIN_VA_START
4234 EXPAND_BUILTIN_VA_START (valist, nextarg);
4235 #else
4236 std_expand_builtin_va_start (valist, nextarg);
4237 #endif
4239 return const0_rtx;
4242 /* The "standard" implementation of va_arg: read the value from the
4243 current (padded) address and increment by the (padded) size. */
4245 tree
4246 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4248 tree addr, t, type_size, rounded_size, valist_tmp;
4249 unsigned HOST_WIDE_INT align, boundary;
4250 bool indirect;
4252 #ifdef ARGS_GROW_DOWNWARD
4253 /* All of the alignment and movement below is for args-grow-up machines.
4254 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4255 implement their own specialized gimplify_va_arg_expr routines. */
4256 gcc_unreachable ();
4257 #endif
4259 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4260 if (indirect)
4261 type = build_pointer_type (type);
4263 align = PARM_BOUNDARY / BITS_PER_UNIT;
4264 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4266 /* Hoist the valist value into a temporary for the moment. */
4267 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4269 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4270 requires greater alignment, we must perform dynamic alignment. */
4271 if (boundary > align
4272 && !integer_zerop (TYPE_SIZE (type)))
4274 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4275 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4276 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4277 gimplify_and_add (t, pre_p);
4279 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4280 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4281 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4282 gimplify_and_add (t, pre_p);
4284 else
4285 boundary = align;
4287 /* If the actual alignment is less than the alignment of the type,
4288 adjust the type accordingly so that we don't assume strict alignment
4289 when deferencing the pointer. */
4290 boundary *= BITS_PER_UNIT;
4291 if (boundary < TYPE_ALIGN (type))
4293 type = build_variant_type_copy (type);
4294 TYPE_ALIGN (type) = boundary;
4297 /* Compute the rounded size of the type. */
4298 type_size = size_in_bytes (type);
4299 rounded_size = round_up (type_size, align);
4301 /* Reduce rounded_size so it's sharable with the postqueue. */
4302 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4304 /* Get AP. */
4305 addr = valist_tmp;
4306 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4308 /* Small args are padded downward. */
4309 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4310 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4311 size_binop (MINUS_EXPR, rounded_size, type_size));
4312 t = fold_convert (TREE_TYPE (addr), t);
4313 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4316 /* Compute new value for AP. */
4317 t = fold_convert (TREE_TYPE (valist), rounded_size);
4318 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4319 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4320 gimplify_and_add (t, pre_p);
4322 addr = fold_convert (build_pointer_type (type), addr);
4324 if (indirect)
4325 addr = build_va_arg_indirect_ref (addr);
4327 return build_va_arg_indirect_ref (addr);
4330 /* Build an indirect-ref expression over the given TREE, which represents a
4331 piece of a va_arg() expansion. */
4332 tree
4333 build_va_arg_indirect_ref (tree addr)
4335 addr = build_fold_indirect_ref (addr);
4337 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4338 mf_mark (addr);
4340 return addr;
4343 /* Return a dummy expression of type TYPE in order to keep going after an
4344 error. */
4346 static tree
4347 dummy_object (tree type)
4349 tree t = build_int_cst (build_pointer_type (type), 0);
4350 return build1 (INDIRECT_REF, type, t);
4353 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4354 builtin function, but a very special sort of operator. */
4356 enum gimplify_status
4357 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4359 tree promoted_type, want_va_type, have_va_type;
4360 tree valist = TREE_OPERAND (*expr_p, 0);
4361 tree type = TREE_TYPE (*expr_p);
4362 tree t;
4364 /* Verify that valist is of the proper type. */
4365 want_va_type = va_list_type_node;
4366 have_va_type = TREE_TYPE (valist);
4368 if (have_va_type == error_mark_node)
4369 return GS_ERROR;
4371 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4373 /* If va_list is an array type, the argument may have decayed
4374 to a pointer type, e.g. by being passed to another function.
4375 In that case, unwrap both types so that we can compare the
4376 underlying records. */
4377 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4378 || POINTER_TYPE_P (have_va_type))
4380 want_va_type = TREE_TYPE (want_va_type);
4381 have_va_type = TREE_TYPE (have_va_type);
4385 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4387 error ("first argument to %<va_arg%> not of type %<va_list%>");
4388 return GS_ERROR;
4391 /* Generate a diagnostic for requesting data of a type that cannot
4392 be passed through `...' due to type promotion at the call site. */
4393 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4394 != type)
4396 static bool gave_help;
4398 /* Unfortunately, this is merely undefined, rather than a constraint
4399 violation, so we cannot make this an error. If this call is never
4400 executed, the program is still strictly conforming. */
4401 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4402 type, promoted_type);
4403 if (! gave_help)
4405 gave_help = true;
4406 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4407 promoted_type, type);
4410 /* We can, however, treat "undefined" any way we please.
4411 Call abort to encourage the user to fix the program. */
4412 inform ("if this code is reached, the program will abort");
4413 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4414 NULL);
4415 append_to_statement_list (t, pre_p);
4417 /* This is dead code, but go ahead and finish so that the
4418 mode of the result comes out right. */
4419 *expr_p = dummy_object (type);
4420 return GS_ALL_DONE;
4422 else
4424 /* Make it easier for the backends by protecting the valist argument
4425 from multiple evaluations. */
4426 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4428 /* For this case, the backends will be expecting a pointer to
4429 TREE_TYPE (va_list_type_node), but it's possible we've
4430 actually been given an array (an actual va_list_type_node).
4431 So fix it. */
4432 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4434 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4435 valist = build_fold_addr_expr_with_type (valist, p1);
4437 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4439 else
4440 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4442 if (!targetm.gimplify_va_arg_expr)
4443 /* FIXME:Once most targets are converted we should merely
4444 assert this is non-null. */
4445 return GS_ALL_DONE;
4447 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4448 return GS_OK;
4452 /* Expand ARGLIST, from a call to __builtin_va_end. */
4454 static rtx
4455 expand_builtin_va_end (tree arglist)
4457 tree valist = TREE_VALUE (arglist);
4459 /* Evaluate for side effects, if needed. I hate macros that don't
4460 do that. */
4461 if (TREE_SIDE_EFFECTS (valist))
4462 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4464 return const0_rtx;
4467 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4468 builtin rather than just as an assignment in stdarg.h because of the
4469 nastiness of array-type va_list types. */
4471 static rtx
4472 expand_builtin_va_copy (tree arglist)
4474 tree dst, src, t;
4476 dst = TREE_VALUE (arglist);
4477 src = TREE_VALUE (TREE_CHAIN (arglist));
4479 dst = stabilize_va_list (dst, 1);
4480 src = stabilize_va_list (src, 0);
4482 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4484 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4485 TREE_SIDE_EFFECTS (t) = 1;
4486 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4488 else
4490 rtx dstb, srcb, size;
4492 /* Evaluate to pointers. */
4493 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4494 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4495 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4496 VOIDmode, EXPAND_NORMAL);
4498 dstb = convert_memory_address (Pmode, dstb);
4499 srcb = convert_memory_address (Pmode, srcb);
4501 /* "Dereference" to BLKmode memories. */
4502 dstb = gen_rtx_MEM (BLKmode, dstb);
4503 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4504 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4505 srcb = gen_rtx_MEM (BLKmode, srcb);
4506 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4507 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4509 /* Copy. */
4510 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4513 return const0_rtx;
4516 /* Expand a call to one of the builtin functions __builtin_frame_address or
4517 __builtin_return_address. */
4519 static rtx
4520 expand_builtin_frame_address (tree fndecl, tree arglist)
4522 /* The argument must be a nonnegative integer constant.
4523 It counts the number of frames to scan up the stack.
4524 The value is the return address saved in that frame. */
4525 if (arglist == 0)
4526 /* Warning about missing arg was already issued. */
4527 return const0_rtx;
4528 else if (! host_integerp (TREE_VALUE (arglist), 1))
4530 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4531 error ("invalid argument to %<__builtin_frame_address%>");
4532 else
4533 error ("invalid argument to %<__builtin_return_address%>");
4534 return const0_rtx;
4536 else
4538 rtx tem
4539 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4540 tree_low_cst (TREE_VALUE (arglist), 1));
4542 /* Some ports cannot access arbitrary stack frames. */
4543 if (tem == NULL)
4545 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4546 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4547 else
4548 warning (0, "unsupported argument to %<__builtin_return_address%>");
4549 return const0_rtx;
4552 /* For __builtin_frame_address, return what we've got. */
4553 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4554 return tem;
4556 if (!REG_P (tem)
4557 && ! CONSTANT_P (tem))
4558 tem = copy_to_mode_reg (Pmode, tem);
4559 return tem;
4563 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4564 we failed and the caller should emit a normal call, otherwise try to get
4565 the result in TARGET, if convenient. */
4567 static rtx
4568 expand_builtin_alloca (tree arglist, rtx target)
4570 rtx op0;
4571 rtx result;
4573 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4574 should always expand to function calls. These can be intercepted
4575 in libmudflap. */
4576 if (flag_mudflap)
4577 return 0;
4579 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4580 return 0;
4582 /* Compute the argument. */
4583 op0 = expand_normal (TREE_VALUE (arglist));
4585 /* Allocate the desired space. */
4586 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4587 result = convert_memory_address (ptr_mode, result);
4589 return result;
4592 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4593 Return 0 if a normal call should be emitted rather than expanding the
4594 function in-line. If convenient, the result should be placed in TARGET.
4595 SUBTARGET may be used as the target for computing one of EXP's operands. */
4597 static rtx
4598 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4599 rtx subtarget, optab op_optab)
4601 rtx op0;
4602 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4603 return 0;
4605 /* Compute the argument. */
4606 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4607 /* Compute op, into TARGET if possible.
4608 Set TARGET to wherever the result comes back. */
4609 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4610 op_optab, op0, target, 1);
4611 gcc_assert (target);
4613 return convert_to_mode (target_mode, target, 0);
4616 /* If the string passed to fputs is a constant and is one character
4617 long, we attempt to transform this call into __builtin_fputc(). */
4619 static rtx
4620 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4622 /* Verify the arguments in the original call. */
4623 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4625 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4626 unlocked, NULL_TREE);
4627 if (result)
4628 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4630 return 0;
4633 /* Expand a call to __builtin_expect. We return our argument and emit a
4634 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4635 a non-jump context. */
4637 static rtx
4638 expand_builtin_expect (tree arglist, rtx target)
4640 tree exp, c;
4641 rtx note, rtx_c;
4643 if (arglist == NULL_TREE
4644 || TREE_CHAIN (arglist) == NULL_TREE)
4645 return const0_rtx;
4646 exp = TREE_VALUE (arglist);
4647 c = TREE_VALUE (TREE_CHAIN (arglist));
4649 if (TREE_CODE (c) != INTEGER_CST)
4651 error ("second argument to %<__builtin_expect%> must be a constant");
4652 c = integer_zero_node;
4655 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4657 /* Don't bother with expected value notes for integral constants. */
4658 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4660 /* We do need to force this into a register so that we can be
4661 moderately sure to be able to correctly interpret the branch
4662 condition later. */
4663 target = force_reg (GET_MODE (target), target);
4665 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4667 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4668 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4671 return target;
4674 /* Like expand_builtin_expect, except do this in a jump context. This is
4675 called from do_jump if the conditional is a __builtin_expect. Return either
4676 a list of insns to emit the jump or NULL if we cannot optimize
4677 __builtin_expect. We need to optimize this at jump time so that machines
4678 like the PowerPC don't turn the test into a SCC operation, and then jump
4679 based on the test being 0/1. */
4682 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4684 tree arglist = TREE_OPERAND (exp, 1);
4685 tree arg0 = TREE_VALUE (arglist);
4686 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4687 rtx ret = NULL_RTX;
4689 /* Only handle __builtin_expect (test, 0) and
4690 __builtin_expect (test, 1). */
4691 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4692 && (integer_zerop (arg1) || integer_onep (arg1)))
4694 rtx insn, drop_through_label, temp;
4696 /* Expand the jump insns. */
4697 start_sequence ();
4698 do_jump (arg0, if_false_label, if_true_label);
4699 ret = get_insns ();
4701 drop_through_label = get_last_insn ();
4702 if (drop_through_label && NOTE_P (drop_through_label))
4703 drop_through_label = prev_nonnote_insn (drop_through_label);
4704 if (drop_through_label && !LABEL_P (drop_through_label))
4705 drop_through_label = NULL_RTX;
4706 end_sequence ();
4708 if (! if_true_label)
4709 if_true_label = drop_through_label;
4710 if (! if_false_label)
4711 if_false_label = drop_through_label;
4713 /* Go through and add the expect's to each of the conditional jumps. */
4714 insn = ret;
4715 while (insn != NULL_RTX)
4717 rtx next = NEXT_INSN (insn);
4719 if (JUMP_P (insn) && any_condjump_p (insn))
4721 rtx ifelse = SET_SRC (pc_set (insn));
4722 rtx then_dest = XEXP (ifelse, 1);
4723 rtx else_dest = XEXP (ifelse, 2);
4724 int taken = -1;
4726 /* First check if we recognize any of the labels. */
4727 if (GET_CODE (then_dest) == LABEL_REF
4728 && XEXP (then_dest, 0) == if_true_label)
4729 taken = 1;
4730 else if (GET_CODE (then_dest) == LABEL_REF
4731 && XEXP (then_dest, 0) == if_false_label)
4732 taken = 0;
4733 else if (GET_CODE (else_dest) == LABEL_REF
4734 && XEXP (else_dest, 0) == if_false_label)
4735 taken = 1;
4736 else if (GET_CODE (else_dest) == LABEL_REF
4737 && XEXP (else_dest, 0) == if_true_label)
4738 taken = 0;
4739 /* Otherwise check where we drop through. */
4740 else if (else_dest == pc_rtx)
4742 if (next && NOTE_P (next))
4743 next = next_nonnote_insn (next);
4745 if (next && JUMP_P (next)
4746 && any_uncondjump_p (next))
4747 temp = XEXP (SET_SRC (pc_set (next)), 0);
4748 else
4749 temp = next;
4751 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4752 else that can't possibly match either target label. */
4753 if (temp == if_false_label)
4754 taken = 1;
4755 else if (temp == if_true_label)
4756 taken = 0;
4758 else if (then_dest == pc_rtx)
4760 if (next && NOTE_P (next))
4761 next = next_nonnote_insn (next);
4763 if (next && JUMP_P (next)
4764 && any_uncondjump_p (next))
4765 temp = XEXP (SET_SRC (pc_set (next)), 0);
4766 else
4767 temp = next;
4769 if (temp == if_false_label)
4770 taken = 0;
4771 else if (temp == if_true_label)
4772 taken = 1;
4775 if (taken != -1)
4777 /* If the test is expected to fail, reverse the
4778 probabilities. */
4779 if (integer_zerop (arg1))
4780 taken = 1 - taken;
4781 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4785 insn = next;
4789 return ret;
4792 void
4793 expand_builtin_trap (void)
4795 #ifdef HAVE_trap
4796 if (HAVE_trap)
4797 emit_insn (gen_trap ());
4798 else
4799 #endif
4800 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4801 emit_barrier ();
4804 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4805 Return 0 if a normal call should be emitted rather than expanding
4806 the function inline. If convenient, the result should be placed
4807 in TARGET. SUBTARGET may be used as the target for computing
4808 the operand. */
4810 static rtx
4811 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4813 enum machine_mode mode;
4814 tree arg;
4815 rtx op0;
4817 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4818 return 0;
4820 arg = TREE_VALUE (arglist);
4821 mode = TYPE_MODE (TREE_TYPE (arg));
4822 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4823 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4826 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4827 Return NULL is a normal call should be emitted rather than expanding the
4828 function inline. If convenient, the result should be placed in TARGET.
4829 SUBTARGET may be used as the target for computing the operand. */
4831 static rtx
4832 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4834 rtx op0, op1;
4835 tree arg;
4837 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4838 return 0;
4840 arg = TREE_VALUE (arglist);
4841 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4843 arg = TREE_VALUE (TREE_CHAIN (arglist));
4844 op1 = expand_normal (arg);
4846 return expand_copysign (op0, op1, target);
4849 /* Create a new constant string literal and return a char* pointer to it.
4850 The STRING_CST value is the LEN characters at STR. */
4851 tree
4852 build_string_literal (int len, const char *str)
4854 tree t, elem, index, type;
4856 t = build_string (len, str);
4857 elem = build_type_variant (char_type_node, 1, 0);
4858 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4859 type = build_array_type (elem, index);
4860 TREE_TYPE (t) = type;
4861 TREE_CONSTANT (t) = 1;
4862 TREE_INVARIANT (t) = 1;
4863 TREE_READONLY (t) = 1;
4864 TREE_STATIC (t) = 1;
4866 type = build_pointer_type (type);
4867 t = build1 (ADDR_EXPR, type, t);
4869 type = build_pointer_type (elem);
4870 t = build1 (NOP_EXPR, type, t);
4871 return t;
4874 /* Expand EXP, a call to printf or printf_unlocked.
4875 Return 0 if a normal call should be emitted rather than transforming
4876 the function inline. If convenient, the result should be placed in
4877 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4878 call. */
4879 static rtx
4880 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4881 bool unlocked)
4883 tree arglist = TREE_OPERAND (exp, 1);
4884 /* If we're using an unlocked function, assume the other unlocked
4885 functions exist explicitly. */
4886 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4887 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4888 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4889 : implicit_built_in_decls[BUILT_IN_PUTS];
4890 const char *fmt_str;
4891 tree fn, fmt, arg;
4893 /* If the return value is used, don't do the transformation. */
4894 if (target != const0_rtx)
4895 return 0;
4897 /* Verify the required arguments in the original call. */
4898 if (! arglist)
4899 return 0;
4900 fmt = TREE_VALUE (arglist);
4901 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4902 return 0;
4903 arglist = TREE_CHAIN (arglist);
4905 /* Check whether the format is a literal string constant. */
4906 fmt_str = c_getstr (fmt);
4907 if (fmt_str == NULL)
4908 return 0;
4910 if (!init_target_chars())
4911 return 0;
4913 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4914 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4916 if (! arglist
4917 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4918 || TREE_CHAIN (arglist))
4919 return 0;
4920 fn = fn_puts;
4922 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4923 else if (strcmp (fmt_str, target_percent_c) == 0)
4925 if (! arglist
4926 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4927 || TREE_CHAIN (arglist))
4928 return 0;
4929 fn = fn_putchar;
4931 else
4933 /* We can't handle anything else with % args or %% ... yet. */
4934 if (strchr (fmt_str, target_percent))
4935 return 0;
4937 if (arglist)
4938 return 0;
4940 /* If the format specifier was "", printf does nothing. */
4941 if (fmt_str[0] == '\0')
4942 return const0_rtx;
4943 /* If the format specifier has length of 1, call putchar. */
4944 if (fmt_str[1] == '\0')
4946 /* Given printf("c"), (where c is any one character,)
4947 convert "c"[0] to an int and pass that to the replacement
4948 function. */
4949 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4950 arglist = build_tree_list (NULL_TREE, arg);
4951 fn = fn_putchar;
4953 else
4955 /* If the format specifier was "string\n", call puts("string"). */
4956 size_t len = strlen (fmt_str);
4957 if ((unsigned char)fmt_str[len - 1] == target_newline)
4959 /* Create a NUL-terminated string that's one char shorter
4960 than the original, stripping off the trailing '\n'. */
4961 char *newstr = alloca (len);
4962 memcpy (newstr, fmt_str, len - 1);
4963 newstr[len - 1] = 0;
4965 arg = build_string_literal (len, newstr);
4966 arglist = build_tree_list (NULL_TREE, arg);
4967 fn = fn_puts;
4969 else
4970 /* We'd like to arrange to call fputs(string,stdout) here,
4971 but we need stdout and don't have a way to get it yet. */
4972 return 0;
4976 if (!fn)
4977 return 0;
4978 fn = build_function_call_expr (fn, arglist);
4979 if (TREE_CODE (fn) == CALL_EXPR)
4980 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4981 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4984 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4985 Return 0 if a normal call should be emitted rather than transforming
4986 the function inline. If convenient, the result should be placed in
4987 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4988 call. */
4989 static rtx
4990 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4991 bool unlocked)
4993 tree arglist = TREE_OPERAND (exp, 1);
4994 /* If we're using an unlocked function, assume the other unlocked
4995 functions exist explicitly. */
4996 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4997 : implicit_built_in_decls[BUILT_IN_FPUTC];
4998 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4999 : implicit_built_in_decls[BUILT_IN_FPUTS];
5000 const char *fmt_str;
5001 tree fn, fmt, fp, arg;
5003 /* If the return value is used, don't do the transformation. */
5004 if (target != const0_rtx)
5005 return 0;
5007 /* Verify the required arguments in the original call. */
5008 if (! arglist)
5009 return 0;
5010 fp = TREE_VALUE (arglist);
5011 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5012 return 0;
5013 arglist = TREE_CHAIN (arglist);
5014 if (! arglist)
5015 return 0;
5016 fmt = TREE_VALUE (arglist);
5017 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5018 return 0;
5019 arglist = TREE_CHAIN (arglist);
5021 /* Check whether the format is a literal string constant. */
5022 fmt_str = c_getstr (fmt);
5023 if (fmt_str == NULL)
5024 return 0;
5026 if (!init_target_chars())
5027 return 0;
5029 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5030 if (strcmp (fmt_str, target_percent_s) == 0)
5032 if (! arglist
5033 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5034 || TREE_CHAIN (arglist))
5035 return 0;
5036 arg = TREE_VALUE (arglist);
5037 arglist = build_tree_list (NULL_TREE, fp);
5038 arglist = tree_cons (NULL_TREE, arg, arglist);
5039 fn = fn_fputs;
5041 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5042 else if (strcmp (fmt_str, target_percent_c) == 0)
5044 if (! arglist
5045 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5046 || TREE_CHAIN (arglist))
5047 return 0;
5048 arg = TREE_VALUE (arglist);
5049 arglist = build_tree_list (NULL_TREE, fp);
5050 arglist = tree_cons (NULL_TREE, arg, arglist);
5051 fn = fn_fputc;
5053 else
5055 /* We can't handle anything else with % args or %% ... yet. */
5056 if (strchr (fmt_str, target_percent))
5057 return 0;
5059 if (arglist)
5060 return 0;
5062 /* If the format specifier was "", fprintf does nothing. */
5063 if (fmt_str[0] == '\0')
5065 /* Evaluate and ignore FILE* argument for side-effects. */
5066 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5067 return const0_rtx;
5070 /* When "string" doesn't contain %, replace all cases of
5071 fprintf(stream,string) with fputs(string,stream). The fputs
5072 builtin will take care of special cases like length == 1. */
5073 arglist = build_tree_list (NULL_TREE, fp);
5074 arglist = tree_cons (NULL_TREE, fmt, arglist);
5075 fn = fn_fputs;
5078 if (!fn)
5079 return 0;
5080 fn = build_function_call_expr (fn, arglist);
5081 if (TREE_CODE (fn) == CALL_EXPR)
5082 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5083 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5086 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5087 a normal call should be emitted rather than expanding the function
5088 inline. If convenient, the result should be placed in TARGET with
5089 mode MODE. */
5091 static rtx
5092 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5094 tree orig_arglist, dest, fmt;
5095 const char *fmt_str;
5097 orig_arglist = arglist;
5099 /* Verify the required arguments in the original call. */
5100 if (! arglist)
5101 return 0;
5102 dest = TREE_VALUE (arglist);
5103 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5104 return 0;
5105 arglist = TREE_CHAIN (arglist);
5106 if (! arglist)
5107 return 0;
5108 fmt = TREE_VALUE (arglist);
5109 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5110 return 0;
5111 arglist = TREE_CHAIN (arglist);
5113 /* Check whether the format is a literal string constant. */
5114 fmt_str = c_getstr (fmt);
5115 if (fmt_str == NULL)
5116 return 0;
5118 if (!init_target_chars())
5119 return 0;
5121 /* If the format doesn't contain % args or %%, use strcpy. */
5122 if (strchr (fmt_str, target_percent) == 0)
5124 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5125 tree exp;
5127 if (arglist || ! fn)
5128 return 0;
5129 expand_expr (build_function_call_expr (fn, orig_arglist),
5130 const0_rtx, VOIDmode, EXPAND_NORMAL);
5131 if (target == const0_rtx)
5132 return const0_rtx;
5133 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5134 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5136 /* If the format is "%s", use strcpy if the result isn't used. */
5137 else if (strcmp (fmt_str, target_percent_s) == 0)
5139 tree fn, arg, len;
5140 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5142 if (! fn)
5143 return 0;
5145 if (! arglist || TREE_CHAIN (arglist))
5146 return 0;
5147 arg = TREE_VALUE (arglist);
5148 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5149 return 0;
5151 if (target != const0_rtx)
5153 len = c_strlen (arg, 1);
5154 if (! len || TREE_CODE (len) != INTEGER_CST)
5155 return 0;
5157 else
5158 len = NULL_TREE;
5160 arglist = build_tree_list (NULL_TREE, arg);
5161 arglist = tree_cons (NULL_TREE, dest, arglist);
5162 expand_expr (build_function_call_expr (fn, arglist),
5163 const0_rtx, VOIDmode, EXPAND_NORMAL);
5165 if (target == const0_rtx)
5166 return const0_rtx;
5167 return expand_expr (len, target, mode, EXPAND_NORMAL);
5170 return 0;
5173 /* Expand a call to either the entry or exit function profiler. */
5175 static rtx
5176 expand_builtin_profile_func (bool exitp)
5178 rtx this, which;
5180 this = DECL_RTL (current_function_decl);
5181 gcc_assert (MEM_P (this));
5182 this = XEXP (this, 0);
5184 if (exitp)
5185 which = profile_function_exit_libfunc;
5186 else
5187 which = profile_function_entry_libfunc;
5189 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5190 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5192 Pmode);
5194 return const0_rtx;
5197 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5199 static rtx
5200 round_trampoline_addr (rtx tramp)
5202 rtx temp, addend, mask;
5204 /* If we don't need too much alignment, we'll have been guaranteed
5205 proper alignment by get_trampoline_type. */
5206 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5207 return tramp;
5209 /* Round address up to desired boundary. */
5210 temp = gen_reg_rtx (Pmode);
5211 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5212 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5214 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5215 temp, 0, OPTAB_LIB_WIDEN);
5216 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5217 temp, 0, OPTAB_LIB_WIDEN);
5219 return tramp;
5222 static rtx
5223 expand_builtin_init_trampoline (tree arglist)
5225 tree t_tramp, t_func, t_chain;
5226 rtx r_tramp, r_func, r_chain;
5227 #ifdef TRAMPOLINE_TEMPLATE
5228 rtx blktramp;
5229 #endif
5231 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5232 POINTER_TYPE, VOID_TYPE))
5233 return NULL_RTX;
5235 t_tramp = TREE_VALUE (arglist);
5236 arglist = TREE_CHAIN (arglist);
5237 t_func = TREE_VALUE (arglist);
5238 arglist = TREE_CHAIN (arglist);
5239 t_chain = TREE_VALUE (arglist);
5241 r_tramp = expand_normal (t_tramp);
5242 r_func = expand_normal (t_func);
5243 r_chain = expand_normal (t_chain);
5245 /* Generate insns to initialize the trampoline. */
5246 r_tramp = round_trampoline_addr (r_tramp);
5247 #ifdef TRAMPOLINE_TEMPLATE
5248 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5249 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5250 emit_block_move (blktramp, assemble_trampoline_template (),
5251 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5252 #endif
5253 trampolines_created = 1;
5254 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5256 return const0_rtx;
5259 static rtx
5260 expand_builtin_adjust_trampoline (tree arglist)
5262 rtx tramp;
5264 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5265 return NULL_RTX;
5267 tramp = expand_normal (TREE_VALUE (arglist));
5268 tramp = round_trampoline_addr (tramp);
5269 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5270 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5271 #endif
5273 return tramp;
5276 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5277 Return NULL_RTX if a normal call should be emitted rather than expanding
5278 the function in-line. EXP is the expression that is a call to the builtin
5279 function; if convenient, the result should be placed in TARGET. */
5281 static rtx
5282 expand_builtin_signbit (tree exp, rtx target)
5284 const struct real_format *fmt;
5285 enum machine_mode fmode, imode, rmode;
5286 HOST_WIDE_INT hi, lo;
5287 tree arg, arglist;
5288 int word, bitpos;
5289 rtx temp;
5291 arglist = TREE_OPERAND (exp, 1);
5292 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5293 return 0;
5295 arg = TREE_VALUE (arglist);
5296 fmode = TYPE_MODE (TREE_TYPE (arg));
5297 rmode = TYPE_MODE (TREE_TYPE (exp));
5298 fmt = REAL_MODE_FORMAT (fmode);
5300 /* For floating point formats without a sign bit, implement signbit
5301 as "ARG < 0.0". */
5302 bitpos = fmt->signbit_ro;
5303 if (bitpos < 0)
5305 /* But we can't do this if the format supports signed zero. */
5306 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5307 return 0;
5309 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5310 build_real (TREE_TYPE (arg), dconst0));
5311 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5314 temp = expand_normal (arg);
5315 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5317 imode = int_mode_for_mode (fmode);
5318 if (imode == BLKmode)
5319 return 0;
5320 temp = gen_lowpart (imode, temp);
5322 else
5324 imode = word_mode;
5325 /* Handle targets with different FP word orders. */
5326 if (FLOAT_WORDS_BIG_ENDIAN)
5327 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5328 else
5329 word = bitpos / BITS_PER_WORD;
5330 temp = operand_subword_force (temp, word, fmode);
5331 bitpos = bitpos % BITS_PER_WORD;
5334 /* Force the intermediate word_mode (or narrower) result into a
5335 register. This avoids attempting to create paradoxical SUBREGs
5336 of floating point modes below. */
5337 temp = force_reg (imode, temp);
5339 /* If the bitpos is within the "result mode" lowpart, the operation
5340 can be implement with a single bitwise AND. Otherwise, we need
5341 a right shift and an AND. */
5343 if (bitpos < GET_MODE_BITSIZE (rmode))
5345 if (bitpos < HOST_BITS_PER_WIDE_INT)
5347 hi = 0;
5348 lo = (HOST_WIDE_INT) 1 << bitpos;
5350 else
5352 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5353 lo = 0;
5356 if (imode != rmode)
5357 temp = gen_lowpart (rmode, temp);
5358 temp = expand_binop (rmode, and_optab, temp,
5359 immed_double_const (lo, hi, rmode),
5360 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5362 else
5364 /* Perform a logical right shift to place the signbit in the least
5365 significant bit, then truncate the result to the desired mode
5366 and mask just this bit. */
5367 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5368 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5369 temp = gen_lowpart (rmode, temp);
5370 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5371 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5374 return temp;
5377 /* Expand fork or exec calls. TARGET is the desired target of the
5378 call. ARGLIST is the list of arguments of the call. FN is the
5379 identificator of the actual function. IGNORE is nonzero if the
5380 value is to be ignored. */
5382 static rtx
5383 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5385 tree id, decl;
5386 tree call;
5388 /* If we are not profiling, just call the function. */
5389 if (!profile_arc_flag)
5390 return NULL_RTX;
5392 /* Otherwise call the wrapper. This should be equivalent for the rest of
5393 compiler, so the code does not diverge, and the wrapper may run the
5394 code necessary for keeping the profiling sane. */
5396 switch (DECL_FUNCTION_CODE (fn))
5398 case BUILT_IN_FORK:
5399 id = get_identifier ("__gcov_fork");
5400 break;
5402 case BUILT_IN_EXECL:
5403 id = get_identifier ("__gcov_execl");
5404 break;
5406 case BUILT_IN_EXECV:
5407 id = get_identifier ("__gcov_execv");
5408 break;
5410 case BUILT_IN_EXECLP:
5411 id = get_identifier ("__gcov_execlp");
5412 break;
5414 case BUILT_IN_EXECLE:
5415 id = get_identifier ("__gcov_execle");
5416 break;
5418 case BUILT_IN_EXECVP:
5419 id = get_identifier ("__gcov_execvp");
5420 break;
5422 case BUILT_IN_EXECVE:
5423 id = get_identifier ("__gcov_execve");
5424 break;
5426 default:
5427 gcc_unreachable ();
5430 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5431 DECL_EXTERNAL (decl) = 1;
5432 TREE_PUBLIC (decl) = 1;
5433 DECL_ARTIFICIAL (decl) = 1;
5434 TREE_NOTHROW (decl) = 1;
5435 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5436 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5437 call = build_function_call_expr (decl, arglist);
5439 return expand_call (call, target, ignore);
5443 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5444 the pointer in these functions is void*, the tree optimizers may remove
5445 casts. The mode computed in expand_builtin isn't reliable either, due
5446 to __sync_bool_compare_and_swap.
5448 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5449 group of builtins. This gives us log2 of the mode size. */
5451 static inline enum machine_mode
5452 get_builtin_sync_mode (int fcode_diff)
5454 /* The size is not negotiable, so ask not to get BLKmode in return
5455 if the target indicates that a smaller size would be better. */
5456 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5459 /* Expand the memory expression LOC and return the appropriate memory operand
5460 for the builtin_sync operations. */
5462 static rtx
5463 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5465 rtx addr, mem;
5467 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5469 /* Note that we explicitly do not want any alias information for this
5470 memory, so that we kill all other live memories. Otherwise we don't
5471 satisfy the full barrier semantics of the intrinsic. */
5472 mem = validize_mem (gen_rtx_MEM (mode, addr));
5474 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5475 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5476 MEM_VOLATILE_P (mem) = 1;
5478 return mem;
5481 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5482 ARGLIST is the operands list to the function. CODE is the rtx code
5483 that corresponds to the arithmetic or logical operation from the name;
5484 an exception here is that NOT actually means NAND. TARGET is an optional
5485 place for us to store the results; AFTER is true if this is the
5486 fetch_and_xxx form. IGNORE is true if we don't actually care about
5487 the result of the operation at all. */
5489 static rtx
5490 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5491 enum rtx_code code, bool after,
5492 rtx target, bool ignore)
5494 rtx val, mem;
5495 enum machine_mode old_mode;
5497 /* Expand the operands. */
5498 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5500 arglist = TREE_CHAIN (arglist);
5501 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5502 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5503 of CONST_INTs, where we know the old_mode only from the call argument. */
5504 old_mode = GET_MODE (val);
5505 if (old_mode == VOIDmode)
5506 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5507 val = convert_modes (mode, old_mode, val, 1);
5509 if (ignore)
5510 return expand_sync_operation (mem, val, code);
5511 else
5512 return expand_sync_fetch_operation (mem, val, code, after, target);
5515 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5516 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5517 true if this is the boolean form. TARGET is a place for us to store the
5518 results; this is NOT optional if IS_BOOL is true. */
5520 static rtx
5521 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5522 bool is_bool, rtx target)
5524 rtx old_val, new_val, mem;
5525 enum machine_mode old_mode;
5527 /* Expand the operands. */
5528 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5530 arglist = TREE_CHAIN (arglist);
5531 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5532 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5533 of CONST_INTs, where we know the old_mode only from the call argument. */
5534 old_mode = GET_MODE (old_val);
5535 if (old_mode == VOIDmode)
5536 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5537 old_val = convert_modes (mode, old_mode, old_val, 1);
5539 arglist = TREE_CHAIN (arglist);
5540 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5541 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5542 of CONST_INTs, where we know the old_mode only from the call argument. */
5543 old_mode = GET_MODE (new_val);
5544 if (old_mode == VOIDmode)
5545 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5546 new_val = convert_modes (mode, old_mode, new_val, 1);
5548 if (is_bool)
5549 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5550 else
5551 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5554 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5555 general form is actually an atomic exchange, and some targets only
5556 support a reduced form with the second argument being a constant 1.
5557 ARGLIST is the operands list to the function; TARGET is an optional
5558 place for us to store the results. */
5560 static rtx
5561 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5562 rtx target)
5564 rtx val, mem;
5565 enum machine_mode old_mode;
5567 /* Expand the operands. */
5568 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5570 arglist = TREE_CHAIN (arglist);
5571 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5572 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5573 of CONST_INTs, where we know the old_mode only from the call argument. */
5574 old_mode = GET_MODE (val);
5575 if (old_mode == VOIDmode)
5576 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5577 val = convert_modes (mode, old_mode, val, 1);
5579 return expand_sync_lock_test_and_set (mem, val, target);
5582 /* Expand the __sync_synchronize intrinsic. */
5584 static void
5585 expand_builtin_synchronize (void)
5587 tree x;
5589 #ifdef HAVE_memory_barrier
5590 if (HAVE_memory_barrier)
5592 emit_insn (gen_memory_barrier ());
5593 return;
5595 #endif
5597 /* If no explicit memory barrier instruction is available, create an
5598 empty asm stmt with a memory clobber. */
5599 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5600 tree_cons (NULL, build_string (6, "memory"), NULL));
5601 ASM_VOLATILE_P (x) = 1;
5602 expand_asm_expr (x);
5605 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5606 to the function. */
5608 static void
5609 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5611 enum insn_code icode;
5612 rtx mem, insn;
5613 rtx val = const0_rtx;
5615 /* Expand the operands. */
5616 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5618 /* If there is an explicit operation in the md file, use it. */
5619 icode = sync_lock_release[mode];
5620 if (icode != CODE_FOR_nothing)
5622 if (!insn_data[icode].operand[1].predicate (val, mode))
5623 val = force_reg (mode, val);
5625 insn = GEN_FCN (icode) (mem, val);
5626 if (insn)
5628 emit_insn (insn);
5629 return;
5633 /* Otherwise we can implement this operation by emitting a barrier
5634 followed by a store of zero. */
5635 expand_builtin_synchronize ();
5636 emit_move_insn (mem, val);
5639 /* Expand an expression EXP that calls a built-in function,
5640 with result going to TARGET if that's convenient
5641 (and in mode MODE if that's convenient).
5642 SUBTARGET may be used as the target for computing one of EXP's operands.
5643 IGNORE is nonzero if the value is to be ignored. */
5646 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5647 int ignore)
5649 tree fndecl = get_callee_fndecl (exp);
5650 tree arglist = TREE_OPERAND (exp, 1);
5651 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5652 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5654 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5655 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5657 /* When not optimizing, generate calls to library functions for a certain
5658 set of builtins. */
5659 if (!optimize
5660 && !called_as_built_in (fndecl)
5661 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5662 && fcode != BUILT_IN_ALLOCA)
5663 return expand_call (exp, target, ignore);
5665 /* The built-in function expanders test for target == const0_rtx
5666 to determine whether the function's result will be ignored. */
5667 if (ignore)
5668 target = const0_rtx;
5670 /* If the result of a pure or const built-in function is ignored, and
5671 none of its arguments are volatile, we can avoid expanding the
5672 built-in call and just evaluate the arguments for side-effects. */
5673 if (target == const0_rtx
5674 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5676 bool volatilep = false;
5677 tree arg;
5679 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5680 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5682 volatilep = true;
5683 break;
5686 if (! volatilep)
5688 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5689 expand_expr (TREE_VALUE (arg), const0_rtx,
5690 VOIDmode, EXPAND_NORMAL);
5691 return const0_rtx;
5695 switch (fcode)
5697 CASE_FLT_FN (BUILT_IN_FABS):
5698 target = expand_builtin_fabs (arglist, target, subtarget);
5699 if (target)
5700 return target;
5701 break;
5703 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5704 target = expand_builtin_copysign (arglist, target, subtarget);
5705 if (target)
5706 return target;
5707 break;
5709 /* Just do a normal library call if we were unable to fold
5710 the values. */
5711 CASE_FLT_FN (BUILT_IN_CABS):
5712 break;
5714 CASE_FLT_FN (BUILT_IN_EXP):
5715 CASE_FLT_FN (BUILT_IN_EXP10):
5716 CASE_FLT_FN (BUILT_IN_POW10):
5717 CASE_FLT_FN (BUILT_IN_EXP2):
5718 CASE_FLT_FN (BUILT_IN_EXPM1):
5719 CASE_FLT_FN (BUILT_IN_LOGB):
5720 CASE_FLT_FN (BUILT_IN_ILOGB):
5721 CASE_FLT_FN (BUILT_IN_LOG):
5722 CASE_FLT_FN (BUILT_IN_LOG10):
5723 CASE_FLT_FN (BUILT_IN_LOG2):
5724 CASE_FLT_FN (BUILT_IN_LOG1P):
5725 CASE_FLT_FN (BUILT_IN_TAN):
5726 CASE_FLT_FN (BUILT_IN_ASIN):
5727 CASE_FLT_FN (BUILT_IN_ACOS):
5728 CASE_FLT_FN (BUILT_IN_ATAN):
5729 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5730 because of possible accuracy problems. */
5731 if (! flag_unsafe_math_optimizations)
5732 break;
5733 CASE_FLT_FN (BUILT_IN_SQRT):
5734 CASE_FLT_FN (BUILT_IN_FLOOR):
5735 CASE_FLT_FN (BUILT_IN_CEIL):
5736 CASE_FLT_FN (BUILT_IN_TRUNC):
5737 CASE_FLT_FN (BUILT_IN_ROUND):
5738 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5739 CASE_FLT_FN (BUILT_IN_RINT):
5740 CASE_FLT_FN (BUILT_IN_LRINT):
5741 CASE_FLT_FN (BUILT_IN_LLRINT):
5742 target = expand_builtin_mathfn (exp, target, subtarget);
5743 if (target)
5744 return target;
5745 break;
5747 CASE_FLT_FN (BUILT_IN_LCEIL):
5748 CASE_FLT_FN (BUILT_IN_LLCEIL):
5749 CASE_FLT_FN (BUILT_IN_LFLOOR):
5750 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5751 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5752 if (target)
5753 return target;
5754 break;
5756 CASE_FLT_FN (BUILT_IN_POW):
5757 target = expand_builtin_pow (exp, target, subtarget);
5758 if (target)
5759 return target;
5760 break;
5762 CASE_FLT_FN (BUILT_IN_POWI):
5763 target = expand_builtin_powi (exp, target, subtarget);
5764 if (target)
5765 return target;
5766 break;
5768 CASE_FLT_FN (BUILT_IN_ATAN2):
5769 CASE_FLT_FN (BUILT_IN_LDEXP):
5770 CASE_FLT_FN (BUILT_IN_FMOD):
5771 CASE_FLT_FN (BUILT_IN_DREM):
5772 if (! flag_unsafe_math_optimizations)
5773 break;
5774 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5775 if (target)
5776 return target;
5777 break;
5779 CASE_FLT_FN (BUILT_IN_SIN):
5780 CASE_FLT_FN (BUILT_IN_COS):
5781 if (! flag_unsafe_math_optimizations)
5782 break;
5783 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5784 if (target)
5785 return target;
5786 break;
5788 CASE_FLT_FN (BUILT_IN_SINCOS):
5789 if (! flag_unsafe_math_optimizations)
5790 break;
5791 target = expand_builtin_sincos (exp);
5792 if (target)
5793 return target;
5794 break;
5796 case BUILT_IN_APPLY_ARGS:
5797 return expand_builtin_apply_args ();
5799 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5800 FUNCTION with a copy of the parameters described by
5801 ARGUMENTS, and ARGSIZE. It returns a block of memory
5802 allocated on the stack into which is stored all the registers
5803 that might possibly be used for returning the result of a
5804 function. ARGUMENTS is the value returned by
5805 __builtin_apply_args. ARGSIZE is the number of bytes of
5806 arguments that must be copied. ??? How should this value be
5807 computed? We'll also need a safe worst case value for varargs
5808 functions. */
5809 case BUILT_IN_APPLY:
5810 if (!validate_arglist (arglist, POINTER_TYPE,
5811 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5812 && !validate_arglist (arglist, REFERENCE_TYPE,
5813 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5814 return const0_rtx;
5815 else
5817 int i;
5818 tree t;
5819 rtx ops[3];
5821 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5822 ops[i] = expand_normal (TREE_VALUE (t));
5824 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5827 /* __builtin_return (RESULT) causes the function to return the
5828 value described by RESULT. RESULT is address of the block of
5829 memory returned by __builtin_apply. */
5830 case BUILT_IN_RETURN:
5831 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5832 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5833 return const0_rtx;
5835 case BUILT_IN_SAVEREGS:
5836 return expand_builtin_saveregs ();
5838 case BUILT_IN_ARGS_INFO:
5839 return expand_builtin_args_info (arglist);
5841 /* Return the address of the first anonymous stack arg. */
5842 case BUILT_IN_NEXT_ARG:
5843 if (fold_builtin_next_arg (arglist))
5844 return const0_rtx;
5845 return expand_builtin_next_arg ();
5847 case BUILT_IN_CLASSIFY_TYPE:
5848 return expand_builtin_classify_type (arglist);
5850 case BUILT_IN_CONSTANT_P:
5851 return const0_rtx;
5853 case BUILT_IN_FRAME_ADDRESS:
5854 case BUILT_IN_RETURN_ADDRESS:
5855 return expand_builtin_frame_address (fndecl, arglist);
5857 /* Returns the address of the area where the structure is returned.
5858 0 otherwise. */
5859 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5860 if (arglist != 0
5861 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5862 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5863 return const0_rtx;
5864 else
5865 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5867 case BUILT_IN_ALLOCA:
5868 target = expand_builtin_alloca (arglist, target);
5869 if (target)
5870 return target;
5871 break;
5873 case BUILT_IN_STACK_SAVE:
5874 return expand_stack_save ();
5876 case BUILT_IN_STACK_RESTORE:
5877 expand_stack_restore (TREE_VALUE (arglist));
5878 return const0_rtx;
5880 CASE_INT_FN (BUILT_IN_FFS):
5881 case BUILT_IN_FFSIMAX:
5882 target = expand_builtin_unop (target_mode, arglist, target,
5883 subtarget, ffs_optab);
5884 if (target)
5885 return target;
5886 break;
5888 CASE_INT_FN (BUILT_IN_CLZ):
5889 case BUILT_IN_CLZIMAX:
5890 target = expand_builtin_unop (target_mode, arglist, target,
5891 subtarget, clz_optab);
5892 if (target)
5893 return target;
5894 break;
5896 CASE_INT_FN (BUILT_IN_CTZ):
5897 case BUILT_IN_CTZIMAX:
5898 target = expand_builtin_unop (target_mode, arglist, target,
5899 subtarget, ctz_optab);
5900 if (target)
5901 return target;
5902 break;
5904 CASE_INT_FN (BUILT_IN_POPCOUNT):
5905 case BUILT_IN_POPCOUNTIMAX:
5906 target = expand_builtin_unop (target_mode, arglist, target,
5907 subtarget, popcount_optab);
5908 if (target)
5909 return target;
5910 break;
5912 CASE_INT_FN (BUILT_IN_PARITY):
5913 case BUILT_IN_PARITYIMAX:
5914 target = expand_builtin_unop (target_mode, arglist, target,
5915 subtarget, parity_optab);
5916 if (target)
5917 return target;
5918 break;
5920 case BUILT_IN_STRLEN:
5921 target = expand_builtin_strlen (arglist, target, target_mode);
5922 if (target)
5923 return target;
5924 break;
5926 case BUILT_IN_STRCPY:
5927 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5928 if (target)
5929 return target;
5930 break;
5932 case BUILT_IN_STRNCPY:
5933 target = expand_builtin_strncpy (exp, target, mode);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_STPCPY:
5939 target = expand_builtin_stpcpy (exp, target, mode);
5940 if (target)
5941 return target;
5942 break;
5944 case BUILT_IN_STRCAT:
5945 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5946 if (target)
5947 return target;
5948 break;
5950 case BUILT_IN_STRNCAT:
5951 target = expand_builtin_strncat (arglist, target, mode);
5952 if (target)
5953 return target;
5954 break;
5956 case BUILT_IN_STRSPN:
5957 target = expand_builtin_strspn (arglist, target, mode);
5958 if (target)
5959 return target;
5960 break;
5962 case BUILT_IN_STRCSPN:
5963 target = expand_builtin_strcspn (arglist, target, mode);
5964 if (target)
5965 return target;
5966 break;
5968 case BUILT_IN_STRSTR:
5969 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5970 if (target)
5971 return target;
5972 break;
5974 case BUILT_IN_STRPBRK:
5975 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5976 if (target)
5977 return target;
5978 break;
5980 case BUILT_IN_INDEX:
5981 case BUILT_IN_STRCHR:
5982 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5983 if (target)
5984 return target;
5985 break;
5987 case BUILT_IN_RINDEX:
5988 case BUILT_IN_STRRCHR:
5989 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5990 if (target)
5991 return target;
5992 break;
5994 case BUILT_IN_MEMCPY:
5995 target = expand_builtin_memcpy (exp, target, mode);
5996 if (target)
5997 return target;
5998 break;
6000 case BUILT_IN_MEMPCPY:
6001 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6002 if (target)
6003 return target;
6004 break;
6006 case BUILT_IN_MEMMOVE:
6007 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6008 mode, exp);
6009 if (target)
6010 return target;
6011 break;
6013 case BUILT_IN_BCOPY:
6014 target = expand_builtin_bcopy (exp);
6015 if (target)
6016 return target;
6017 break;
6019 case BUILT_IN_MEMSET:
6020 target = expand_builtin_memset (arglist, target, mode, exp);
6021 if (target)
6022 return target;
6023 break;
6025 case BUILT_IN_BZERO:
6026 target = expand_builtin_bzero (exp);
6027 if (target)
6028 return target;
6029 break;
6031 case BUILT_IN_STRCMP:
6032 target = expand_builtin_strcmp (exp, target, mode);
6033 if (target)
6034 return target;
6035 break;
6037 case BUILT_IN_STRNCMP:
6038 target = expand_builtin_strncmp (exp, target, mode);
6039 if (target)
6040 return target;
6041 break;
6043 case BUILT_IN_BCMP:
6044 case BUILT_IN_MEMCMP:
6045 target = expand_builtin_memcmp (exp, arglist, target, mode);
6046 if (target)
6047 return target;
6048 break;
6050 case BUILT_IN_SETJMP:
6051 /* This should have been lowered to the builtins below. */
6052 gcc_unreachable ();
6054 case BUILT_IN_SETJMP_SETUP:
6055 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6056 and the receiver label. */
6057 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6059 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6060 VOIDmode, EXPAND_NORMAL);
6061 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6062 rtx label_r = label_rtx (label);
6064 /* This is copied from the handling of non-local gotos. */
6065 expand_builtin_setjmp_setup (buf_addr, label_r);
6066 nonlocal_goto_handler_labels
6067 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6068 nonlocal_goto_handler_labels);
6069 /* ??? Do not let expand_label treat us as such since we would
6070 not want to be both on the list of non-local labels and on
6071 the list of forced labels. */
6072 FORCED_LABEL (label) = 0;
6073 return const0_rtx;
6075 break;
6077 case BUILT_IN_SETJMP_DISPATCHER:
6078 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6079 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6081 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6082 rtx label_r = label_rtx (label);
6084 /* Remove the dispatcher label from the list of non-local labels
6085 since the receiver labels have been added to it above. */
6086 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6087 return const0_rtx;
6089 break;
6091 case BUILT_IN_SETJMP_RECEIVER:
6092 /* __builtin_setjmp_receiver is passed the receiver label. */
6093 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6095 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6096 rtx label_r = label_rtx (label);
6098 expand_builtin_setjmp_receiver (label_r);
6099 return const0_rtx;
6101 break;
6103 /* __builtin_longjmp is passed a pointer to an array of five words.
6104 It's similar to the C library longjmp function but works with
6105 __builtin_setjmp above. */
6106 case BUILT_IN_LONGJMP:
6107 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6109 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6110 VOIDmode, EXPAND_NORMAL);
6111 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6113 if (value != const1_rtx)
6115 error ("%<__builtin_longjmp%> second argument must be 1");
6116 return const0_rtx;
6119 expand_builtin_longjmp (buf_addr, value);
6120 return const0_rtx;
6122 break;
6124 case BUILT_IN_NONLOCAL_GOTO:
6125 target = expand_builtin_nonlocal_goto (arglist);
6126 if (target)
6127 return target;
6128 break;
6130 /* This updates the setjmp buffer that is its argument with the value
6131 of the current stack pointer. */
6132 case BUILT_IN_UPDATE_SETJMP_BUF:
6133 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6135 rtx buf_addr
6136 = expand_normal (TREE_VALUE (arglist));
6138 expand_builtin_update_setjmp_buf (buf_addr);
6139 return const0_rtx;
6141 break;
6143 case BUILT_IN_TRAP:
6144 expand_builtin_trap ();
6145 return const0_rtx;
6147 case BUILT_IN_PRINTF:
6148 target = expand_builtin_printf (exp, target, mode, false);
6149 if (target)
6150 return target;
6151 break;
6153 case BUILT_IN_PRINTF_UNLOCKED:
6154 target = expand_builtin_printf (exp, target, mode, true);
6155 if (target)
6156 return target;
6157 break;
6159 case BUILT_IN_FPUTS:
6160 target = expand_builtin_fputs (arglist, target, false);
6161 if (target)
6162 return target;
6163 break;
6164 case BUILT_IN_FPUTS_UNLOCKED:
6165 target = expand_builtin_fputs (arglist, target, true);
6166 if (target)
6167 return target;
6168 break;
6170 case BUILT_IN_FPRINTF:
6171 target = expand_builtin_fprintf (exp, target, mode, false);
6172 if (target)
6173 return target;
6174 break;
6176 case BUILT_IN_FPRINTF_UNLOCKED:
6177 target = expand_builtin_fprintf (exp, target, mode, true);
6178 if (target)
6179 return target;
6180 break;
6182 case BUILT_IN_SPRINTF:
6183 target = expand_builtin_sprintf (arglist, target, mode);
6184 if (target)
6185 return target;
6186 break;
6188 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6189 target = expand_builtin_signbit (exp, target);
6190 if (target)
6191 return target;
6192 break;
6194 /* Various hooks for the DWARF 2 __throw routine. */
6195 case BUILT_IN_UNWIND_INIT:
6196 expand_builtin_unwind_init ();
6197 return const0_rtx;
6198 case BUILT_IN_DWARF_CFA:
6199 return virtual_cfa_rtx;
6200 #ifdef DWARF2_UNWIND_INFO
6201 case BUILT_IN_DWARF_SP_COLUMN:
6202 return expand_builtin_dwarf_sp_column ();
6203 case BUILT_IN_INIT_DWARF_REG_SIZES:
6204 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6205 return const0_rtx;
6206 #endif
6207 case BUILT_IN_FROB_RETURN_ADDR:
6208 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6209 case BUILT_IN_EXTRACT_RETURN_ADDR:
6210 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6211 case BUILT_IN_EH_RETURN:
6212 expand_builtin_eh_return (TREE_VALUE (arglist),
6213 TREE_VALUE (TREE_CHAIN (arglist)));
6214 return const0_rtx;
6215 #ifdef EH_RETURN_DATA_REGNO
6216 case BUILT_IN_EH_RETURN_DATA_REGNO:
6217 return expand_builtin_eh_return_data_regno (arglist);
6218 #endif
6219 case BUILT_IN_EXTEND_POINTER:
6220 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6222 case BUILT_IN_VA_START:
6223 case BUILT_IN_STDARG_START:
6224 return expand_builtin_va_start (arglist);
6225 case BUILT_IN_VA_END:
6226 return expand_builtin_va_end (arglist);
6227 case BUILT_IN_VA_COPY:
6228 return expand_builtin_va_copy (arglist);
6229 case BUILT_IN_EXPECT:
6230 return expand_builtin_expect (arglist, target);
6231 case BUILT_IN_PREFETCH:
6232 expand_builtin_prefetch (arglist);
6233 return const0_rtx;
6235 case BUILT_IN_PROFILE_FUNC_ENTER:
6236 return expand_builtin_profile_func (false);
6237 case BUILT_IN_PROFILE_FUNC_EXIT:
6238 return expand_builtin_profile_func (true);
6240 case BUILT_IN_INIT_TRAMPOLINE:
6241 return expand_builtin_init_trampoline (arglist);
6242 case BUILT_IN_ADJUST_TRAMPOLINE:
6243 return expand_builtin_adjust_trampoline (arglist);
6245 case BUILT_IN_FORK:
6246 case BUILT_IN_EXECL:
6247 case BUILT_IN_EXECV:
6248 case BUILT_IN_EXECLP:
6249 case BUILT_IN_EXECLE:
6250 case BUILT_IN_EXECVP:
6251 case BUILT_IN_EXECVE:
6252 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6253 if (target)
6254 return target;
6255 break;
6257 case BUILT_IN_FETCH_AND_ADD_1:
6258 case BUILT_IN_FETCH_AND_ADD_2:
6259 case BUILT_IN_FETCH_AND_ADD_4:
6260 case BUILT_IN_FETCH_AND_ADD_8:
6261 case BUILT_IN_FETCH_AND_ADD_16:
6262 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6263 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6264 false, target, ignore);
6265 if (target)
6266 return target;
6267 break;
6269 case BUILT_IN_FETCH_AND_SUB_1:
6270 case BUILT_IN_FETCH_AND_SUB_2:
6271 case BUILT_IN_FETCH_AND_SUB_4:
6272 case BUILT_IN_FETCH_AND_SUB_8:
6273 case BUILT_IN_FETCH_AND_SUB_16:
6274 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6275 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6276 false, target, ignore);
6277 if (target)
6278 return target;
6279 break;
6281 case BUILT_IN_FETCH_AND_OR_1:
6282 case BUILT_IN_FETCH_AND_OR_2:
6283 case BUILT_IN_FETCH_AND_OR_4:
6284 case BUILT_IN_FETCH_AND_OR_8:
6285 case BUILT_IN_FETCH_AND_OR_16:
6286 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6287 target = expand_builtin_sync_operation (mode, arglist, IOR,
6288 false, target, ignore);
6289 if (target)
6290 return target;
6291 break;
6293 case BUILT_IN_FETCH_AND_AND_1:
6294 case BUILT_IN_FETCH_AND_AND_2:
6295 case BUILT_IN_FETCH_AND_AND_4:
6296 case BUILT_IN_FETCH_AND_AND_8:
6297 case BUILT_IN_FETCH_AND_AND_16:
6298 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6299 target = expand_builtin_sync_operation (mode, arglist, AND,
6300 false, target, ignore);
6301 if (target)
6302 return target;
6303 break;
6305 case BUILT_IN_FETCH_AND_XOR_1:
6306 case BUILT_IN_FETCH_AND_XOR_2:
6307 case BUILT_IN_FETCH_AND_XOR_4:
6308 case BUILT_IN_FETCH_AND_XOR_8:
6309 case BUILT_IN_FETCH_AND_XOR_16:
6310 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6311 target = expand_builtin_sync_operation (mode, arglist, XOR,
6312 false, target, ignore);
6313 if (target)
6314 return target;
6315 break;
6317 case BUILT_IN_FETCH_AND_NAND_1:
6318 case BUILT_IN_FETCH_AND_NAND_2:
6319 case BUILT_IN_FETCH_AND_NAND_4:
6320 case BUILT_IN_FETCH_AND_NAND_8:
6321 case BUILT_IN_FETCH_AND_NAND_16:
6322 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6323 target = expand_builtin_sync_operation (mode, arglist, NOT,
6324 false, target, ignore);
6325 if (target)
6326 return target;
6327 break;
6329 case BUILT_IN_ADD_AND_FETCH_1:
6330 case BUILT_IN_ADD_AND_FETCH_2:
6331 case BUILT_IN_ADD_AND_FETCH_4:
6332 case BUILT_IN_ADD_AND_FETCH_8:
6333 case BUILT_IN_ADD_AND_FETCH_16:
6334 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6335 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6336 true, target, ignore);
6337 if (target)
6338 return target;
6339 break;
6341 case BUILT_IN_SUB_AND_FETCH_1:
6342 case BUILT_IN_SUB_AND_FETCH_2:
6343 case BUILT_IN_SUB_AND_FETCH_4:
6344 case BUILT_IN_SUB_AND_FETCH_8:
6345 case BUILT_IN_SUB_AND_FETCH_16:
6346 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6347 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6348 true, target, ignore);
6349 if (target)
6350 return target;
6351 break;
6353 case BUILT_IN_OR_AND_FETCH_1:
6354 case BUILT_IN_OR_AND_FETCH_2:
6355 case BUILT_IN_OR_AND_FETCH_4:
6356 case BUILT_IN_OR_AND_FETCH_8:
6357 case BUILT_IN_OR_AND_FETCH_16:
6358 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6359 target = expand_builtin_sync_operation (mode, arglist, IOR,
6360 true, target, ignore);
6361 if (target)
6362 return target;
6363 break;
6365 case BUILT_IN_AND_AND_FETCH_1:
6366 case BUILT_IN_AND_AND_FETCH_2:
6367 case BUILT_IN_AND_AND_FETCH_4:
6368 case BUILT_IN_AND_AND_FETCH_8:
6369 case BUILT_IN_AND_AND_FETCH_16:
6370 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6371 target = expand_builtin_sync_operation (mode, arglist, AND,
6372 true, target, ignore);
6373 if (target)
6374 return target;
6375 break;
6377 case BUILT_IN_XOR_AND_FETCH_1:
6378 case BUILT_IN_XOR_AND_FETCH_2:
6379 case BUILT_IN_XOR_AND_FETCH_4:
6380 case BUILT_IN_XOR_AND_FETCH_8:
6381 case BUILT_IN_XOR_AND_FETCH_16:
6382 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6383 target = expand_builtin_sync_operation (mode, arglist, XOR,
6384 true, target, ignore);
6385 if (target)
6386 return target;
6387 break;
6389 case BUILT_IN_NAND_AND_FETCH_1:
6390 case BUILT_IN_NAND_AND_FETCH_2:
6391 case BUILT_IN_NAND_AND_FETCH_4:
6392 case BUILT_IN_NAND_AND_FETCH_8:
6393 case BUILT_IN_NAND_AND_FETCH_16:
6394 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6395 target = expand_builtin_sync_operation (mode, arglist, NOT,
6396 true, target, ignore);
6397 if (target)
6398 return target;
6399 break;
6401 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6402 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6403 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6404 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6405 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6406 if (mode == VOIDmode)
6407 mode = TYPE_MODE (boolean_type_node);
6408 if (!target || !register_operand (target, mode))
6409 target = gen_reg_rtx (mode);
6411 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6412 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6413 if (target)
6414 return target;
6415 break;
6417 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6418 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6419 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6420 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6421 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6422 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6423 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6424 if (target)
6425 return target;
6426 break;
6428 case BUILT_IN_LOCK_TEST_AND_SET_1:
6429 case BUILT_IN_LOCK_TEST_AND_SET_2:
6430 case BUILT_IN_LOCK_TEST_AND_SET_4:
6431 case BUILT_IN_LOCK_TEST_AND_SET_8:
6432 case BUILT_IN_LOCK_TEST_AND_SET_16:
6433 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6434 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6435 if (target)
6436 return target;
6437 break;
6439 case BUILT_IN_LOCK_RELEASE_1:
6440 case BUILT_IN_LOCK_RELEASE_2:
6441 case BUILT_IN_LOCK_RELEASE_4:
6442 case BUILT_IN_LOCK_RELEASE_8:
6443 case BUILT_IN_LOCK_RELEASE_16:
6444 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6445 expand_builtin_lock_release (mode, arglist);
6446 return const0_rtx;
6448 case BUILT_IN_SYNCHRONIZE:
6449 expand_builtin_synchronize ();
6450 return const0_rtx;
6452 case BUILT_IN_OBJECT_SIZE:
6453 return expand_builtin_object_size (exp);
6455 case BUILT_IN_MEMCPY_CHK:
6456 case BUILT_IN_MEMPCPY_CHK:
6457 case BUILT_IN_MEMMOVE_CHK:
6458 case BUILT_IN_MEMSET_CHK:
6459 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6460 if (target)
6461 return target;
6462 break;
6464 case BUILT_IN_STRCPY_CHK:
6465 case BUILT_IN_STPCPY_CHK:
6466 case BUILT_IN_STRNCPY_CHK:
6467 case BUILT_IN_STRCAT_CHK:
6468 case BUILT_IN_SNPRINTF_CHK:
6469 case BUILT_IN_VSNPRINTF_CHK:
6470 maybe_emit_chk_warning (exp, fcode);
6471 break;
6473 case BUILT_IN_SPRINTF_CHK:
6474 case BUILT_IN_VSPRINTF_CHK:
6475 maybe_emit_sprintf_chk_warning (exp, fcode);
6476 break;
6478 default: /* just do library call, if unknown builtin */
6479 break;
6482 /* The switch statement above can drop through to cause the function
6483 to be called normally. */
6484 return expand_call (exp, target, ignore);
6487 /* Determine whether a tree node represents a call to a built-in
6488 function. If the tree T is a call to a built-in function with
6489 the right number of arguments of the appropriate types, return
6490 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6491 Otherwise the return value is END_BUILTINS. */
6493 enum built_in_function
6494 builtin_mathfn_code (tree t)
6496 tree fndecl, arglist, parmlist;
6497 tree argtype, parmtype;
6499 if (TREE_CODE (t) != CALL_EXPR
6500 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6501 return END_BUILTINS;
6503 fndecl = get_callee_fndecl (t);
6504 if (fndecl == NULL_TREE
6505 || TREE_CODE (fndecl) != FUNCTION_DECL
6506 || ! DECL_BUILT_IN (fndecl)
6507 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6508 return END_BUILTINS;
6510 arglist = TREE_OPERAND (t, 1);
6511 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6512 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6514 /* If a function doesn't take a variable number of arguments,
6515 the last element in the list will have type `void'. */
6516 parmtype = TREE_VALUE (parmlist);
6517 if (VOID_TYPE_P (parmtype))
6519 if (arglist)
6520 return END_BUILTINS;
6521 return DECL_FUNCTION_CODE (fndecl);
6524 if (! arglist)
6525 return END_BUILTINS;
6527 argtype = TREE_TYPE (TREE_VALUE (arglist));
6529 if (SCALAR_FLOAT_TYPE_P (parmtype))
6531 if (! SCALAR_FLOAT_TYPE_P (argtype))
6532 return END_BUILTINS;
6534 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6536 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6537 return END_BUILTINS;
6539 else if (POINTER_TYPE_P (parmtype))
6541 if (! POINTER_TYPE_P (argtype))
6542 return END_BUILTINS;
6544 else if (INTEGRAL_TYPE_P (parmtype))
6546 if (! INTEGRAL_TYPE_P (argtype))
6547 return END_BUILTINS;
6549 else
6550 return END_BUILTINS;
6552 arglist = TREE_CHAIN (arglist);
6555 /* Variable-length argument list. */
6556 return DECL_FUNCTION_CODE (fndecl);
6559 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6560 constant. ARGLIST is the argument list of the call. */
6562 static tree
6563 fold_builtin_constant_p (tree arglist)
6565 if (arglist == 0)
6566 return 0;
6568 arglist = TREE_VALUE (arglist);
6570 /* We return 1 for a numeric type that's known to be a constant
6571 value at compile-time or for an aggregate type that's a
6572 literal constant. */
6573 STRIP_NOPS (arglist);
6575 /* If we know this is a constant, emit the constant of one. */
6576 if (CONSTANT_CLASS_P (arglist)
6577 || (TREE_CODE (arglist) == CONSTRUCTOR
6578 && TREE_CONSTANT (arglist)))
6579 return integer_one_node;
6580 if (TREE_CODE (arglist) == ADDR_EXPR)
6582 tree op = TREE_OPERAND (arglist, 0);
6583 if (TREE_CODE (op) == STRING_CST
6584 || (TREE_CODE (op) == ARRAY_REF
6585 && integer_zerop (TREE_OPERAND (op, 1))
6586 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6587 return integer_one_node;
6590 /* If this expression has side effects, show we don't know it to be a
6591 constant. Likewise if it's a pointer or aggregate type since in
6592 those case we only want literals, since those are only optimized
6593 when generating RTL, not later.
6594 And finally, if we are compiling an initializer, not code, we
6595 need to return a definite result now; there's not going to be any
6596 more optimization done. */
6597 if (TREE_SIDE_EFFECTS (arglist)
6598 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6599 || POINTER_TYPE_P (TREE_TYPE (arglist))
6600 || cfun == 0
6601 || folding_initializer)
6602 return integer_zero_node;
6604 return 0;
6607 /* Fold a call to __builtin_expect, if we expect that a comparison against
6608 the argument will fold to a constant. In practice, this means a true
6609 constant or the address of a non-weak symbol. ARGLIST is the argument
6610 list of the call. */
6612 static tree
6613 fold_builtin_expect (tree arglist)
6615 tree arg, inner;
6617 if (arglist == 0)
6618 return 0;
6620 arg = TREE_VALUE (arglist);
6622 /* If the argument isn't invariant, then there's nothing we can do. */
6623 if (!TREE_INVARIANT (arg))
6624 return 0;
6626 /* If we're looking at an address of a weak decl, then do not fold. */
6627 inner = arg;
6628 STRIP_NOPS (inner);
6629 if (TREE_CODE (inner) == ADDR_EXPR)
6633 inner = TREE_OPERAND (inner, 0);
6635 while (TREE_CODE (inner) == COMPONENT_REF
6636 || TREE_CODE (inner) == ARRAY_REF);
6637 if (DECL_P (inner) && DECL_WEAK (inner))
6638 return 0;
6641 /* Otherwise, ARG already has the proper type for the return value. */
6642 return arg;
6645 /* Fold a call to __builtin_classify_type. */
6647 static tree
6648 fold_builtin_classify_type (tree arglist)
6650 if (arglist == 0)
6651 return build_int_cst (NULL_TREE, no_type_class);
6653 return build_int_cst (NULL_TREE,
6654 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6657 /* Fold a call to __builtin_strlen. */
6659 static tree
6660 fold_builtin_strlen (tree arglist)
6662 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6663 return NULL_TREE;
6664 else
6666 tree len = c_strlen (TREE_VALUE (arglist), 0);
6668 if (len)
6670 /* Convert from the internal "sizetype" type to "size_t". */
6671 if (size_type_node)
6672 len = fold_convert (size_type_node, len);
6673 return len;
6676 return NULL_TREE;
6680 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6682 static tree
6683 fold_builtin_inf (tree type, int warn)
6685 REAL_VALUE_TYPE real;
6687 /* __builtin_inff is intended to be usable to define INFINITY on all
6688 targets. If an infinity is not available, INFINITY expands "to a
6689 positive constant of type float that overflows at translation
6690 time", footnote "In this case, using INFINITY will violate the
6691 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6692 Thus we pedwarn to ensure this constraint violation is
6693 diagnosed. */
6694 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6695 pedwarn ("target format does not support infinity");
6697 real_inf (&real);
6698 return build_real (type, real);
6701 /* Fold a call to __builtin_nan or __builtin_nans. */
6703 static tree
6704 fold_builtin_nan (tree arglist, tree type, int quiet)
6706 REAL_VALUE_TYPE real;
6707 const char *str;
6709 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6710 return 0;
6711 str = c_getstr (TREE_VALUE (arglist));
6712 if (!str)
6713 return 0;
6715 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6716 return 0;
6718 return build_real (type, real);
6721 /* Return true if the floating point expression T has an integer value.
6722 We also allow +Inf, -Inf and NaN to be considered integer values. */
6724 static bool
6725 integer_valued_real_p (tree t)
6727 switch (TREE_CODE (t))
6729 case FLOAT_EXPR:
6730 return true;
6732 case ABS_EXPR:
6733 case SAVE_EXPR:
6734 case NON_LVALUE_EXPR:
6735 return integer_valued_real_p (TREE_OPERAND (t, 0));
6737 case COMPOUND_EXPR:
6738 case MODIFY_EXPR:
6739 case BIND_EXPR:
6740 return integer_valued_real_p (TREE_OPERAND (t, 1));
6742 case PLUS_EXPR:
6743 case MINUS_EXPR:
6744 case MULT_EXPR:
6745 case MIN_EXPR:
6746 case MAX_EXPR:
6747 return integer_valued_real_p (TREE_OPERAND (t, 0))
6748 && integer_valued_real_p (TREE_OPERAND (t, 1));
6750 case COND_EXPR:
6751 return integer_valued_real_p (TREE_OPERAND (t, 1))
6752 && integer_valued_real_p (TREE_OPERAND (t, 2));
6754 case REAL_CST:
6755 if (! TREE_CONSTANT_OVERFLOW (t))
6757 REAL_VALUE_TYPE c, cint;
6759 c = TREE_REAL_CST (t);
6760 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6761 return real_identical (&c, &cint);
6763 break;
6765 case NOP_EXPR:
6767 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6768 if (TREE_CODE (type) == INTEGER_TYPE)
6769 return true;
6770 if (TREE_CODE (type) == REAL_TYPE)
6771 return integer_valued_real_p (TREE_OPERAND (t, 0));
6772 break;
6775 case CALL_EXPR:
6776 switch (builtin_mathfn_code (t))
6778 CASE_FLT_FN (BUILT_IN_CEIL):
6779 CASE_FLT_FN (BUILT_IN_FLOOR):
6780 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6781 CASE_FLT_FN (BUILT_IN_RINT):
6782 CASE_FLT_FN (BUILT_IN_ROUND):
6783 CASE_FLT_FN (BUILT_IN_TRUNC):
6784 return true;
6786 default:
6787 break;
6789 break;
6791 default:
6792 break;
6794 return false;
6797 /* EXP is assumed to be builtin call where truncation can be propagated
6798 across (for instance floor((double)f) == (double)floorf (f).
6799 Do the transformation. */
6801 static tree
6802 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6804 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6805 tree arg;
6807 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6808 return 0;
6810 arg = TREE_VALUE (arglist);
6811 /* Integer rounding functions are idempotent. */
6812 if (fcode == builtin_mathfn_code (arg))
6813 return arg;
6815 /* If argument is already integer valued, and we don't need to worry
6816 about setting errno, there's no need to perform rounding. */
6817 if (! flag_errno_math && integer_valued_real_p (arg))
6818 return arg;
6820 if (optimize)
6822 tree arg0 = strip_float_extensions (arg);
6823 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6824 tree newtype = TREE_TYPE (arg0);
6825 tree decl;
6827 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6828 && (decl = mathfn_built_in (newtype, fcode)))
6830 arglist =
6831 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6832 return fold_convert (ftype,
6833 build_function_call_expr (decl, arglist));
6836 return 0;
6839 /* EXP is assumed to be builtin call which can narrow the FP type of
6840 the argument, for instance lround((double)f) -> lroundf (f). */
6842 static tree
6843 fold_fixed_mathfn (tree fndecl, tree arglist)
6845 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6846 tree arg;
6848 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6849 return 0;
6851 arg = TREE_VALUE (arglist);
6853 /* If argument is already integer valued, and we don't need to worry
6854 about setting errno, there's no need to perform rounding. */
6855 if (! flag_errno_math && integer_valued_real_p (arg))
6856 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6858 if (optimize)
6860 tree ftype = TREE_TYPE (arg);
6861 tree arg0 = strip_float_extensions (arg);
6862 tree newtype = TREE_TYPE (arg0);
6863 tree decl;
6865 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6866 && (decl = mathfn_built_in (newtype, fcode)))
6868 arglist =
6869 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6870 return build_function_call_expr (decl, arglist);
6874 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6875 sizeof (long long) == sizeof (long). */
6876 if (TYPE_PRECISION (long_long_integer_type_node)
6877 == TYPE_PRECISION (long_integer_type_node))
6879 tree newfn = NULL_TREE;
6880 switch (fcode)
6882 CASE_FLT_FN (BUILT_IN_LLCEIL):
6883 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6884 break;
6886 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6887 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6888 break;
6890 CASE_FLT_FN (BUILT_IN_LLROUND):
6891 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6892 break;
6894 CASE_FLT_FN (BUILT_IN_LLRINT):
6895 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6896 break;
6898 default:
6899 break;
6902 if (newfn)
6904 tree newcall = build_function_call_expr (newfn, arglist);
6905 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6909 return 0;
6912 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6913 is the argument list, TYPE is the return type and FNDECL is the
6914 original function DECL. Return NULL_TREE if no if no simplification
6915 can be made. */
6917 static tree
6918 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6920 tree arg;
6922 if (!arglist || TREE_CHAIN (arglist))
6923 return NULL_TREE;
6925 arg = TREE_VALUE (arglist);
6926 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6927 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6928 return NULL_TREE;
6930 /* Evaluate cabs of a constant at compile-time. */
6931 if (flag_unsafe_math_optimizations
6932 && TREE_CODE (arg) == COMPLEX_CST
6933 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6934 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6935 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6936 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6938 REAL_VALUE_TYPE r, i;
6940 r = TREE_REAL_CST (TREE_REALPART (arg));
6941 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6943 real_arithmetic (&r, MULT_EXPR, &r, &r);
6944 real_arithmetic (&i, MULT_EXPR, &i, &i);
6945 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6946 if (real_sqrt (&r, TYPE_MODE (type), &r)
6947 || ! flag_trapping_math)
6948 return build_real (type, r);
6951 /* If either part is zero, cabs is fabs of the other. */
6952 if (TREE_CODE (arg) == COMPLEX_EXPR
6953 && real_zerop (TREE_OPERAND (arg, 0)))
6954 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6955 if (TREE_CODE (arg) == COMPLEX_EXPR
6956 && real_zerop (TREE_OPERAND (arg, 1)))
6957 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6959 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6960 if (TREE_CODE (arg) == NEGATE_EXPR
6961 || TREE_CODE (arg) == CONJ_EXPR)
6963 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6964 return build_function_call_expr (fndecl, arglist);
6967 /* Don't do this when optimizing for size. */
6968 if (flag_unsafe_math_optimizations
6969 && optimize && !optimize_size)
6971 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6973 if (sqrtfn != NULL_TREE)
6975 tree rpart, ipart, result, arglist;
6977 arg = builtin_save_expr (arg);
6979 rpart = fold_build1 (REALPART_EXPR, type, arg);
6980 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6982 rpart = builtin_save_expr (rpart);
6983 ipart = builtin_save_expr (ipart);
6985 result = fold_build2 (PLUS_EXPR, type,
6986 fold_build2 (MULT_EXPR, type,
6987 rpart, rpart),
6988 fold_build2 (MULT_EXPR, type,
6989 ipart, ipart));
6991 arglist = build_tree_list (NULL_TREE, result);
6992 return build_function_call_expr (sqrtfn, arglist);
6996 return NULL_TREE;
6999 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7000 NULL_TREE if no simplification can be made. */
7002 static tree
7003 fold_builtin_sqrt (tree arglist, tree type)
7006 enum built_in_function fcode;
7007 tree arg = TREE_VALUE (arglist);
7009 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7010 return NULL_TREE;
7012 /* Optimize sqrt of constant value. */
7013 if (TREE_CODE (arg) == REAL_CST
7014 && ! TREE_CONSTANT_OVERFLOW (arg))
7016 REAL_VALUE_TYPE r, x;
7018 x = TREE_REAL_CST (arg);
7019 if (real_sqrt (&r, TYPE_MODE (type), &x)
7020 || (!flag_trapping_math && !flag_errno_math))
7021 return build_real (type, r);
7024 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7025 fcode = builtin_mathfn_code (arg);
7026 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7028 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7029 arg = fold_build2 (MULT_EXPR, type,
7030 TREE_VALUE (TREE_OPERAND (arg, 1)),
7031 build_real (type, dconsthalf));
7032 arglist = build_tree_list (NULL_TREE, arg);
7033 return build_function_call_expr (expfn, arglist);
7036 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7037 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7039 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7041 if (powfn)
7043 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7044 tree tree_root;
7045 /* The inner root was either sqrt or cbrt. */
7046 REAL_VALUE_TYPE dconstroot =
7047 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7049 /* Adjust for the outer root. */
7050 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7051 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7052 tree_root = build_real (type, dconstroot);
7053 arglist = tree_cons (NULL_TREE, arg0,
7054 build_tree_list (NULL_TREE, tree_root));
7055 return build_function_call_expr (powfn, arglist);
7059 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7060 if (flag_unsafe_math_optimizations
7061 && (fcode == BUILT_IN_POW
7062 || fcode == BUILT_IN_POWF
7063 || fcode == BUILT_IN_POWL))
7065 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7066 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7067 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7068 tree narg1;
7069 if (!tree_expr_nonnegative_p (arg0))
7070 arg0 = build1 (ABS_EXPR, type, arg0);
7071 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7072 build_real (type, dconsthalf));
7073 arglist = tree_cons (NULL_TREE, arg0,
7074 build_tree_list (NULL_TREE, narg1));
7075 return build_function_call_expr (powfn, arglist);
7078 return NULL_TREE;
7081 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7082 NULL_TREE if no simplification can be made. */
7083 static tree
7084 fold_builtin_cbrt (tree arglist, tree type)
7086 tree arg = TREE_VALUE (arglist);
7087 const enum built_in_function fcode = builtin_mathfn_code (arg);
7089 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7090 return NULL_TREE;
7092 /* Optimize cbrt of constant value. */
7093 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7094 return arg;
7096 if (flag_unsafe_math_optimizations)
7098 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7099 if (BUILTIN_EXPONENT_P (fcode))
7101 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7102 const REAL_VALUE_TYPE third_trunc =
7103 real_value_truncate (TYPE_MODE (type), dconstthird);
7104 arg = fold_build2 (MULT_EXPR, type,
7105 TREE_VALUE (TREE_OPERAND (arg, 1)),
7106 build_real (type, third_trunc));
7107 arglist = build_tree_list (NULL_TREE, arg);
7108 return build_function_call_expr (expfn, arglist);
7111 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7112 if (BUILTIN_SQRT_P (fcode))
7114 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7116 if (powfn)
7118 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7119 tree tree_root;
7120 REAL_VALUE_TYPE dconstroot = dconstthird;
7122 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7123 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7124 tree_root = build_real (type, dconstroot);
7125 arglist = tree_cons (NULL_TREE, arg0,
7126 build_tree_list (NULL_TREE, tree_root));
7127 return build_function_call_expr (powfn, arglist);
7131 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7132 if (BUILTIN_CBRT_P (fcode))
7134 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7135 if (tree_expr_nonnegative_p (arg0))
7137 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7139 if (powfn)
7141 tree tree_root;
7142 REAL_VALUE_TYPE dconstroot;
7144 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7145 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7146 tree_root = build_real (type, dconstroot);
7147 arglist = tree_cons (NULL_TREE, arg0,
7148 build_tree_list (NULL_TREE, tree_root));
7149 return build_function_call_expr (powfn, arglist);
7154 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7155 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7156 || fcode == BUILT_IN_POWL)
7158 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7159 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7160 if (tree_expr_nonnegative_p (arg00))
7162 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7163 const REAL_VALUE_TYPE dconstroot
7164 = real_value_truncate (TYPE_MODE (type), dconstthird);
7165 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7166 build_real (type, dconstroot));
7167 arglist = tree_cons (NULL_TREE, arg00,
7168 build_tree_list (NULL_TREE, narg01));
7169 return build_function_call_expr (powfn, arglist);
7173 return NULL_TREE;
7176 /* Fold function call to builtin sin, sinf, or sinl. Return
7177 NULL_TREE if no simplification can be made. */
7178 static tree
7179 fold_builtin_sin (tree arglist)
7181 tree arg = TREE_VALUE (arglist);
7183 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7184 return NULL_TREE;
7186 /* Optimize sin (0.0) = 0.0. */
7187 if (real_zerop (arg))
7188 return arg;
7190 return NULL_TREE;
7193 /* Fold function call to builtin cos, cosf, or cosl. Return
7194 NULL_TREE if no simplification can be made. */
7195 static tree
7196 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7198 tree arg = TREE_VALUE (arglist);
7200 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7201 return NULL_TREE;
7203 /* Optimize cos (0.0) = 1.0. */
7204 if (real_zerop (arg))
7205 return build_real (type, dconst1);
7207 /* Optimize cos(-x) into cos (x). */
7208 if (TREE_CODE (arg) == NEGATE_EXPR)
7210 tree args = build_tree_list (NULL_TREE,
7211 TREE_OPERAND (arg, 0));
7212 return build_function_call_expr (fndecl, args);
7215 return NULL_TREE;
7218 /* Fold function call to builtin tan, tanf, or tanl. Return
7219 NULL_TREE if no simplification can be made. */
7220 static tree
7221 fold_builtin_tan (tree arglist)
7223 enum built_in_function fcode;
7224 tree arg = TREE_VALUE (arglist);
7226 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7227 return NULL_TREE;
7229 /* Optimize tan(0.0) = 0.0. */
7230 if (real_zerop (arg))
7231 return arg;
7233 /* Optimize tan(atan(x)) = x. */
7234 fcode = builtin_mathfn_code (arg);
7235 if (flag_unsafe_math_optimizations
7236 && (fcode == BUILT_IN_ATAN
7237 || fcode == BUILT_IN_ATANF
7238 || fcode == BUILT_IN_ATANL))
7239 return TREE_VALUE (TREE_OPERAND (arg, 1));
7241 return NULL_TREE;
7244 /* Fold function call to builtin atan, atanf, or atanl. Return
7245 NULL_TREE if no simplification can be made. */
7247 static tree
7248 fold_builtin_atan (tree arglist, tree type)
7251 tree arg = TREE_VALUE (arglist);
7253 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7254 return NULL_TREE;
7256 /* Optimize atan(0.0) = 0.0. */
7257 if (real_zerop (arg))
7258 return arg;
7260 /* Optimize atan(1.0) = pi/4. */
7261 if (real_onep (arg))
7263 REAL_VALUE_TYPE cst;
7265 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7266 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7267 return build_real (type, cst);
7270 return NULL_TREE;
7273 /* Fold function call to builtin trunc, truncf or truncl. Return
7274 NULL_TREE if no simplification can be made. */
7276 static tree
7277 fold_builtin_trunc (tree fndecl, tree arglist)
7279 tree arg;
7281 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7282 return 0;
7284 /* Optimize trunc of constant value. */
7285 arg = TREE_VALUE (arglist);
7286 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7288 REAL_VALUE_TYPE r, x;
7289 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7291 x = TREE_REAL_CST (arg);
7292 real_trunc (&r, TYPE_MODE (type), &x);
7293 return build_real (type, r);
7296 return fold_trunc_transparent_mathfn (fndecl, arglist);
7299 /* Fold function call to builtin floor, floorf or floorl. Return
7300 NULL_TREE if no simplification can be made. */
7302 static tree
7303 fold_builtin_floor (tree fndecl, tree arglist)
7305 tree arg;
7307 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7308 return 0;
7310 /* Optimize floor of constant value. */
7311 arg = TREE_VALUE (arglist);
7312 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7314 REAL_VALUE_TYPE x;
7316 x = TREE_REAL_CST (arg);
7317 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7319 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7320 REAL_VALUE_TYPE r;
7322 real_floor (&r, TYPE_MODE (type), &x);
7323 return build_real (type, r);
7327 return fold_trunc_transparent_mathfn (fndecl, arglist);
7330 /* Fold function call to builtin ceil, ceilf or ceill. Return
7331 NULL_TREE if no simplification can be made. */
7333 static tree
7334 fold_builtin_ceil (tree fndecl, tree arglist)
7336 tree arg;
7338 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7339 return 0;
7341 /* Optimize ceil of constant value. */
7342 arg = TREE_VALUE (arglist);
7343 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7345 REAL_VALUE_TYPE x;
7347 x = TREE_REAL_CST (arg);
7348 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7350 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7351 REAL_VALUE_TYPE r;
7353 real_ceil (&r, TYPE_MODE (type), &x);
7354 return build_real (type, r);
7358 return fold_trunc_transparent_mathfn (fndecl, arglist);
7361 /* Fold function call to builtin round, roundf or roundl. Return
7362 NULL_TREE if no simplification can be made. */
7364 static tree
7365 fold_builtin_round (tree fndecl, tree arglist)
7367 tree arg;
7369 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7370 return 0;
7372 /* Optimize round of constant value. */
7373 arg = TREE_VALUE (arglist);
7374 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7376 REAL_VALUE_TYPE x;
7378 x = TREE_REAL_CST (arg);
7379 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7381 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7382 REAL_VALUE_TYPE r;
7384 real_round (&r, TYPE_MODE (type), &x);
7385 return build_real (type, r);
7389 return fold_trunc_transparent_mathfn (fndecl, arglist);
7392 /* Fold function call to builtin lround, lroundf or lroundl (or the
7393 corresponding long long versions) and other rounding functions.
7394 Return NULL_TREE if no simplification can be made. */
7396 static tree
7397 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7399 tree arg;
7401 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7402 return 0;
7404 /* Optimize lround of constant value. */
7405 arg = TREE_VALUE (arglist);
7406 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7408 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7410 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7412 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7413 tree ftype = TREE_TYPE (arg), result;
7414 HOST_WIDE_INT hi, lo;
7415 REAL_VALUE_TYPE r;
7417 switch (DECL_FUNCTION_CODE (fndecl))
7419 CASE_FLT_FN (BUILT_IN_LFLOOR):
7420 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7421 real_floor (&r, TYPE_MODE (ftype), &x);
7422 break;
7424 CASE_FLT_FN (BUILT_IN_LCEIL):
7425 CASE_FLT_FN (BUILT_IN_LLCEIL):
7426 real_ceil (&r, TYPE_MODE (ftype), &x);
7427 break;
7429 CASE_FLT_FN (BUILT_IN_LROUND):
7430 CASE_FLT_FN (BUILT_IN_LLROUND):
7431 real_round (&r, TYPE_MODE (ftype), &x);
7432 break;
7434 default:
7435 gcc_unreachable ();
7438 REAL_VALUE_TO_INT (&lo, &hi, r);
7439 result = build_int_cst_wide (NULL_TREE, lo, hi);
7440 if (int_fits_type_p (result, itype))
7441 return fold_convert (itype, result);
7445 return fold_fixed_mathfn (fndecl, arglist);
7448 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7449 and their long and long long variants (i.e. ffsl and ffsll).
7450 Return NULL_TREE if no simplification can be made. */
7452 static tree
7453 fold_builtin_bitop (tree fndecl, tree arglist)
7455 tree arg;
7457 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7458 return NULL_TREE;
7460 /* Optimize for constant argument. */
7461 arg = TREE_VALUE (arglist);
7462 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7464 HOST_WIDE_INT hi, width, result;
7465 unsigned HOST_WIDE_INT lo;
7466 tree type;
7468 type = TREE_TYPE (arg);
7469 width = TYPE_PRECISION (type);
7470 lo = TREE_INT_CST_LOW (arg);
7472 /* Clear all the bits that are beyond the type's precision. */
7473 if (width > HOST_BITS_PER_WIDE_INT)
7475 hi = TREE_INT_CST_HIGH (arg);
7476 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7477 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7479 else
7481 hi = 0;
7482 if (width < HOST_BITS_PER_WIDE_INT)
7483 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7486 switch (DECL_FUNCTION_CODE (fndecl))
7488 CASE_INT_FN (BUILT_IN_FFS):
7489 if (lo != 0)
7490 result = exact_log2 (lo & -lo) + 1;
7491 else if (hi != 0)
7492 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7493 else
7494 result = 0;
7495 break;
7497 CASE_INT_FN (BUILT_IN_CLZ):
7498 if (hi != 0)
7499 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7500 else if (lo != 0)
7501 result = width - floor_log2 (lo) - 1;
7502 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7503 result = width;
7504 break;
7506 CASE_INT_FN (BUILT_IN_CTZ):
7507 if (lo != 0)
7508 result = exact_log2 (lo & -lo);
7509 else if (hi != 0)
7510 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7511 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7512 result = width;
7513 break;
7515 CASE_INT_FN (BUILT_IN_POPCOUNT):
7516 result = 0;
7517 while (lo)
7518 result++, lo &= lo - 1;
7519 while (hi)
7520 result++, hi &= hi - 1;
7521 break;
7523 CASE_INT_FN (BUILT_IN_PARITY):
7524 result = 0;
7525 while (lo)
7526 result++, lo &= lo - 1;
7527 while (hi)
7528 result++, hi &= hi - 1;
7529 result &= 1;
7530 break;
7532 default:
7533 gcc_unreachable ();
7536 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7539 return NULL_TREE;
7542 /* Return true if EXPR is the real constant contained in VALUE. */
7544 static bool
7545 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7547 STRIP_NOPS (expr);
7549 return ((TREE_CODE (expr) == REAL_CST
7550 && ! TREE_CONSTANT_OVERFLOW (expr)
7551 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7552 || (TREE_CODE (expr) == COMPLEX_CST
7553 && real_dconstp (TREE_REALPART (expr), value)
7554 && real_zerop (TREE_IMAGPART (expr))));
7557 /* A subroutine of fold_builtin to fold the various logarithmic
7558 functions. EXP is the CALL_EXPR of a call to a builtin logN
7559 function. VALUE is the base of the logN function. */
7561 static tree
7562 fold_builtin_logarithm (tree fndecl, tree arglist,
7563 const REAL_VALUE_TYPE *value)
7565 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7567 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7568 tree arg = TREE_VALUE (arglist);
7569 const enum built_in_function fcode = builtin_mathfn_code (arg);
7571 /* Optimize logN(1.0) = 0.0. */
7572 if (real_onep (arg))
7573 return build_real (type, dconst0);
7575 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7576 exactly, then only do this if flag_unsafe_math_optimizations. */
7577 if (exact_real_truncate (TYPE_MODE (type), value)
7578 || flag_unsafe_math_optimizations)
7580 const REAL_VALUE_TYPE value_truncate =
7581 real_value_truncate (TYPE_MODE (type), *value);
7582 if (real_dconstp (arg, &value_truncate))
7583 return build_real (type, dconst1);
7586 /* Special case, optimize logN(expN(x)) = x. */
7587 if (flag_unsafe_math_optimizations
7588 && ((value == &dconste
7589 && (fcode == BUILT_IN_EXP
7590 || fcode == BUILT_IN_EXPF
7591 || fcode == BUILT_IN_EXPL))
7592 || (value == &dconst2
7593 && (fcode == BUILT_IN_EXP2
7594 || fcode == BUILT_IN_EXP2F
7595 || fcode == BUILT_IN_EXP2L))
7596 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7597 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7599 /* Optimize logN(func()) for various exponential functions. We
7600 want to determine the value "x" and the power "exponent" in
7601 order to transform logN(x**exponent) into exponent*logN(x). */
7602 if (flag_unsafe_math_optimizations)
7604 tree exponent = 0, x = 0;
7606 switch (fcode)
7608 CASE_FLT_FN (BUILT_IN_EXP):
7609 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7610 x = build_real (type,
7611 real_value_truncate (TYPE_MODE (type), dconste));
7612 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7613 break;
7614 CASE_FLT_FN (BUILT_IN_EXP2):
7615 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7616 x = build_real (type, dconst2);
7617 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7618 break;
7619 CASE_FLT_FN (BUILT_IN_EXP10):
7620 CASE_FLT_FN (BUILT_IN_POW10):
7621 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7622 x = build_real (type, dconst10);
7623 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7624 break;
7625 CASE_FLT_FN (BUILT_IN_SQRT):
7626 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7627 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7628 exponent = build_real (type, dconsthalf);
7629 break;
7630 CASE_FLT_FN (BUILT_IN_CBRT):
7631 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7632 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7633 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7634 dconstthird));
7635 break;
7636 CASE_FLT_FN (BUILT_IN_POW):
7637 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7638 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7639 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7640 break;
7641 default:
7642 break;
7645 /* Now perform the optimization. */
7646 if (x && exponent)
7648 tree logfn;
7649 arglist = build_tree_list (NULL_TREE, x);
7650 logfn = build_function_call_expr (fndecl, arglist);
7651 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7656 return 0;
7659 /* Fold a builtin function call to pow, powf, or powl. Return
7660 NULL_TREE if no simplification can be made. */
7661 static tree
7662 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7664 tree arg0 = TREE_VALUE (arglist);
7665 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7667 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7668 return NULL_TREE;
7670 /* Optimize pow(1.0,y) = 1.0. */
7671 if (real_onep (arg0))
7672 return omit_one_operand (type, build_real (type, dconst1), arg1);
7674 if (TREE_CODE (arg1) == REAL_CST
7675 && ! TREE_CONSTANT_OVERFLOW (arg1))
7677 REAL_VALUE_TYPE cint;
7678 REAL_VALUE_TYPE c;
7679 HOST_WIDE_INT n;
7681 c = TREE_REAL_CST (arg1);
7683 /* Optimize pow(x,0.0) = 1.0. */
7684 if (REAL_VALUES_EQUAL (c, dconst0))
7685 return omit_one_operand (type, build_real (type, dconst1),
7686 arg0);
7688 /* Optimize pow(x,1.0) = x. */
7689 if (REAL_VALUES_EQUAL (c, dconst1))
7690 return arg0;
7692 /* Optimize pow(x,-1.0) = 1.0/x. */
7693 if (REAL_VALUES_EQUAL (c, dconstm1))
7694 return fold_build2 (RDIV_EXPR, type,
7695 build_real (type, dconst1), arg0);
7697 /* Optimize pow(x,0.5) = sqrt(x). */
7698 if (flag_unsafe_math_optimizations
7699 && REAL_VALUES_EQUAL (c, dconsthalf))
7701 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7703 if (sqrtfn != NULL_TREE)
7705 tree arglist = build_tree_list (NULL_TREE, arg0);
7706 return build_function_call_expr (sqrtfn, arglist);
7710 /* Check for an integer exponent. */
7711 n = real_to_integer (&c);
7712 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7713 if (real_identical (&c, &cint))
7715 /* Attempt to evaluate pow at compile-time. */
7716 if (TREE_CODE (arg0) == REAL_CST
7717 && ! TREE_CONSTANT_OVERFLOW (arg0))
7719 REAL_VALUE_TYPE x;
7720 bool inexact;
7722 x = TREE_REAL_CST (arg0);
7723 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7724 if (flag_unsafe_math_optimizations || !inexact)
7725 return build_real (type, x);
7728 /* Strip sign ops from even integer powers. */
7729 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7731 tree narg0 = fold_strip_sign_ops (arg0);
7732 if (narg0)
7734 arglist = build_tree_list (NULL_TREE, arg1);
7735 arglist = tree_cons (NULL_TREE, narg0, arglist);
7736 return build_function_call_expr (fndecl, arglist);
7742 if (flag_unsafe_math_optimizations)
7744 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7746 /* Optimize pow(expN(x),y) = expN(x*y). */
7747 if (BUILTIN_EXPONENT_P (fcode))
7749 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7750 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7751 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7752 arglist = build_tree_list (NULL_TREE, arg);
7753 return build_function_call_expr (expfn, arglist);
7756 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7757 if (BUILTIN_SQRT_P (fcode))
7759 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7760 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7761 build_real (type, dconsthalf));
7763 arglist = tree_cons (NULL_TREE, narg0,
7764 build_tree_list (NULL_TREE, narg1));
7765 return build_function_call_expr (fndecl, arglist);
7768 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7769 if (BUILTIN_CBRT_P (fcode))
7771 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7772 if (tree_expr_nonnegative_p (arg))
7774 const REAL_VALUE_TYPE dconstroot
7775 = real_value_truncate (TYPE_MODE (type), dconstthird);
7776 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7777 build_real (type, dconstroot));
7778 arglist = tree_cons (NULL_TREE, arg,
7779 build_tree_list (NULL_TREE, narg1));
7780 return build_function_call_expr (fndecl, arglist);
7784 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7785 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7786 || fcode == BUILT_IN_POWL)
7788 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7789 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7790 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7791 arglist = tree_cons (NULL_TREE, arg00,
7792 build_tree_list (NULL_TREE, narg1));
7793 return build_function_call_expr (fndecl, arglist);
7797 return NULL_TREE;
7800 /* Fold a builtin function call to powi, powif, or powil. Return
7801 NULL_TREE if no simplification can be made. */
7802 static tree
7803 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7805 tree arg0 = TREE_VALUE (arglist);
7806 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7808 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7809 return NULL_TREE;
7811 /* Optimize pow(1.0,y) = 1.0. */
7812 if (real_onep (arg0))
7813 return omit_one_operand (type, build_real (type, dconst1), arg1);
7815 if (host_integerp (arg1, 0))
7817 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7819 /* Evaluate powi at compile-time. */
7820 if (TREE_CODE (arg0) == REAL_CST
7821 && ! TREE_CONSTANT_OVERFLOW (arg0))
7823 REAL_VALUE_TYPE x;
7824 x = TREE_REAL_CST (arg0);
7825 real_powi (&x, TYPE_MODE (type), &x, c);
7826 return build_real (type, x);
7829 /* Optimize pow(x,0) = 1.0. */
7830 if (c == 0)
7831 return omit_one_operand (type, build_real (type, dconst1),
7832 arg0);
7834 /* Optimize pow(x,1) = x. */
7835 if (c == 1)
7836 return arg0;
7838 /* Optimize pow(x,-1) = 1.0/x. */
7839 if (c == -1)
7840 return fold_build2 (RDIV_EXPR, type,
7841 build_real (type, dconst1), arg0);
7844 return NULL_TREE;
7847 /* A subroutine of fold_builtin to fold the various exponent
7848 functions. EXP is the CALL_EXPR of a call to a builtin function.
7849 VALUE is the value which will be raised to a power. */
7851 static tree
7852 fold_builtin_exponent (tree fndecl, tree arglist,
7853 const REAL_VALUE_TYPE *value)
7855 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7857 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7858 tree arg = TREE_VALUE (arglist);
7860 /* Optimize exp*(0.0) = 1.0. */
7861 if (real_zerop (arg))
7862 return build_real (type, dconst1);
7864 /* Optimize expN(1.0) = N. */
7865 if (real_onep (arg))
7867 REAL_VALUE_TYPE cst;
7869 real_convert (&cst, TYPE_MODE (type), value);
7870 return build_real (type, cst);
7873 /* Attempt to evaluate expN(integer) at compile-time. */
7874 if (flag_unsafe_math_optimizations
7875 && TREE_CODE (arg) == REAL_CST
7876 && ! TREE_CONSTANT_OVERFLOW (arg))
7878 REAL_VALUE_TYPE cint;
7879 REAL_VALUE_TYPE c;
7880 HOST_WIDE_INT n;
7882 c = TREE_REAL_CST (arg);
7883 n = real_to_integer (&c);
7884 real_from_integer (&cint, VOIDmode, n,
7885 n < 0 ? -1 : 0, 0);
7886 if (real_identical (&c, &cint))
7888 REAL_VALUE_TYPE x;
7890 real_powi (&x, TYPE_MODE (type), value, n);
7891 return build_real (type, x);
7895 /* Optimize expN(logN(x)) = x. */
7896 if (flag_unsafe_math_optimizations)
7898 const enum built_in_function fcode = builtin_mathfn_code (arg);
7900 if ((value == &dconste
7901 && (fcode == BUILT_IN_LOG
7902 || fcode == BUILT_IN_LOGF
7903 || fcode == BUILT_IN_LOGL))
7904 || (value == &dconst2
7905 && (fcode == BUILT_IN_LOG2
7906 || fcode == BUILT_IN_LOG2F
7907 || fcode == BUILT_IN_LOG2L))
7908 || (value == &dconst10
7909 && (fcode == BUILT_IN_LOG10
7910 || fcode == BUILT_IN_LOG10F
7911 || fcode == BUILT_IN_LOG10L)))
7912 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7916 return 0;
7919 /* Return true if VAR is a VAR_DECL or a component thereof. */
7921 static bool
7922 var_decl_component_p (tree var)
7924 tree inner = var;
7925 while (handled_component_p (inner))
7926 inner = TREE_OPERAND (inner, 0);
7927 return SSA_VAR_P (inner);
7930 /* Fold function call to builtin memset. Return
7931 NULL_TREE if no simplification can be made. */
7933 static tree
7934 fold_builtin_memset (tree arglist, tree type, bool ignore)
7936 tree dest, c, len, var, ret;
7937 unsigned HOST_WIDE_INT length, cval;
7939 if (!validate_arglist (arglist,
7940 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
7941 return 0;
7943 dest = TREE_VALUE (arglist);
7944 c = TREE_VALUE (TREE_CHAIN (arglist));
7945 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7947 if (! host_integerp (len, 1))
7948 return 0;
7950 /* If the LEN parameter is zero, return DEST. */
7951 if (integer_zerop (len))
7952 return omit_one_operand (type, dest, c);
7954 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
7955 return 0;
7957 var = dest;
7958 STRIP_NOPS (var);
7959 if (TREE_CODE (var) != ADDR_EXPR)
7960 return 0;
7962 var = TREE_OPERAND (var, 0);
7963 if (TREE_THIS_VOLATILE (var))
7964 return 0;
7966 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
7967 && !POINTER_TYPE_P (TREE_TYPE (var)))
7968 return 0;
7970 if (! var_decl_component_p (var))
7971 return 0;
7973 length = tree_low_cst (len, 1);
7974 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
7975 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
7976 < (int) length)
7977 return 0;
7979 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
7980 return 0;
7982 if (integer_zerop (c))
7983 cval = 0;
7984 else
7986 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
7987 return 0;
7989 cval = tree_low_cst (c, 1);
7990 cval &= 0xff;
7991 cval |= cval << 8;
7992 cval |= cval << 16;
7993 cval |= (cval << 31) << 1;
7996 ret = build_int_cst_type (TREE_TYPE (var), cval);
7997 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
7998 if (ignore)
7999 return ret;
8001 return omit_one_operand (type, dest, ret);
8004 /* Fold function call to builtin memset. Return
8005 NULL_TREE if no simplification can be made. */
8007 static tree
8008 fold_builtin_bzero (tree arglist, bool ignore)
8010 tree dest, size, newarglist;
8012 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8013 return 0;
8015 if (!ignore)
8016 return 0;
8018 dest = TREE_VALUE (arglist);
8019 size = TREE_VALUE (TREE_CHAIN (arglist));
8021 /* New argument list transforming bzero(ptr x, int y) to
8022 memset(ptr x, int 0, size_t y). This is done this way
8023 so that if it isn't expanded inline, we fallback to
8024 calling bzero instead of memset. */
8026 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8027 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8028 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8029 return fold_builtin_memset (newarglist, void_type_node, ignore);
8032 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8033 NULL_TREE if no simplification can be made.
8034 If ENDP is 0, return DEST (like memcpy).
8035 If ENDP is 1, return DEST+LEN (like mempcpy).
8036 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8037 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8038 (memmove). */
8040 static tree
8041 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8043 tree dest, src, len, destvar, srcvar, expr;
8044 unsigned HOST_WIDE_INT length;
8046 if (! validate_arglist (arglist,
8047 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8048 return 0;
8050 dest = TREE_VALUE (arglist);
8051 src = TREE_VALUE (TREE_CHAIN (arglist));
8052 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8054 /* If the LEN parameter is zero, return DEST. */
8055 if (integer_zerop (len))
8056 return omit_one_operand (type, dest, src);
8058 /* If SRC and DEST are the same (and not volatile), return
8059 DEST{,+LEN,+LEN-1}. */
8060 if (operand_equal_p (src, dest, 0))
8061 expr = len;
8062 else
8064 if (! host_integerp (len, 1))
8065 return 0;
8067 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8068 return 0;
8070 destvar = dest;
8071 STRIP_NOPS (destvar);
8072 if (TREE_CODE (destvar) != ADDR_EXPR)
8073 return 0;
8075 destvar = TREE_OPERAND (destvar, 0);
8076 if (TREE_THIS_VOLATILE (destvar))
8077 return 0;
8079 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8080 && !POINTER_TYPE_P (TREE_TYPE (destvar))
8081 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8082 return 0;
8084 if (! var_decl_component_p (destvar))
8085 return 0;
8087 srcvar = src;
8088 STRIP_NOPS (srcvar);
8089 if (TREE_CODE (srcvar) != ADDR_EXPR)
8090 return 0;
8092 srcvar = TREE_OPERAND (srcvar, 0);
8093 if (TREE_THIS_VOLATILE (srcvar))
8094 return 0;
8096 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8097 && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8098 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8099 return 0;
8101 if (! var_decl_component_p (srcvar))
8102 return 0;
8104 length = tree_low_cst (len, 1);
8105 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8106 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8107 < (int) length
8108 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8109 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8110 < (int) length)
8111 return 0;
8113 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8114 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8115 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8116 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8117 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8118 else
8119 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8120 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8123 if (ignore)
8124 return expr;
8126 if (endp == 0 || endp == 3)
8127 return omit_one_operand (type, dest, expr);
8129 if (expr == len)
8130 expr = 0;
8132 if (endp == 2)
8133 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8134 ssize_int (1));
8136 len = fold_convert (TREE_TYPE (dest), len);
8137 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8138 dest = fold_convert (type, dest);
8139 if (expr)
8140 dest = omit_one_operand (type, dest, expr);
8141 return dest;
8144 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8145 simplification can be made. */
8147 static tree
8148 fold_builtin_bcopy (tree arglist, bool ignore)
8150 tree src, dest, size, newarglist;
8152 if (!validate_arglist (arglist,
8153 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8154 return 0;
8156 if (! ignore)
8157 return 0;
8159 src = TREE_VALUE (arglist);
8160 dest = TREE_VALUE (TREE_CHAIN (arglist));
8161 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8163 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8164 memmove(ptr y, ptr x, size_t z). This is done this way
8165 so that if it isn't expanded inline, we fallback to
8166 calling bcopy instead of memmove. */
8168 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8169 newarglist = tree_cons (NULL_TREE, src, newarglist);
8170 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8172 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8175 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8176 the length of the string to be copied. Return NULL_TREE if no
8177 simplification can be made. */
8179 tree
8180 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8182 tree dest, src, fn;
8184 if (!validate_arglist (arglist,
8185 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8186 return 0;
8188 dest = TREE_VALUE (arglist);
8189 src = TREE_VALUE (TREE_CHAIN (arglist));
8191 /* If SRC and DEST are the same (and not volatile), return DEST. */
8192 if (operand_equal_p (src, dest, 0))
8193 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8195 if (optimize_size)
8196 return 0;
8198 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8199 if (!fn)
8200 return 0;
8202 if (!len)
8204 len = c_strlen (src, 1);
8205 if (! len || TREE_SIDE_EFFECTS (len))
8206 return 0;
8209 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8210 arglist = build_tree_list (NULL_TREE, len);
8211 arglist = tree_cons (NULL_TREE, src, arglist);
8212 arglist = tree_cons (NULL_TREE, dest, arglist);
8213 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8214 build_function_call_expr (fn, arglist));
8217 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8218 the length of the source string. Return NULL_TREE if no simplification
8219 can be made. */
8221 tree
8222 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8224 tree dest, src, len, fn;
8226 if (!validate_arglist (arglist,
8227 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8228 return 0;
8230 dest = TREE_VALUE (arglist);
8231 src = TREE_VALUE (TREE_CHAIN (arglist));
8232 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8234 /* If the LEN parameter is zero, return DEST. */
8235 if (integer_zerop (len))
8236 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8238 /* We can't compare slen with len as constants below if len is not a
8239 constant. */
8240 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8241 return 0;
8243 if (!slen)
8244 slen = c_strlen (src, 1);
8246 /* Now, we must be passed a constant src ptr parameter. */
8247 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8248 return 0;
8250 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8252 /* We do not support simplification of this case, though we do
8253 support it when expanding trees into RTL. */
8254 /* FIXME: generate a call to __builtin_memset. */
8255 if (tree_int_cst_lt (slen, len))
8256 return 0;
8258 /* OK transform into builtin memcpy. */
8259 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8260 if (!fn)
8261 return 0;
8262 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8263 build_function_call_expr (fn, arglist));
8266 /* Fold function call to builtin memcmp. Return
8267 NULL_TREE if no simplification can be made. */
8269 static tree
8270 fold_builtin_memcmp (tree arglist)
8272 tree arg1, arg2, len;
8273 const char *p1, *p2;
8275 if (!validate_arglist (arglist,
8276 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8277 return 0;
8279 arg1 = TREE_VALUE (arglist);
8280 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8281 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8283 /* If the LEN parameter is zero, return zero. */
8284 if (integer_zerop (len))
8285 return omit_two_operands (integer_type_node, integer_zero_node,
8286 arg1, arg2);
8288 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8289 if (operand_equal_p (arg1, arg2, 0))
8290 return omit_one_operand (integer_type_node, integer_zero_node, len);
8292 p1 = c_getstr (arg1);
8293 p2 = c_getstr (arg2);
8295 /* If all arguments are constant, and the value of len is not greater
8296 than the lengths of arg1 and arg2, evaluate at compile-time. */
8297 if (host_integerp (len, 1) && p1 && p2
8298 && compare_tree_int (len, strlen (p1) + 1) <= 0
8299 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8301 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8303 if (r > 0)
8304 return integer_one_node;
8305 else if (r < 0)
8306 return integer_minus_one_node;
8307 else
8308 return integer_zero_node;
8311 /* If len parameter is one, return an expression corresponding to
8312 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8313 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8315 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8316 tree cst_uchar_ptr_node
8317 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8319 tree ind1 = fold_convert (integer_type_node,
8320 build1 (INDIRECT_REF, cst_uchar_node,
8321 fold_convert (cst_uchar_ptr_node,
8322 arg1)));
8323 tree ind2 = fold_convert (integer_type_node,
8324 build1 (INDIRECT_REF, cst_uchar_node,
8325 fold_convert (cst_uchar_ptr_node,
8326 arg2)));
8327 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8330 return 0;
8333 /* Fold function call to builtin strcmp. Return
8334 NULL_TREE if no simplification can be made. */
8336 static tree
8337 fold_builtin_strcmp (tree arglist)
8339 tree arg1, arg2;
8340 const char *p1, *p2;
8342 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8343 return 0;
8345 arg1 = TREE_VALUE (arglist);
8346 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8348 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8349 if (operand_equal_p (arg1, arg2, 0))
8350 return integer_zero_node;
8352 p1 = c_getstr (arg1);
8353 p2 = c_getstr (arg2);
8355 if (p1 && p2)
8357 const int i = strcmp (p1, p2);
8358 if (i < 0)
8359 return integer_minus_one_node;
8360 else if (i > 0)
8361 return integer_one_node;
8362 else
8363 return integer_zero_node;
8366 /* If the second arg is "", return *(const unsigned char*)arg1. */
8367 if (p2 && *p2 == '\0')
8369 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8370 tree cst_uchar_ptr_node
8371 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8373 return fold_convert (integer_type_node,
8374 build1 (INDIRECT_REF, cst_uchar_node,
8375 fold_convert (cst_uchar_ptr_node,
8376 arg1)));
8379 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8380 if (p1 && *p1 == '\0')
8382 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8383 tree cst_uchar_ptr_node
8384 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8386 tree temp = fold_convert (integer_type_node,
8387 build1 (INDIRECT_REF, cst_uchar_node,
8388 fold_convert (cst_uchar_ptr_node,
8389 arg2)));
8390 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8393 return 0;
8396 /* Fold function call to builtin strncmp. Return
8397 NULL_TREE if no simplification can be made. */
8399 static tree
8400 fold_builtin_strncmp (tree arglist)
8402 tree arg1, arg2, len;
8403 const char *p1, *p2;
8405 if (!validate_arglist (arglist,
8406 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8407 return 0;
8409 arg1 = TREE_VALUE (arglist);
8410 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8411 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8413 /* If the LEN parameter is zero, return zero. */
8414 if (integer_zerop (len))
8415 return omit_two_operands (integer_type_node, integer_zero_node,
8416 arg1, arg2);
8418 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8419 if (operand_equal_p (arg1, arg2, 0))
8420 return omit_one_operand (integer_type_node, integer_zero_node, len);
8422 p1 = c_getstr (arg1);
8423 p2 = c_getstr (arg2);
8425 if (host_integerp (len, 1) && p1 && p2)
8427 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8428 if (i > 0)
8429 return integer_one_node;
8430 else if (i < 0)
8431 return integer_minus_one_node;
8432 else
8433 return integer_zero_node;
8436 /* If the second arg is "", and the length is greater than zero,
8437 return *(const unsigned char*)arg1. */
8438 if (p2 && *p2 == '\0'
8439 && TREE_CODE (len) == INTEGER_CST
8440 && tree_int_cst_sgn (len) == 1)
8442 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8443 tree cst_uchar_ptr_node
8444 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8446 return fold_convert (integer_type_node,
8447 build1 (INDIRECT_REF, cst_uchar_node,
8448 fold_convert (cst_uchar_ptr_node,
8449 arg1)));
8452 /* If the first arg is "", and the length is greater than zero,
8453 return -*(const unsigned char*)arg2. */
8454 if (p1 && *p1 == '\0'
8455 && TREE_CODE (len) == INTEGER_CST
8456 && tree_int_cst_sgn (len) == 1)
8458 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8459 tree cst_uchar_ptr_node
8460 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8462 tree temp = fold_convert (integer_type_node,
8463 build1 (INDIRECT_REF, cst_uchar_node,
8464 fold_convert (cst_uchar_ptr_node,
8465 arg2)));
8466 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8469 /* If len parameter is one, return an expression corresponding to
8470 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8471 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8473 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8474 tree cst_uchar_ptr_node
8475 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8477 tree ind1 = fold_convert (integer_type_node,
8478 build1 (INDIRECT_REF, cst_uchar_node,
8479 fold_convert (cst_uchar_ptr_node,
8480 arg1)));
8481 tree ind2 = fold_convert (integer_type_node,
8482 build1 (INDIRECT_REF, cst_uchar_node,
8483 fold_convert (cst_uchar_ptr_node,
8484 arg2)));
8485 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8488 return 0;
8491 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8492 NULL_TREE if no simplification can be made. */
8494 static tree
8495 fold_builtin_signbit (tree fndecl, tree arglist)
8497 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8498 tree arg, temp;
8500 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8501 return NULL_TREE;
8503 arg = TREE_VALUE (arglist);
8505 /* If ARG is a compile-time constant, determine the result. */
8506 if (TREE_CODE (arg) == REAL_CST
8507 && !TREE_CONSTANT_OVERFLOW (arg))
8509 REAL_VALUE_TYPE c;
8511 c = TREE_REAL_CST (arg);
8512 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8513 return fold_convert (type, temp);
8516 /* If ARG is non-negative, the result is always zero. */
8517 if (tree_expr_nonnegative_p (arg))
8518 return omit_one_operand (type, integer_zero_node, arg);
8520 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8521 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8522 return fold_build2 (LT_EXPR, type, arg,
8523 build_real (TREE_TYPE (arg), dconst0));
8525 return NULL_TREE;
8528 /* Fold function call to builtin copysign, copysignf or copysignl.
8529 Return NULL_TREE if no simplification can be made. */
8531 static tree
8532 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8534 tree arg1, arg2, tem;
8536 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8537 return NULL_TREE;
8539 arg1 = TREE_VALUE (arglist);
8540 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8542 /* copysign(X,X) is X. */
8543 if (operand_equal_p (arg1, arg2, 0))
8544 return fold_convert (type, arg1);
8546 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8547 if (TREE_CODE (arg1) == REAL_CST
8548 && TREE_CODE (arg2) == REAL_CST
8549 && !TREE_CONSTANT_OVERFLOW (arg1)
8550 && !TREE_CONSTANT_OVERFLOW (arg2))
8552 REAL_VALUE_TYPE c1, c2;
8554 c1 = TREE_REAL_CST (arg1);
8555 c2 = TREE_REAL_CST (arg2);
8556 /* c1.sign := c2.sign. */
8557 real_copysign (&c1, &c2);
8558 return build_real (type, c1);
8561 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8562 Remember to evaluate Y for side-effects. */
8563 if (tree_expr_nonnegative_p (arg2))
8564 return omit_one_operand (type,
8565 fold_build1 (ABS_EXPR, type, arg1),
8566 arg2);
8568 /* Strip sign changing operations for the first argument. */
8569 tem = fold_strip_sign_ops (arg1);
8570 if (tem)
8572 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8573 return build_function_call_expr (fndecl, arglist);
8576 return NULL_TREE;
8579 /* Fold a call to builtin isascii. */
8581 static tree
8582 fold_builtin_isascii (tree arglist)
8584 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8585 return 0;
8586 else
8588 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8589 tree arg = TREE_VALUE (arglist);
8591 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8592 build_int_cst (NULL_TREE,
8593 ~ (unsigned HOST_WIDE_INT) 0x7f));
8594 arg = fold_build2 (EQ_EXPR, integer_type_node,
8595 arg, integer_zero_node);
8597 if (in_gimple_form && !TREE_CONSTANT (arg))
8598 return NULL_TREE;
8599 else
8600 return arg;
8604 /* Fold a call to builtin toascii. */
8606 static tree
8607 fold_builtin_toascii (tree arglist)
8609 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8610 return 0;
8611 else
8613 /* Transform toascii(c) -> (c & 0x7f). */
8614 tree arg = TREE_VALUE (arglist);
8616 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8617 build_int_cst (NULL_TREE, 0x7f));
8621 /* Fold a call to builtin isdigit. */
8623 static tree
8624 fold_builtin_isdigit (tree arglist)
8626 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8627 return 0;
8628 else
8630 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8631 /* According to the C standard, isdigit is unaffected by locale.
8632 However, it definitely is affected by the target character set. */
8633 tree arg;
8634 unsigned HOST_WIDE_INT target_digit0
8635 = lang_hooks.to_target_charset ('0');
8637 if (target_digit0 == 0)
8638 return NULL_TREE;
8640 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8641 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8642 build_int_cst (unsigned_type_node, target_digit0));
8643 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8644 build_int_cst (unsigned_type_node, 9));
8645 if (in_gimple_form && !TREE_CONSTANT (arg))
8646 return NULL_TREE;
8647 else
8648 return arg;
8652 /* Fold a call to fabs, fabsf or fabsl. */
8654 static tree
8655 fold_builtin_fabs (tree arglist, tree type)
8657 tree arg;
8659 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8660 return 0;
8662 arg = TREE_VALUE (arglist);
8663 arg = fold_convert (type, arg);
8664 if (TREE_CODE (arg) == REAL_CST)
8665 return fold_abs_const (arg, type);
8666 return fold_build1 (ABS_EXPR, type, arg);
8669 /* Fold a call to abs, labs, llabs or imaxabs. */
8671 static tree
8672 fold_builtin_abs (tree arglist, tree type)
8674 tree arg;
8676 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8677 return 0;
8679 arg = TREE_VALUE (arglist);
8680 arg = fold_convert (type, arg);
8681 if (TREE_CODE (arg) == INTEGER_CST)
8682 return fold_abs_const (arg, type);
8683 return fold_build1 (ABS_EXPR, type, arg);
8686 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8687 EXP is the CALL_EXPR for the call. */
8689 static tree
8690 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8692 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8693 tree arg;
8694 REAL_VALUE_TYPE r;
8696 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8698 /* Check that we have exactly one argument. */
8699 if (arglist == 0)
8701 error ("too few arguments to function %qs",
8702 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8703 return error_mark_node;
8705 else if (TREE_CHAIN (arglist) != 0)
8707 error ("too many arguments to function %qs",
8708 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8709 return error_mark_node;
8711 else
8713 error ("non-floating-point argument to function %qs",
8714 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8715 return error_mark_node;
8719 arg = TREE_VALUE (arglist);
8720 switch (builtin_index)
8722 case BUILT_IN_ISINF:
8723 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8724 return omit_one_operand (type, integer_zero_node, arg);
8726 if (TREE_CODE (arg) == REAL_CST)
8728 r = TREE_REAL_CST (arg);
8729 if (real_isinf (&r))
8730 return real_compare (GT_EXPR, &r, &dconst0)
8731 ? integer_one_node : integer_minus_one_node;
8732 else
8733 return integer_zero_node;
8736 return NULL_TREE;
8738 case BUILT_IN_FINITE:
8739 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8740 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8741 return omit_one_operand (type, integer_one_node, arg);
8743 if (TREE_CODE (arg) == REAL_CST)
8745 r = TREE_REAL_CST (arg);
8746 return real_isinf (&r) || real_isnan (&r)
8747 ? integer_zero_node : integer_one_node;
8750 return NULL_TREE;
8752 case BUILT_IN_ISNAN:
8753 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8754 return omit_one_operand (type, integer_zero_node, arg);
8756 if (TREE_CODE (arg) == REAL_CST)
8758 r = TREE_REAL_CST (arg);
8759 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8762 arg = builtin_save_expr (arg);
8763 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8765 default:
8766 gcc_unreachable ();
8770 /* Fold a call to an unordered comparison function such as
8771 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8772 being called and ARGLIST is the argument list for the call.
8773 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8774 the opposite of the desired result. UNORDERED_CODE is used
8775 for modes that can hold NaNs and ORDERED_CODE is used for
8776 the rest. */
8778 static tree
8779 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8780 enum tree_code unordered_code,
8781 enum tree_code ordered_code)
8783 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8784 enum tree_code code;
8785 tree arg0, arg1;
8786 tree type0, type1;
8787 enum tree_code code0, code1;
8788 tree cmp_type = NULL_TREE;
8790 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8792 /* Check that we have exactly two arguments. */
8793 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8795 error ("too few arguments to function %qs",
8796 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8797 return error_mark_node;
8799 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8801 error ("too many arguments to function %qs",
8802 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8803 return error_mark_node;
8807 arg0 = TREE_VALUE (arglist);
8808 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8810 type0 = TREE_TYPE (arg0);
8811 type1 = TREE_TYPE (arg1);
8813 code0 = TREE_CODE (type0);
8814 code1 = TREE_CODE (type1);
8816 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8817 /* Choose the wider of two real types. */
8818 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8819 ? type0 : type1;
8820 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8821 cmp_type = type0;
8822 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8823 cmp_type = type1;
8824 else
8826 error ("non-floating-point argument to function %qs",
8827 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8828 return error_mark_node;
8831 arg0 = fold_convert (cmp_type, arg0);
8832 arg1 = fold_convert (cmp_type, arg1);
8834 if (unordered_code == UNORDERED_EXPR)
8836 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8837 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8838 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8841 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8842 : ordered_code;
8843 return fold_build1 (TRUTH_NOT_EXPR, type,
8844 fold_build2 (code, type, arg0, arg1));
8847 /* Used by constant folding to simplify calls to builtin functions. EXP is
8848 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8849 result of the function call is ignored. This function returns NULL_TREE
8850 if no simplification was possible. */
8852 static tree
8853 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8855 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8856 enum built_in_function fcode;
8858 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8859 return targetm.fold_builtin (fndecl, arglist, ignore);
8861 fcode = DECL_FUNCTION_CODE (fndecl);
8862 switch (fcode)
8864 case BUILT_IN_FPUTS:
8865 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8867 case BUILT_IN_FPUTS_UNLOCKED:
8868 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8870 case BUILT_IN_STRSTR:
8871 return fold_builtin_strstr (arglist, type);
8873 case BUILT_IN_STRCAT:
8874 return fold_builtin_strcat (arglist);
8876 case BUILT_IN_STRNCAT:
8877 return fold_builtin_strncat (arglist);
8879 case BUILT_IN_STRSPN:
8880 return fold_builtin_strspn (arglist);
8882 case BUILT_IN_STRCSPN:
8883 return fold_builtin_strcspn (arglist);
8885 case BUILT_IN_STRCHR:
8886 case BUILT_IN_INDEX:
8887 return fold_builtin_strchr (arglist, type);
8889 case BUILT_IN_STRRCHR:
8890 case BUILT_IN_RINDEX:
8891 return fold_builtin_strrchr (arglist, type);
8893 case BUILT_IN_STRCPY:
8894 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8896 case BUILT_IN_STRNCPY:
8897 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8899 case BUILT_IN_STRCMP:
8900 return fold_builtin_strcmp (arglist);
8902 case BUILT_IN_STRNCMP:
8903 return fold_builtin_strncmp (arglist);
8905 case BUILT_IN_STRPBRK:
8906 return fold_builtin_strpbrk (arglist, type);
8908 case BUILT_IN_BCMP:
8909 case BUILT_IN_MEMCMP:
8910 return fold_builtin_memcmp (arglist);
8912 case BUILT_IN_SPRINTF:
8913 return fold_builtin_sprintf (arglist, ignore);
8915 case BUILT_IN_CONSTANT_P:
8917 tree val;
8919 val = fold_builtin_constant_p (arglist);
8920 /* Gimplification will pull the CALL_EXPR for the builtin out of
8921 an if condition. When not optimizing, we'll not CSE it back.
8922 To avoid link error types of regressions, return false now. */
8923 if (!val && !optimize)
8924 val = integer_zero_node;
8926 return val;
8929 case BUILT_IN_EXPECT:
8930 return fold_builtin_expect (arglist);
8932 case BUILT_IN_CLASSIFY_TYPE:
8933 return fold_builtin_classify_type (arglist);
8935 case BUILT_IN_STRLEN:
8936 return fold_builtin_strlen (arglist);
8938 CASE_FLT_FN (BUILT_IN_FABS):
8939 return fold_builtin_fabs (arglist, type);
8941 case BUILT_IN_ABS:
8942 case BUILT_IN_LABS:
8943 case BUILT_IN_LLABS:
8944 case BUILT_IN_IMAXABS:
8945 return fold_builtin_abs (arglist, type);
8947 CASE_FLT_FN (BUILT_IN_CONJ):
8948 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8949 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8950 break;
8952 CASE_FLT_FN (BUILT_IN_CREAL):
8953 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8954 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8955 TREE_VALUE (arglist)));
8956 break;
8958 CASE_FLT_FN (BUILT_IN_CIMAG):
8959 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8960 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8961 TREE_VALUE (arglist)));
8962 break;
8964 CASE_FLT_FN (BUILT_IN_CABS):
8965 return fold_builtin_cabs (arglist, type, fndecl);
8967 CASE_FLT_FN (BUILT_IN_SQRT):
8968 return fold_builtin_sqrt (arglist, type);
8970 CASE_FLT_FN (BUILT_IN_CBRT):
8971 return fold_builtin_cbrt (arglist, type);
8973 CASE_FLT_FN (BUILT_IN_SIN):
8974 return fold_builtin_sin (arglist);
8976 CASE_FLT_FN (BUILT_IN_COS):
8977 return fold_builtin_cos (arglist, type, fndecl);
8979 CASE_FLT_FN (BUILT_IN_EXP):
8980 return fold_builtin_exponent (fndecl, arglist, &dconste);
8982 CASE_FLT_FN (BUILT_IN_EXP2):
8983 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8985 CASE_FLT_FN (BUILT_IN_EXP10):
8986 CASE_FLT_FN (BUILT_IN_POW10):
8987 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8989 CASE_FLT_FN (BUILT_IN_LOG):
8990 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8992 CASE_FLT_FN (BUILT_IN_LOG2):
8993 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8995 CASE_FLT_FN (BUILT_IN_LOG10):
8996 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8998 CASE_FLT_FN (BUILT_IN_TAN):
8999 return fold_builtin_tan (arglist);
9001 CASE_FLT_FN (BUILT_IN_ATAN):
9002 return fold_builtin_atan (arglist, type);
9004 CASE_FLT_FN (BUILT_IN_POW):
9005 return fold_builtin_pow (fndecl, arglist, type);
9007 CASE_FLT_FN (BUILT_IN_POWI):
9008 return fold_builtin_powi (fndecl, arglist, type);
9010 CASE_FLT_FN (BUILT_IN_INF):
9011 case BUILT_IN_INFD32:
9012 case BUILT_IN_INFD64:
9013 case BUILT_IN_INFD128:
9014 return fold_builtin_inf (type, true);
9016 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9017 return fold_builtin_inf (type, false);
9019 CASE_FLT_FN (BUILT_IN_NAN):
9020 case BUILT_IN_NAND32:
9021 case BUILT_IN_NAND64:
9022 case BUILT_IN_NAND128:
9023 return fold_builtin_nan (arglist, type, true);
9025 CASE_FLT_FN (BUILT_IN_NANS):
9026 return fold_builtin_nan (arglist, type, false);
9028 CASE_FLT_FN (BUILT_IN_FLOOR):
9029 return fold_builtin_floor (fndecl, arglist);
9031 CASE_FLT_FN (BUILT_IN_CEIL):
9032 return fold_builtin_ceil (fndecl, arglist);
9034 CASE_FLT_FN (BUILT_IN_TRUNC):
9035 return fold_builtin_trunc (fndecl, arglist);
9037 CASE_FLT_FN (BUILT_IN_ROUND):
9038 return fold_builtin_round (fndecl, arglist);
9040 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9041 CASE_FLT_FN (BUILT_IN_RINT):
9042 return fold_trunc_transparent_mathfn (fndecl, arglist);
9044 CASE_FLT_FN (BUILT_IN_LCEIL):
9045 CASE_FLT_FN (BUILT_IN_LLCEIL):
9046 CASE_FLT_FN (BUILT_IN_LFLOOR):
9047 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9048 CASE_FLT_FN (BUILT_IN_LROUND):
9049 CASE_FLT_FN (BUILT_IN_LLROUND):
9050 return fold_builtin_int_roundingfn (fndecl, arglist);
9052 CASE_FLT_FN (BUILT_IN_LRINT):
9053 CASE_FLT_FN (BUILT_IN_LLRINT):
9054 return fold_fixed_mathfn (fndecl, arglist);
9056 CASE_INT_FN (BUILT_IN_FFS):
9057 CASE_INT_FN (BUILT_IN_CLZ):
9058 CASE_INT_FN (BUILT_IN_CTZ):
9059 CASE_INT_FN (BUILT_IN_POPCOUNT):
9060 CASE_INT_FN (BUILT_IN_PARITY):
9061 return fold_builtin_bitop (fndecl, arglist);
9063 case BUILT_IN_MEMSET:
9064 return fold_builtin_memset (arglist, type, ignore);
9066 case BUILT_IN_MEMCPY:
9067 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9069 case BUILT_IN_MEMPCPY:
9070 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9072 case BUILT_IN_MEMMOVE:
9073 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9075 case BUILT_IN_BZERO:
9076 return fold_builtin_bzero (arglist, ignore);
9078 case BUILT_IN_BCOPY:
9079 return fold_builtin_bcopy (arglist, ignore);
9081 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9082 return fold_builtin_signbit (fndecl, arglist);
9084 case BUILT_IN_ISASCII:
9085 return fold_builtin_isascii (arglist);
9087 case BUILT_IN_TOASCII:
9088 return fold_builtin_toascii (arglist);
9090 case BUILT_IN_ISDIGIT:
9091 return fold_builtin_isdigit (arglist);
9093 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9094 return fold_builtin_copysign (fndecl, arglist, type);
9096 CASE_FLT_FN (BUILT_IN_FINITE):
9097 case BUILT_IN_FINITED32:
9098 case BUILT_IN_FINITED64:
9099 case BUILT_IN_FINITED128:
9100 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9102 CASE_FLT_FN (BUILT_IN_ISINF):
9103 case BUILT_IN_ISINFD32:
9104 case BUILT_IN_ISINFD64:
9105 case BUILT_IN_ISINFD128:
9106 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9108 CASE_FLT_FN (BUILT_IN_ISNAN):
9109 case BUILT_IN_ISNAND32:
9110 case BUILT_IN_ISNAND64:
9111 case BUILT_IN_ISNAND128:
9112 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9114 case BUILT_IN_ISGREATER:
9115 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9116 case BUILT_IN_ISGREATEREQUAL:
9117 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9118 case BUILT_IN_ISLESS:
9119 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9120 case BUILT_IN_ISLESSEQUAL:
9121 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9122 case BUILT_IN_ISLESSGREATER:
9123 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9124 case BUILT_IN_ISUNORDERED:
9125 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9126 NOP_EXPR);
9128 /* We do the folding for va_start in the expander. */
9129 case BUILT_IN_VA_START:
9130 break;
9132 case BUILT_IN_OBJECT_SIZE:
9133 return fold_builtin_object_size (arglist);
9134 case BUILT_IN_MEMCPY_CHK:
9135 case BUILT_IN_MEMPCPY_CHK:
9136 case BUILT_IN_MEMMOVE_CHK:
9137 case BUILT_IN_MEMSET_CHK:
9138 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9139 DECL_FUNCTION_CODE (fndecl));
9140 case BUILT_IN_STRCPY_CHK:
9141 case BUILT_IN_STPCPY_CHK:
9142 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9143 DECL_FUNCTION_CODE (fndecl));
9144 case BUILT_IN_STRNCPY_CHK:
9145 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9146 case BUILT_IN_STRCAT_CHK:
9147 return fold_builtin_strcat_chk (fndecl, arglist);
9148 case BUILT_IN_STRNCAT_CHK:
9149 return fold_builtin_strncat_chk (fndecl, arglist);
9150 case BUILT_IN_SPRINTF_CHK:
9151 case BUILT_IN_VSPRINTF_CHK:
9152 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9153 case BUILT_IN_SNPRINTF_CHK:
9154 case BUILT_IN_VSNPRINTF_CHK:
9155 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9156 DECL_FUNCTION_CODE (fndecl));
9158 case BUILT_IN_PRINTF:
9159 case BUILT_IN_PRINTF_UNLOCKED:
9160 case BUILT_IN_VPRINTF:
9161 case BUILT_IN_PRINTF_CHK:
9162 case BUILT_IN_VPRINTF_CHK:
9163 return fold_builtin_printf (fndecl, arglist, ignore,
9164 DECL_FUNCTION_CODE (fndecl));
9166 case BUILT_IN_FPRINTF:
9167 case BUILT_IN_FPRINTF_UNLOCKED:
9168 case BUILT_IN_VFPRINTF:
9169 case BUILT_IN_FPRINTF_CHK:
9170 case BUILT_IN_VFPRINTF_CHK:
9171 return fold_builtin_fprintf (fndecl, arglist, ignore,
9172 DECL_FUNCTION_CODE (fndecl));
9174 default:
9175 break;
9178 return 0;
9181 /* A wrapper function for builtin folding that prevents warnings for
9182 "statement without effect" and the like, caused by removing the
9183 call node earlier than the warning is generated. */
9185 tree
9186 fold_builtin (tree fndecl, tree arglist, bool ignore)
9188 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9189 if (exp)
9191 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9192 TREE_NO_WARNING (exp) = 1;
9195 return exp;
9198 /* Conveniently construct a function call expression. */
9200 tree
9201 build_function_call_expr (tree fn, tree arglist)
9203 tree call_expr;
9205 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9206 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9207 call_expr, arglist, NULL_TREE);
9210 /* This function validates the types of a function call argument list
9211 represented as a tree chain of parameters against a specified list
9212 of tree_codes. If the last specifier is a 0, that represents an
9213 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9215 static int
9216 validate_arglist (tree arglist, ...)
9218 enum tree_code code;
9219 int res = 0;
9220 va_list ap;
9222 va_start (ap, arglist);
9226 code = va_arg (ap, enum tree_code);
9227 switch (code)
9229 case 0:
9230 /* This signifies an ellipses, any further arguments are all ok. */
9231 res = 1;
9232 goto end;
9233 case VOID_TYPE:
9234 /* This signifies an endlink, if no arguments remain, return
9235 true, otherwise return false. */
9236 res = arglist == 0;
9237 goto end;
9238 default:
9239 /* If no parameters remain or the parameter's code does not
9240 match the specified code, return false. Otherwise continue
9241 checking any remaining arguments. */
9242 if (arglist == 0)
9243 goto end;
9244 if (code == POINTER_TYPE)
9246 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9247 goto end;
9249 else if (code == INTEGER_TYPE)
9251 if (! INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9252 goto end;
9254 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9255 goto end;
9256 break;
9258 arglist = TREE_CHAIN (arglist);
9260 while (1);
9262 /* We need gotos here since we can only have one VA_CLOSE in a
9263 function. */
9264 end: ;
9265 va_end (ap);
9267 return res;
9270 /* Default target-specific builtin expander that does nothing. */
9273 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9274 rtx target ATTRIBUTE_UNUSED,
9275 rtx subtarget ATTRIBUTE_UNUSED,
9276 enum machine_mode mode ATTRIBUTE_UNUSED,
9277 int ignore ATTRIBUTE_UNUSED)
9279 return NULL_RTX;
9282 /* Returns true is EXP represents data that would potentially reside
9283 in a readonly section. */
9285 static bool
9286 readonly_data_expr (tree exp)
9288 STRIP_NOPS (exp);
9290 if (TREE_CODE (exp) != ADDR_EXPR)
9291 return false;
9293 exp = get_base_address (TREE_OPERAND (exp, 0));
9294 if (!exp)
9295 return false;
9297 /* Make sure we call decl_readonly_section only for trees it
9298 can handle (since it returns true for everything it doesn't
9299 understand). */
9300 if (TREE_CODE (exp) == STRING_CST
9301 || TREE_CODE (exp) == CONSTRUCTOR
9302 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9303 return decl_readonly_section (exp, 0);
9304 else
9305 return false;
9308 /* Simplify a call to the strstr builtin.
9310 Return 0 if no simplification was possible, otherwise return the
9311 simplified form of the call as a tree.
9313 The simplified form may be a constant or other expression which
9314 computes the same value, but in a more efficient manner (including
9315 calls to other builtin functions).
9317 The call may contain arguments which need to be evaluated, but
9318 which are not useful to determine the result of the call. In
9319 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9320 COMPOUND_EXPR will be an argument which must be evaluated.
9321 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9322 COMPOUND_EXPR in the chain will contain the tree for the simplified
9323 form of the builtin function call. */
9325 static tree
9326 fold_builtin_strstr (tree arglist, tree type)
9328 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9329 return 0;
9330 else
9332 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9333 tree fn;
9334 const char *p1, *p2;
9336 p2 = c_getstr (s2);
9337 if (p2 == NULL)
9338 return 0;
9340 p1 = c_getstr (s1);
9341 if (p1 != NULL)
9343 const char *r = strstr (p1, p2);
9344 tree tem;
9346 if (r == NULL)
9347 return build_int_cst (TREE_TYPE (s1), 0);
9349 /* Return an offset into the constant string argument. */
9350 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9351 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9352 return fold_convert (type, tem);
9355 /* The argument is const char *, and the result is char *, so we need
9356 a type conversion here to avoid a warning. */
9357 if (p2[0] == '\0')
9358 return fold_convert (type, s1);
9360 if (p2[1] != '\0')
9361 return 0;
9363 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9364 if (!fn)
9365 return 0;
9367 /* New argument list transforming strstr(s1, s2) to
9368 strchr(s1, s2[0]). */
9369 arglist = build_tree_list (NULL_TREE,
9370 build_int_cst (NULL_TREE, p2[0]));
9371 arglist = tree_cons (NULL_TREE, s1, arglist);
9372 return build_function_call_expr (fn, arglist);
9376 /* Simplify a call to the strchr builtin.
9378 Return 0 if no simplification was possible, otherwise return the
9379 simplified form of the call as a tree.
9381 The simplified form may be a constant or other expression which
9382 computes the same value, but in a more efficient manner (including
9383 calls to other builtin functions).
9385 The call may contain arguments which need to be evaluated, but
9386 which are not useful to determine the result of the call. In
9387 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9388 COMPOUND_EXPR will be an argument which must be evaluated.
9389 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9390 COMPOUND_EXPR in the chain will contain the tree for the simplified
9391 form of the builtin function call. */
9393 static tree
9394 fold_builtin_strchr (tree arglist, tree type)
9396 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9397 return 0;
9398 else
9400 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9401 const char *p1;
9403 if (TREE_CODE (s2) != INTEGER_CST)
9404 return 0;
9406 p1 = c_getstr (s1);
9407 if (p1 != NULL)
9409 char c;
9410 const char *r;
9411 tree tem;
9413 if (target_char_cast (s2, &c))
9414 return 0;
9416 r = strchr (p1, c);
9418 if (r == NULL)
9419 return build_int_cst (TREE_TYPE (s1), 0);
9421 /* Return an offset into the constant string argument. */
9422 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9423 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9424 return fold_convert (type, tem);
9426 return 0;
9430 /* Simplify a call to the strrchr builtin.
9432 Return 0 if no simplification was possible, otherwise return the
9433 simplified form of the call as a tree.
9435 The simplified form may be a constant or other expression which
9436 computes the same value, but in a more efficient manner (including
9437 calls to other builtin functions).
9439 The call may contain arguments which need to be evaluated, but
9440 which are not useful to determine the result of the call. In
9441 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9442 COMPOUND_EXPR will be an argument which must be evaluated.
9443 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9444 COMPOUND_EXPR in the chain will contain the tree for the simplified
9445 form of the builtin function call. */
9447 static tree
9448 fold_builtin_strrchr (tree arglist, tree type)
9450 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9451 return 0;
9452 else
9454 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9455 tree fn;
9456 const char *p1;
9458 if (TREE_CODE (s2) != INTEGER_CST)
9459 return 0;
9461 p1 = c_getstr (s1);
9462 if (p1 != NULL)
9464 char c;
9465 const char *r;
9466 tree tem;
9468 if (target_char_cast (s2, &c))
9469 return 0;
9471 r = strrchr (p1, c);
9473 if (r == NULL)
9474 return build_int_cst (TREE_TYPE (s1), 0);
9476 /* Return an offset into the constant string argument. */
9477 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9478 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9479 return fold_convert (type, tem);
9482 if (! integer_zerop (s2))
9483 return 0;
9485 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9486 if (!fn)
9487 return 0;
9489 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9490 return build_function_call_expr (fn, arglist);
9494 /* Simplify a call to the strpbrk builtin.
9496 Return 0 if no simplification was possible, otherwise return the
9497 simplified form of the call as a tree.
9499 The simplified form may be a constant or other expression which
9500 computes the same value, but in a more efficient manner (including
9501 calls to other builtin functions).
9503 The call may contain arguments which need to be evaluated, but
9504 which are not useful to determine the result of the call. In
9505 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9506 COMPOUND_EXPR will be an argument which must be evaluated.
9507 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9508 COMPOUND_EXPR in the chain will contain the tree for the simplified
9509 form of the builtin function call. */
9511 static tree
9512 fold_builtin_strpbrk (tree arglist, tree type)
9514 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9515 return 0;
9516 else
9518 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9519 tree fn;
9520 const char *p1, *p2;
9522 p2 = c_getstr (s2);
9523 if (p2 == NULL)
9524 return 0;
9526 p1 = c_getstr (s1);
9527 if (p1 != NULL)
9529 const char *r = strpbrk (p1, p2);
9530 tree tem;
9532 if (r == NULL)
9533 return build_int_cst (TREE_TYPE (s1), 0);
9535 /* Return an offset into the constant string argument. */
9536 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9537 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9538 return fold_convert (type, tem);
9541 if (p2[0] == '\0')
9542 /* strpbrk(x, "") == NULL.
9543 Evaluate and ignore s1 in case it had side-effects. */
9544 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9546 if (p2[1] != '\0')
9547 return 0; /* Really call strpbrk. */
9549 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9550 if (!fn)
9551 return 0;
9553 /* New argument list transforming strpbrk(s1, s2) to
9554 strchr(s1, s2[0]). */
9555 arglist = build_tree_list (NULL_TREE,
9556 build_int_cst (NULL_TREE, p2[0]));
9557 arglist = tree_cons (NULL_TREE, s1, arglist);
9558 return build_function_call_expr (fn, arglist);
9562 /* Simplify a call to the strcat builtin.
9564 Return 0 if no simplification was possible, otherwise return the
9565 simplified form of the call as a tree.
9567 The simplified form may be a constant or other expression which
9568 computes the same value, but in a more efficient manner (including
9569 calls to other builtin functions).
9571 The call may contain arguments which need to be evaluated, but
9572 which are not useful to determine the result of the call. In
9573 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9574 COMPOUND_EXPR will be an argument which must be evaluated.
9575 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9576 COMPOUND_EXPR in the chain will contain the tree for the simplified
9577 form of the builtin function call. */
9579 static tree
9580 fold_builtin_strcat (tree arglist)
9582 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9583 return 0;
9584 else
9586 tree dst = TREE_VALUE (arglist),
9587 src = TREE_VALUE (TREE_CHAIN (arglist));
9588 const char *p = c_getstr (src);
9590 /* If the string length is zero, return the dst parameter. */
9591 if (p && *p == '\0')
9592 return dst;
9594 return 0;
9598 /* Simplify a call to the strncat builtin.
9600 Return 0 if no simplification was possible, otherwise return the
9601 simplified form of the call as a tree.
9603 The simplified form may be a constant or other expression which
9604 computes the same value, but in a more efficient manner (including
9605 calls to other builtin functions).
9607 The call may contain arguments which need to be evaluated, but
9608 which are not useful to determine the result of the call. In
9609 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9610 COMPOUND_EXPR will be an argument which must be evaluated.
9611 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9612 COMPOUND_EXPR in the chain will contain the tree for the simplified
9613 form of the builtin function call. */
9615 static tree
9616 fold_builtin_strncat (tree arglist)
9618 if (!validate_arglist (arglist,
9619 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9620 return 0;
9621 else
9623 tree dst = TREE_VALUE (arglist);
9624 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9625 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9626 const char *p = c_getstr (src);
9628 /* If the requested length is zero, or the src parameter string
9629 length is zero, return the dst parameter. */
9630 if (integer_zerop (len) || (p && *p == '\0'))
9631 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9633 /* If the requested len is greater than or equal to the string
9634 length, call strcat. */
9635 if (TREE_CODE (len) == INTEGER_CST && p
9636 && compare_tree_int (len, strlen (p)) >= 0)
9638 tree newarglist
9639 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9640 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9642 /* If the replacement _DECL isn't initialized, don't do the
9643 transformation. */
9644 if (!fn)
9645 return 0;
9647 return build_function_call_expr (fn, newarglist);
9649 return 0;
9653 /* Simplify a call to the strspn builtin.
9655 Return 0 if no simplification was possible, otherwise return the
9656 simplified form of the call as a tree.
9658 The simplified form may be a constant or other expression which
9659 computes the same value, but in a more efficient manner (including
9660 calls to other builtin functions).
9662 The call may contain arguments which need to be evaluated, but
9663 which are not useful to determine the result of the call. In
9664 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9665 COMPOUND_EXPR will be an argument which must be evaluated.
9666 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9667 COMPOUND_EXPR in the chain will contain the tree for the simplified
9668 form of the builtin function call. */
9670 static tree
9671 fold_builtin_strspn (tree arglist)
9673 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9674 return 0;
9675 else
9677 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9678 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9680 /* If both arguments are constants, evaluate at compile-time. */
9681 if (p1 && p2)
9683 const size_t r = strspn (p1, p2);
9684 return size_int (r);
9687 /* If either argument is "", return 0. */
9688 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9689 /* Evaluate and ignore both arguments in case either one has
9690 side-effects. */
9691 return omit_two_operands (integer_type_node, integer_zero_node,
9692 s1, s2);
9693 return 0;
9697 /* Simplify a call to the strcspn builtin.
9699 Return 0 if no simplification was possible, otherwise return the
9700 simplified form of the call as a tree.
9702 The simplified form may be a constant or other expression which
9703 computes the same value, but in a more efficient manner (including
9704 calls to other builtin functions).
9706 The call may contain arguments which need to be evaluated, but
9707 which are not useful to determine the result of the call. In
9708 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9709 COMPOUND_EXPR will be an argument which must be evaluated.
9710 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9711 COMPOUND_EXPR in the chain will contain the tree for the simplified
9712 form of the builtin function call. */
9714 static tree
9715 fold_builtin_strcspn (tree arglist)
9717 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9718 return 0;
9719 else
9721 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9722 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9724 /* If both arguments are constants, evaluate at compile-time. */
9725 if (p1 && p2)
9727 const size_t r = strcspn (p1, p2);
9728 return size_int (r);
9731 /* If the first argument is "", return 0. */
9732 if (p1 && *p1 == '\0')
9734 /* Evaluate and ignore argument s2 in case it has
9735 side-effects. */
9736 return omit_one_operand (integer_type_node,
9737 integer_zero_node, s2);
9740 /* If the second argument is "", return __builtin_strlen(s1). */
9741 if (p2 && *p2 == '\0')
9743 tree newarglist = build_tree_list (NULL_TREE, s1),
9744 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9746 /* If the replacement _DECL isn't initialized, don't do the
9747 transformation. */
9748 if (!fn)
9749 return 0;
9751 return build_function_call_expr (fn, newarglist);
9753 return 0;
9757 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9758 by the builtin will be ignored. UNLOCKED is true is true if this
9759 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9760 the known length of the string. Return NULL_TREE if no simplification
9761 was possible. */
9763 tree
9764 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9766 tree fn;
9767 /* If we're using an unlocked function, assume the other unlocked
9768 functions exist explicitly. */
9769 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9770 : implicit_built_in_decls[BUILT_IN_FPUTC];
9771 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9772 : implicit_built_in_decls[BUILT_IN_FWRITE];
9774 /* If the return value is used, don't do the transformation. */
9775 if (!ignore)
9776 return 0;
9778 /* Verify the arguments in the original call. */
9779 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9780 return 0;
9782 if (! len)
9783 len = c_strlen (TREE_VALUE (arglist), 0);
9785 /* Get the length of the string passed to fputs. If the length
9786 can't be determined, punt. */
9787 if (!len
9788 || TREE_CODE (len) != INTEGER_CST)
9789 return 0;
9791 switch (compare_tree_int (len, 1))
9793 case -1: /* length is 0, delete the call entirely . */
9794 return omit_one_operand (integer_type_node, integer_zero_node,
9795 TREE_VALUE (TREE_CHAIN (arglist)));
9797 case 0: /* length is 1, call fputc. */
9799 const char *p = c_getstr (TREE_VALUE (arglist));
9801 if (p != NULL)
9803 /* New argument list transforming fputs(string, stream) to
9804 fputc(string[0], stream). */
9805 arglist = build_tree_list (NULL_TREE,
9806 TREE_VALUE (TREE_CHAIN (arglist)));
9807 arglist = tree_cons (NULL_TREE,
9808 build_int_cst (NULL_TREE, p[0]),
9809 arglist);
9810 fn = fn_fputc;
9811 break;
9814 /* FALLTHROUGH */
9815 case 1: /* length is greater than 1, call fwrite. */
9817 tree string_arg;
9819 /* If optimizing for size keep fputs. */
9820 if (optimize_size)
9821 return 0;
9822 string_arg = TREE_VALUE (arglist);
9823 /* New argument list transforming fputs(string, stream) to
9824 fwrite(string, 1, len, stream). */
9825 arglist = build_tree_list (NULL_TREE,
9826 TREE_VALUE (TREE_CHAIN (arglist)));
9827 arglist = tree_cons (NULL_TREE, len, arglist);
9828 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9829 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9830 fn = fn_fwrite;
9831 break;
9833 default:
9834 gcc_unreachable ();
9837 /* If the replacement _DECL isn't initialized, don't do the
9838 transformation. */
9839 if (!fn)
9840 return 0;
9842 /* These optimizations are only performed when the result is ignored,
9843 hence there's no need to cast the result to integer_type_node. */
9844 return build_function_call_expr (fn, arglist);
9847 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9848 produced. False otherwise. This is done so that we don't output the error
9849 or warning twice or three times. */
9850 bool
9851 fold_builtin_next_arg (tree arglist)
9853 tree fntype = TREE_TYPE (current_function_decl);
9855 if (TYPE_ARG_TYPES (fntype) == 0
9856 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9857 == void_type_node))
9859 error ("%<va_start%> used in function with fixed args");
9860 return true;
9862 else if (!arglist)
9864 /* Evidently an out of date version of <stdarg.h>; can't validate
9865 va_start's second argument, but can still work as intended. */
9866 warning (0, "%<__builtin_next_arg%> called without an argument");
9867 return true;
9869 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9870 when we checked the arguments and if needed issued a warning. */
9871 else if (!TREE_CHAIN (arglist)
9872 || !integer_zerop (TREE_VALUE (arglist))
9873 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9874 || TREE_CHAIN (TREE_CHAIN (arglist)))
9876 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9877 tree arg = TREE_VALUE (arglist);
9879 if (TREE_CHAIN (arglist))
9881 error ("%<va_start%> used with too many arguments");
9882 return true;
9885 /* Strip off all nops for the sake of the comparison. This
9886 is not quite the same as STRIP_NOPS. It does more.
9887 We must also strip off INDIRECT_EXPR for C++ reference
9888 parameters. */
9889 while (TREE_CODE (arg) == NOP_EXPR
9890 || TREE_CODE (arg) == CONVERT_EXPR
9891 || TREE_CODE (arg) == NON_LVALUE_EXPR
9892 || TREE_CODE (arg) == INDIRECT_REF)
9893 arg = TREE_OPERAND (arg, 0);
9894 if (arg != last_parm)
9896 /* FIXME: Sometimes with the tree optimizers we can get the
9897 not the last argument even though the user used the last
9898 argument. We just warn and set the arg to be the last
9899 argument so that we will get wrong-code because of
9900 it. */
9901 warning (0, "second parameter of %<va_start%> not last named argument");
9903 /* We want to verify the second parameter just once before the tree
9904 optimizers are run and then avoid keeping it in the tree,
9905 as otherwise we could warn even for correct code like:
9906 void foo (int i, ...)
9907 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9908 TREE_VALUE (arglist) = integer_zero_node;
9909 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9911 return false;
9915 /* Simplify a call to the sprintf builtin.
9917 Return 0 if no simplification was possible, otherwise return the
9918 simplified form of the call as a tree. If IGNORED is true, it means that
9919 the caller does not use the returned value of the function. */
9921 static tree
9922 fold_builtin_sprintf (tree arglist, int ignored)
9924 tree call, retval, dest, fmt;
9925 const char *fmt_str = NULL;
9927 /* Verify the required arguments in the original call. We deal with two
9928 types of sprintf() calls: 'sprintf (str, fmt)' and
9929 'sprintf (dest, "%s", orig)'. */
9930 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9931 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9932 VOID_TYPE))
9933 return NULL_TREE;
9935 /* Get the destination string and the format specifier. */
9936 dest = TREE_VALUE (arglist);
9937 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9938 arglist = TREE_CHAIN (TREE_CHAIN (arglist));
9940 /* Check whether the format is a literal string constant. */
9941 fmt_str = c_getstr (fmt);
9942 if (fmt_str == NULL)
9943 return NULL_TREE;
9945 call = NULL_TREE;
9946 retval = NULL_TREE;
9948 if (!init_target_chars())
9949 return 0;
9951 /* If the format doesn't contain % args or %%, use strcpy. */
9952 if (strchr (fmt_str, target_percent) == NULL)
9954 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9956 if (!fn)
9957 return NULL_TREE;
9959 /* Don't optimize sprintf (buf, "abc", ptr++). */
9960 if (arglist)
9961 return NULL_TREE;
9963 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9964 'format' is known to contain no % formats. */
9965 arglist = build_tree_list (NULL_TREE, fmt);
9966 arglist = tree_cons (NULL_TREE, dest, arglist);
9967 call = build_function_call_expr (fn, arglist);
9968 if (!ignored)
9969 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9972 /* If the format is "%s", use strcpy if the result isn't used. */
9973 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9975 tree fn, orig;
9976 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9978 if (!fn)
9979 return NULL_TREE;
9981 /* Don't crash on sprintf (str1, "%s"). */
9982 if (!arglist)
9983 return NULL_TREE;
9985 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9986 orig = TREE_VALUE (arglist);
9987 arglist = build_tree_list (NULL_TREE, orig);
9988 arglist = tree_cons (NULL_TREE, dest, arglist);
9989 if (!ignored)
9991 retval = c_strlen (orig, 1);
9992 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9993 return NULL_TREE;
9995 call = build_function_call_expr (fn, arglist);
9998 if (call && retval)
10000 retval = fold_convert
10001 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10002 retval);
10003 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10005 else
10006 return call;
10009 /* Expand a call to __builtin_object_size. */
10012 expand_builtin_object_size (tree exp)
10014 tree ost;
10015 int object_size_type;
10016 tree fndecl = get_callee_fndecl (exp);
10017 tree arglist = TREE_OPERAND (exp, 1);
10018 location_t locus = EXPR_LOCATION (exp);
10020 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10022 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10023 &locus, fndecl);
10024 expand_builtin_trap ();
10025 return const0_rtx;
10028 ost = TREE_VALUE (TREE_CHAIN (arglist));
10029 STRIP_NOPS (ost);
10031 if (TREE_CODE (ost) != INTEGER_CST
10032 || tree_int_cst_sgn (ost) < 0
10033 || compare_tree_int (ost, 3) > 0)
10035 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10036 &locus, fndecl);
10037 expand_builtin_trap ();
10038 return const0_rtx;
10041 object_size_type = tree_low_cst (ost, 0);
10043 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10046 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10047 FCODE is the BUILT_IN_* to use.
10048 Return 0 if we failed; the caller should emit a normal call,
10049 otherwise try to get the result in TARGET, if convenient (and in
10050 mode MODE if that's convenient). */
10052 static rtx
10053 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10054 enum built_in_function fcode)
10056 tree arglist = TREE_OPERAND (exp, 1);
10057 tree dest, src, len, size;
10059 if (!validate_arglist (arglist,
10060 POINTER_TYPE,
10061 fcode == BUILT_IN_MEMSET_CHK
10062 ? INTEGER_TYPE : POINTER_TYPE,
10063 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10064 return 0;
10066 dest = TREE_VALUE (arglist);
10067 src = TREE_VALUE (TREE_CHAIN (arglist));
10068 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10069 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10071 if (! host_integerp (size, 1))
10072 return 0;
10074 if (host_integerp (len, 1) || integer_all_onesp (size))
10076 tree fn;
10078 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10080 location_t locus = EXPR_LOCATION (exp);
10081 warning (0, "%Hcall to %D will always overflow destination buffer",
10082 &locus, get_callee_fndecl (exp));
10083 return 0;
10086 arglist = build_tree_list (NULL_TREE, len);
10087 arglist = tree_cons (NULL_TREE, src, arglist);
10088 arglist = tree_cons (NULL_TREE, dest, arglist);
10090 fn = NULL_TREE;
10091 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10092 mem{cpy,pcpy,move,set} is available. */
10093 switch (fcode)
10095 case BUILT_IN_MEMCPY_CHK:
10096 fn = built_in_decls[BUILT_IN_MEMCPY];
10097 break;
10098 case BUILT_IN_MEMPCPY_CHK:
10099 fn = built_in_decls[BUILT_IN_MEMPCPY];
10100 break;
10101 case BUILT_IN_MEMMOVE_CHK:
10102 fn = built_in_decls[BUILT_IN_MEMMOVE];
10103 break;
10104 case BUILT_IN_MEMSET_CHK:
10105 fn = built_in_decls[BUILT_IN_MEMSET];
10106 break;
10107 default:
10108 break;
10111 if (! fn)
10112 return 0;
10114 fn = build_function_call_expr (fn, arglist);
10115 if (TREE_CODE (fn) == CALL_EXPR)
10116 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10117 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10119 else if (fcode == BUILT_IN_MEMSET_CHK)
10120 return 0;
10121 else
10123 unsigned int dest_align
10124 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10126 /* If DEST is not a pointer type, call the normal function. */
10127 if (dest_align == 0)
10128 return 0;
10130 /* If SRC and DEST are the same (and not volatile), do nothing. */
10131 if (operand_equal_p (src, dest, 0))
10133 tree expr;
10135 if (fcode != BUILT_IN_MEMPCPY_CHK)
10137 /* Evaluate and ignore LEN in case it has side-effects. */
10138 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10139 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10142 len = fold_convert (TREE_TYPE (dest), len);
10143 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10144 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10147 /* __memmove_chk special case. */
10148 if (fcode == BUILT_IN_MEMMOVE_CHK)
10150 unsigned int src_align
10151 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10153 if (src_align == 0)
10154 return 0;
10156 /* If src is categorized for a readonly section we can use
10157 normal __memcpy_chk. */
10158 if (readonly_data_expr (src))
10160 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10161 if (!fn)
10162 return 0;
10163 fn = build_function_call_expr (fn, arglist);
10164 if (TREE_CODE (fn) == CALL_EXPR)
10165 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10166 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10169 return 0;
10173 /* Emit warning if a buffer overflow is detected at compile time. */
10175 static void
10176 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10178 int arg_mask, is_strlen = 0;
10179 tree arglist = TREE_OPERAND (exp, 1), a;
10180 tree len, size;
10181 location_t locus;
10183 switch (fcode)
10185 case BUILT_IN_STRCPY_CHK:
10186 case BUILT_IN_STPCPY_CHK:
10187 /* For __strcat_chk the warning will be emitted only if overflowing
10188 by at least strlen (dest) + 1 bytes. */
10189 case BUILT_IN_STRCAT_CHK:
10190 arg_mask = 6;
10191 is_strlen = 1;
10192 break;
10193 case BUILT_IN_STRNCPY_CHK:
10194 arg_mask = 12;
10195 break;
10196 case BUILT_IN_SNPRINTF_CHK:
10197 case BUILT_IN_VSNPRINTF_CHK:
10198 arg_mask = 10;
10199 break;
10200 default:
10201 gcc_unreachable ();
10204 len = NULL_TREE;
10205 size = NULL_TREE;
10206 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10207 if (arg_mask & 1)
10209 if (len)
10210 size = a;
10211 else
10212 len = a;
10215 if (!len || !size)
10216 return;
10218 len = TREE_VALUE (len);
10219 size = TREE_VALUE (size);
10221 if (! host_integerp (size, 1) || integer_all_onesp (size))
10222 return;
10224 if (is_strlen)
10226 len = c_strlen (len, 1);
10227 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10228 return;
10230 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10231 return;
10233 locus = EXPR_LOCATION (exp);
10234 warning (0, "%Hcall to %D will always overflow destination buffer",
10235 &locus, get_callee_fndecl (exp));
10238 /* Emit warning if a buffer overflow is detected at compile time
10239 in __sprintf_chk/__vsprintf_chk calls. */
10241 static void
10242 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10244 tree arglist = TREE_OPERAND (exp, 1);
10245 tree dest, size, len, fmt, flag;
10246 const char *fmt_str;
10248 /* Verify the required arguments in the original call. */
10249 if (! arglist)
10250 return;
10251 dest = TREE_VALUE (arglist);
10252 arglist = TREE_CHAIN (arglist);
10253 if (! arglist)
10254 return;
10255 flag = TREE_VALUE (arglist);
10256 arglist = TREE_CHAIN (arglist);
10257 if (! arglist)
10258 return;
10259 size = TREE_VALUE (arglist);
10260 arglist = TREE_CHAIN (arglist);
10261 if (! arglist)
10262 return;
10263 fmt = TREE_VALUE (arglist);
10264 arglist = TREE_CHAIN (arglist);
10266 if (! host_integerp (size, 1) || integer_all_onesp (size))
10267 return;
10269 /* Check whether the format is a literal string constant. */
10270 fmt_str = c_getstr (fmt);
10271 if (fmt_str == NULL)
10272 return;
10274 if (!init_target_chars())
10275 return;
10277 /* If the format doesn't contain % args or %%, we know its size. */
10278 if (strchr (fmt_str, target_percent) == 0)
10279 len = build_int_cstu (size_type_node, strlen (fmt_str));
10280 /* If the format is "%s" and first ... argument is a string literal,
10281 we know it too. */
10282 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10284 tree arg;
10286 if (! arglist)
10287 return;
10288 arg = TREE_VALUE (arglist);
10289 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10290 return;
10292 len = c_strlen (arg, 1);
10293 if (!len || ! host_integerp (len, 1))
10294 return;
10296 else
10297 return;
10299 if (! tree_int_cst_lt (len, size))
10301 location_t locus = EXPR_LOCATION (exp);
10302 warning (0, "%Hcall to %D will always overflow destination buffer",
10303 &locus, get_callee_fndecl (exp));
10307 /* Fold a call to __builtin_object_size, if possible. */
10309 tree
10310 fold_builtin_object_size (tree arglist)
10312 tree ptr, ost, ret = 0;
10313 int object_size_type;
10315 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10316 return 0;
10318 ptr = TREE_VALUE (arglist);
10319 ost = TREE_VALUE (TREE_CHAIN (arglist));
10320 STRIP_NOPS (ost);
10322 if (TREE_CODE (ost) != INTEGER_CST
10323 || tree_int_cst_sgn (ost) < 0
10324 || compare_tree_int (ost, 3) > 0)
10325 return 0;
10327 object_size_type = tree_low_cst (ost, 0);
10329 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10330 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10331 and (size_t) 0 for types 2 and 3. */
10332 if (TREE_SIDE_EFFECTS (ptr))
10333 return fold_convert (size_type_node,
10334 object_size_type < 2
10335 ? integer_minus_one_node : integer_zero_node);
10337 if (TREE_CODE (ptr) == ADDR_EXPR)
10338 ret = build_int_cstu (size_type_node,
10339 compute_builtin_object_size (ptr, object_size_type));
10341 else if (TREE_CODE (ptr) == SSA_NAME)
10343 unsigned HOST_WIDE_INT bytes;
10345 /* If object size is not known yet, delay folding until
10346 later. Maybe subsequent passes will help determining
10347 it. */
10348 bytes = compute_builtin_object_size (ptr, object_size_type);
10349 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10350 ? -1 : 0))
10351 ret = build_int_cstu (size_type_node, bytes);
10354 if (ret)
10356 ret = force_fit_type (ret, -1, false, false);
10357 if (TREE_CONSTANT_OVERFLOW (ret))
10358 ret = 0;
10361 return ret;
10364 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10365 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10366 code of the builtin. If MAXLEN is not NULL, it is maximum length
10367 passed as third argument. */
10369 tree
10370 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10371 enum built_in_function fcode)
10373 tree dest, src, len, size, fn;
10375 if (!validate_arglist (arglist,
10376 POINTER_TYPE,
10377 fcode == BUILT_IN_MEMSET_CHK
10378 ? INTEGER_TYPE : POINTER_TYPE,
10379 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10380 return 0;
10382 dest = TREE_VALUE (arglist);
10383 /* Actually val for __memset_chk, but it doesn't matter. */
10384 src = TREE_VALUE (TREE_CHAIN (arglist));
10385 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10386 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10388 /* If SRC and DEST are the same (and not volatile), return DEST
10389 (resp. DEST+LEN for __mempcpy_chk). */
10390 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10392 if (fcode != BUILT_IN_MEMPCPY_CHK)
10393 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10394 else
10396 tree temp = fold_convert (TREE_TYPE (dest), len);
10397 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10398 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10402 if (! host_integerp (size, 1))
10403 return 0;
10405 if (! integer_all_onesp (size))
10407 if (! host_integerp (len, 1))
10409 /* If LEN is not constant, try MAXLEN too.
10410 For MAXLEN only allow optimizing into non-_ocs function
10411 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10412 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10414 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10416 /* (void) __mempcpy_chk () can be optimized into
10417 (void) __memcpy_chk (). */
10418 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10419 if (!fn)
10420 return 0;
10422 return build_function_call_expr (fn, arglist);
10424 return 0;
10427 else
10428 maxlen = len;
10430 if (tree_int_cst_lt (size, maxlen))
10431 return 0;
10434 arglist = build_tree_list (NULL_TREE, len);
10435 arglist = tree_cons (NULL_TREE, src, arglist);
10436 arglist = tree_cons (NULL_TREE, dest, arglist);
10438 fn = NULL_TREE;
10439 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10440 mem{cpy,pcpy,move,set} is available. */
10441 switch (fcode)
10443 case BUILT_IN_MEMCPY_CHK:
10444 fn = built_in_decls[BUILT_IN_MEMCPY];
10445 break;
10446 case BUILT_IN_MEMPCPY_CHK:
10447 fn = built_in_decls[BUILT_IN_MEMPCPY];
10448 break;
10449 case BUILT_IN_MEMMOVE_CHK:
10450 fn = built_in_decls[BUILT_IN_MEMMOVE];
10451 break;
10452 case BUILT_IN_MEMSET_CHK:
10453 fn = built_in_decls[BUILT_IN_MEMSET];
10454 break;
10455 default:
10456 break;
10459 if (!fn)
10460 return 0;
10462 return build_function_call_expr (fn, arglist);
10465 /* Fold a call to the __st[rp]cpy_chk builtin.
10466 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10467 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10468 strings passed as second argument. */
10470 tree
10471 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10472 enum built_in_function fcode)
10474 tree dest, src, size, len, fn;
10476 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10477 VOID_TYPE))
10478 return 0;
10480 dest = TREE_VALUE (arglist);
10481 src = TREE_VALUE (TREE_CHAIN (arglist));
10482 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10484 /* If SRC and DEST are the same (and not volatile), return DEST. */
10485 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10486 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10488 if (! host_integerp (size, 1))
10489 return 0;
10491 if (! integer_all_onesp (size))
10493 len = c_strlen (src, 1);
10494 if (! len || ! host_integerp (len, 1))
10496 /* If LEN is not constant, try MAXLEN too.
10497 For MAXLEN only allow optimizing into non-_ocs function
10498 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10499 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10501 if (fcode == BUILT_IN_STPCPY_CHK)
10503 if (! ignore)
10504 return 0;
10506 /* If return value of __stpcpy_chk is ignored,
10507 optimize into __strcpy_chk. */
10508 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10509 if (!fn)
10510 return 0;
10512 return build_function_call_expr (fn, arglist);
10515 if (! len || TREE_SIDE_EFFECTS (len))
10516 return 0;
10518 /* If c_strlen returned something, but not a constant,
10519 transform __strcpy_chk into __memcpy_chk. */
10520 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10521 if (!fn)
10522 return 0;
10524 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10525 arglist = build_tree_list (NULL_TREE, size);
10526 arglist = tree_cons (NULL_TREE, len, arglist);
10527 arglist = tree_cons (NULL_TREE, src, arglist);
10528 arglist = tree_cons (NULL_TREE, dest, arglist);
10529 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10530 build_function_call_expr (fn, arglist));
10533 else
10534 maxlen = len;
10536 if (! tree_int_cst_lt (maxlen, size))
10537 return 0;
10540 arglist = build_tree_list (NULL_TREE, src);
10541 arglist = tree_cons (NULL_TREE, dest, arglist);
10543 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10544 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10545 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10546 if (!fn)
10547 return 0;
10549 return build_function_call_expr (fn, arglist);
10552 /* Fold a call to the __strncpy_chk builtin.
10553 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10555 tree
10556 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10558 tree dest, src, size, len, fn;
10560 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10561 INTEGER_TYPE, VOID_TYPE))
10562 return 0;
10564 dest = TREE_VALUE (arglist);
10565 src = TREE_VALUE (TREE_CHAIN (arglist));
10566 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10567 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10569 if (! host_integerp (size, 1))
10570 return 0;
10572 if (! integer_all_onesp (size))
10574 if (! host_integerp (len, 1))
10576 /* If LEN is not constant, try MAXLEN too.
10577 For MAXLEN only allow optimizing into non-_ocs function
10578 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10579 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10580 return 0;
10582 else
10583 maxlen = len;
10585 if (tree_int_cst_lt (size, maxlen))
10586 return 0;
10589 arglist = build_tree_list (NULL_TREE, len);
10590 arglist = tree_cons (NULL_TREE, src, arglist);
10591 arglist = tree_cons (NULL_TREE, dest, arglist);
10593 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10594 fn = built_in_decls[BUILT_IN_STRNCPY];
10595 if (!fn)
10596 return 0;
10598 return build_function_call_expr (fn, arglist);
10601 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10603 static tree
10604 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10606 tree dest, src, size, fn;
10607 const char *p;
10609 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10610 VOID_TYPE))
10611 return 0;
10613 dest = TREE_VALUE (arglist);
10614 src = TREE_VALUE (TREE_CHAIN (arglist));
10615 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10617 p = c_getstr (src);
10618 /* If the SRC parameter is "", return DEST. */
10619 if (p && *p == '\0')
10620 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10622 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10623 return 0;
10625 arglist = build_tree_list (NULL_TREE, src);
10626 arglist = tree_cons (NULL_TREE, dest, arglist);
10628 /* If __builtin_strcat_chk is used, assume strcat is available. */
10629 fn = built_in_decls[BUILT_IN_STRCAT];
10630 if (!fn)
10631 return 0;
10633 return build_function_call_expr (fn, arglist);
10636 /* Fold a call to the __strncat_chk builtin EXP. */
10638 static tree
10639 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10641 tree dest, src, size, len, fn;
10642 const char *p;
10644 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10645 INTEGER_TYPE, VOID_TYPE))
10646 return 0;
10648 dest = TREE_VALUE (arglist);
10649 src = TREE_VALUE (TREE_CHAIN (arglist));
10650 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10651 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10653 p = c_getstr (src);
10654 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10655 if (p && *p == '\0')
10656 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10657 else if (integer_zerop (len))
10658 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10660 if (! host_integerp (size, 1))
10661 return 0;
10663 if (! integer_all_onesp (size))
10665 tree src_len = c_strlen (src, 1);
10666 if (src_len
10667 && host_integerp (src_len, 1)
10668 && host_integerp (len, 1)
10669 && ! tree_int_cst_lt (len, src_len))
10671 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10672 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10673 if (!fn)
10674 return 0;
10676 arglist = build_tree_list (NULL_TREE, size);
10677 arglist = tree_cons (NULL_TREE, src, arglist);
10678 arglist = tree_cons (NULL_TREE, dest, arglist);
10679 return build_function_call_expr (fn, arglist);
10681 return 0;
10684 arglist = build_tree_list (NULL_TREE, len);
10685 arglist = tree_cons (NULL_TREE, src, arglist);
10686 arglist = tree_cons (NULL_TREE, dest, arglist);
10688 /* If __builtin_strncat_chk is used, assume strncat is available. */
10689 fn = built_in_decls[BUILT_IN_STRNCAT];
10690 if (!fn)
10691 return 0;
10693 return build_function_call_expr (fn, arglist);
10696 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10697 a normal call should be emitted rather than expanding the function
10698 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10700 static tree
10701 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10703 tree dest, size, len, fn, fmt, flag;
10704 const char *fmt_str;
10706 /* Verify the required arguments in the original call. */
10707 if (! arglist)
10708 return 0;
10709 dest = TREE_VALUE (arglist);
10710 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10711 return 0;
10712 arglist = TREE_CHAIN (arglist);
10713 if (! arglist)
10714 return 0;
10715 flag = TREE_VALUE (arglist);
10716 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10717 return 0;
10718 arglist = TREE_CHAIN (arglist);
10719 if (! arglist)
10720 return 0;
10721 size = TREE_VALUE (arglist);
10722 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10723 return 0;
10724 arglist = TREE_CHAIN (arglist);
10725 if (! arglist)
10726 return 0;
10727 fmt = TREE_VALUE (arglist);
10728 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10729 return 0;
10730 arglist = TREE_CHAIN (arglist);
10732 if (! host_integerp (size, 1))
10733 return 0;
10735 len = NULL_TREE;
10737 if (!init_target_chars())
10738 return 0;
10740 /* Check whether the format is a literal string constant. */
10741 fmt_str = c_getstr (fmt);
10742 if (fmt_str != NULL)
10744 /* If the format doesn't contain % args or %%, we know the size. */
10745 if (strchr (fmt_str, target_percent) == 0)
10747 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10748 len = build_int_cstu (size_type_node, strlen (fmt_str));
10750 /* If the format is "%s" and first ... argument is a string literal,
10751 we know the size too. */
10752 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10754 tree arg;
10756 if (arglist && !TREE_CHAIN (arglist))
10758 arg = TREE_VALUE (arglist);
10759 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10761 len = c_strlen (arg, 1);
10762 if (! len || ! host_integerp (len, 1))
10763 len = NULL_TREE;
10769 if (! integer_all_onesp (size))
10771 if (! len || ! tree_int_cst_lt (len, size))
10772 return 0;
10775 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10776 or if format doesn't contain % chars or is "%s". */
10777 if (! integer_zerop (flag))
10779 if (fmt_str == NULL)
10780 return 0;
10781 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10782 return 0;
10785 arglist = tree_cons (NULL_TREE, fmt, arglist);
10786 arglist = tree_cons (NULL_TREE, dest, arglist);
10788 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10789 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10790 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10791 if (!fn)
10792 return 0;
10794 return build_function_call_expr (fn, arglist);
10797 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10798 a normal call should be emitted rather than expanding the function
10799 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10800 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10801 passed as second argument. */
10803 tree
10804 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10805 enum built_in_function fcode)
10807 tree dest, size, len, fn, fmt, flag;
10808 const char *fmt_str;
10810 /* Verify the required arguments in the original call. */
10811 if (! arglist)
10812 return 0;
10813 dest = TREE_VALUE (arglist);
10814 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10815 return 0;
10816 arglist = TREE_CHAIN (arglist);
10817 if (! arglist)
10818 return 0;
10819 len = TREE_VALUE (arglist);
10820 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10821 return 0;
10822 arglist = TREE_CHAIN (arglist);
10823 if (! arglist)
10824 return 0;
10825 flag = TREE_VALUE (arglist);
10826 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10827 return 0;
10828 arglist = TREE_CHAIN (arglist);
10829 if (! arglist)
10830 return 0;
10831 size = TREE_VALUE (arglist);
10832 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10833 return 0;
10834 arglist = TREE_CHAIN (arglist);
10835 if (! arglist)
10836 return 0;
10837 fmt = TREE_VALUE (arglist);
10838 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10839 return 0;
10840 arglist = TREE_CHAIN (arglist);
10842 if (! host_integerp (size, 1))
10843 return 0;
10845 if (! integer_all_onesp (size))
10847 if (! host_integerp (len, 1))
10849 /* If LEN is not constant, try MAXLEN too.
10850 For MAXLEN only allow optimizing into non-_ocs function
10851 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10852 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10853 return 0;
10855 else
10856 maxlen = len;
10858 if (tree_int_cst_lt (size, maxlen))
10859 return 0;
10862 if (!init_target_chars())
10863 return 0;
10865 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10866 or if format doesn't contain % chars or is "%s". */
10867 if (! integer_zerop (flag))
10869 fmt_str = c_getstr (fmt);
10870 if (fmt_str == NULL)
10871 return 0;
10872 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10873 return 0;
10876 arglist = tree_cons (NULL_TREE, fmt, arglist);
10877 arglist = tree_cons (NULL_TREE, len, arglist);
10878 arglist = tree_cons (NULL_TREE, dest, arglist);
10880 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10881 available. */
10882 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10883 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10884 if (!fn)
10885 return 0;
10887 return build_function_call_expr (fn, arglist);
10890 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10892 Return 0 if no simplification was possible, otherwise return the
10893 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10894 code of the function to be simplified. */
10896 static tree
10897 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10898 enum built_in_function fcode)
10900 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10901 const char *fmt_str = NULL;
10903 /* If the return value is used, don't do the transformation. */
10904 if (! ignore)
10905 return 0;
10907 /* Verify the required arguments in the original call. */
10908 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10910 tree flag;
10912 if (! arglist)
10913 return 0;
10914 flag = TREE_VALUE (arglist);
10915 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10916 || TREE_SIDE_EFFECTS (flag))
10917 return 0;
10918 arglist = TREE_CHAIN (arglist);
10921 if (! arglist)
10922 return 0;
10923 fmt = TREE_VALUE (arglist);
10924 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10925 return 0;
10926 arglist = TREE_CHAIN (arglist);
10928 /* Check whether the format is a literal string constant. */
10929 fmt_str = c_getstr (fmt);
10930 if (fmt_str == NULL)
10931 return NULL_TREE;
10933 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10935 /* If we're using an unlocked function, assume the other
10936 unlocked functions exist explicitly. */
10937 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10938 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10940 else
10942 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10943 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10946 if (!init_target_chars())
10947 return 0;
10949 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10951 const char *str;
10953 if (strcmp (fmt_str, target_percent_s) == 0)
10955 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10956 return 0;
10958 if (! arglist
10959 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10960 || TREE_CHAIN (arglist))
10961 return 0;
10963 str = c_getstr (TREE_VALUE (arglist));
10964 if (str == NULL)
10965 return 0;
10967 else
10969 /* The format specifier doesn't contain any '%' characters. */
10970 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10971 && arglist)
10972 return 0;
10973 str = fmt_str;
10976 /* If the string was "", printf does nothing. */
10977 if (str[0] == '\0')
10978 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10980 /* If the string has length of 1, call putchar. */
10981 if (str[1] == '\0')
10983 /* Given printf("c"), (where c is any one character,)
10984 convert "c"[0] to an int and pass that to the replacement
10985 function. */
10986 arg = build_int_cst (NULL_TREE, str[0]);
10987 arglist = build_tree_list (NULL_TREE, arg);
10988 fn = fn_putchar;
10990 else
10992 /* If the string was "string\n", call puts("string"). */
10993 size_t len = strlen (str);
10994 if ((unsigned char)str[len - 1] == target_newline)
10996 /* Create a NUL-terminated string that's one char shorter
10997 than the original, stripping off the trailing '\n'. */
10998 char *newstr = alloca (len);
10999 memcpy (newstr, str, len - 1);
11000 newstr[len - 1] = 0;
11002 arg = build_string_literal (len, newstr);
11003 arglist = build_tree_list (NULL_TREE, arg);
11004 fn = fn_puts;
11006 else
11007 /* We'd like to arrange to call fputs(string,stdout) here,
11008 but we need stdout and don't have a way to get it yet. */
11009 return 0;
11013 /* The other optimizations can be done only on the non-va_list variants. */
11014 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11015 return 0;
11017 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11018 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11020 if (! arglist
11021 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11022 || TREE_CHAIN (arglist))
11023 return 0;
11024 fn = fn_puts;
11027 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11028 else if (strcmp (fmt_str, target_percent_c) == 0)
11030 if (! arglist
11031 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11032 || TREE_CHAIN (arglist))
11033 return 0;
11034 fn = fn_putchar;
11037 if (!fn)
11038 return 0;
11040 call = build_function_call_expr (fn, arglist);
11041 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11044 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11046 Return 0 if no simplification was possible, otherwise return the
11047 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11048 code of the function to be simplified. */
11050 static tree
11051 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11052 enum built_in_function fcode)
11054 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11055 const char *fmt_str = NULL;
11057 /* If the return value is used, don't do the transformation. */
11058 if (! ignore)
11059 return 0;
11061 /* Verify the required arguments in the original call. */
11062 if (! arglist)
11063 return 0;
11064 fp = TREE_VALUE (arglist);
11065 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11066 return 0;
11067 arglist = TREE_CHAIN (arglist);
11069 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11071 tree flag;
11073 if (! arglist)
11074 return 0;
11075 flag = TREE_VALUE (arglist);
11076 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11077 || TREE_SIDE_EFFECTS (flag))
11078 return 0;
11079 arglist = TREE_CHAIN (arglist);
11082 if (! arglist)
11083 return 0;
11084 fmt = TREE_VALUE (arglist);
11085 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11086 return 0;
11087 arglist = TREE_CHAIN (arglist);
11089 /* Check whether the format is a literal string constant. */
11090 fmt_str = c_getstr (fmt);
11091 if (fmt_str == NULL)
11092 return NULL_TREE;
11094 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11096 /* If we're using an unlocked function, assume the other
11097 unlocked functions exist explicitly. */
11098 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11099 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11101 else
11103 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11104 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11107 if (!init_target_chars())
11108 return 0;
11110 /* If the format doesn't contain % args or %%, use strcpy. */
11111 if (strchr (fmt_str, target_percent) == NULL)
11113 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11114 && arglist)
11115 return 0;
11117 /* If the format specifier was "", fprintf does nothing. */
11118 if (fmt_str[0] == '\0')
11120 /* If FP has side-effects, just wait until gimplification is
11121 done. */
11122 if (TREE_SIDE_EFFECTS (fp))
11123 return 0;
11125 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11128 /* When "string" doesn't contain %, replace all cases of
11129 fprintf (fp, string) with fputs (string, fp). The fputs
11130 builtin will take care of special cases like length == 1. */
11131 arglist = build_tree_list (NULL_TREE, fp);
11132 arglist = tree_cons (NULL_TREE, fmt, arglist);
11133 fn = fn_fputs;
11136 /* The other optimizations can be done only on the non-va_list variants. */
11137 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11138 return 0;
11140 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11141 else if (strcmp (fmt_str, target_percent_s) == 0)
11143 if (! arglist
11144 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11145 || TREE_CHAIN (arglist))
11146 return 0;
11147 arg = TREE_VALUE (arglist);
11148 arglist = build_tree_list (NULL_TREE, fp);
11149 arglist = tree_cons (NULL_TREE, arg, arglist);
11150 fn = fn_fputs;
11153 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11154 else if (strcmp (fmt_str, target_percent_c) == 0)
11156 if (! arglist
11157 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11158 || TREE_CHAIN (arglist))
11159 return 0;
11160 arg = TREE_VALUE (arglist);
11161 arglist = build_tree_list (NULL_TREE, fp);
11162 arglist = tree_cons (NULL_TREE, arg, arglist);
11163 fn = fn_fputc;
11166 if (!fn)
11167 return 0;
11169 call = build_function_call_expr (fn, arglist);
11170 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11173 /* Initialize format string characters in the target charset. */
11175 static bool
11176 init_target_chars (void)
11178 static bool init;
11179 if (!init)
11181 target_newline = lang_hooks.to_target_charset ('\n');
11182 target_percent = lang_hooks.to_target_charset ('%');
11183 target_c = lang_hooks.to_target_charset ('c');
11184 target_s = lang_hooks.to_target_charset ('s');
11185 if (target_newline == 0 || target_percent == 0 || target_c == 0
11186 || target_s == 0)
11187 return false;
11189 target_percent_c[0] = target_percent;
11190 target_percent_c[1] = target_c;
11191 target_percent_c[2] = '\0';
11193 target_percent_s[0] = target_percent;
11194 target_percent_s[1] = target_s;
11195 target_percent_s[2] = '\0';
11197 target_percent_s_newline[0] = target_percent;
11198 target_percent_s_newline[1] = target_s;
11199 target_percent_s_newline[2] = target_newline;
11200 target_percent_s_newline[3] = '\0';
11202 init = true;
11204 return true;