* gimplify.c (find_single_pointer_decl_1): New static function.
[official-gcc.git] / gcc / builtins.c
blob12ae9d9f549d7e4bf22e5944c9033e2a4a2e1be7
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
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 tree build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx result_vector (int, rtx);
84 #endif
85 static rtx expand_builtin_setjmp (tree, rtx);
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_sin (tree);
155 static tree fold_builtin_cos (tree, tree, tree);
156 static tree fold_builtin_tan (tree);
157 static tree fold_builtin_atan (tree, tree);
158 static tree fold_builtin_trunc (tree, tree);
159 static tree fold_builtin_floor (tree, tree);
160 static tree fold_builtin_ceil (tree, tree);
161 static tree fold_builtin_round (tree, tree);
162 static tree fold_builtin_int_roundingfn (tree, tree);
163 static tree fold_builtin_bitop (tree, tree);
164 static tree fold_builtin_memcpy (tree, tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree, tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree, tree);
172 static tree fold_builtin_copysign (tree, tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 enum tree_code);
180 static tree fold_builtin_1 (tree, tree, bool);
182 static tree fold_builtin_strpbrk (tree, tree);
183 static tree fold_builtin_strstr (tree, tree);
184 static tree fold_builtin_strrchr (tree, tree);
185 static tree fold_builtin_strcat (tree);
186 static tree fold_builtin_strncat (tree);
187 static tree fold_builtin_strspn (tree);
188 static tree fold_builtin_strcspn (tree);
189 static tree fold_builtin_sprintf (tree, int);
191 static rtx expand_builtin_object_size (tree);
192 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193 enum built_in_function);
194 static void maybe_emit_chk_warning (tree, enum built_in_function);
195 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196 static tree fold_builtin_object_size (tree);
197 static tree fold_builtin_strcat_chk (tree, tree);
198 static tree fold_builtin_strncat_chk (tree, tree);
199 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
203 /* Return true if NODE should be considered for inline expansion regardless
204 of the optimization level. This means whenever a function is invoked with
205 its "internal" name, which normally contains the prefix "__builtin". */
207 static bool called_as_built_in (tree node)
209 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
210 if (strncmp (name, "__builtin_", 10) == 0)
211 return true;
212 if (strncmp (name, "__sync_", 7) == 0)
213 return true;
214 return false;
217 /* Return the alignment in bits of EXP, a pointer valued expression.
218 But don't return more than MAX_ALIGN no matter what.
219 The alignment returned is, by default, the alignment of the thing that
220 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
222 Otherwise, look at the expression to see if we can do better, i.e., if the
223 expression is actually pointing at an object whose alignment is tighter. */
225 static int
226 get_pointer_alignment (tree exp, unsigned int max_align)
228 unsigned int align, inner;
230 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
231 return 0;
233 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
234 align = MIN (align, max_align);
236 while (1)
238 switch (TREE_CODE (exp))
240 case NOP_EXPR:
241 case CONVERT_EXPR:
242 case NON_LVALUE_EXPR:
243 exp = TREE_OPERAND (exp, 0);
244 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
245 return align;
247 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
248 align = MIN (inner, max_align);
249 break;
251 case PLUS_EXPR:
252 /* If sum of pointer + int, restrict our maximum alignment to that
253 imposed by the integer. If not, we can't do any better than
254 ALIGN. */
255 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
256 return align;
258 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
259 & (max_align / BITS_PER_UNIT - 1))
260 != 0)
261 max_align >>= 1;
263 exp = TREE_OPERAND (exp, 0);
264 break;
266 case ADDR_EXPR:
267 /* See what we are pointing at and look at its alignment. */
268 exp = TREE_OPERAND (exp, 0);
269 if (TREE_CODE (exp) == FUNCTION_DECL)
270 align = FUNCTION_BOUNDARY;
271 else if (DECL_P (exp))
272 align = DECL_ALIGN (exp);
273 #ifdef CONSTANT_ALIGNMENT
274 else if (CONSTANT_CLASS_P (exp))
275 align = CONSTANT_ALIGNMENT (exp, align);
276 #endif
277 return MIN (align, max_align);
279 default:
280 return align;
285 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
286 way, because it could contain a zero byte in the middle.
287 TREE_STRING_LENGTH is the size of the character array, not the string.
289 ONLY_VALUE should be nonzero if the result is not going to be emitted
290 into the instruction stream and zero if it is going to be expanded.
291 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
292 is returned, otherwise NULL, since
293 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
294 evaluate the side-effects.
296 The value returned is of type `ssizetype'.
298 Unfortunately, string_constant can't access the values of const char
299 arrays with initializers, so neither can we do so here. */
301 tree
302 c_strlen (tree src, int only_value)
304 tree offset_node;
305 HOST_WIDE_INT offset;
306 int max;
307 const char *ptr;
309 STRIP_NOPS (src);
310 if (TREE_CODE (src) == COND_EXPR
311 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
313 tree len1, len2;
315 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
316 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
317 if (tree_int_cst_equal (len1, len2))
318 return len1;
321 if (TREE_CODE (src) == COMPOUND_EXPR
322 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
323 return c_strlen (TREE_OPERAND (src, 1), only_value);
325 src = string_constant (src, &offset_node);
326 if (src == 0)
327 return 0;
329 max = TREE_STRING_LENGTH (src) - 1;
330 ptr = TREE_STRING_POINTER (src);
332 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
334 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
335 compute the offset to the following null if we don't know where to
336 start searching for it. */
337 int i;
339 for (i = 0; i < max; i++)
340 if (ptr[i] == 0)
341 return 0;
343 /* We don't know the starting offset, but we do know that the string
344 has no internal zero bytes. We can assume that the offset falls
345 within the bounds of the string; otherwise, the programmer deserves
346 what he gets. Subtract the offset from the length of the string,
347 and return that. This would perhaps not be valid if we were dealing
348 with named arrays in addition to literal string constants. */
350 return size_diffop (size_int (max), offset_node);
353 /* We have a known offset into the string. Start searching there for
354 a null character if we can represent it as a single HOST_WIDE_INT. */
355 if (offset_node == 0)
356 offset = 0;
357 else if (! host_integerp (offset_node, 0))
358 offset = -1;
359 else
360 offset = tree_low_cst (offset_node, 0);
362 /* If the offset is known to be out of bounds, warn, and call strlen at
363 runtime. */
364 if (offset < 0 || offset > max)
366 warning (0, "offset outside bounds of constant string");
367 return 0;
370 /* Use strlen to search for the first zero byte. Since any strings
371 constructed with build_string will have nulls appended, we win even
372 if we get handed something like (char[4])"abcd".
374 Since OFFSET is our starting index into the string, no further
375 calculation is needed. */
376 return ssize_int (strlen (ptr + offset));
379 /* Return a char pointer for a C string if it is a string constant
380 or sum of string constant and integer constant. */
382 static const char *
383 c_getstr (tree src)
385 tree offset_node;
387 src = string_constant (src, &offset_node);
388 if (src == 0)
389 return 0;
391 if (offset_node == 0)
392 return TREE_STRING_POINTER (src);
393 else if (!host_integerp (offset_node, 1)
394 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
395 return 0;
397 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
400 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
401 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
403 static rtx
404 c_readstr (const char *str, enum machine_mode mode)
406 HOST_WIDE_INT c[2];
407 HOST_WIDE_INT ch;
408 unsigned int i, j;
410 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
412 c[0] = 0;
413 c[1] = 0;
414 ch = 1;
415 for (i = 0; i < GET_MODE_SIZE (mode); i++)
417 j = i;
418 if (WORDS_BIG_ENDIAN)
419 j = GET_MODE_SIZE (mode) - i - 1;
420 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
421 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
422 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
423 j *= BITS_PER_UNIT;
424 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
426 if (ch)
427 ch = (unsigned char) str[i];
428 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
430 return immed_double_const (c[0], c[1], mode);
433 /* Cast a target constant CST to target CHAR and if that value fits into
434 host char type, return zero and put that value into variable pointed to by
435 P. */
437 static int
438 target_char_cast (tree cst, char *p)
440 unsigned HOST_WIDE_INT val, hostval;
442 if (!host_integerp (cst, 1)
443 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
444 return 1;
446 val = tree_low_cst (cst, 1);
447 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
448 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
450 hostval = val;
451 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
452 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
454 if (val != hostval)
455 return 1;
457 *p = hostval;
458 return 0;
461 /* Similar to save_expr, but assumes that arbitrary code is not executed
462 in between the multiple evaluations. In particular, we assume that a
463 non-addressable local variable will not be modified. */
465 static tree
466 builtin_save_expr (tree exp)
468 if (TREE_ADDRESSABLE (exp) == 0
469 && (TREE_CODE (exp) == PARM_DECL
470 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
471 return exp;
473 return save_expr (exp);
476 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
477 times to get the address of either a higher stack frame, or a return
478 address located within it (depending on FNDECL_CODE). */
480 static rtx
481 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
483 int i;
485 #ifdef INITIAL_FRAME_ADDRESS_RTX
486 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
487 #else
488 rtx tem;
490 /* For a zero count, we don't care what frame address we return, so frame
491 pointer elimination is OK, and using the soft frame pointer is OK.
492 For a non-zero count, we require a stable offset from the current frame
493 pointer to the previous one, so we must use the hard frame pointer, and
494 we must disable frame pointer elimination. */
495 if (count == 0)
496 tem = frame_pointer_rtx;
497 else
499 tem = hard_frame_pointer_rtx;
501 /* Tell reload not to eliminate the frame pointer. */
502 current_function_accesses_prior_frames = 1;
504 #endif
506 /* Some machines need special handling before we can access
507 arbitrary frames. For example, on the sparc, we must first flush
508 all register windows to the stack. */
509 #ifdef SETUP_FRAME_ADDRESSES
510 if (count > 0)
511 SETUP_FRAME_ADDRESSES ();
512 #endif
514 /* On the sparc, the return address is not in the frame, it is in a
515 register. There is no way to access it off of the current frame
516 pointer, but it can be accessed off the previous frame pointer by
517 reading the value from the register window save area. */
518 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
519 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
520 count--;
521 #endif
523 /* Scan back COUNT frames to the specified frame. */
524 for (i = 0; i < count; i++)
526 /* Assume the dynamic chain pointer is in the word that the
527 frame address points to, unless otherwise specified. */
528 #ifdef DYNAMIC_CHAIN_ADDRESS
529 tem = DYNAMIC_CHAIN_ADDRESS (tem);
530 #endif
531 tem = memory_address (Pmode, tem);
532 tem = gen_frame_mem (Pmode, tem);
533 tem = copy_to_reg (tem);
536 /* For __builtin_frame_address, return what we've got. */
537 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
538 return tem;
540 /* For __builtin_return_address, Get the return address from that
541 frame. */
542 #ifdef RETURN_ADDR_RTX
543 tem = RETURN_ADDR_RTX (count, tem);
544 #else
545 tem = memory_address (Pmode,
546 plus_constant (tem, GET_MODE_SIZE (Pmode)));
547 tem = gen_frame_mem (Pmode, tem);
548 #endif
549 return tem;
552 /* Alias set used for setjmp buffer. */
553 static HOST_WIDE_INT setjmp_alias_set = -1;
555 /* Construct the leading half of a __builtin_setjmp call. Control will
556 return to RECEIVER_LABEL. This is used directly by sjlj exception
557 handling code. */
559 void
560 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
562 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
563 rtx stack_save;
564 rtx mem;
566 if (setjmp_alias_set == -1)
567 setjmp_alias_set = new_alias_set ();
569 buf_addr = convert_memory_address (Pmode, buf_addr);
571 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
573 /* We store the frame pointer and the address of receiver_label in
574 the buffer and use the rest of it for the stack save area, which
575 is machine-dependent. */
577 mem = gen_rtx_MEM (Pmode, buf_addr);
578 set_mem_alias_set (mem, setjmp_alias_set);
579 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
581 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
582 set_mem_alias_set (mem, setjmp_alias_set);
584 emit_move_insn (validize_mem (mem),
585 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
587 stack_save = gen_rtx_MEM (sa_mode,
588 plus_constant (buf_addr,
589 2 * GET_MODE_SIZE (Pmode)));
590 set_mem_alias_set (stack_save, setjmp_alias_set);
591 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
593 /* If there is further processing to do, do it. */
594 #ifdef HAVE_builtin_setjmp_setup
595 if (HAVE_builtin_setjmp_setup)
596 emit_insn (gen_builtin_setjmp_setup (buf_addr));
597 #endif
599 /* Tell optimize_save_area_alloca that extra work is going to
600 need to go on during alloca. */
601 current_function_calls_setjmp = 1;
603 /* Set this so all the registers get saved in our frame; we need to be
604 able to copy the saved values for any registers from frames we unwind. */
605 current_function_has_nonlocal_label = 1;
608 /* Construct the trailing part of a __builtin_setjmp call.
609 This is used directly by sjlj exception handling code. */
611 void
612 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
614 /* Clobber the FP when we get here, so we have to make sure it's
615 marked as used by this function. */
616 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
618 /* Mark the static chain as clobbered here so life information
619 doesn't get messed up for it. */
620 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
622 /* Now put in the code to restore the frame pointer, and argument
623 pointer, if needed. */
624 #ifdef HAVE_nonlocal_goto
625 if (! HAVE_nonlocal_goto)
626 #endif
627 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
629 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
630 if (fixed_regs[ARG_POINTER_REGNUM])
632 #ifdef ELIMINABLE_REGS
633 size_t i;
634 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
636 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
637 if (elim_regs[i].from == ARG_POINTER_REGNUM
638 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
639 break;
641 if (i == ARRAY_SIZE (elim_regs))
642 #endif
644 /* Now restore our arg pointer from the address at which it
645 was saved in our stack frame. */
646 emit_move_insn (virtual_incoming_args_rtx,
647 copy_to_reg (get_arg_pointer_save_area (cfun)));
650 #endif
652 #ifdef HAVE_builtin_setjmp_receiver
653 if (HAVE_builtin_setjmp_receiver)
654 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
655 else
656 #endif
657 #ifdef HAVE_nonlocal_goto_receiver
658 if (HAVE_nonlocal_goto_receiver)
659 emit_insn (gen_nonlocal_goto_receiver ());
660 else
661 #endif
662 { /* Nothing */ }
664 /* @@@ This is a kludge. Not all machine descriptions define a blockage
665 insn, but we must not allow the code we just generated to be reordered
666 by scheduling. Specifically, the update of the frame pointer must
667 happen immediately, not later. So emit an ASM_INPUT to act as blockage
668 insn. */
669 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
672 /* __builtin_setjmp is passed a pointer to an array of five words (not
673 all will be used on all machines). It operates similarly to the C
674 library function of the same name, but is more efficient. Much of
675 the code below (and for longjmp) is copied from the handling of
676 non-local gotos.
678 NOTE: This is intended for use by GNAT and the exception handling
679 scheme in the compiler and will only work in the method used by
680 them. */
682 static rtx
683 expand_builtin_setjmp (tree arglist, rtx target)
685 rtx buf_addr, next_lab, cont_lab;
687 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
688 return NULL_RTX;
690 if (target == 0 || !REG_P (target)
691 || REGNO (target) < FIRST_PSEUDO_REGISTER)
692 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
694 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
696 next_lab = gen_label_rtx ();
697 cont_lab = gen_label_rtx ();
699 expand_builtin_setjmp_setup (buf_addr, next_lab);
701 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
702 ensure that pending stack adjustments are flushed. */
703 emit_move_insn (target, const0_rtx);
704 emit_jump (cont_lab);
706 emit_label (next_lab);
708 expand_builtin_setjmp_receiver (next_lab);
710 /* Set TARGET to one. */
711 emit_move_insn (target, const1_rtx);
712 emit_label (cont_lab);
714 /* Tell flow about the strange goings on. Putting `next_lab' on
715 `nonlocal_goto_handler_labels' to indicates that function
716 calls may traverse the arc back to this label. */
718 current_function_has_nonlocal_label = 1;
719 nonlocal_goto_handler_labels
720 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
722 return target;
725 /* __builtin_longjmp is passed a pointer to an array of five words (not
726 all will be used on all machines). It operates similarly to the C
727 library function of the same name, but is more efficient. Much of
728 the code below is copied from the handling of non-local gotos.
730 NOTE: This is intended for use by GNAT and the exception handling
731 scheme in the compiler and will only work in the method used by
732 them. */
734 static void
735 expand_builtin_longjmp (rtx buf_addr, rtx value)
737 rtx fp, lab, stack, insn, last;
738 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
740 if (setjmp_alias_set == -1)
741 setjmp_alias_set = new_alias_set ();
743 buf_addr = convert_memory_address (Pmode, buf_addr);
745 buf_addr = force_reg (Pmode, buf_addr);
747 /* We used to store value in static_chain_rtx, but that fails if pointers
748 are smaller than integers. We instead require that the user must pass
749 a second argument of 1, because that is what builtin_setjmp will
750 return. This also makes EH slightly more efficient, since we are no
751 longer copying around a value that we don't care about. */
752 gcc_assert (value == const1_rtx);
754 last = get_last_insn ();
755 #ifdef HAVE_builtin_longjmp
756 if (HAVE_builtin_longjmp)
757 emit_insn (gen_builtin_longjmp (buf_addr));
758 else
759 #endif
761 fp = gen_rtx_MEM (Pmode, buf_addr);
762 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
763 GET_MODE_SIZE (Pmode)));
765 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
766 2 * GET_MODE_SIZE (Pmode)));
767 set_mem_alias_set (fp, setjmp_alias_set);
768 set_mem_alias_set (lab, setjmp_alias_set);
769 set_mem_alias_set (stack, setjmp_alias_set);
771 /* Pick up FP, label, and SP from the block and jump. This code is
772 from expand_goto in stmt.c; see there for detailed comments. */
773 #if HAVE_nonlocal_goto
774 if (HAVE_nonlocal_goto)
775 /* We have to pass a value to the nonlocal_goto pattern that will
776 get copied into the static_chain pointer, but it does not matter
777 what that value is, because builtin_setjmp does not use it. */
778 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
779 else
780 #endif
782 lab = copy_to_reg (lab);
784 emit_insn (gen_rtx_CLOBBER (VOIDmode,
785 gen_rtx_MEM (BLKmode,
786 gen_rtx_SCRATCH (VOIDmode))));
787 emit_insn (gen_rtx_CLOBBER (VOIDmode,
788 gen_rtx_MEM (BLKmode,
789 hard_frame_pointer_rtx)));
791 emit_move_insn (hard_frame_pointer_rtx, fp);
792 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
794 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
795 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
796 emit_indirect_jump (lab);
800 /* Search backwards and mark the jump insn as a non-local goto.
801 Note that this precludes the use of __builtin_longjmp to a
802 __builtin_setjmp target in the same function. However, we've
803 already cautioned the user that these functions are for
804 internal exception handling use only. */
805 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
807 gcc_assert (insn != last);
809 if (JUMP_P (insn))
811 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
812 REG_NOTES (insn));
813 break;
815 else if (CALL_P (insn))
816 break;
820 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
821 and the address of the save area. */
823 static rtx
824 expand_builtin_nonlocal_goto (tree arglist)
826 tree t_label, t_save_area;
827 rtx r_label, r_save_area, r_fp, r_sp, insn;
829 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
830 return NULL_RTX;
832 t_label = TREE_VALUE (arglist);
833 arglist = TREE_CHAIN (arglist);
834 t_save_area = TREE_VALUE (arglist);
836 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
837 r_label = convert_memory_address (Pmode, r_label);
838 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
839 r_save_area = convert_memory_address (Pmode, r_save_area);
840 r_fp = gen_rtx_MEM (Pmode, r_save_area);
841 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
842 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
844 current_function_has_nonlocal_goto = 1;
846 #if HAVE_nonlocal_goto
847 /* ??? We no longer need to pass the static chain value, afaik. */
848 if (HAVE_nonlocal_goto)
849 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
850 else
851 #endif
853 r_label = copy_to_reg (r_label);
855 emit_insn (gen_rtx_CLOBBER (VOIDmode,
856 gen_rtx_MEM (BLKmode,
857 gen_rtx_SCRATCH (VOIDmode))));
859 emit_insn (gen_rtx_CLOBBER (VOIDmode,
860 gen_rtx_MEM (BLKmode,
861 hard_frame_pointer_rtx)));
863 /* Restore frame pointer for containing function.
864 This sets the actual hard register used for the frame pointer
865 to the location of the function's incoming static chain info.
866 The non-local goto handler will then adjust it to contain the
867 proper value and reload the argument pointer, if needed. */
868 emit_move_insn (hard_frame_pointer_rtx, r_fp);
869 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
871 /* USE of hard_frame_pointer_rtx added for consistency;
872 not clear if really needed. */
873 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
874 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
875 emit_indirect_jump (r_label);
878 /* Search backwards to the jump insn and mark it as a
879 non-local goto. */
880 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
882 if (JUMP_P (insn))
884 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
885 const0_rtx, REG_NOTES (insn));
886 break;
888 else if (CALL_P (insn))
889 break;
892 return const0_rtx;
895 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
896 (not all will be used on all machines) that was passed to __builtin_setjmp.
897 It updates the stack pointer in that block to correspond to the current
898 stack pointer. */
900 static void
901 expand_builtin_update_setjmp_buf (rtx buf_addr)
903 enum machine_mode sa_mode = Pmode;
904 rtx stack_save;
907 #ifdef HAVE_save_stack_nonlocal
908 if (HAVE_save_stack_nonlocal)
909 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
910 #endif
911 #ifdef STACK_SAVEAREA_MODE
912 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
913 #endif
915 stack_save
916 = gen_rtx_MEM (sa_mode,
917 memory_address
918 (sa_mode,
919 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
921 #ifdef HAVE_setjmp
922 if (HAVE_setjmp)
923 emit_insn (gen_setjmp ());
924 #endif
926 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
929 /* Expand a call to __builtin_prefetch. For a target that does not support
930 data prefetch, evaluate the memory address argument in case it has side
931 effects. */
933 static void
934 expand_builtin_prefetch (tree arglist)
936 tree arg0, arg1, arg2;
937 rtx op0, op1, op2;
939 if (!validate_arglist (arglist, POINTER_TYPE, 0))
940 return;
942 arg0 = TREE_VALUE (arglist);
943 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
944 zero (read) and argument 2 (locality) defaults to 3 (high degree of
945 locality). */
946 if (TREE_CHAIN (arglist))
948 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
949 if (TREE_CHAIN (TREE_CHAIN (arglist)))
950 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
951 else
952 arg2 = build_int_cst (NULL_TREE, 3);
954 else
956 arg1 = integer_zero_node;
957 arg2 = build_int_cst (NULL_TREE, 3);
960 /* Argument 0 is an address. */
961 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
963 /* Argument 1 (read/write flag) must be a compile-time constant int. */
964 if (TREE_CODE (arg1) != INTEGER_CST)
966 error ("second argument to %<__builtin_prefetch%> must be a constant");
967 arg1 = integer_zero_node;
969 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
970 /* Argument 1 must be either zero or one. */
971 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
973 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
974 " using zero");
975 op1 = const0_rtx;
978 /* Argument 2 (locality) must be a compile-time constant int. */
979 if (TREE_CODE (arg2) != INTEGER_CST)
981 error ("third argument to %<__builtin_prefetch%> must be a constant");
982 arg2 = integer_zero_node;
984 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
985 /* Argument 2 must be 0, 1, 2, or 3. */
986 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
988 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
989 op2 = const0_rtx;
992 #ifdef HAVE_prefetch
993 if (HAVE_prefetch)
995 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
996 (op0,
997 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
998 || (GET_MODE (op0) != Pmode))
1000 op0 = convert_memory_address (Pmode, op0);
1001 op0 = force_reg (Pmode, op0);
1003 emit_insn (gen_prefetch (op0, op1, op2));
1005 #endif
1007 /* Don't do anything with direct references to volatile memory, but
1008 generate code to handle other side effects. */
1009 if (!MEM_P (op0) && side_effects_p (op0))
1010 emit_insn (op0);
1013 /* Get a MEM rtx for expression EXP which is the address of an operand
1014 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1015 the maximum length of the block of memory that might be accessed or
1016 NULL if unknown. */
1018 static rtx
1019 get_memory_rtx (tree exp, tree len)
1021 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1022 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1024 /* Get an expression we can use to find the attributes to assign to MEM.
1025 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1026 we can. First remove any nops. */
1027 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1028 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1029 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1030 exp = TREE_OPERAND (exp, 0);
1032 if (TREE_CODE (exp) == ADDR_EXPR)
1033 exp = TREE_OPERAND (exp, 0);
1034 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1035 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1036 else
1037 exp = NULL;
1039 /* Honor attributes derived from exp, except for the alias set
1040 (as builtin stringops may alias with anything) and the size
1041 (as stringops may access multiple array elements). */
1042 if (exp)
1044 set_mem_attributes (mem, exp, 0);
1046 /* Allow the string and memory builtins to overflow from one
1047 field into another, see http://gcc.gnu.org/PR23561.
1048 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1049 memory accessed by the string or memory builtin will fit
1050 within the field. */
1051 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1053 tree mem_expr = MEM_EXPR (mem);
1054 HOST_WIDE_INT offset = -1, length = -1;
1055 tree inner = exp;
1057 while (TREE_CODE (inner) == ARRAY_REF
1058 || TREE_CODE (inner) == NOP_EXPR
1059 || TREE_CODE (inner) == CONVERT_EXPR
1060 || TREE_CODE (inner) == NON_LVALUE_EXPR
1061 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1062 || TREE_CODE (inner) == SAVE_EXPR)
1063 inner = TREE_OPERAND (inner, 0);
1065 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1067 if (MEM_OFFSET (mem)
1068 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1069 offset = INTVAL (MEM_OFFSET (mem));
1071 if (offset >= 0 && len && host_integerp (len, 0))
1072 length = tree_low_cst (len, 0);
1074 while (TREE_CODE (inner) == COMPONENT_REF)
1076 tree field = TREE_OPERAND (inner, 1);
1077 gcc_assert (! DECL_BIT_FIELD (field));
1078 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1079 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1081 if (length >= 0
1082 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1083 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1085 HOST_WIDE_INT size
1086 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1087 /* If we can prove the memory starting at XEXP (mem, 0)
1088 and ending at XEXP (mem, 0) + LENGTH will fit into
1089 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1090 if (offset <= size
1091 && length <= size
1092 && offset + length <= size)
1093 break;
1096 if (offset >= 0
1097 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1098 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1099 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1100 / BITS_PER_UNIT;
1101 else
1103 offset = -1;
1104 length = -1;
1107 mem_expr = TREE_OPERAND (mem_expr, 0);
1108 inner = TREE_OPERAND (inner, 0);
1111 if (mem_expr == NULL)
1112 offset = -1;
1113 if (mem_expr != MEM_EXPR (mem))
1115 set_mem_expr (mem, mem_expr);
1116 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1119 set_mem_alias_set (mem, 0);
1120 set_mem_size (mem, NULL_RTX);
1123 return mem;
1126 /* Built-in functions to perform an untyped call and return. */
1128 /* For each register that may be used for calling a function, this
1129 gives a mode used to copy the register's value. VOIDmode indicates
1130 the register is not used for calling a function. If the machine
1131 has register windows, this gives only the outbound registers.
1132 INCOMING_REGNO gives the corresponding inbound register. */
1133 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1135 /* For each register that may be used for returning values, this gives
1136 a mode used to copy the register's value. VOIDmode indicates the
1137 register is not used for returning values. If the machine has
1138 register windows, this gives only the outbound registers.
1139 INCOMING_REGNO gives the corresponding inbound register. */
1140 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1142 /* For each register that may be used for calling a function, this
1143 gives the offset of that register into the block returned by
1144 __builtin_apply_args. 0 indicates that the register is not
1145 used for calling a function. */
1146 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1148 /* Return the size required for the block returned by __builtin_apply_args,
1149 and initialize apply_args_mode. */
1151 static int
1152 apply_args_size (void)
1154 static int size = -1;
1155 int align;
1156 unsigned int regno;
1157 enum machine_mode mode;
1159 /* The values computed by this function never change. */
1160 if (size < 0)
1162 /* The first value is the incoming arg-pointer. */
1163 size = GET_MODE_SIZE (Pmode);
1165 /* The second value is the structure value address unless this is
1166 passed as an "invisible" first argument. */
1167 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1168 size += GET_MODE_SIZE (Pmode);
1170 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1171 if (FUNCTION_ARG_REGNO_P (regno))
1173 mode = reg_raw_mode[regno];
1175 gcc_assert (mode != VOIDmode);
1177 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1178 if (size % align != 0)
1179 size = CEIL (size, align) * align;
1180 apply_args_reg_offset[regno] = size;
1181 size += GET_MODE_SIZE (mode);
1182 apply_args_mode[regno] = mode;
1184 else
1186 apply_args_mode[regno] = VOIDmode;
1187 apply_args_reg_offset[regno] = 0;
1190 return size;
1193 /* Return the size required for the block returned by __builtin_apply,
1194 and initialize apply_result_mode. */
1196 static int
1197 apply_result_size (void)
1199 static int size = -1;
1200 int align, regno;
1201 enum machine_mode mode;
1203 /* The values computed by this function never change. */
1204 if (size < 0)
1206 size = 0;
1208 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1209 if (FUNCTION_VALUE_REGNO_P (regno))
1211 mode = reg_raw_mode[regno];
1213 gcc_assert (mode != VOIDmode);
1215 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1216 if (size % align != 0)
1217 size = CEIL (size, align) * align;
1218 size += GET_MODE_SIZE (mode);
1219 apply_result_mode[regno] = mode;
1221 else
1222 apply_result_mode[regno] = VOIDmode;
1224 /* Allow targets that use untyped_call and untyped_return to override
1225 the size so that machine-specific information can be stored here. */
1226 #ifdef APPLY_RESULT_SIZE
1227 size = APPLY_RESULT_SIZE;
1228 #endif
1230 return size;
1233 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1234 /* Create a vector describing the result block RESULT. If SAVEP is true,
1235 the result block is used to save the values; otherwise it is used to
1236 restore the values. */
1238 static rtx
1239 result_vector (int savep, rtx result)
1241 int regno, size, align, nelts;
1242 enum machine_mode mode;
1243 rtx reg, mem;
1244 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1246 size = nelts = 0;
1247 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1248 if ((mode = apply_result_mode[regno]) != VOIDmode)
1250 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1251 if (size % align != 0)
1252 size = CEIL (size, align) * align;
1253 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1254 mem = adjust_address (result, mode, size);
1255 savevec[nelts++] = (savep
1256 ? gen_rtx_SET (VOIDmode, mem, reg)
1257 : gen_rtx_SET (VOIDmode, reg, mem));
1258 size += GET_MODE_SIZE (mode);
1260 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1262 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1264 /* Save the state required to perform an untyped call with the same
1265 arguments as were passed to the current function. */
1267 static rtx
1268 expand_builtin_apply_args_1 (void)
1270 rtx registers, tem;
1271 int size, align, regno;
1272 enum machine_mode mode;
1273 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1275 /* Create a block where the arg-pointer, structure value address,
1276 and argument registers can be saved. */
1277 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1279 /* Walk past the arg-pointer and structure value address. */
1280 size = GET_MODE_SIZE (Pmode);
1281 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1282 size += GET_MODE_SIZE (Pmode);
1284 /* Save each register used in calling a function to the block. */
1285 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1286 if ((mode = apply_args_mode[regno]) != VOIDmode)
1288 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1289 if (size % align != 0)
1290 size = CEIL (size, align) * align;
1292 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1294 emit_move_insn (adjust_address (registers, mode, size), tem);
1295 size += GET_MODE_SIZE (mode);
1298 /* Save the arg pointer to the block. */
1299 tem = copy_to_reg (virtual_incoming_args_rtx);
1300 #ifdef STACK_GROWS_DOWNWARD
1301 /* We need the pointer as the caller actually passed them to us, not
1302 as we might have pretended they were passed. Make sure it's a valid
1303 operand, as emit_move_insn isn't expected to handle a PLUS. */
1305 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1306 NULL_RTX);
1307 #endif
1308 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1310 size = GET_MODE_SIZE (Pmode);
1312 /* Save the structure value address unless this is passed as an
1313 "invisible" first argument. */
1314 if (struct_incoming_value)
1316 emit_move_insn (adjust_address (registers, Pmode, size),
1317 copy_to_reg (struct_incoming_value));
1318 size += GET_MODE_SIZE (Pmode);
1321 /* Return the address of the block. */
1322 return copy_addr_to_reg (XEXP (registers, 0));
1325 /* __builtin_apply_args returns block of memory allocated on
1326 the stack into which is stored the arg pointer, structure
1327 value address, static chain, and all the registers that might
1328 possibly be used in performing a function call. The code is
1329 moved to the start of the function so the incoming values are
1330 saved. */
1332 static rtx
1333 expand_builtin_apply_args (void)
1335 /* Don't do __builtin_apply_args more than once in a function.
1336 Save the result of the first call and reuse it. */
1337 if (apply_args_value != 0)
1338 return apply_args_value;
1340 /* When this function is called, it means that registers must be
1341 saved on entry to this function. So we migrate the
1342 call to the first insn of this function. */
1343 rtx temp;
1344 rtx seq;
1346 start_sequence ();
1347 temp = expand_builtin_apply_args_1 ();
1348 seq = get_insns ();
1349 end_sequence ();
1351 apply_args_value = temp;
1353 /* Put the insns after the NOTE that starts the function.
1354 If this is inside a start_sequence, make the outer-level insn
1355 chain current, so the code is placed at the start of the
1356 function. */
1357 push_topmost_sequence ();
1358 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1359 pop_topmost_sequence ();
1360 return temp;
1364 /* Perform an untyped call and save the state required to perform an
1365 untyped return of whatever value was returned by the given function. */
1367 static rtx
1368 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1370 int size, align, regno;
1371 enum machine_mode mode;
1372 rtx incoming_args, result, reg, dest, src, call_insn;
1373 rtx old_stack_level = 0;
1374 rtx call_fusage = 0;
1375 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1377 arguments = convert_memory_address (Pmode, arguments);
1379 /* Create a block where the return registers can be saved. */
1380 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1382 /* Fetch the arg pointer from the ARGUMENTS block. */
1383 incoming_args = gen_reg_rtx (Pmode);
1384 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1385 #ifndef STACK_GROWS_DOWNWARD
1386 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1387 incoming_args, 0, OPTAB_LIB_WIDEN);
1388 #endif
1390 /* Push a new argument block and copy the arguments. Do not allow
1391 the (potential) memcpy call below to interfere with our stack
1392 manipulations. */
1393 do_pending_stack_adjust ();
1394 NO_DEFER_POP;
1396 /* Save the stack with nonlocal if available. */
1397 #ifdef HAVE_save_stack_nonlocal
1398 if (HAVE_save_stack_nonlocal)
1399 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1400 else
1401 #endif
1402 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1404 /* Allocate a block of memory onto the stack and copy the memory
1405 arguments to the outgoing arguments address. */
1406 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1407 dest = virtual_outgoing_args_rtx;
1408 #ifndef STACK_GROWS_DOWNWARD
1409 if (GET_CODE (argsize) == CONST_INT)
1410 dest = plus_constant (dest, -INTVAL (argsize));
1411 else
1412 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1413 #endif
1414 dest = gen_rtx_MEM (BLKmode, dest);
1415 set_mem_align (dest, PARM_BOUNDARY);
1416 src = gen_rtx_MEM (BLKmode, incoming_args);
1417 set_mem_align (src, PARM_BOUNDARY);
1418 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1420 /* Refer to the argument block. */
1421 apply_args_size ();
1422 arguments = gen_rtx_MEM (BLKmode, arguments);
1423 set_mem_align (arguments, PARM_BOUNDARY);
1425 /* Walk past the arg-pointer and structure value address. */
1426 size = GET_MODE_SIZE (Pmode);
1427 if (struct_value)
1428 size += GET_MODE_SIZE (Pmode);
1430 /* Restore each of the registers previously saved. Make USE insns
1431 for each of these registers for use in making the call. */
1432 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1433 if ((mode = apply_args_mode[regno]) != VOIDmode)
1435 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1436 if (size % align != 0)
1437 size = CEIL (size, align) * align;
1438 reg = gen_rtx_REG (mode, regno);
1439 emit_move_insn (reg, adjust_address (arguments, mode, size));
1440 use_reg (&call_fusage, reg);
1441 size += GET_MODE_SIZE (mode);
1444 /* Restore the structure value address unless this is passed as an
1445 "invisible" first argument. */
1446 size = GET_MODE_SIZE (Pmode);
1447 if (struct_value)
1449 rtx value = gen_reg_rtx (Pmode);
1450 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1451 emit_move_insn (struct_value, value);
1452 if (REG_P (struct_value))
1453 use_reg (&call_fusage, struct_value);
1454 size += GET_MODE_SIZE (Pmode);
1457 /* All arguments and registers used for the call are set up by now! */
1458 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1460 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1461 and we don't want to load it into a register as an optimization,
1462 because prepare_call_address already did it if it should be done. */
1463 if (GET_CODE (function) != SYMBOL_REF)
1464 function = memory_address (FUNCTION_MODE, function);
1466 /* Generate the actual call instruction and save the return value. */
1467 #ifdef HAVE_untyped_call
1468 if (HAVE_untyped_call)
1469 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1470 result, result_vector (1, result)));
1471 else
1472 #endif
1473 #ifdef HAVE_call_value
1474 if (HAVE_call_value)
1476 rtx valreg = 0;
1478 /* Locate the unique return register. It is not possible to
1479 express a call that sets more than one return register using
1480 call_value; use untyped_call for that. In fact, untyped_call
1481 only needs to save the return registers in the given block. */
1482 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1483 if ((mode = apply_result_mode[regno]) != VOIDmode)
1485 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1487 valreg = gen_rtx_REG (mode, regno);
1490 emit_call_insn (GEN_CALL_VALUE (valreg,
1491 gen_rtx_MEM (FUNCTION_MODE, function),
1492 const0_rtx, NULL_RTX, const0_rtx));
1494 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1496 else
1497 #endif
1498 gcc_unreachable ();
1500 /* Find the CALL insn we just emitted, and attach the register usage
1501 information. */
1502 call_insn = last_call_insn ();
1503 add_function_usage_to (call_insn, call_fusage);
1505 /* Restore the stack. */
1506 #ifdef HAVE_save_stack_nonlocal
1507 if (HAVE_save_stack_nonlocal)
1508 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1509 else
1510 #endif
1511 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1513 OK_DEFER_POP;
1515 /* Return the address of the result block. */
1516 result = copy_addr_to_reg (XEXP (result, 0));
1517 return convert_memory_address (ptr_mode, result);
1520 /* Perform an untyped return. */
1522 static void
1523 expand_builtin_return (rtx result)
1525 int size, align, regno;
1526 enum machine_mode mode;
1527 rtx reg;
1528 rtx call_fusage = 0;
1530 result = convert_memory_address (Pmode, result);
1532 apply_result_size ();
1533 result = gen_rtx_MEM (BLKmode, result);
1535 #ifdef HAVE_untyped_return
1536 if (HAVE_untyped_return)
1538 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1539 emit_barrier ();
1540 return;
1542 #endif
1544 /* Restore the return value and note that each value is used. */
1545 size = 0;
1546 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1547 if ((mode = apply_result_mode[regno]) != VOIDmode)
1549 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1550 if (size % align != 0)
1551 size = CEIL (size, align) * align;
1552 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1553 emit_move_insn (reg, adjust_address (result, mode, size));
1555 push_to_sequence (call_fusage);
1556 emit_insn (gen_rtx_USE (VOIDmode, reg));
1557 call_fusage = get_insns ();
1558 end_sequence ();
1559 size += GET_MODE_SIZE (mode);
1562 /* Put the USE insns before the return. */
1563 emit_insn (call_fusage);
1565 /* Return whatever values was restored by jumping directly to the end
1566 of the function. */
1567 expand_naked_return ();
1570 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1572 static enum type_class
1573 type_to_class (tree type)
1575 switch (TREE_CODE (type))
1577 case VOID_TYPE: return void_type_class;
1578 case INTEGER_TYPE: return integer_type_class;
1579 case CHAR_TYPE: return char_type_class;
1580 case ENUMERAL_TYPE: return enumeral_type_class;
1581 case BOOLEAN_TYPE: return boolean_type_class;
1582 case POINTER_TYPE: return pointer_type_class;
1583 case REFERENCE_TYPE: return reference_type_class;
1584 case OFFSET_TYPE: return offset_type_class;
1585 case REAL_TYPE: return real_type_class;
1586 case COMPLEX_TYPE: return complex_type_class;
1587 case FUNCTION_TYPE: return function_type_class;
1588 case METHOD_TYPE: return method_type_class;
1589 case RECORD_TYPE: return record_type_class;
1590 case UNION_TYPE:
1591 case QUAL_UNION_TYPE: return union_type_class;
1592 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1593 ? string_type_class : array_type_class);
1594 case LANG_TYPE: return lang_type_class;
1595 default: return no_type_class;
1599 /* Expand a call to __builtin_classify_type with arguments found in
1600 ARGLIST. */
1602 static rtx
1603 expand_builtin_classify_type (tree arglist)
1605 if (arglist != 0)
1606 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1607 return GEN_INT (no_type_class);
1610 /* This helper macro, meant to be used in mathfn_built_in below,
1611 determines which among a set of three builtin math functions is
1612 appropriate for a given type mode. The `F' and `L' cases are
1613 automatically generated from the `double' case. */
1614 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1615 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1616 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1617 fcodel = BUILT_IN_MATHFN##L ; break;
1619 /* Return mathematic function equivalent to FN but operating directly
1620 on TYPE, if available. If we can't do the conversion, return zero. */
1621 tree
1622 mathfn_built_in (tree type, enum built_in_function fn)
1624 enum built_in_function fcode, fcodef, fcodel;
1626 switch (fn)
1628 CASE_MATHFN (BUILT_IN_ACOS)
1629 CASE_MATHFN (BUILT_IN_ACOSH)
1630 CASE_MATHFN (BUILT_IN_ASIN)
1631 CASE_MATHFN (BUILT_IN_ASINH)
1632 CASE_MATHFN (BUILT_IN_ATAN)
1633 CASE_MATHFN (BUILT_IN_ATAN2)
1634 CASE_MATHFN (BUILT_IN_ATANH)
1635 CASE_MATHFN (BUILT_IN_CBRT)
1636 CASE_MATHFN (BUILT_IN_CEIL)
1637 CASE_MATHFN (BUILT_IN_COPYSIGN)
1638 CASE_MATHFN (BUILT_IN_COS)
1639 CASE_MATHFN (BUILT_IN_COSH)
1640 CASE_MATHFN (BUILT_IN_DREM)
1641 CASE_MATHFN (BUILT_IN_ERF)
1642 CASE_MATHFN (BUILT_IN_ERFC)
1643 CASE_MATHFN (BUILT_IN_EXP)
1644 CASE_MATHFN (BUILT_IN_EXP10)
1645 CASE_MATHFN (BUILT_IN_EXP2)
1646 CASE_MATHFN (BUILT_IN_EXPM1)
1647 CASE_MATHFN (BUILT_IN_FABS)
1648 CASE_MATHFN (BUILT_IN_FDIM)
1649 CASE_MATHFN (BUILT_IN_FLOOR)
1650 CASE_MATHFN (BUILT_IN_FMA)
1651 CASE_MATHFN (BUILT_IN_FMAX)
1652 CASE_MATHFN (BUILT_IN_FMIN)
1653 CASE_MATHFN (BUILT_IN_FMOD)
1654 CASE_MATHFN (BUILT_IN_FREXP)
1655 CASE_MATHFN (BUILT_IN_GAMMA)
1656 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1657 CASE_MATHFN (BUILT_IN_HYPOT)
1658 CASE_MATHFN (BUILT_IN_ILOGB)
1659 CASE_MATHFN (BUILT_IN_INF)
1660 CASE_MATHFN (BUILT_IN_J0)
1661 CASE_MATHFN (BUILT_IN_J1)
1662 CASE_MATHFN (BUILT_IN_JN)
1663 CASE_MATHFN (BUILT_IN_LCEIL)
1664 CASE_MATHFN (BUILT_IN_LDEXP)
1665 CASE_MATHFN (BUILT_IN_LFLOOR)
1666 CASE_MATHFN (BUILT_IN_LGAMMA)
1667 CASE_MATHFN (BUILT_IN_LLCEIL)
1668 CASE_MATHFN (BUILT_IN_LLFLOOR)
1669 CASE_MATHFN (BUILT_IN_LLRINT)
1670 CASE_MATHFN (BUILT_IN_LLROUND)
1671 CASE_MATHFN (BUILT_IN_LOG)
1672 CASE_MATHFN (BUILT_IN_LOG10)
1673 CASE_MATHFN (BUILT_IN_LOG1P)
1674 CASE_MATHFN (BUILT_IN_LOG2)
1675 CASE_MATHFN (BUILT_IN_LOGB)
1676 CASE_MATHFN (BUILT_IN_LRINT)
1677 CASE_MATHFN (BUILT_IN_LROUND)
1678 CASE_MATHFN (BUILT_IN_MODF)
1679 CASE_MATHFN (BUILT_IN_NAN)
1680 CASE_MATHFN (BUILT_IN_NANS)
1681 CASE_MATHFN (BUILT_IN_NEARBYINT)
1682 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1683 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1684 CASE_MATHFN (BUILT_IN_POW)
1685 CASE_MATHFN (BUILT_IN_POWI)
1686 CASE_MATHFN (BUILT_IN_POW10)
1687 CASE_MATHFN (BUILT_IN_REMAINDER)
1688 CASE_MATHFN (BUILT_IN_REMQUO)
1689 CASE_MATHFN (BUILT_IN_RINT)
1690 CASE_MATHFN (BUILT_IN_ROUND)
1691 CASE_MATHFN (BUILT_IN_SCALB)
1692 CASE_MATHFN (BUILT_IN_SCALBLN)
1693 CASE_MATHFN (BUILT_IN_SCALBN)
1694 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1695 CASE_MATHFN (BUILT_IN_SIN)
1696 CASE_MATHFN (BUILT_IN_SINCOS)
1697 CASE_MATHFN (BUILT_IN_SINH)
1698 CASE_MATHFN (BUILT_IN_SQRT)
1699 CASE_MATHFN (BUILT_IN_TAN)
1700 CASE_MATHFN (BUILT_IN_TANH)
1701 CASE_MATHFN (BUILT_IN_TGAMMA)
1702 CASE_MATHFN (BUILT_IN_TRUNC)
1703 CASE_MATHFN (BUILT_IN_Y0)
1704 CASE_MATHFN (BUILT_IN_Y1)
1705 CASE_MATHFN (BUILT_IN_YN)
1707 default:
1708 return 0;
1711 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1712 return implicit_built_in_decls[fcode];
1713 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1714 return implicit_built_in_decls[fcodef];
1715 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1716 return implicit_built_in_decls[fcodel];
1717 else
1718 return 0;
1721 /* If errno must be maintained, expand the RTL to check if the result,
1722 TARGET, of a built-in function call, EXP, is NaN, and if so set
1723 errno to EDOM. */
1725 static void
1726 expand_errno_check (tree exp, rtx target)
1728 rtx lab = gen_label_rtx ();
1730 /* Test the result; if it is NaN, set errno=EDOM because
1731 the argument was not in the domain. */
1732 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1733 0, lab);
1735 #ifdef TARGET_EDOM
1736 /* If this built-in doesn't throw an exception, set errno directly. */
1737 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1739 #ifdef GEN_ERRNO_RTX
1740 rtx errno_rtx = GEN_ERRNO_RTX;
1741 #else
1742 rtx errno_rtx
1743 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1744 #endif
1745 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1746 emit_label (lab);
1747 return;
1749 #endif
1751 /* We can't set errno=EDOM directly; let the library call do it.
1752 Pop the arguments right away in case the call gets deleted. */
1753 NO_DEFER_POP;
1754 expand_call (exp, target, 0);
1755 OK_DEFER_POP;
1756 emit_label (lab);
1760 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1761 Return 0 if a normal call should be emitted rather than expanding the
1762 function in-line. EXP is the expression that is a call to the builtin
1763 function; if convenient, the result should be placed in TARGET.
1764 SUBTARGET may be used as the target for computing one of EXP's operands. */
1766 static rtx
1767 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1769 optab builtin_optab;
1770 rtx op0, insns, before_call;
1771 tree fndecl = get_callee_fndecl (exp);
1772 tree arglist = TREE_OPERAND (exp, 1);
1773 enum machine_mode mode;
1774 bool errno_set = false;
1775 tree arg, narg;
1777 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1778 return 0;
1780 arg = TREE_VALUE (arglist);
1782 switch (DECL_FUNCTION_CODE (fndecl))
1784 case BUILT_IN_SQRT:
1785 case BUILT_IN_SQRTF:
1786 case BUILT_IN_SQRTL:
1787 errno_set = ! tree_expr_nonnegative_p (arg);
1788 builtin_optab = sqrt_optab;
1789 break;
1790 case BUILT_IN_EXP:
1791 case BUILT_IN_EXPF:
1792 case BUILT_IN_EXPL:
1793 errno_set = true; builtin_optab = exp_optab; break;
1794 case BUILT_IN_EXP10:
1795 case BUILT_IN_EXP10F:
1796 case BUILT_IN_EXP10L:
1797 case BUILT_IN_POW10:
1798 case BUILT_IN_POW10F:
1799 case BUILT_IN_POW10L:
1800 errno_set = true; builtin_optab = exp10_optab; break;
1801 case BUILT_IN_EXP2:
1802 case BUILT_IN_EXP2F:
1803 case BUILT_IN_EXP2L:
1804 errno_set = true; builtin_optab = exp2_optab; break;
1805 case BUILT_IN_EXPM1:
1806 case BUILT_IN_EXPM1F:
1807 case BUILT_IN_EXPM1L:
1808 errno_set = true; builtin_optab = expm1_optab; break;
1809 case BUILT_IN_LOGB:
1810 case BUILT_IN_LOGBF:
1811 case BUILT_IN_LOGBL:
1812 errno_set = true; builtin_optab = logb_optab; break;
1813 case BUILT_IN_ILOGB:
1814 case BUILT_IN_ILOGBF:
1815 case BUILT_IN_ILOGBL:
1816 errno_set = true; builtin_optab = ilogb_optab; break;
1817 case BUILT_IN_LOG:
1818 case BUILT_IN_LOGF:
1819 case BUILT_IN_LOGL:
1820 errno_set = true; builtin_optab = log_optab; break;
1821 case BUILT_IN_LOG10:
1822 case BUILT_IN_LOG10F:
1823 case BUILT_IN_LOG10L:
1824 errno_set = true; builtin_optab = log10_optab; break;
1825 case BUILT_IN_LOG2:
1826 case BUILT_IN_LOG2F:
1827 case BUILT_IN_LOG2L:
1828 errno_set = true; builtin_optab = log2_optab; break;
1829 case BUILT_IN_LOG1P:
1830 case BUILT_IN_LOG1PF:
1831 case BUILT_IN_LOG1PL:
1832 errno_set = true; builtin_optab = log1p_optab; break;
1833 case BUILT_IN_ASIN:
1834 case BUILT_IN_ASINF:
1835 case BUILT_IN_ASINL:
1836 builtin_optab = asin_optab; break;
1837 case BUILT_IN_ACOS:
1838 case BUILT_IN_ACOSF:
1839 case BUILT_IN_ACOSL:
1840 builtin_optab = acos_optab; break;
1841 case BUILT_IN_TAN:
1842 case BUILT_IN_TANF:
1843 case BUILT_IN_TANL:
1844 builtin_optab = tan_optab; break;
1845 case BUILT_IN_ATAN:
1846 case BUILT_IN_ATANF:
1847 case BUILT_IN_ATANL:
1848 builtin_optab = atan_optab; break;
1849 case BUILT_IN_FLOOR:
1850 case BUILT_IN_FLOORF:
1851 case BUILT_IN_FLOORL:
1852 builtin_optab = floor_optab; break;
1853 case BUILT_IN_CEIL:
1854 case BUILT_IN_CEILF:
1855 case BUILT_IN_CEILL:
1856 builtin_optab = ceil_optab; break;
1857 case BUILT_IN_TRUNC:
1858 case BUILT_IN_TRUNCF:
1859 case BUILT_IN_TRUNCL:
1860 builtin_optab = btrunc_optab; break;
1861 case BUILT_IN_ROUND:
1862 case BUILT_IN_ROUNDF:
1863 case BUILT_IN_ROUNDL:
1864 builtin_optab = round_optab; break;
1865 case BUILT_IN_NEARBYINT:
1866 case BUILT_IN_NEARBYINTF:
1867 case BUILT_IN_NEARBYINTL:
1868 builtin_optab = nearbyint_optab; break;
1869 case BUILT_IN_RINT:
1870 case BUILT_IN_RINTF:
1871 case BUILT_IN_RINTL:
1872 builtin_optab = rint_optab; break;
1873 case BUILT_IN_LRINT:
1874 case BUILT_IN_LRINTF:
1875 case BUILT_IN_LRINTL:
1876 case BUILT_IN_LLRINT:
1877 case BUILT_IN_LLRINTF:
1878 case BUILT_IN_LLRINTL:
1879 builtin_optab = lrint_optab; break;
1880 default:
1881 gcc_unreachable ();
1884 /* Make a suitable register to place result in. */
1885 mode = TYPE_MODE (TREE_TYPE (exp));
1887 if (! flag_errno_math || ! HONOR_NANS (mode))
1888 errno_set = false;
1890 /* Before working hard, check whether the instruction is available. */
1891 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1893 target = gen_reg_rtx (mode);
1895 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1896 need to expand the argument again. This way, we will not perform
1897 side-effects more the once. */
1898 narg = builtin_save_expr (arg);
1899 if (narg != arg)
1901 arg = narg;
1902 arglist = build_tree_list (NULL_TREE, arg);
1903 exp = build_function_call_expr (fndecl, arglist);
1906 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1908 start_sequence ();
1910 /* Compute into TARGET.
1911 Set TARGET to wherever the result comes back. */
1912 target = expand_unop (mode, builtin_optab, op0, target, 0);
1914 if (target != 0)
1916 if (errno_set)
1917 expand_errno_check (exp, target);
1919 /* Output the entire sequence. */
1920 insns = get_insns ();
1921 end_sequence ();
1922 emit_insn (insns);
1923 return target;
1926 /* If we were unable to expand via the builtin, stop the sequence
1927 (without outputting the insns) and call to the library function
1928 with the stabilized argument list. */
1929 end_sequence ();
1932 before_call = get_last_insn ();
1934 target = expand_call (exp, target, target == const0_rtx);
1936 /* If this is a sqrt operation and we don't care about errno, try to
1937 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1938 This allows the semantics of the libcall to be visible to the RTL
1939 optimizers. */
1940 if (builtin_optab == sqrt_optab && !errno_set)
1942 /* Search backwards through the insns emitted by expand_call looking
1943 for the instruction with the REG_RETVAL note. */
1944 rtx last = get_last_insn ();
1945 while (last != before_call)
1947 if (find_reg_note (last, REG_RETVAL, NULL))
1949 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1950 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1951 two elements, i.e. symbol_ref(sqrt) and the operand. */
1952 if (note
1953 && GET_CODE (note) == EXPR_LIST
1954 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1955 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1956 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1958 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1959 /* Check operand is a register with expected mode. */
1960 if (operand
1961 && REG_P (operand)
1962 && GET_MODE (operand) == mode)
1964 /* Replace the REG_EQUAL note with a SQRT rtx. */
1965 rtx equiv = gen_rtx_SQRT (mode, operand);
1966 set_unique_reg_note (last, REG_EQUAL, equiv);
1969 break;
1971 last = PREV_INSN (last);
1975 return target;
1978 /* Expand a call to the builtin binary math functions (pow and atan2).
1979 Return 0 if a normal call should be emitted rather than expanding the
1980 function in-line. EXP is the expression that is a call to the builtin
1981 function; if convenient, the result should be placed in TARGET.
1982 SUBTARGET may be used as the target for computing one of EXP's
1983 operands. */
1985 static rtx
1986 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1988 optab builtin_optab;
1989 rtx op0, op1, insns;
1990 int op1_type = REAL_TYPE;
1991 tree fndecl = get_callee_fndecl (exp);
1992 tree arglist = TREE_OPERAND (exp, 1);
1993 tree arg0, arg1, temp, narg;
1994 enum machine_mode mode;
1995 bool errno_set = true;
1996 bool stable = true;
1998 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1999 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2000 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2001 op1_type = INTEGER_TYPE;
2003 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2004 return 0;
2006 arg0 = TREE_VALUE (arglist);
2007 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2009 switch (DECL_FUNCTION_CODE (fndecl))
2011 case BUILT_IN_POW:
2012 case BUILT_IN_POWF:
2013 case BUILT_IN_POWL:
2014 builtin_optab = pow_optab; break;
2015 case BUILT_IN_ATAN2:
2016 case BUILT_IN_ATAN2F:
2017 case BUILT_IN_ATAN2L:
2018 builtin_optab = atan2_optab; break;
2019 case BUILT_IN_LDEXP:
2020 case BUILT_IN_LDEXPF:
2021 case BUILT_IN_LDEXPL:
2022 builtin_optab = ldexp_optab; break;
2023 case BUILT_IN_FMOD:
2024 case BUILT_IN_FMODF:
2025 case BUILT_IN_FMODL:
2026 builtin_optab = fmod_optab; break;
2027 case BUILT_IN_DREM:
2028 case BUILT_IN_DREMF:
2029 case BUILT_IN_DREML:
2030 builtin_optab = drem_optab; break;
2031 default:
2032 gcc_unreachable ();
2035 /* Make a suitable register to place result in. */
2036 mode = TYPE_MODE (TREE_TYPE (exp));
2038 /* Before working hard, check whether the instruction is available. */
2039 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2040 return 0;
2042 target = gen_reg_rtx (mode);
2044 if (! flag_errno_math || ! HONOR_NANS (mode))
2045 errno_set = false;
2047 /* Always stabilize the argument list. */
2048 narg = builtin_save_expr (arg1);
2049 if (narg != arg1)
2051 arg1 = narg;
2052 temp = build_tree_list (NULL_TREE, narg);
2053 stable = false;
2055 else
2056 temp = TREE_CHAIN (arglist);
2058 narg = builtin_save_expr (arg0);
2059 if (narg != arg0)
2061 arg0 = narg;
2062 arglist = tree_cons (NULL_TREE, narg, temp);
2063 stable = false;
2065 else if (! stable)
2066 arglist = tree_cons (NULL_TREE, arg0, temp);
2068 if (! stable)
2069 exp = build_function_call_expr (fndecl, arglist);
2071 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2072 op1 = expand_expr (arg1, 0, VOIDmode, 0);
2074 start_sequence ();
2076 /* Compute into TARGET.
2077 Set TARGET to wherever the result comes back. */
2078 target = expand_binop (mode, builtin_optab, op0, op1,
2079 target, 0, OPTAB_DIRECT);
2081 /* If we were unable to expand via the builtin, stop the sequence
2082 (without outputting the insns) and call to the library function
2083 with the stabilized argument list. */
2084 if (target == 0)
2086 end_sequence ();
2087 return expand_call (exp, target, target == const0_rtx);
2090 if (errno_set)
2091 expand_errno_check (exp, target);
2093 /* Output the entire sequence. */
2094 insns = get_insns ();
2095 end_sequence ();
2096 emit_insn (insns);
2098 return target;
2101 /* Expand a call to the builtin sin and cos math functions.
2102 Return 0 if a normal call should be emitted rather than expanding the
2103 function in-line. EXP is the expression that is a call to the builtin
2104 function; if convenient, the result should be placed in TARGET.
2105 SUBTARGET may be used as the target for computing one of EXP's
2106 operands. */
2108 static rtx
2109 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2111 optab builtin_optab;
2112 rtx op0, insns;
2113 tree fndecl = get_callee_fndecl (exp);
2114 tree arglist = TREE_OPERAND (exp, 1);
2115 enum machine_mode mode;
2116 bool errno_set = false;
2117 tree arg, narg;
2119 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2120 return 0;
2122 arg = TREE_VALUE (arglist);
2124 switch (DECL_FUNCTION_CODE (fndecl))
2126 case BUILT_IN_SIN:
2127 case BUILT_IN_SINF:
2128 case BUILT_IN_SINL:
2129 case BUILT_IN_COS:
2130 case BUILT_IN_COSF:
2131 case BUILT_IN_COSL:
2132 builtin_optab = sincos_optab; break;
2133 default:
2134 gcc_unreachable ();
2137 /* Make a suitable register to place result in. */
2138 mode = TYPE_MODE (TREE_TYPE (exp));
2140 if (! flag_errno_math || ! HONOR_NANS (mode))
2141 errno_set = false;
2143 /* Check if sincos insn is available, otherwise fallback
2144 to sin or cos insn. */
2145 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2146 switch (DECL_FUNCTION_CODE (fndecl))
2148 case BUILT_IN_SIN:
2149 case BUILT_IN_SINF:
2150 case BUILT_IN_SINL:
2151 builtin_optab = sin_optab; break;
2152 case BUILT_IN_COS:
2153 case BUILT_IN_COSF:
2154 case BUILT_IN_COSL:
2155 builtin_optab = cos_optab; break;
2156 default:
2157 gcc_unreachable ();
2161 /* Before working hard, check whether the instruction is available. */
2162 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2164 target = gen_reg_rtx (mode);
2166 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2167 need to expand the argument again. This way, we will not perform
2168 side-effects more the once. */
2169 narg = save_expr (arg);
2170 if (narg != arg)
2172 arg = narg;
2173 arglist = build_tree_list (NULL_TREE, arg);
2174 exp = build_function_call_expr (fndecl, arglist);
2177 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2179 start_sequence ();
2181 /* Compute into TARGET.
2182 Set TARGET to wherever the result comes back. */
2183 if (builtin_optab == sincos_optab)
2185 int result;
2187 switch (DECL_FUNCTION_CODE (fndecl))
2189 case BUILT_IN_SIN:
2190 case BUILT_IN_SINF:
2191 case BUILT_IN_SINL:
2192 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2193 break;
2194 case BUILT_IN_COS:
2195 case BUILT_IN_COSF:
2196 case BUILT_IN_COSL:
2197 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2198 break;
2199 default:
2200 gcc_unreachable ();
2202 gcc_assert (result);
2204 else
2206 target = expand_unop (mode, builtin_optab, op0, target, 0);
2209 if (target != 0)
2211 if (errno_set)
2212 expand_errno_check (exp, target);
2214 /* Output the entire sequence. */
2215 insns = get_insns ();
2216 end_sequence ();
2217 emit_insn (insns);
2218 return target;
2221 /* If we were unable to expand via the builtin, stop the sequence
2222 (without outputting the insns) and call to the library function
2223 with the stabilized argument list. */
2224 end_sequence ();
2227 target = expand_call (exp, target, target == const0_rtx);
2229 return target;
2232 /* Expand a call to one of the builtin rounding functions (lfloor).
2233 If expanding via optab fails, lower expression to (int)(floor(x)).
2234 EXP is the expression that is a call to the builtin function;
2235 if convenient, the result should be placed in TARGET. SUBTARGET may
2236 be used as the target for computing one of EXP's operands. */
2238 static rtx
2239 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2241 optab builtin_optab;
2242 rtx op0, insns, tmp;
2243 tree fndecl = get_callee_fndecl (exp);
2244 tree arglist = TREE_OPERAND (exp, 1);
2245 enum built_in_function fallback_fn;
2246 tree fallback_fndecl;
2247 enum machine_mode mode;
2248 tree arg, narg;
2250 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2251 gcc_unreachable ();
2253 arg = TREE_VALUE (arglist);
2255 switch (DECL_FUNCTION_CODE (fndecl))
2257 case BUILT_IN_LCEIL:
2258 case BUILT_IN_LCEILF:
2259 case BUILT_IN_LCEILL:
2260 case BUILT_IN_LLCEIL:
2261 case BUILT_IN_LLCEILF:
2262 case BUILT_IN_LLCEILL:
2263 builtin_optab = lceil_optab;
2264 fallback_fn = BUILT_IN_CEIL;
2265 break;
2267 case BUILT_IN_LFLOOR:
2268 case BUILT_IN_LFLOORF:
2269 case BUILT_IN_LFLOORL:
2270 case BUILT_IN_LLFLOOR:
2271 case BUILT_IN_LLFLOORF:
2272 case BUILT_IN_LLFLOORL:
2273 builtin_optab = lfloor_optab;
2274 fallback_fn = BUILT_IN_FLOOR;
2275 break;
2277 default:
2278 gcc_unreachable ();
2281 /* Make a suitable register to place result in. */
2282 mode = TYPE_MODE (TREE_TYPE (exp));
2284 /* Before working hard, check whether the instruction is available. */
2285 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2287 target = gen_reg_rtx (mode);
2289 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2290 need to expand the argument again. This way, we will not perform
2291 side-effects more the once. */
2292 narg = builtin_save_expr (arg);
2293 if (narg != arg)
2295 arg = narg;
2296 arglist = build_tree_list (NULL_TREE, arg);
2297 exp = build_function_call_expr (fndecl, arglist);
2300 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2302 start_sequence ();
2304 /* Compute into TARGET.
2305 Set TARGET to wherever the result comes back. */
2306 target = expand_unop (mode, builtin_optab, op0, target, 0);
2308 if (target != 0)
2310 /* Output the entire sequence. */
2311 insns = get_insns ();
2312 end_sequence ();
2313 emit_insn (insns);
2314 return target;
2317 /* If we were unable to expand via the builtin, stop the sequence
2318 (without outputting the insns). */
2319 end_sequence ();
2322 /* Fall back to floating point rounding optab. */
2323 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2324 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2325 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2326 gcc_assert (fallback_fndecl != NULL_TREE);
2327 exp = build_function_call_expr (fallback_fndecl, arglist);
2329 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2331 /* Truncate the result of floating point optab to integer
2332 via expand_fix (). */
2333 target = gen_reg_rtx (mode);
2334 expand_fix (target, tmp, 0);
2336 return target;
2339 /* To evaluate powi(x,n), the floating point value x raised to the
2340 constant integer exponent n, we use a hybrid algorithm that
2341 combines the "window method" with look-up tables. For an
2342 introduction to exponentiation algorithms and "addition chains",
2343 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2344 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2345 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2346 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2348 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2349 multiplications to inline before calling the system library's pow
2350 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2351 so this default never requires calling pow, powf or powl. */
2353 #ifndef POWI_MAX_MULTS
2354 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2355 #endif
2357 /* The size of the "optimal power tree" lookup table. All
2358 exponents less than this value are simply looked up in the
2359 powi_table below. This threshold is also used to size the
2360 cache of pseudo registers that hold intermediate results. */
2361 #define POWI_TABLE_SIZE 256
2363 /* The size, in bits of the window, used in the "window method"
2364 exponentiation algorithm. This is equivalent to a radix of
2365 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2366 #define POWI_WINDOW_SIZE 3
2368 /* The following table is an efficient representation of an
2369 "optimal power tree". For each value, i, the corresponding
2370 value, j, in the table states than an optimal evaluation
2371 sequence for calculating pow(x,i) can be found by evaluating
2372 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2373 100 integers is given in Knuth's "Seminumerical algorithms". */
2375 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2377 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2378 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2379 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2380 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2381 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2382 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2383 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2384 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2385 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2386 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2387 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2388 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2389 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2390 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2391 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2392 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2393 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2394 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2395 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2396 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2397 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2398 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2399 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2400 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2401 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2402 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2403 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2404 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2405 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2406 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2407 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2408 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2412 /* Return the number of multiplications required to calculate
2413 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2414 subroutine of powi_cost. CACHE is an array indicating
2415 which exponents have already been calculated. */
2417 static int
2418 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2420 /* If we've already calculated this exponent, then this evaluation
2421 doesn't require any additional multiplications. */
2422 if (cache[n])
2423 return 0;
2425 cache[n] = true;
2426 return powi_lookup_cost (n - powi_table[n], cache)
2427 + powi_lookup_cost (powi_table[n], cache) + 1;
2430 /* Return the number of multiplications required to calculate
2431 powi(x,n) for an arbitrary x, given the exponent N. This
2432 function needs to be kept in sync with expand_powi below. */
2434 static int
2435 powi_cost (HOST_WIDE_INT n)
2437 bool cache[POWI_TABLE_SIZE];
2438 unsigned HOST_WIDE_INT digit;
2439 unsigned HOST_WIDE_INT val;
2440 int result;
2442 if (n == 0)
2443 return 0;
2445 /* Ignore the reciprocal when calculating the cost. */
2446 val = (n < 0) ? -n : n;
2448 /* Initialize the exponent cache. */
2449 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2450 cache[1] = true;
2452 result = 0;
2454 while (val >= POWI_TABLE_SIZE)
2456 if (val & 1)
2458 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2459 result += powi_lookup_cost (digit, cache)
2460 + POWI_WINDOW_SIZE + 1;
2461 val >>= POWI_WINDOW_SIZE;
2463 else
2465 val >>= 1;
2466 result++;
2470 return result + powi_lookup_cost (val, cache);
2473 /* Recursive subroutine of expand_powi. This function takes the array,
2474 CACHE, of already calculated exponents and an exponent N and returns
2475 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2477 static rtx
2478 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2480 unsigned HOST_WIDE_INT digit;
2481 rtx target, result;
2482 rtx op0, op1;
2484 if (n < POWI_TABLE_SIZE)
2486 if (cache[n])
2487 return cache[n];
2489 target = gen_reg_rtx (mode);
2490 cache[n] = target;
2492 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2493 op1 = expand_powi_1 (mode, powi_table[n], cache);
2495 else if (n & 1)
2497 target = gen_reg_rtx (mode);
2498 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2499 op0 = expand_powi_1 (mode, n - digit, cache);
2500 op1 = expand_powi_1 (mode, digit, cache);
2502 else
2504 target = gen_reg_rtx (mode);
2505 op0 = expand_powi_1 (mode, n >> 1, cache);
2506 op1 = op0;
2509 result = expand_mult (mode, op0, op1, target, 0);
2510 if (result != target)
2511 emit_move_insn (target, result);
2512 return target;
2515 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2516 floating point operand in mode MODE, and N is the exponent. This
2517 function needs to be kept in sync with powi_cost above. */
2519 static rtx
2520 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2522 unsigned HOST_WIDE_INT val;
2523 rtx cache[POWI_TABLE_SIZE];
2524 rtx result;
2526 if (n == 0)
2527 return CONST1_RTX (mode);
2529 val = (n < 0) ? -n : n;
2531 memset (cache, 0, sizeof (cache));
2532 cache[1] = x;
2534 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2536 /* If the original exponent was negative, reciprocate the result. */
2537 if (n < 0)
2538 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2539 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2541 return result;
2544 /* Expand a call to the pow built-in mathematical function. Return 0 if
2545 a normal call should be emitted rather than expanding the function
2546 in-line. EXP is the expression that is a call to the builtin
2547 function; if convenient, the result should be placed in TARGET. */
2549 static rtx
2550 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2552 tree arglist = TREE_OPERAND (exp, 1);
2553 tree arg0, arg1;
2555 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2556 return 0;
2558 arg0 = TREE_VALUE (arglist);
2559 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2561 if (TREE_CODE (arg1) == REAL_CST
2562 && ! TREE_CONSTANT_OVERFLOW (arg1))
2564 REAL_VALUE_TYPE cint;
2565 REAL_VALUE_TYPE c;
2566 HOST_WIDE_INT n;
2568 c = TREE_REAL_CST (arg1);
2569 n = real_to_integer (&c);
2570 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2571 if (real_identical (&c, &cint))
2573 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2574 Otherwise, check the number of multiplications required.
2575 Note that pow never sets errno for an integer exponent. */
2576 if ((n >= -1 && n <= 2)
2577 || (flag_unsafe_math_optimizations
2578 && ! optimize_size
2579 && powi_cost (n) <= POWI_MAX_MULTS))
2581 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2582 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2583 op = force_reg (mode, op);
2584 return expand_powi (op, mode, n);
2589 if (! flag_unsafe_math_optimizations)
2590 return NULL_RTX;
2591 return expand_builtin_mathfn_2 (exp, target, subtarget);
2594 /* Expand a call to the powi built-in mathematical function. Return 0 if
2595 a normal call should be emitted rather than expanding the function
2596 in-line. EXP is the expression that is a call to the builtin
2597 function; if convenient, the result should be placed in TARGET. */
2599 static rtx
2600 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2602 tree arglist = TREE_OPERAND (exp, 1);
2603 tree arg0, arg1;
2604 rtx op0, op1;
2605 enum machine_mode mode;
2606 enum machine_mode mode2;
2608 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2609 return 0;
2611 arg0 = TREE_VALUE (arglist);
2612 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2613 mode = TYPE_MODE (TREE_TYPE (exp));
2615 /* Handle constant power. */
2617 if (TREE_CODE (arg1) == INTEGER_CST
2618 && ! TREE_CONSTANT_OVERFLOW (arg1))
2620 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2622 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2623 Otherwise, check the number of multiplications required. */
2624 if ((TREE_INT_CST_HIGH (arg1) == 0
2625 || TREE_INT_CST_HIGH (arg1) == -1)
2626 && ((n >= -1 && n <= 2)
2627 || (! optimize_size
2628 && powi_cost (n) <= POWI_MAX_MULTS)))
2630 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2631 op0 = force_reg (mode, op0);
2632 return expand_powi (op0, mode, n);
2636 /* Emit a libcall to libgcc. */
2638 /* Mode of the 2nd argument must match that of an int. */
2639 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2641 if (target == NULL_RTX)
2642 target = gen_reg_rtx (mode);
2644 op0 = expand_expr (arg0, subtarget, mode, 0);
2645 if (GET_MODE (op0) != mode)
2646 op0 = convert_to_mode (mode, op0, 0);
2647 op1 = expand_expr (arg1, 0, mode2, 0);
2648 if (GET_MODE (op1) != mode2)
2649 op1 = convert_to_mode (mode2, op1, 0);
2651 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2652 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2653 op0, mode, op1, mode2);
2655 return target;
2658 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2659 if we failed the caller should emit a normal call, otherwise
2660 try to get the result in TARGET, if convenient. */
2662 static rtx
2663 expand_builtin_strlen (tree arglist, rtx target,
2664 enum machine_mode target_mode)
2666 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2667 return 0;
2668 else
2670 rtx pat;
2671 tree len, src = TREE_VALUE (arglist);
2672 rtx result, src_reg, char_rtx, before_strlen;
2673 enum machine_mode insn_mode = target_mode, char_mode;
2674 enum insn_code icode = CODE_FOR_nothing;
2675 int align;
2677 /* If the length can be computed at compile-time, return it. */
2678 len = c_strlen (src, 0);
2679 if (len)
2680 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2682 /* If the length can be computed at compile-time and is constant
2683 integer, but there are side-effects in src, evaluate
2684 src for side-effects, then return len.
2685 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2686 can be optimized into: i++; x = 3; */
2687 len = c_strlen (src, 1);
2688 if (len && TREE_CODE (len) == INTEGER_CST)
2690 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2691 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2694 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2696 /* If SRC is not a pointer type, don't do this operation inline. */
2697 if (align == 0)
2698 return 0;
2700 /* Bail out if we can't compute strlen in the right mode. */
2701 while (insn_mode != VOIDmode)
2703 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2704 if (icode != CODE_FOR_nothing)
2705 break;
2707 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2709 if (insn_mode == VOIDmode)
2710 return 0;
2712 /* Make a place to write the result of the instruction. */
2713 result = target;
2714 if (! (result != 0
2715 && REG_P (result)
2716 && GET_MODE (result) == insn_mode
2717 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2718 result = gen_reg_rtx (insn_mode);
2720 /* Make a place to hold the source address. We will not expand
2721 the actual source until we are sure that the expansion will
2722 not fail -- there are trees that cannot be expanded twice. */
2723 src_reg = gen_reg_rtx (Pmode);
2725 /* Mark the beginning of the strlen sequence so we can emit the
2726 source operand later. */
2727 before_strlen = get_last_insn ();
2729 char_rtx = const0_rtx;
2730 char_mode = insn_data[(int) icode].operand[2].mode;
2731 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2732 char_mode))
2733 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2735 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2736 char_rtx, GEN_INT (align));
2737 if (! pat)
2738 return 0;
2739 emit_insn (pat);
2741 /* Now that we are assured of success, expand the source. */
2742 start_sequence ();
2743 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2744 if (pat != src_reg)
2745 emit_move_insn (src_reg, pat);
2746 pat = get_insns ();
2747 end_sequence ();
2749 if (before_strlen)
2750 emit_insn_after (pat, before_strlen);
2751 else
2752 emit_insn_before (pat, get_insns ());
2754 /* Return the value in the proper mode for this function. */
2755 if (GET_MODE (result) == target_mode)
2756 target = result;
2757 else if (target != 0)
2758 convert_move (target, result, 0);
2759 else
2760 target = convert_to_mode (target_mode, result, 0);
2762 return target;
2766 /* Expand a call to the strstr builtin. Return 0 if we failed the
2767 caller should emit a normal call, otherwise try to get the result
2768 in TARGET, if convenient (and in mode MODE if that's convenient). */
2770 static rtx
2771 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2773 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2775 tree result = fold_builtin_strstr (arglist, type);
2776 if (result)
2777 return expand_expr (result, target, mode, EXPAND_NORMAL);
2779 return 0;
2782 /* Expand a call to the strchr builtin. Return 0 if we failed the
2783 caller should emit a normal call, otherwise try to get the result
2784 in TARGET, if convenient (and in mode MODE if that's convenient). */
2786 static rtx
2787 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2789 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2791 tree result = fold_builtin_strchr (arglist, type);
2792 if (result)
2793 return expand_expr (result, target, mode, EXPAND_NORMAL);
2795 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2797 return 0;
2800 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2801 caller should emit a normal call, otherwise try to get the result
2802 in TARGET, if convenient (and in mode MODE if that's convenient). */
2804 static rtx
2805 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2807 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2809 tree result = fold_builtin_strrchr (arglist, type);
2810 if (result)
2811 return expand_expr (result, target, mode, EXPAND_NORMAL);
2813 return 0;
2816 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2817 caller should emit a normal call, otherwise try to get the result
2818 in TARGET, if convenient (and in mode MODE if that's convenient). */
2820 static rtx
2821 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2823 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2825 tree result = fold_builtin_strpbrk (arglist, type);
2826 if (result)
2827 return expand_expr (result, target, mode, EXPAND_NORMAL);
2829 return 0;
2832 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2833 bytes from constant string DATA + OFFSET and return it as target
2834 constant. */
2836 static rtx
2837 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2838 enum machine_mode mode)
2840 const char *str = (const char *) data;
2842 gcc_assert (offset >= 0
2843 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2844 <= strlen (str) + 1));
2846 return c_readstr (str + offset, mode);
2849 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2850 Return 0 if we failed, the caller should emit a normal call,
2851 otherwise try to get the result in TARGET, if convenient (and in
2852 mode MODE if that's convenient). */
2853 static rtx
2854 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2856 tree fndecl = get_callee_fndecl (exp);
2857 tree arglist = TREE_OPERAND (exp, 1);
2858 if (!validate_arglist (arglist,
2859 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2860 return 0;
2861 else
2863 tree dest = TREE_VALUE (arglist);
2864 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2865 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2866 const char *src_str;
2867 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2868 unsigned int dest_align
2869 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2870 rtx dest_mem, src_mem, dest_addr, len_rtx;
2871 tree result = fold_builtin_memcpy (fndecl, arglist);
2873 if (result)
2874 return expand_expr (result, target, mode, EXPAND_NORMAL);
2876 /* If DEST is not a pointer type, call the normal function. */
2877 if (dest_align == 0)
2878 return 0;
2880 /* If either SRC is not a pointer type, don't do this
2881 operation in-line. */
2882 if (src_align == 0)
2883 return 0;
2885 dest_mem = get_memory_rtx (dest, len);
2886 set_mem_align (dest_mem, dest_align);
2887 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2888 src_str = c_getstr (src);
2890 /* If SRC is a string constant and block move would be done
2891 by pieces, we can avoid loading the string from memory
2892 and only stored the computed constants. */
2893 if (src_str
2894 && GET_CODE (len_rtx) == CONST_INT
2895 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2896 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2897 (void *) src_str, dest_align))
2899 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2900 builtin_memcpy_read_str,
2901 (void *) src_str, dest_align, 0);
2902 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2903 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2904 return dest_mem;
2907 src_mem = get_memory_rtx (src, len);
2908 set_mem_align (src_mem, src_align);
2910 /* Copy word part most expediently. */
2911 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2912 CALL_EXPR_TAILCALL (exp)
2913 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2915 if (dest_addr == 0)
2917 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2918 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2920 return dest_addr;
2924 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2925 Return 0 if we failed; the caller should emit a normal call,
2926 otherwise try to get the result in TARGET, if convenient (and in
2927 mode MODE if that's convenient). If ENDP is 0 return the
2928 destination pointer, if ENDP is 1 return the end pointer ala
2929 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2930 stpcpy. */
2932 static rtx
2933 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2934 int endp)
2936 if (!validate_arglist (arglist,
2937 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2938 return 0;
2939 /* If return value is ignored, transform mempcpy into memcpy. */
2940 else if (target == const0_rtx)
2942 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2944 if (!fn)
2945 return 0;
2947 return expand_expr (build_function_call_expr (fn, arglist),
2948 target, mode, EXPAND_NORMAL);
2950 else
2952 tree dest = TREE_VALUE (arglist);
2953 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2954 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2955 const char *src_str;
2956 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2957 unsigned int dest_align
2958 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2959 rtx dest_mem, src_mem, len_rtx;
2960 tree result = fold_builtin_mempcpy (arglist, type, endp);
2962 if (result)
2963 return expand_expr (result, target, mode, EXPAND_NORMAL);
2965 /* If either SRC or DEST is not a pointer type, don't do this
2966 operation in-line. */
2967 if (dest_align == 0 || src_align == 0)
2968 return 0;
2970 /* If LEN is not constant, call the normal function. */
2971 if (! host_integerp (len, 1))
2972 return 0;
2974 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2975 src_str = c_getstr (src);
2977 /* If SRC is a string constant and block move would be done
2978 by pieces, we can avoid loading the string from memory
2979 and only stored the computed constants. */
2980 if (src_str
2981 && GET_CODE (len_rtx) == CONST_INT
2982 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2983 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2984 (void *) src_str, dest_align))
2986 dest_mem = get_memory_rtx (dest, len);
2987 set_mem_align (dest_mem, dest_align);
2988 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2989 builtin_memcpy_read_str,
2990 (void *) src_str, dest_align, endp);
2991 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2992 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2993 return dest_mem;
2996 if (GET_CODE (len_rtx) == CONST_INT
2997 && can_move_by_pieces (INTVAL (len_rtx),
2998 MIN (dest_align, src_align)))
3000 dest_mem = get_memory_rtx (dest, len);
3001 set_mem_align (dest_mem, dest_align);
3002 src_mem = get_memory_rtx (src, len);
3003 set_mem_align (src_mem, src_align);
3004 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3005 MIN (dest_align, src_align), endp);
3006 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3007 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3008 return dest_mem;
3011 return 0;
3015 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3016 if we failed; the caller should emit a normal call. */
3018 static rtx
3019 expand_builtin_memmove (tree arglist, tree type, rtx target,
3020 enum machine_mode mode, tree orig_exp)
3022 if (!validate_arglist (arglist,
3023 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3024 return 0;
3025 else
3027 tree dest = TREE_VALUE (arglist);
3028 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3029 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3031 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3032 unsigned int dest_align
3033 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3034 tree result = fold_builtin_memmove (arglist, type);
3036 if (result)
3037 return expand_expr (result, target, mode, EXPAND_NORMAL);
3039 /* If DEST is not a pointer type, call the normal function. */
3040 if (dest_align == 0)
3041 return 0;
3043 /* If either SRC is not a pointer type, don't do this
3044 operation in-line. */
3045 if (src_align == 0)
3046 return 0;
3048 /* If src is categorized for a readonly section we can use
3049 normal memcpy. */
3050 if (readonly_data_expr (src))
3052 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3053 if (!fn)
3054 return 0;
3055 fn = build_function_call_expr (fn, arglist);
3056 if (TREE_CODE (fn) == CALL_EXPR)
3057 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3058 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3061 /* If length is 1 and we can expand memcpy call inline,
3062 it is ok to use memcpy as well. */
3063 if (integer_onep (len))
3065 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3066 /*endp=*/0);
3067 if (ret)
3068 return ret;
3071 /* Otherwise, call the normal function. */
3072 return 0;
3076 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3077 if we failed the caller should emit a normal call. */
3079 static rtx
3080 expand_builtin_bcopy (tree exp)
3082 tree arglist = TREE_OPERAND (exp, 1);
3083 tree type = TREE_TYPE (exp);
3084 tree src, dest, size, newarglist;
3086 if (!validate_arglist (arglist,
3087 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3088 return NULL_RTX;
3090 src = TREE_VALUE (arglist);
3091 dest = TREE_VALUE (TREE_CHAIN (arglist));
3092 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3094 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3095 memmove(ptr y, ptr x, size_t z). This is done this way
3096 so that if it isn't expanded inline, we fallback to
3097 calling bcopy instead of memmove. */
3099 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3100 newarglist = tree_cons (NULL_TREE, src, newarglist);
3101 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3103 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3106 #ifndef HAVE_movstr
3107 # define HAVE_movstr 0
3108 # define CODE_FOR_movstr CODE_FOR_nothing
3109 #endif
3111 /* Expand into a movstr instruction, if one is available. Return 0 if
3112 we failed, the caller should emit a normal call, otherwise try to
3113 get the result in TARGET, if convenient. If ENDP is 0 return the
3114 destination pointer, if ENDP is 1 return the end pointer ala
3115 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3116 stpcpy. */
3118 static rtx
3119 expand_movstr (tree dest, tree src, rtx target, int endp)
3121 rtx end;
3122 rtx dest_mem;
3123 rtx src_mem;
3124 rtx insn;
3125 const struct insn_data * data;
3127 if (!HAVE_movstr)
3128 return 0;
3130 dest_mem = get_memory_rtx (dest, NULL);
3131 src_mem = get_memory_rtx (src, NULL);
3132 if (!endp)
3134 target = force_reg (Pmode, XEXP (dest_mem, 0));
3135 dest_mem = replace_equiv_address (dest_mem, target);
3136 end = gen_reg_rtx (Pmode);
3138 else
3140 if (target == 0 || target == const0_rtx)
3142 end = gen_reg_rtx (Pmode);
3143 if (target == 0)
3144 target = end;
3146 else
3147 end = target;
3150 data = insn_data + CODE_FOR_movstr;
3152 if (data->operand[0].mode != VOIDmode)
3153 end = gen_lowpart (data->operand[0].mode, end);
3155 insn = data->genfun (end, dest_mem, src_mem);
3157 gcc_assert (insn);
3159 emit_insn (insn);
3161 /* movstr is supposed to set end to the address of the NUL
3162 terminator. If the caller requested a mempcpy-like return value,
3163 adjust it. */
3164 if (endp == 1 && target != const0_rtx)
3166 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3167 emit_move_insn (target, force_operand (tem, NULL_RTX));
3170 return target;
3173 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3174 if we failed the caller should emit a normal call, otherwise try to get
3175 the result in TARGET, if convenient (and in mode MODE if that's
3176 convenient). */
3178 static rtx
3179 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3181 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3183 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3184 if (result)
3185 return expand_expr (result, target, mode, EXPAND_NORMAL);
3187 return expand_movstr (TREE_VALUE (arglist),
3188 TREE_VALUE (TREE_CHAIN (arglist)),
3189 target, /*endp=*/0);
3191 return 0;
3194 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3195 Return 0 if we failed the caller should emit a normal call,
3196 otherwise try to get the result in TARGET, if convenient (and in
3197 mode MODE if that's convenient). */
3199 static rtx
3200 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3202 tree arglist = TREE_OPERAND (exp, 1);
3203 /* If return value is ignored, transform stpcpy into strcpy. */
3204 if (target == const0_rtx)
3206 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3207 if (!fn)
3208 return 0;
3210 return expand_expr (build_function_call_expr (fn, arglist),
3211 target, mode, EXPAND_NORMAL);
3214 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3215 return 0;
3216 else
3218 tree dst, src, len, lenp1;
3219 tree narglist;
3220 rtx ret;
3222 /* Ensure we get an actual string whose length can be evaluated at
3223 compile-time, not an expression containing a string. This is
3224 because the latter will potentially produce pessimized code
3225 when used to produce the return value. */
3226 src = TREE_VALUE (TREE_CHAIN (arglist));
3227 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3228 return expand_movstr (TREE_VALUE (arglist),
3229 TREE_VALUE (TREE_CHAIN (arglist)),
3230 target, /*endp=*/2);
3232 dst = TREE_VALUE (arglist);
3233 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3234 narglist = build_tree_list (NULL_TREE, lenp1);
3235 narglist = tree_cons (NULL_TREE, src, narglist);
3236 narglist = tree_cons (NULL_TREE, dst, narglist);
3237 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3238 target, mode, /*endp=*/2);
3240 if (ret)
3241 return ret;
3243 if (TREE_CODE (len) == INTEGER_CST)
3245 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3247 if (GET_CODE (len_rtx) == CONST_INT)
3249 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3250 arglist, target, mode);
3252 if (ret)
3254 if (! target)
3256 if (mode != VOIDmode)
3257 target = gen_reg_rtx (mode);
3258 else
3259 target = gen_reg_rtx (GET_MODE (ret));
3261 if (GET_MODE (target) != GET_MODE (ret))
3262 ret = gen_lowpart (GET_MODE (target), ret);
3264 ret = plus_constant (ret, INTVAL (len_rtx));
3265 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3266 gcc_assert (ret);
3268 return target;
3273 return expand_movstr (TREE_VALUE (arglist),
3274 TREE_VALUE (TREE_CHAIN (arglist)),
3275 target, /*endp=*/2);
3279 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3280 bytes from constant string DATA + OFFSET and return it as target
3281 constant. */
3283 static rtx
3284 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3285 enum machine_mode mode)
3287 const char *str = (const char *) data;
3289 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3290 return const0_rtx;
3292 return c_readstr (str + offset, mode);
3295 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3296 if we failed the caller should emit a normal call. */
3298 static rtx
3299 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3301 tree fndecl = get_callee_fndecl (exp);
3302 tree arglist = TREE_OPERAND (exp, 1);
3303 if (validate_arglist (arglist,
3304 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3306 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3307 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3308 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3310 if (result)
3311 return expand_expr (result, target, mode, EXPAND_NORMAL);
3313 /* We must be passed a constant len and src parameter. */
3314 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3315 return 0;
3317 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3319 /* We're required to pad with trailing zeros if the requested
3320 len is greater than strlen(s2)+1. In that case try to
3321 use store_by_pieces, if it fails, punt. */
3322 if (tree_int_cst_lt (slen, len))
3324 tree dest = TREE_VALUE (arglist);
3325 unsigned int dest_align
3326 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3327 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3328 rtx dest_mem;
3330 if (!p || dest_align == 0 || !host_integerp (len, 1)
3331 || !can_store_by_pieces (tree_low_cst (len, 1),
3332 builtin_strncpy_read_str,
3333 (void *) p, dest_align))
3334 return 0;
3336 dest_mem = get_memory_rtx (dest, len);
3337 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3338 builtin_strncpy_read_str,
3339 (void *) p, dest_align, 0);
3340 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3341 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3342 return dest_mem;
3345 return 0;
3348 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3349 bytes from constant string DATA + OFFSET and return it as target
3350 constant. */
3352 static rtx
3353 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3354 enum machine_mode mode)
3356 const char *c = (const char *) data;
3357 char *p = alloca (GET_MODE_SIZE (mode));
3359 memset (p, *c, GET_MODE_SIZE (mode));
3361 return c_readstr (p, mode);
3364 /* Callback routine for store_by_pieces. Return the RTL of a register
3365 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3366 char value given in the RTL register data. For example, if mode is
3367 4 bytes wide, return the RTL for 0x01010101*data. */
3369 static rtx
3370 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3371 enum machine_mode mode)
3373 rtx target, coeff;
3374 size_t size;
3375 char *p;
3377 size = GET_MODE_SIZE (mode);
3378 if (size == 1)
3379 return (rtx) data;
3381 p = alloca (size);
3382 memset (p, 1, size);
3383 coeff = c_readstr (p, mode);
3385 target = convert_to_mode (mode, (rtx) data, 1);
3386 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3387 return force_reg (mode, target);
3390 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3391 if we failed the caller should emit a normal call, otherwise try to get
3392 the result in TARGET, if convenient (and in mode MODE if that's
3393 convenient). */
3395 static rtx
3396 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3397 tree orig_exp)
3399 if (!validate_arglist (arglist,
3400 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3401 return 0;
3402 else
3404 tree dest = TREE_VALUE (arglist);
3405 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3406 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3407 char c;
3409 unsigned int dest_align
3410 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3411 rtx dest_mem, dest_addr, len_rtx;
3413 /* If DEST is not a pointer type, don't do this
3414 operation in-line. */
3415 if (dest_align == 0)
3416 return 0;
3418 /* If the LEN parameter is zero, return DEST. */
3419 if (integer_zerop (len))
3421 /* Evaluate and ignore VAL in case it has side-effects. */
3422 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3423 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3426 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3427 dest_mem = get_memory_rtx (dest, len);
3429 if (TREE_CODE (val) != INTEGER_CST)
3431 rtx val_rtx;
3433 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3434 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3436 /* Assume that we can memset by pieces if we can store the
3437 * the coefficients by pieces (in the required modes).
3438 * We can't pass builtin_memset_gen_str as that emits RTL. */
3439 c = 1;
3440 if (host_integerp (len, 1)
3441 && !(optimize_size && tree_low_cst (len, 1) > 1)
3442 && can_store_by_pieces (tree_low_cst (len, 1),
3443 builtin_memset_read_str, &c, dest_align))
3445 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3446 val_rtx);
3447 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3448 builtin_memset_gen_str, val_rtx, dest_align, 0);
3450 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3451 dest_align))
3452 return 0;
3454 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3455 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3456 return dest_mem;
3459 if (target_char_cast (val, &c))
3460 return 0;
3462 if (c)
3464 if (host_integerp (len, 1)
3465 && !(optimize_size && tree_low_cst (len, 1) > 1)
3466 && can_store_by_pieces (tree_low_cst (len, 1),
3467 builtin_memset_read_str, &c, dest_align))
3468 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3469 builtin_memset_read_str, &c, dest_align, 0);
3470 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3471 dest_align))
3472 return 0;
3474 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3475 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3476 return dest_mem;
3479 set_mem_align (dest_mem, dest_align);
3480 dest_addr = clear_storage (dest_mem, len_rtx,
3481 CALL_EXPR_TAILCALL (orig_exp)
3482 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3484 if (dest_addr == 0)
3486 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3487 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3490 return dest_addr;
3494 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3495 if we failed the caller should emit a normal call. */
3497 static rtx
3498 expand_builtin_bzero (tree exp)
3500 tree arglist = TREE_OPERAND (exp, 1);
3501 tree dest, size, newarglist;
3503 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3504 return NULL_RTX;
3506 dest = TREE_VALUE (arglist);
3507 size = TREE_VALUE (TREE_CHAIN (arglist));
3509 /* New argument list transforming bzero(ptr x, int y) to
3510 memset(ptr x, int 0, size_t y). This is done this way
3511 so that if it isn't expanded inline, we fallback to
3512 calling bzero instead of memset. */
3514 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3515 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3516 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3518 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3521 /* Expand expression EXP, which is a call to the memcmp built-in function.
3522 ARGLIST is the argument list for this call. Return 0 if we failed and the
3523 caller should emit a normal call, otherwise try to get the result in
3524 TARGET, if convenient (and in mode MODE, if that's convenient). */
3526 static rtx
3527 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3528 enum machine_mode mode)
3530 if (!validate_arglist (arglist,
3531 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3532 return 0;
3533 else
3535 tree result = fold_builtin_memcmp (arglist);
3536 if (result)
3537 return expand_expr (result, target, mode, EXPAND_NORMAL);
3540 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3542 tree arg1 = TREE_VALUE (arglist);
3543 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3544 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3545 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3546 rtx result;
3547 rtx insn;
3549 int arg1_align
3550 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3551 int arg2_align
3552 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3553 enum machine_mode insn_mode;
3555 #ifdef HAVE_cmpmemsi
3556 if (HAVE_cmpmemsi)
3557 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3558 else
3559 #endif
3560 #ifdef HAVE_cmpstrnsi
3561 if (HAVE_cmpstrnsi)
3562 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3563 else
3564 #endif
3565 return 0;
3567 /* If we don't have POINTER_TYPE, call the function. */
3568 if (arg1_align == 0 || arg2_align == 0)
3569 return 0;
3571 /* Make a place to write the result of the instruction. */
3572 result = target;
3573 if (! (result != 0
3574 && REG_P (result) && GET_MODE (result) == insn_mode
3575 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3576 result = gen_reg_rtx (insn_mode);
3578 arg1_rtx = get_memory_rtx (arg1, len);
3579 arg2_rtx = get_memory_rtx (arg2, len);
3580 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3582 /* Set MEM_SIZE as appropriate. */
3583 if (GET_CODE (arg3_rtx) == CONST_INT)
3585 set_mem_size (arg1_rtx, arg3_rtx);
3586 set_mem_size (arg2_rtx, arg3_rtx);
3589 #ifdef HAVE_cmpmemsi
3590 if (HAVE_cmpmemsi)
3591 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3592 GEN_INT (MIN (arg1_align, arg2_align)));
3593 else
3594 #endif
3595 #ifdef HAVE_cmpstrnsi
3596 if (HAVE_cmpstrnsi)
3597 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3598 GEN_INT (MIN (arg1_align, arg2_align)));
3599 else
3600 #endif
3601 gcc_unreachable ();
3603 if (insn)
3604 emit_insn (insn);
3605 else
3606 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3607 TYPE_MODE (integer_type_node), 3,
3608 XEXP (arg1_rtx, 0), Pmode,
3609 XEXP (arg2_rtx, 0), Pmode,
3610 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3611 TYPE_UNSIGNED (sizetype)),
3612 TYPE_MODE (sizetype));
3614 /* Return the value in the proper mode for this function. */
3615 mode = TYPE_MODE (TREE_TYPE (exp));
3616 if (GET_MODE (result) == mode)
3617 return result;
3618 else if (target != 0)
3620 convert_move (target, result, 0);
3621 return target;
3623 else
3624 return convert_to_mode (mode, result, 0);
3626 #endif
3628 return 0;
3631 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3632 if we failed the caller should emit a normal call, otherwise try to get
3633 the result in TARGET, if convenient. */
3635 static rtx
3636 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3638 tree arglist = TREE_OPERAND (exp, 1);
3640 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3641 return 0;
3642 else
3644 tree result = fold_builtin_strcmp (arglist);
3645 if (result)
3646 return expand_expr (result, target, mode, EXPAND_NORMAL);
3649 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3650 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3651 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3653 rtx arg1_rtx, arg2_rtx;
3654 rtx result, insn = NULL_RTX;
3655 tree fndecl, fn;
3657 tree arg1 = TREE_VALUE (arglist);
3658 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3659 int arg1_align
3660 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3661 int arg2_align
3662 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3664 /* If we don't have POINTER_TYPE, call the function. */
3665 if (arg1_align == 0 || arg2_align == 0)
3666 return 0;
3668 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3669 arg1 = builtin_save_expr (arg1);
3670 arg2 = builtin_save_expr (arg2);
3672 arg1_rtx = get_memory_rtx (arg1, NULL);
3673 arg2_rtx = get_memory_rtx (arg2, NULL);
3675 #ifdef HAVE_cmpstrsi
3676 /* Try to call cmpstrsi. */
3677 if (HAVE_cmpstrsi)
3679 enum machine_mode insn_mode
3680 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3682 /* Make a place to write the result of the instruction. */
3683 result = target;
3684 if (! (result != 0
3685 && REG_P (result) && GET_MODE (result) == insn_mode
3686 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3687 result = gen_reg_rtx (insn_mode);
3689 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3690 GEN_INT (MIN (arg1_align, arg2_align)));
3692 #endif
3693 #if HAVE_cmpstrnsi
3694 /* Try to determine at least one length and call cmpstrnsi. */
3695 if (!insn && HAVE_cmpstrnsi)
3697 tree len;
3698 rtx arg3_rtx;
3700 enum machine_mode insn_mode
3701 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3702 tree len1 = c_strlen (arg1, 1);
3703 tree len2 = c_strlen (arg2, 1);
3705 if (len1)
3706 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3707 if (len2)
3708 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3710 /* If we don't have a constant length for the first, use the length
3711 of the second, if we know it. We don't require a constant for
3712 this case; some cost analysis could be done if both are available
3713 but neither is constant. For now, assume they're equally cheap,
3714 unless one has side effects. If both strings have constant lengths,
3715 use the smaller. */
3717 if (!len1)
3718 len = len2;
3719 else if (!len2)
3720 len = len1;
3721 else if (TREE_SIDE_EFFECTS (len1))
3722 len = len2;
3723 else if (TREE_SIDE_EFFECTS (len2))
3724 len = len1;
3725 else if (TREE_CODE (len1) != INTEGER_CST)
3726 len = len2;
3727 else if (TREE_CODE (len2) != INTEGER_CST)
3728 len = len1;
3729 else if (tree_int_cst_lt (len1, len2))
3730 len = len1;
3731 else
3732 len = len2;
3734 /* If both arguments have side effects, we cannot optimize. */
3735 if (!len || TREE_SIDE_EFFECTS (len))
3736 return 0;
3738 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3739 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3741 /* Make a place to write the result of the instruction. */
3742 result = target;
3743 if (! (result != 0
3744 && REG_P (result) && GET_MODE (result) == insn_mode
3745 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3746 result = gen_reg_rtx (insn_mode);
3748 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3749 GEN_INT (MIN (arg1_align, arg2_align)));
3751 #endif
3753 if (insn)
3755 emit_insn (insn);
3757 /* Return the value in the proper mode for this function. */
3758 mode = TYPE_MODE (TREE_TYPE (exp));
3759 if (GET_MODE (result) == mode)
3760 return result;
3761 if (target == 0)
3762 return convert_to_mode (mode, result, 0);
3763 convert_move (target, result, 0);
3764 return target;
3767 /* Expand the library call ourselves using a stabilized argument
3768 list to avoid re-evaluating the function's arguments twice. */
3769 arglist = build_tree_list (NULL_TREE, arg2);
3770 arglist = tree_cons (NULL_TREE, arg1, arglist);
3771 fndecl = get_callee_fndecl (exp);
3772 fn = build_function_call_expr (fndecl, arglist);
3773 if (TREE_CODE (fn) == CALL_EXPR)
3774 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3775 return expand_call (fn, target, target == const0_rtx);
3777 #endif
3778 return 0;
3781 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3782 if we failed the caller should emit a normal call, otherwise try to get
3783 the result in TARGET, if convenient. */
3785 static rtx
3786 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3788 tree arglist = TREE_OPERAND (exp, 1);
3790 if (!validate_arglist (arglist,
3791 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3792 return 0;
3793 else
3795 tree result = fold_builtin_strncmp (arglist);
3796 if (result)
3797 return expand_expr (result, target, mode, EXPAND_NORMAL);
3800 /* If c_strlen can determine an expression for one of the string
3801 lengths, and it doesn't have side effects, then emit cmpstrnsi
3802 using length MIN(strlen(string)+1, arg3). */
3803 #ifdef HAVE_cmpstrnsi
3804 if (HAVE_cmpstrnsi)
3806 tree arg1 = TREE_VALUE (arglist);
3807 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3808 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3809 tree len, len1, len2;
3810 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3811 rtx result, insn;
3812 tree fndecl, fn;
3814 int arg1_align
3815 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3816 int arg2_align
3817 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3818 enum machine_mode insn_mode
3819 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3821 len1 = c_strlen (arg1, 1);
3822 len2 = c_strlen (arg2, 1);
3824 if (len1)
3825 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3826 if (len2)
3827 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3829 /* If we don't have a constant length for the first, use the length
3830 of the second, if we know it. We don't require a constant for
3831 this case; some cost analysis could be done if both are available
3832 but neither is constant. For now, assume they're equally cheap,
3833 unless one has side effects. If both strings have constant lengths,
3834 use the smaller. */
3836 if (!len1)
3837 len = len2;
3838 else if (!len2)
3839 len = len1;
3840 else if (TREE_SIDE_EFFECTS (len1))
3841 len = len2;
3842 else if (TREE_SIDE_EFFECTS (len2))
3843 len = len1;
3844 else if (TREE_CODE (len1) != INTEGER_CST)
3845 len = len2;
3846 else if (TREE_CODE (len2) != INTEGER_CST)
3847 len = len1;
3848 else if (tree_int_cst_lt (len1, len2))
3849 len = len1;
3850 else
3851 len = len2;
3853 /* If both arguments have side effects, we cannot optimize. */
3854 if (!len || TREE_SIDE_EFFECTS (len))
3855 return 0;
3857 /* The actual new length parameter is MIN(len,arg3). */
3858 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3859 fold_convert (TREE_TYPE (len), arg3));
3861 /* If we don't have POINTER_TYPE, call the function. */
3862 if (arg1_align == 0 || arg2_align == 0)
3863 return 0;
3865 /* Make a place to write the result of the instruction. */
3866 result = target;
3867 if (! (result != 0
3868 && REG_P (result) && GET_MODE (result) == insn_mode
3869 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3870 result = gen_reg_rtx (insn_mode);
3872 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3873 arg1 = builtin_save_expr (arg1);
3874 arg2 = builtin_save_expr (arg2);
3875 len = builtin_save_expr (len);
3877 arg1_rtx = get_memory_rtx (arg1, len);
3878 arg2_rtx = get_memory_rtx (arg2, len);
3879 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3880 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3881 GEN_INT (MIN (arg1_align, arg2_align)));
3882 if (insn)
3884 emit_insn (insn);
3886 /* Return the value in the proper mode for this function. */
3887 mode = TYPE_MODE (TREE_TYPE (exp));
3888 if (GET_MODE (result) == mode)
3889 return result;
3890 if (target == 0)
3891 return convert_to_mode (mode, result, 0);
3892 convert_move (target, result, 0);
3893 return target;
3896 /* Expand the library call ourselves using a stabilized argument
3897 list to avoid re-evaluating the function's arguments twice. */
3898 arglist = build_tree_list (NULL_TREE, len);
3899 arglist = tree_cons (NULL_TREE, arg2, arglist);
3900 arglist = tree_cons (NULL_TREE, arg1, arglist);
3901 fndecl = get_callee_fndecl (exp);
3902 fn = build_function_call_expr (fndecl, arglist);
3903 if (TREE_CODE (fn) == CALL_EXPR)
3904 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3905 return expand_call (fn, target, target == const0_rtx);
3907 #endif
3908 return 0;
3911 /* Expand expression EXP, which is a call to the strcat builtin.
3912 Return 0 if we failed the caller should emit a normal call,
3913 otherwise try to get the result in TARGET, if convenient. */
3915 static rtx
3916 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3918 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3919 return 0;
3920 else
3922 tree dst = TREE_VALUE (arglist),
3923 src = TREE_VALUE (TREE_CHAIN (arglist));
3924 const char *p = c_getstr (src);
3926 /* If the string length is zero, return the dst parameter. */
3927 if (p && *p == '\0')
3928 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3930 if (!optimize_size)
3932 /* See if we can store by pieces into (dst + strlen(dst)). */
3933 tree newsrc, newdst,
3934 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3935 rtx insns;
3937 /* Stabilize the argument list. */
3938 newsrc = builtin_save_expr (src);
3939 if (newsrc != src)
3940 arglist = build_tree_list (NULL_TREE, newsrc);
3941 else
3942 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3944 dst = builtin_save_expr (dst);
3946 start_sequence ();
3948 /* Create strlen (dst). */
3949 newdst =
3950 build_function_call_expr (strlen_fn,
3951 build_tree_list (NULL_TREE, dst));
3952 /* Create (dst + (cast) strlen (dst)). */
3953 newdst = fold_convert (TREE_TYPE (dst), newdst);
3954 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3956 newdst = builtin_save_expr (newdst);
3957 arglist = tree_cons (NULL_TREE, newdst, arglist);
3959 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3961 end_sequence (); /* Stop sequence. */
3962 return 0;
3965 /* Output the entire sequence. */
3966 insns = get_insns ();
3967 end_sequence ();
3968 emit_insn (insns);
3970 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3973 return 0;
3977 /* Expand expression EXP, which is a call to the strncat builtin.
3978 Return 0 if we failed the caller should emit a normal call,
3979 otherwise try to get the result in TARGET, if convenient. */
3981 static rtx
3982 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3984 if (validate_arglist (arglist,
3985 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3987 tree result = fold_builtin_strncat (arglist);
3988 if (result)
3989 return expand_expr (result, target, mode, EXPAND_NORMAL);
3991 return 0;
3994 /* Expand expression EXP, which is a call to the strspn builtin.
3995 Return 0 if we failed the caller should emit a normal call,
3996 otherwise try to get the result in TARGET, if convenient. */
3998 static rtx
3999 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4001 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4003 tree result = fold_builtin_strspn (arglist);
4004 if (result)
4005 return expand_expr (result, target, mode, EXPAND_NORMAL);
4007 return 0;
4010 /* Expand expression EXP, which is a call to the strcspn builtin.
4011 Return 0 if we failed the caller should emit a normal call,
4012 otherwise try to get the result in TARGET, if convenient. */
4014 static rtx
4015 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4017 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4019 tree result = fold_builtin_strcspn (arglist);
4020 if (result)
4021 return expand_expr (result, target, mode, EXPAND_NORMAL);
4023 return 0;
4026 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4027 if that's convenient. */
4030 expand_builtin_saveregs (void)
4032 rtx val, seq;
4034 /* Don't do __builtin_saveregs more than once in a function.
4035 Save the result of the first call and reuse it. */
4036 if (saveregs_value != 0)
4037 return saveregs_value;
4039 /* When this function is called, it means that registers must be
4040 saved on entry to this function. So we migrate the call to the
4041 first insn of this function. */
4043 start_sequence ();
4045 /* Do whatever the machine needs done in this case. */
4046 val = targetm.calls.expand_builtin_saveregs ();
4048 seq = get_insns ();
4049 end_sequence ();
4051 saveregs_value = val;
4053 /* Put the insns after the NOTE that starts the function. If this
4054 is inside a start_sequence, make the outer-level insn chain current, so
4055 the code is placed at the start of the function. */
4056 push_topmost_sequence ();
4057 emit_insn_after (seq, entry_of_function ());
4058 pop_topmost_sequence ();
4060 return val;
4063 /* __builtin_args_info (N) returns word N of the arg space info
4064 for the current function. The number and meanings of words
4065 is controlled by the definition of CUMULATIVE_ARGS. */
4067 static rtx
4068 expand_builtin_args_info (tree arglist)
4070 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4071 int *word_ptr = (int *) &current_function_args_info;
4073 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4075 if (arglist != 0)
4077 if (!host_integerp (TREE_VALUE (arglist), 0))
4078 error ("argument of %<__builtin_args_info%> must be constant");
4079 else
4081 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4083 if (wordnum < 0 || wordnum >= nwords)
4084 error ("argument of %<__builtin_args_info%> out of range");
4085 else
4086 return GEN_INT (word_ptr[wordnum]);
4089 else
4090 error ("missing argument in %<__builtin_args_info%>");
4092 return const0_rtx;
4095 /* Expand a call to __builtin_next_arg. */
4097 static rtx
4098 expand_builtin_next_arg (void)
4100 /* Checking arguments is already done in fold_builtin_next_arg
4101 that must be called before this function. */
4102 return expand_binop (Pmode, add_optab,
4103 current_function_internal_arg_pointer,
4104 current_function_arg_offset_rtx,
4105 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4108 /* Make it easier for the backends by protecting the valist argument
4109 from multiple evaluations. */
4111 static tree
4112 stabilize_va_list (tree valist, int needs_lvalue)
4114 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4116 if (TREE_SIDE_EFFECTS (valist))
4117 valist = save_expr (valist);
4119 /* For this case, the backends will be expecting a pointer to
4120 TREE_TYPE (va_list_type_node), but it's possible we've
4121 actually been given an array (an actual va_list_type_node).
4122 So fix it. */
4123 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4125 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4126 valist = build_fold_addr_expr_with_type (valist, p1);
4129 else
4131 tree pt;
4133 if (! needs_lvalue)
4135 if (! TREE_SIDE_EFFECTS (valist))
4136 return valist;
4138 pt = build_pointer_type (va_list_type_node);
4139 valist = fold_build1 (ADDR_EXPR, pt, valist);
4140 TREE_SIDE_EFFECTS (valist) = 1;
4143 if (TREE_SIDE_EFFECTS (valist))
4144 valist = save_expr (valist);
4145 valist = build_fold_indirect_ref (valist);
4148 return valist;
4151 /* The "standard" definition of va_list is void*. */
4153 tree
4154 std_build_builtin_va_list (void)
4156 return ptr_type_node;
4159 /* The "standard" implementation of va_start: just assign `nextarg' to
4160 the variable. */
4162 void
4163 std_expand_builtin_va_start (tree valist, rtx nextarg)
4165 tree t;
4167 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4168 make_tree (ptr_type_node, nextarg));
4169 TREE_SIDE_EFFECTS (t) = 1;
4171 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4174 /* Expand ARGLIST, from a call to __builtin_va_start. */
4176 static rtx
4177 expand_builtin_va_start (tree arglist)
4179 rtx nextarg;
4180 tree chain, valist;
4182 chain = TREE_CHAIN (arglist);
4184 if (!chain)
4186 error ("too few arguments to function %<va_start%>");
4187 return const0_rtx;
4190 if (fold_builtin_next_arg (chain))
4191 return const0_rtx;
4193 nextarg = expand_builtin_next_arg ();
4194 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4196 #ifdef EXPAND_BUILTIN_VA_START
4197 EXPAND_BUILTIN_VA_START (valist, nextarg);
4198 #else
4199 std_expand_builtin_va_start (valist, nextarg);
4200 #endif
4202 return const0_rtx;
4205 /* The "standard" implementation of va_arg: read the value from the
4206 current (padded) address and increment by the (padded) size. */
4208 tree
4209 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4211 tree addr, t, type_size, rounded_size, valist_tmp;
4212 unsigned HOST_WIDE_INT align, boundary;
4213 bool indirect;
4215 #ifdef ARGS_GROW_DOWNWARD
4216 /* All of the alignment and movement below is for args-grow-up machines.
4217 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4218 implement their own specialized gimplify_va_arg_expr routines. */
4219 gcc_unreachable ();
4220 #endif
4222 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4223 if (indirect)
4224 type = build_pointer_type (type);
4226 align = PARM_BOUNDARY / BITS_PER_UNIT;
4227 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4229 /* Hoist the valist value into a temporary for the moment. */
4230 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4232 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4233 requires greater alignment, we must perform dynamic alignment. */
4234 if (boundary > align)
4236 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4237 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4238 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4239 gimplify_and_add (t, pre_p);
4241 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4242 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4243 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4244 gimplify_and_add (t, pre_p);
4246 else
4247 boundary = align;
4249 /* If the actual alignment is less than the alignment of the type,
4250 adjust the type accordingly so that we don't assume strict alignment
4251 when deferencing the pointer. */
4252 boundary *= BITS_PER_UNIT;
4253 if (boundary < TYPE_ALIGN (type))
4255 type = build_variant_type_copy (type);
4256 TYPE_ALIGN (type) = boundary;
4259 /* Compute the rounded size of the type. */
4260 type_size = size_in_bytes (type);
4261 rounded_size = round_up (type_size, align);
4263 /* Reduce rounded_size so it's sharable with the postqueue. */
4264 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4266 /* Get AP. */
4267 addr = valist_tmp;
4268 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4270 /* Small args are padded downward. */
4271 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4272 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4273 size_binop (MINUS_EXPR, rounded_size, type_size));
4274 t = fold_convert (TREE_TYPE (addr), t);
4275 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4278 /* Compute new value for AP. */
4279 t = fold_convert (TREE_TYPE (valist), rounded_size);
4280 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4281 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4282 gimplify_and_add (t, pre_p);
4284 addr = fold_convert (build_pointer_type (type), addr);
4286 if (indirect)
4287 addr = build_va_arg_indirect_ref (addr);
4289 return build_va_arg_indirect_ref (addr);
4292 /* Build an indirect-ref expression over the given TREE, which represents a
4293 piece of a va_arg() expansion. */
4294 tree
4295 build_va_arg_indirect_ref (tree addr)
4297 addr = build_fold_indirect_ref (addr);
4299 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4300 mf_mark (addr);
4302 return addr;
4305 /* Return a dummy expression of type TYPE in order to keep going after an
4306 error. */
4308 static tree
4309 dummy_object (tree type)
4311 tree t = convert (build_pointer_type (type), null_pointer_node);
4312 return build1 (INDIRECT_REF, type, t);
4315 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4316 builtin function, but a very special sort of operator. */
4318 enum gimplify_status
4319 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4321 tree promoted_type, want_va_type, have_va_type;
4322 tree valist = TREE_OPERAND (*expr_p, 0);
4323 tree type = TREE_TYPE (*expr_p);
4324 tree t;
4326 /* Verify that valist is of the proper type. */
4327 want_va_type = va_list_type_node;
4328 have_va_type = TREE_TYPE (valist);
4330 if (have_va_type == error_mark_node)
4331 return GS_ERROR;
4333 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4335 /* If va_list is an array type, the argument may have decayed
4336 to a pointer type, e.g. by being passed to another function.
4337 In that case, unwrap both types so that we can compare the
4338 underlying records. */
4339 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4340 || POINTER_TYPE_P (have_va_type))
4342 want_va_type = TREE_TYPE (want_va_type);
4343 have_va_type = TREE_TYPE (have_va_type);
4347 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4349 error ("first argument to %<va_arg%> not of type %<va_list%>");
4350 return GS_ERROR;
4353 /* Generate a diagnostic for requesting data of a type that cannot
4354 be passed through `...' due to type promotion at the call site. */
4355 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4356 != type)
4358 static bool gave_help;
4360 /* Unfortunately, this is merely undefined, rather than a constraint
4361 violation, so we cannot make this an error. If this call is never
4362 executed, the program is still strictly conforming. */
4363 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4364 type, promoted_type);
4365 if (! gave_help)
4367 gave_help = true;
4368 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4369 promoted_type, type);
4372 /* We can, however, treat "undefined" any way we please.
4373 Call abort to encourage the user to fix the program. */
4374 inform ("if this code is reached, the program will abort");
4375 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4376 NULL);
4377 append_to_statement_list (t, pre_p);
4379 /* This is dead code, but go ahead and finish so that the
4380 mode of the result comes out right. */
4381 *expr_p = dummy_object (type);
4382 return GS_ALL_DONE;
4384 else
4386 /* Make it easier for the backends by protecting the valist argument
4387 from multiple evaluations. */
4388 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4390 /* For this case, the backends will be expecting a pointer to
4391 TREE_TYPE (va_list_type_node), but it's possible we've
4392 actually been given an array (an actual va_list_type_node).
4393 So fix it. */
4394 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4396 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4397 valist = build_fold_addr_expr_with_type (valist, p1);
4399 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4401 else
4402 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4404 if (!targetm.gimplify_va_arg_expr)
4405 /* FIXME:Once most targets are converted we should merely
4406 assert this is non-null. */
4407 return GS_ALL_DONE;
4409 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4410 return GS_OK;
4414 /* Expand ARGLIST, from a call to __builtin_va_end. */
4416 static rtx
4417 expand_builtin_va_end (tree arglist)
4419 tree valist = TREE_VALUE (arglist);
4421 /* Evaluate for side effects, if needed. I hate macros that don't
4422 do that. */
4423 if (TREE_SIDE_EFFECTS (valist))
4424 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4426 return const0_rtx;
4429 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4430 builtin rather than just as an assignment in stdarg.h because of the
4431 nastiness of array-type va_list types. */
4433 static rtx
4434 expand_builtin_va_copy (tree arglist)
4436 tree dst, src, t;
4438 dst = TREE_VALUE (arglist);
4439 src = TREE_VALUE (TREE_CHAIN (arglist));
4441 dst = stabilize_va_list (dst, 1);
4442 src = stabilize_va_list (src, 0);
4444 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4446 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4447 TREE_SIDE_EFFECTS (t) = 1;
4448 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4450 else
4452 rtx dstb, srcb, size;
4454 /* Evaluate to pointers. */
4455 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4456 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4457 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4458 VOIDmode, EXPAND_NORMAL);
4460 dstb = convert_memory_address (Pmode, dstb);
4461 srcb = convert_memory_address (Pmode, srcb);
4463 /* "Dereference" to BLKmode memories. */
4464 dstb = gen_rtx_MEM (BLKmode, dstb);
4465 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4466 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4467 srcb = gen_rtx_MEM (BLKmode, srcb);
4468 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4469 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4471 /* Copy. */
4472 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4475 return const0_rtx;
4478 /* Expand a call to one of the builtin functions __builtin_frame_address or
4479 __builtin_return_address. */
4481 static rtx
4482 expand_builtin_frame_address (tree fndecl, tree arglist)
4484 /* The argument must be a nonnegative integer constant.
4485 It counts the number of frames to scan up the stack.
4486 The value is the return address saved in that frame. */
4487 if (arglist == 0)
4488 /* Warning about missing arg was already issued. */
4489 return const0_rtx;
4490 else if (! host_integerp (TREE_VALUE (arglist), 1))
4492 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4493 error ("invalid argument to %<__builtin_frame_address%>");
4494 else
4495 error ("invalid argument to %<__builtin_return_address%>");
4496 return const0_rtx;
4498 else
4500 rtx tem
4501 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4502 tree_low_cst (TREE_VALUE (arglist), 1));
4504 /* Some ports cannot access arbitrary stack frames. */
4505 if (tem == NULL)
4507 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4508 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4509 else
4510 warning (0, "unsupported argument to %<__builtin_return_address%>");
4511 return const0_rtx;
4514 /* For __builtin_frame_address, return what we've got. */
4515 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4516 return tem;
4518 if (!REG_P (tem)
4519 && ! CONSTANT_P (tem))
4520 tem = copy_to_mode_reg (Pmode, tem);
4521 return tem;
4525 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4526 we failed and the caller should emit a normal call, otherwise try to get
4527 the result in TARGET, if convenient. */
4529 static rtx
4530 expand_builtin_alloca (tree arglist, rtx target)
4532 rtx op0;
4533 rtx result;
4535 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4536 should always expand to function calls. These can be intercepted
4537 in libmudflap. */
4538 if (flag_mudflap)
4539 return 0;
4541 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4542 return 0;
4544 /* Compute the argument. */
4545 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4547 /* Allocate the desired space. */
4548 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4549 result = convert_memory_address (ptr_mode, result);
4551 return result;
4554 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4555 Return 0 if a normal call should be emitted rather than expanding the
4556 function in-line. If convenient, the result should be placed in TARGET.
4557 SUBTARGET may be used as the target for computing one of EXP's operands. */
4559 static rtx
4560 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4561 rtx subtarget, optab op_optab)
4563 rtx op0;
4564 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4565 return 0;
4567 /* Compute the argument. */
4568 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4569 /* Compute op, into TARGET if possible.
4570 Set TARGET to wherever the result comes back. */
4571 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4572 op_optab, op0, target, 1);
4573 gcc_assert (target);
4575 return convert_to_mode (target_mode, target, 0);
4578 /* If the string passed to fputs is a constant and is one character
4579 long, we attempt to transform this call into __builtin_fputc(). */
4581 static rtx
4582 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4584 /* Verify the arguments in the original call. */
4585 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4587 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4588 unlocked, NULL_TREE);
4589 if (result)
4590 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4592 return 0;
4595 /* Expand a call to __builtin_expect. We return our argument and emit a
4596 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4597 a non-jump context. */
4599 static rtx
4600 expand_builtin_expect (tree arglist, rtx target)
4602 tree exp, c;
4603 rtx note, rtx_c;
4605 if (arglist == NULL_TREE
4606 || TREE_CHAIN (arglist) == NULL_TREE)
4607 return const0_rtx;
4608 exp = TREE_VALUE (arglist);
4609 c = TREE_VALUE (TREE_CHAIN (arglist));
4611 if (TREE_CODE (c) != INTEGER_CST)
4613 error ("second argument to %<__builtin_expect%> must be a constant");
4614 c = integer_zero_node;
4617 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4619 /* Don't bother with expected value notes for integral constants. */
4620 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4622 /* We do need to force this into a register so that we can be
4623 moderately sure to be able to correctly interpret the branch
4624 condition later. */
4625 target = force_reg (GET_MODE (target), target);
4627 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4629 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4630 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4633 return target;
4636 /* Like expand_builtin_expect, except do this in a jump context. This is
4637 called from do_jump if the conditional is a __builtin_expect. Return either
4638 a list of insns to emit the jump or NULL if we cannot optimize
4639 __builtin_expect. We need to optimize this at jump time so that machines
4640 like the PowerPC don't turn the test into a SCC operation, and then jump
4641 based on the test being 0/1. */
4644 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4646 tree arglist = TREE_OPERAND (exp, 1);
4647 tree arg0 = TREE_VALUE (arglist);
4648 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4649 rtx ret = NULL_RTX;
4651 /* Only handle __builtin_expect (test, 0) and
4652 __builtin_expect (test, 1). */
4653 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4654 && (integer_zerop (arg1) || integer_onep (arg1)))
4656 rtx insn, drop_through_label, temp;
4658 /* Expand the jump insns. */
4659 start_sequence ();
4660 do_jump (arg0, if_false_label, if_true_label);
4661 ret = get_insns ();
4663 drop_through_label = get_last_insn ();
4664 if (drop_through_label && NOTE_P (drop_through_label))
4665 drop_through_label = prev_nonnote_insn (drop_through_label);
4666 if (drop_through_label && !LABEL_P (drop_through_label))
4667 drop_through_label = NULL_RTX;
4668 end_sequence ();
4670 if (! if_true_label)
4671 if_true_label = drop_through_label;
4672 if (! if_false_label)
4673 if_false_label = drop_through_label;
4675 /* Go through and add the expect's to each of the conditional jumps. */
4676 insn = ret;
4677 while (insn != NULL_RTX)
4679 rtx next = NEXT_INSN (insn);
4681 if (JUMP_P (insn) && any_condjump_p (insn))
4683 rtx ifelse = SET_SRC (pc_set (insn));
4684 rtx then_dest = XEXP (ifelse, 1);
4685 rtx else_dest = XEXP (ifelse, 2);
4686 int taken = -1;
4688 /* First check if we recognize any of the labels. */
4689 if (GET_CODE (then_dest) == LABEL_REF
4690 && XEXP (then_dest, 0) == if_true_label)
4691 taken = 1;
4692 else if (GET_CODE (then_dest) == LABEL_REF
4693 && XEXP (then_dest, 0) == if_false_label)
4694 taken = 0;
4695 else if (GET_CODE (else_dest) == LABEL_REF
4696 && XEXP (else_dest, 0) == if_false_label)
4697 taken = 1;
4698 else if (GET_CODE (else_dest) == LABEL_REF
4699 && XEXP (else_dest, 0) == if_true_label)
4700 taken = 0;
4701 /* Otherwise check where we drop through. */
4702 else if (else_dest == pc_rtx)
4704 if (next && NOTE_P (next))
4705 next = next_nonnote_insn (next);
4707 if (next && JUMP_P (next)
4708 && any_uncondjump_p (next))
4709 temp = XEXP (SET_SRC (pc_set (next)), 0);
4710 else
4711 temp = next;
4713 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4714 else that can't possibly match either target label. */
4715 if (temp == if_false_label)
4716 taken = 1;
4717 else if (temp == if_true_label)
4718 taken = 0;
4720 else if (then_dest == pc_rtx)
4722 if (next && NOTE_P (next))
4723 next = next_nonnote_insn (next);
4725 if (next && JUMP_P (next)
4726 && any_uncondjump_p (next))
4727 temp = XEXP (SET_SRC (pc_set (next)), 0);
4728 else
4729 temp = next;
4731 if (temp == if_false_label)
4732 taken = 0;
4733 else if (temp == if_true_label)
4734 taken = 1;
4737 if (taken != -1)
4739 /* If the test is expected to fail, reverse the
4740 probabilities. */
4741 if (integer_zerop (arg1))
4742 taken = 1 - taken;
4743 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4747 insn = next;
4751 return ret;
4754 static void
4755 expand_builtin_trap (void)
4757 #ifdef HAVE_trap
4758 if (HAVE_trap)
4759 emit_insn (gen_trap ());
4760 else
4761 #endif
4762 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4763 emit_barrier ();
4766 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4767 Return 0 if a normal call should be emitted rather than expanding
4768 the function inline. If convenient, the result should be placed
4769 in TARGET. SUBTARGET may be used as the target for computing
4770 the operand. */
4772 static rtx
4773 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4775 enum machine_mode mode;
4776 tree arg;
4777 rtx op0;
4779 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4780 return 0;
4782 arg = TREE_VALUE (arglist);
4783 mode = TYPE_MODE (TREE_TYPE (arg));
4784 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4785 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4788 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4789 Return NULL is a normal call should be emitted rather than expanding the
4790 function inline. If convenient, the result should be placed in TARGET.
4791 SUBTARGET may be used as the target for computing the operand. */
4793 static rtx
4794 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4796 rtx op0, op1;
4797 tree arg;
4799 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4800 return 0;
4802 arg = TREE_VALUE (arglist);
4803 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4805 arg = TREE_VALUE (TREE_CHAIN (arglist));
4806 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4808 return expand_copysign (op0, op1, target);
4811 /* Create a new constant string literal and return a char* pointer to it.
4812 The STRING_CST value is the LEN characters at STR. */
4813 static tree
4814 build_string_literal (int len, const char *str)
4816 tree t, elem, index, type;
4818 t = build_string (len, str);
4819 elem = build_type_variant (char_type_node, 1, 0);
4820 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4821 type = build_array_type (elem, index);
4822 TREE_TYPE (t) = type;
4823 TREE_CONSTANT (t) = 1;
4824 TREE_INVARIANT (t) = 1;
4825 TREE_READONLY (t) = 1;
4826 TREE_STATIC (t) = 1;
4828 type = build_pointer_type (type);
4829 t = build1 (ADDR_EXPR, type, t);
4831 type = build_pointer_type (elem);
4832 t = build1 (NOP_EXPR, type, t);
4833 return t;
4836 /* Expand EXP, a call to printf or printf_unlocked.
4837 Return 0 if a normal call should be emitted rather than transforming
4838 the function inline. If convenient, the result should be placed in
4839 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4840 call. */
4841 static rtx
4842 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4843 bool unlocked)
4845 tree arglist = TREE_OPERAND (exp, 1);
4846 tree fn_putchar = unlocked
4847 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4848 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4849 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4850 : implicit_built_in_decls[BUILT_IN_PUTS];
4851 const char *fmt_str;
4852 tree fn, fmt, arg;
4854 /* If the return value is used, don't do the transformation. */
4855 if (target != const0_rtx)
4856 return 0;
4858 /* Verify the required arguments in the original call. */
4859 if (! arglist)
4860 return 0;
4861 fmt = TREE_VALUE (arglist);
4862 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4863 return 0;
4864 arglist = TREE_CHAIN (arglist);
4866 /* Check whether the format is a literal string constant. */
4867 fmt_str = c_getstr (fmt);
4868 if (fmt_str == NULL)
4869 return 0;
4871 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4872 if (strcmp (fmt_str, "%s\n") == 0)
4874 if (! arglist
4875 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4876 || TREE_CHAIN (arglist))
4877 return 0;
4878 fn = fn_puts;
4880 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4881 else if (strcmp (fmt_str, "%c") == 0)
4883 if (! arglist
4884 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4885 || TREE_CHAIN (arglist))
4886 return 0;
4887 fn = fn_putchar;
4889 else
4891 /* We can't handle anything else with % args or %% ... yet. */
4892 if (strchr (fmt_str, '%'))
4893 return 0;
4895 if (arglist)
4896 return 0;
4898 /* If the format specifier was "", printf does nothing. */
4899 if (fmt_str[0] == '\0')
4900 return const0_rtx;
4901 /* If the format specifier has length of 1, call putchar. */
4902 if (fmt_str[1] == '\0')
4904 /* Given printf("c"), (where c is any one character,)
4905 convert "c"[0] to an int and pass that to the replacement
4906 function. */
4907 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4908 arglist = build_tree_list (NULL_TREE, arg);
4909 fn = fn_putchar;
4911 else
4913 /* If the format specifier was "string\n", call puts("string"). */
4914 size_t len = strlen (fmt_str);
4915 if (fmt_str[len - 1] == '\n')
4917 /* Create a NUL-terminated string that's one char shorter
4918 than the original, stripping off the trailing '\n'. */
4919 char *newstr = alloca (len);
4920 memcpy (newstr, fmt_str, len - 1);
4921 newstr[len - 1] = 0;
4923 arg = build_string_literal (len, newstr);
4924 arglist = build_tree_list (NULL_TREE, arg);
4925 fn = fn_puts;
4927 else
4928 /* We'd like to arrange to call fputs(string,stdout) here,
4929 but we need stdout and don't have a way to get it yet. */
4930 return 0;
4934 if (!fn)
4935 return 0;
4936 fn = build_function_call_expr (fn, arglist);
4937 if (TREE_CODE (fn) == CALL_EXPR)
4938 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4939 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4942 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4943 Return 0 if a normal call should be emitted rather than transforming
4944 the function inline. If convenient, the result should be placed in
4945 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4946 call. */
4947 static rtx
4948 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4949 bool unlocked)
4951 tree arglist = TREE_OPERAND (exp, 1);
4952 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4953 : implicit_built_in_decls[BUILT_IN_FPUTC];
4954 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4955 : implicit_built_in_decls[BUILT_IN_FPUTS];
4956 const char *fmt_str;
4957 tree fn, fmt, fp, arg;
4959 /* If the return value is used, don't do the transformation. */
4960 if (target != const0_rtx)
4961 return 0;
4963 /* Verify the required arguments in the original call. */
4964 if (! arglist)
4965 return 0;
4966 fp = TREE_VALUE (arglist);
4967 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4968 return 0;
4969 arglist = TREE_CHAIN (arglist);
4970 if (! arglist)
4971 return 0;
4972 fmt = TREE_VALUE (arglist);
4973 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4974 return 0;
4975 arglist = TREE_CHAIN (arglist);
4977 /* Check whether the format is a literal string constant. */
4978 fmt_str = c_getstr (fmt);
4979 if (fmt_str == NULL)
4980 return 0;
4982 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4983 if (strcmp (fmt_str, "%s") == 0)
4985 if (! arglist
4986 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4987 || TREE_CHAIN (arglist))
4988 return 0;
4989 arg = TREE_VALUE (arglist);
4990 arglist = build_tree_list (NULL_TREE, fp);
4991 arglist = tree_cons (NULL_TREE, arg, arglist);
4992 fn = fn_fputs;
4994 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4995 else if (strcmp (fmt_str, "%c") == 0)
4997 if (! arglist
4998 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4999 || TREE_CHAIN (arglist))
5000 return 0;
5001 arg = TREE_VALUE (arglist);
5002 arglist = build_tree_list (NULL_TREE, fp);
5003 arglist = tree_cons (NULL_TREE, arg, arglist);
5004 fn = fn_fputc;
5006 else
5008 /* We can't handle anything else with % args or %% ... yet. */
5009 if (strchr (fmt_str, '%'))
5010 return 0;
5012 if (arglist)
5013 return 0;
5015 /* If the format specifier was "", fprintf does nothing. */
5016 if (fmt_str[0] == '\0')
5018 /* Evaluate and ignore FILE* argument for side-effects. */
5019 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5020 return const0_rtx;
5023 /* When "string" doesn't contain %, replace all cases of
5024 fprintf(stream,string) with fputs(string,stream). The fputs
5025 builtin will take care of special cases like length == 1. */
5026 arglist = build_tree_list (NULL_TREE, fp);
5027 arglist = tree_cons (NULL_TREE, fmt, arglist);
5028 fn = fn_fputs;
5031 if (!fn)
5032 return 0;
5033 fn = build_function_call_expr (fn, arglist);
5034 if (TREE_CODE (fn) == CALL_EXPR)
5035 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5036 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5039 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5040 a normal call should be emitted rather than expanding the function
5041 inline. If convenient, the result should be placed in TARGET with
5042 mode MODE. */
5044 static rtx
5045 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5047 tree orig_arglist, dest, fmt;
5048 const char *fmt_str;
5050 orig_arglist = arglist;
5052 /* Verify the required arguments in the original call. */
5053 if (! arglist)
5054 return 0;
5055 dest = TREE_VALUE (arglist);
5056 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5057 return 0;
5058 arglist = TREE_CHAIN (arglist);
5059 if (! arglist)
5060 return 0;
5061 fmt = TREE_VALUE (arglist);
5062 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5063 return 0;
5064 arglist = TREE_CHAIN (arglist);
5066 /* Check whether the format is a literal string constant. */
5067 fmt_str = c_getstr (fmt);
5068 if (fmt_str == NULL)
5069 return 0;
5071 /* If the format doesn't contain % args or %%, use strcpy. */
5072 if (strchr (fmt_str, '%') == 0)
5074 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5075 tree exp;
5077 if (arglist || ! fn)
5078 return 0;
5079 expand_expr (build_function_call_expr (fn, orig_arglist),
5080 const0_rtx, VOIDmode, EXPAND_NORMAL);
5081 if (target == const0_rtx)
5082 return const0_rtx;
5083 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5084 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5086 /* If the format is "%s", use strcpy if the result isn't used. */
5087 else if (strcmp (fmt_str, "%s") == 0)
5089 tree fn, arg, len;
5090 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5092 if (! fn)
5093 return 0;
5095 if (! arglist || TREE_CHAIN (arglist))
5096 return 0;
5097 arg = TREE_VALUE (arglist);
5098 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5099 return 0;
5101 if (target != const0_rtx)
5103 len = c_strlen (arg, 1);
5104 if (! len || TREE_CODE (len) != INTEGER_CST)
5105 return 0;
5107 else
5108 len = NULL_TREE;
5110 arglist = build_tree_list (NULL_TREE, arg);
5111 arglist = tree_cons (NULL_TREE, dest, arglist);
5112 expand_expr (build_function_call_expr (fn, arglist),
5113 const0_rtx, VOIDmode, EXPAND_NORMAL);
5115 if (target == const0_rtx)
5116 return const0_rtx;
5117 return expand_expr (len, target, mode, EXPAND_NORMAL);
5120 return 0;
5123 /* Expand a call to either the entry or exit function profiler. */
5125 static rtx
5126 expand_builtin_profile_func (bool exitp)
5128 rtx this, which;
5130 this = DECL_RTL (current_function_decl);
5131 gcc_assert (MEM_P (this));
5132 this = XEXP (this, 0);
5134 if (exitp)
5135 which = profile_function_exit_libfunc;
5136 else
5137 which = profile_function_entry_libfunc;
5139 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5140 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5142 Pmode);
5144 return const0_rtx;
5147 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5149 static rtx
5150 round_trampoline_addr (rtx tramp)
5152 rtx temp, addend, mask;
5154 /* If we don't need too much alignment, we'll have been guaranteed
5155 proper alignment by get_trampoline_type. */
5156 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5157 return tramp;
5159 /* Round address up to desired boundary. */
5160 temp = gen_reg_rtx (Pmode);
5161 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5162 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5164 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5165 temp, 0, OPTAB_LIB_WIDEN);
5166 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5167 temp, 0, OPTAB_LIB_WIDEN);
5169 return tramp;
5172 static rtx
5173 expand_builtin_init_trampoline (tree arglist)
5175 tree t_tramp, t_func, t_chain;
5176 rtx r_tramp, r_func, r_chain;
5177 #ifdef TRAMPOLINE_TEMPLATE
5178 rtx blktramp;
5179 #endif
5181 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5182 POINTER_TYPE, VOID_TYPE))
5183 return NULL_RTX;
5185 t_tramp = TREE_VALUE (arglist);
5186 arglist = TREE_CHAIN (arglist);
5187 t_func = TREE_VALUE (arglist);
5188 arglist = TREE_CHAIN (arglist);
5189 t_chain = TREE_VALUE (arglist);
5191 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5192 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5193 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5195 /* Generate insns to initialize the trampoline. */
5196 r_tramp = round_trampoline_addr (r_tramp);
5197 #ifdef TRAMPOLINE_TEMPLATE
5198 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5199 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5200 emit_block_move (blktramp, assemble_trampoline_template (),
5201 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5202 #endif
5203 trampolines_created = 1;
5204 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5206 return const0_rtx;
5209 static rtx
5210 expand_builtin_adjust_trampoline (tree arglist)
5212 rtx tramp;
5214 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5215 return NULL_RTX;
5217 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5218 tramp = round_trampoline_addr (tramp);
5219 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5220 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5221 #endif
5223 return tramp;
5226 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5227 Return NULL_RTX if a normal call should be emitted rather than expanding
5228 the function in-line. EXP is the expression that is a call to the builtin
5229 function; if convenient, the result should be placed in TARGET. */
5231 static rtx
5232 expand_builtin_signbit (tree exp, rtx target)
5234 const struct real_format *fmt;
5235 enum machine_mode fmode, imode, rmode;
5236 HOST_WIDE_INT hi, lo;
5237 tree arg, arglist;
5238 int word, bitpos;
5239 rtx temp;
5241 arglist = TREE_OPERAND (exp, 1);
5242 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5243 return 0;
5245 arg = TREE_VALUE (arglist);
5246 fmode = TYPE_MODE (TREE_TYPE (arg));
5247 rmode = TYPE_MODE (TREE_TYPE (exp));
5248 fmt = REAL_MODE_FORMAT (fmode);
5250 /* For floating point formats without a sign bit, implement signbit
5251 as "ARG < 0.0". */
5252 bitpos = fmt->signbit_ro;
5253 if (bitpos < 0)
5255 /* But we can't do this if the format supports signed zero. */
5256 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5257 return 0;
5259 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5260 build_real (TREE_TYPE (arg), dconst0));
5261 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5264 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5265 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5267 imode = int_mode_for_mode (fmode);
5268 if (imode == BLKmode)
5269 return 0;
5270 temp = gen_lowpart (imode, temp);
5272 else
5274 imode = word_mode;
5275 /* Handle targets with different FP word orders. */
5276 if (FLOAT_WORDS_BIG_ENDIAN)
5277 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5278 else
5279 word = bitpos / BITS_PER_WORD;
5280 temp = operand_subword_force (temp, word, fmode);
5281 bitpos = bitpos % BITS_PER_WORD;
5284 /* Force the intermediate word_mode (or narrower) result into a
5285 register. This avoids attempting to create paradoxical SUBREGs
5286 of floating point modes below. */
5287 temp = force_reg (imode, temp);
5289 /* If the bitpos is within the "result mode" lowpart, the operation
5290 can be implement with a single bitwise AND. Otherwise, we need
5291 a right shift and an AND. */
5293 if (bitpos < GET_MODE_BITSIZE (rmode))
5295 if (bitpos < HOST_BITS_PER_WIDE_INT)
5297 hi = 0;
5298 lo = (HOST_WIDE_INT) 1 << bitpos;
5300 else
5302 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5303 lo = 0;
5306 if (imode != rmode)
5307 temp = gen_lowpart (rmode, temp);
5308 temp = expand_binop (rmode, and_optab, temp,
5309 immed_double_const (lo, hi, rmode),
5310 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5312 else
5314 /* Perform a logical right shift to place the signbit in the least
5315 significant bit, then truncate the result to the desired mode
5316 and mask just this bit. */
5317 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5318 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5319 temp = gen_lowpart (rmode, temp);
5320 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5321 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5324 return temp;
5327 /* Expand fork or exec calls. TARGET is the desired target of the
5328 call. ARGLIST is the list of arguments of the call. FN is the
5329 identificator of the actual function. IGNORE is nonzero if the
5330 value is to be ignored. */
5332 static rtx
5333 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5335 tree id, decl;
5336 tree call;
5338 /* If we are not profiling, just call the function. */
5339 if (!profile_arc_flag)
5340 return NULL_RTX;
5342 /* Otherwise call the wrapper. This should be equivalent for the rest of
5343 compiler, so the code does not diverge, and the wrapper may run the
5344 code necessary for keeping the profiling sane. */
5346 switch (DECL_FUNCTION_CODE (fn))
5348 case BUILT_IN_FORK:
5349 id = get_identifier ("__gcov_fork");
5350 break;
5352 case BUILT_IN_EXECL:
5353 id = get_identifier ("__gcov_execl");
5354 break;
5356 case BUILT_IN_EXECV:
5357 id = get_identifier ("__gcov_execv");
5358 break;
5360 case BUILT_IN_EXECLP:
5361 id = get_identifier ("__gcov_execlp");
5362 break;
5364 case BUILT_IN_EXECLE:
5365 id = get_identifier ("__gcov_execle");
5366 break;
5368 case BUILT_IN_EXECVP:
5369 id = get_identifier ("__gcov_execvp");
5370 break;
5372 case BUILT_IN_EXECVE:
5373 id = get_identifier ("__gcov_execve");
5374 break;
5376 default:
5377 gcc_unreachable ();
5380 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5381 DECL_EXTERNAL (decl) = 1;
5382 TREE_PUBLIC (decl) = 1;
5383 DECL_ARTIFICIAL (decl) = 1;
5384 TREE_NOTHROW (decl) = 1;
5385 call = build_function_call_expr (decl, arglist);
5387 return expand_call (call, target, ignore);
5391 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5392 the pointer in these functions is void*, the tree optimizers may remove
5393 casts. The mode computed in expand_builtin isn't reliable either, due
5394 to __sync_bool_compare_and_swap.
5396 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5397 group of builtins. This gives us log2 of the mode size. */
5399 static inline enum machine_mode
5400 get_builtin_sync_mode (int fcode_diff)
5402 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 1);
5405 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5406 ARGLIST is the operands list to the function. CODE is the rtx code
5407 that corresponds to the arithmetic or logical operation from the name;
5408 an exception here is that NOT actually means NAND. TARGET is an optional
5409 place for us to store the results; AFTER is true if this is the
5410 fetch_and_xxx form. IGNORE is true if we don't actually care about
5411 the result of the operation at all. */
5413 static rtx
5414 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5415 enum rtx_code code, bool after,
5416 rtx target, bool ignore)
5418 rtx addr, val, mem;
5420 /* Expand the operands. */
5421 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5423 arglist = TREE_CHAIN (arglist);
5424 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5426 /* Note that we explicitly do not want any alias information for this
5427 memory, so that we kill all other live memories. Otherwise we don't
5428 satisfy the full barrier semantics of the intrinsic. */
5429 mem = validize_mem (gen_rtx_MEM (mode, addr));
5430 MEM_VOLATILE_P (mem) = 1;
5432 if (ignore)
5433 return expand_sync_operation (mem, val, code);
5434 else
5435 return expand_sync_fetch_operation (mem, val, code, after, target);
5438 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5439 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5440 true if this is the boolean form. TARGET is a place for us to store the
5441 results; this is NOT optional if IS_BOOL is true. */
5443 static rtx
5444 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5445 bool is_bool, rtx target)
5447 rtx addr, old_val, new_val, mem;
5449 /* Expand the operands. */
5450 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5452 arglist = TREE_CHAIN (arglist);
5453 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5455 arglist = TREE_CHAIN (arglist);
5456 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5458 /* Note that we explicitly do not want any alias information for this
5459 memory, so that we kill all other live memories. Otherwise we don't
5460 satisfy the full barrier semantics of the intrinsic. */
5461 mem = validize_mem (gen_rtx_MEM (mode, addr));
5462 MEM_VOLATILE_P (mem) = 1;
5464 if (is_bool)
5465 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5466 else
5467 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5470 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5471 general form is actually an atomic exchange, and some targets only
5472 support a reduced form with the second argument being a constant 1.
5473 ARGLIST is the operands list to the function; TARGET is an optional
5474 place for us to store the results. */
5476 static rtx
5477 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5478 rtx target)
5480 rtx addr, val, mem;
5482 /* Expand the operands. */
5483 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5485 arglist = TREE_CHAIN (arglist);
5486 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5488 /* Note that we explicitly do not want any alias information for this
5489 memory, so that we kill all other live memories. Otherwise we don't
5490 satisfy the barrier semantics of the intrinsic. */
5491 mem = validize_mem (gen_rtx_MEM (mode, addr));
5492 MEM_VOLATILE_P (mem) = 1;
5494 return expand_sync_lock_test_and_set (mem, val, target);
5497 /* Expand the __sync_synchronize intrinsic. */
5499 static void
5500 expand_builtin_synchronize (void)
5502 rtx body;
5504 #ifdef HAVE_memory_barrier
5505 if (HAVE_memory_barrier)
5507 emit_insn (gen_memory_barrier ());
5508 return;
5510 #endif
5512 /* If no explicit memory barrier instruction is available, create an empty
5513 asm stmt that will prevent compiler movement across the barrier. */
5514 body = gen_rtx_ASM_INPUT (VOIDmode, "");
5515 MEM_VOLATILE_P (body) = 1;
5516 emit_insn (body);
5519 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5520 to the function. */
5522 static void
5523 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5525 enum insn_code icode;
5526 rtx addr, mem, insn;
5527 rtx val = const0_rtx;
5529 /* Expand the operands. */
5530 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5532 /* Note that we explicitly do not want any alias information for this
5533 memory, so that we kill all other live memories. Otherwise we don't
5534 satisfy the barrier semantics of the intrinsic. */
5535 mem = validize_mem (gen_rtx_MEM (mode, addr));
5536 MEM_VOLATILE_P (mem) = 1;
5538 /* If there is an explicit operation in the md file, use it. */
5539 icode = sync_lock_release[mode];
5540 if (icode != CODE_FOR_nothing)
5542 if (!insn_data[icode].operand[1].predicate (val, mode))
5543 val = force_reg (mode, val);
5545 insn = GEN_FCN (icode) (mem, val);
5546 if (insn)
5548 emit_insn (insn);
5549 return;
5553 /* Otherwise we can implement this operation by emitting a barrier
5554 followed by a store of zero. */
5555 expand_builtin_synchronize ();
5556 emit_move_insn (mem, val);
5559 /* Expand an expression EXP that calls a built-in function,
5560 with result going to TARGET if that's convenient
5561 (and in mode MODE if that's convenient).
5562 SUBTARGET may be used as the target for computing one of EXP's operands.
5563 IGNORE is nonzero if the value is to be ignored. */
5566 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5567 int ignore)
5569 tree fndecl = get_callee_fndecl (exp);
5570 tree arglist = TREE_OPERAND (exp, 1);
5571 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5572 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5574 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5575 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5577 /* When not optimizing, generate calls to library functions for a certain
5578 set of builtins. */
5579 if (!optimize
5580 && !called_as_built_in (fndecl)
5581 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5582 && fcode != BUILT_IN_ALLOCA)
5583 return expand_call (exp, target, ignore);
5585 /* The built-in function expanders test for target == const0_rtx
5586 to determine whether the function's result will be ignored. */
5587 if (ignore)
5588 target = const0_rtx;
5590 /* If the result of a pure or const built-in function is ignored, and
5591 none of its arguments are volatile, we can avoid expanding the
5592 built-in call and just evaluate the arguments for side-effects. */
5593 if (target == const0_rtx
5594 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5596 bool volatilep = false;
5597 tree arg;
5599 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5600 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5602 volatilep = true;
5603 break;
5606 if (! volatilep)
5608 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5609 expand_expr (TREE_VALUE (arg), const0_rtx,
5610 VOIDmode, EXPAND_NORMAL);
5611 return const0_rtx;
5615 switch (fcode)
5617 case BUILT_IN_FABS:
5618 case BUILT_IN_FABSF:
5619 case BUILT_IN_FABSL:
5620 target = expand_builtin_fabs (arglist, target, subtarget);
5621 if (target)
5622 return target;
5623 break;
5625 case BUILT_IN_COPYSIGN:
5626 case BUILT_IN_COPYSIGNF:
5627 case BUILT_IN_COPYSIGNL:
5628 target = expand_builtin_copysign (arglist, target, subtarget);
5629 if (target)
5630 return target;
5631 break;
5633 /* Just do a normal library call if we were unable to fold
5634 the values. */
5635 case BUILT_IN_CABS:
5636 case BUILT_IN_CABSF:
5637 case BUILT_IN_CABSL:
5638 break;
5640 case BUILT_IN_EXP:
5641 case BUILT_IN_EXPF:
5642 case BUILT_IN_EXPL:
5643 case BUILT_IN_EXP10:
5644 case BUILT_IN_EXP10F:
5645 case BUILT_IN_EXP10L:
5646 case BUILT_IN_POW10:
5647 case BUILT_IN_POW10F:
5648 case BUILT_IN_POW10L:
5649 case BUILT_IN_EXP2:
5650 case BUILT_IN_EXP2F:
5651 case BUILT_IN_EXP2L:
5652 case BUILT_IN_EXPM1:
5653 case BUILT_IN_EXPM1F:
5654 case BUILT_IN_EXPM1L:
5655 case BUILT_IN_LOGB:
5656 case BUILT_IN_LOGBF:
5657 case BUILT_IN_LOGBL:
5658 case BUILT_IN_ILOGB:
5659 case BUILT_IN_ILOGBF:
5660 case BUILT_IN_ILOGBL:
5661 case BUILT_IN_LOG:
5662 case BUILT_IN_LOGF:
5663 case BUILT_IN_LOGL:
5664 case BUILT_IN_LOG10:
5665 case BUILT_IN_LOG10F:
5666 case BUILT_IN_LOG10L:
5667 case BUILT_IN_LOG2:
5668 case BUILT_IN_LOG2F:
5669 case BUILT_IN_LOG2L:
5670 case BUILT_IN_LOG1P:
5671 case BUILT_IN_LOG1PF:
5672 case BUILT_IN_LOG1PL:
5673 case BUILT_IN_TAN:
5674 case BUILT_IN_TANF:
5675 case BUILT_IN_TANL:
5676 case BUILT_IN_ASIN:
5677 case BUILT_IN_ASINF:
5678 case BUILT_IN_ASINL:
5679 case BUILT_IN_ACOS:
5680 case BUILT_IN_ACOSF:
5681 case BUILT_IN_ACOSL:
5682 case BUILT_IN_ATAN:
5683 case BUILT_IN_ATANF:
5684 case BUILT_IN_ATANL:
5685 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5686 because of possible accuracy problems. */
5687 if (! flag_unsafe_math_optimizations)
5688 break;
5689 case BUILT_IN_SQRT:
5690 case BUILT_IN_SQRTF:
5691 case BUILT_IN_SQRTL:
5692 case BUILT_IN_FLOOR:
5693 case BUILT_IN_FLOORF:
5694 case BUILT_IN_FLOORL:
5695 case BUILT_IN_CEIL:
5696 case BUILT_IN_CEILF:
5697 case BUILT_IN_CEILL:
5698 case BUILT_IN_TRUNC:
5699 case BUILT_IN_TRUNCF:
5700 case BUILT_IN_TRUNCL:
5701 case BUILT_IN_ROUND:
5702 case BUILT_IN_ROUNDF:
5703 case BUILT_IN_ROUNDL:
5704 case BUILT_IN_NEARBYINT:
5705 case BUILT_IN_NEARBYINTF:
5706 case BUILT_IN_NEARBYINTL:
5707 case BUILT_IN_RINT:
5708 case BUILT_IN_RINTF:
5709 case BUILT_IN_RINTL:
5710 case BUILT_IN_LRINT:
5711 case BUILT_IN_LRINTF:
5712 case BUILT_IN_LRINTL:
5713 case BUILT_IN_LLRINT:
5714 case BUILT_IN_LLRINTF:
5715 case BUILT_IN_LLRINTL:
5716 target = expand_builtin_mathfn (exp, target, subtarget);
5717 if (target)
5718 return target;
5719 break;
5721 case BUILT_IN_LCEIL:
5722 case BUILT_IN_LCEILF:
5723 case BUILT_IN_LCEILL:
5724 case BUILT_IN_LLCEIL:
5725 case BUILT_IN_LLCEILF:
5726 case BUILT_IN_LLCEILL:
5727 case BUILT_IN_LFLOOR:
5728 case BUILT_IN_LFLOORF:
5729 case BUILT_IN_LFLOORL:
5730 case BUILT_IN_LLFLOOR:
5731 case BUILT_IN_LLFLOORF:
5732 case BUILT_IN_LLFLOORL:
5733 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5734 if (target)
5735 return target;
5736 break;
5738 case BUILT_IN_POW:
5739 case BUILT_IN_POWF:
5740 case BUILT_IN_POWL:
5741 target = expand_builtin_pow (exp, target, subtarget);
5742 if (target)
5743 return target;
5744 break;
5746 case BUILT_IN_POWI:
5747 case BUILT_IN_POWIF:
5748 case BUILT_IN_POWIL:
5749 target = expand_builtin_powi (exp, target, subtarget);
5750 if (target)
5751 return target;
5752 break;
5754 case BUILT_IN_ATAN2:
5755 case BUILT_IN_ATAN2F:
5756 case BUILT_IN_ATAN2L:
5757 case BUILT_IN_LDEXP:
5758 case BUILT_IN_LDEXPF:
5759 case BUILT_IN_LDEXPL:
5760 case BUILT_IN_FMOD:
5761 case BUILT_IN_FMODF:
5762 case BUILT_IN_FMODL:
5763 case BUILT_IN_DREM:
5764 case BUILT_IN_DREMF:
5765 case BUILT_IN_DREML:
5766 if (! flag_unsafe_math_optimizations)
5767 break;
5768 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5769 if (target)
5770 return target;
5771 break;
5773 case BUILT_IN_SIN:
5774 case BUILT_IN_SINF:
5775 case BUILT_IN_SINL:
5776 case BUILT_IN_COS:
5777 case BUILT_IN_COSF:
5778 case BUILT_IN_COSL:
5779 if (! flag_unsafe_math_optimizations)
5780 break;
5781 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5782 if (target)
5783 return target;
5784 break;
5786 case BUILT_IN_APPLY_ARGS:
5787 return expand_builtin_apply_args ();
5789 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5790 FUNCTION with a copy of the parameters described by
5791 ARGUMENTS, and ARGSIZE. It returns a block of memory
5792 allocated on the stack into which is stored all the registers
5793 that might possibly be used for returning the result of a
5794 function. ARGUMENTS is the value returned by
5795 __builtin_apply_args. ARGSIZE is the number of bytes of
5796 arguments that must be copied. ??? How should this value be
5797 computed? We'll also need a safe worst case value for varargs
5798 functions. */
5799 case BUILT_IN_APPLY:
5800 if (!validate_arglist (arglist, POINTER_TYPE,
5801 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5802 && !validate_arglist (arglist, REFERENCE_TYPE,
5803 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5804 return const0_rtx;
5805 else
5807 int i;
5808 tree t;
5809 rtx ops[3];
5811 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5812 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5814 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5817 /* __builtin_return (RESULT) causes the function to return the
5818 value described by RESULT. RESULT is address of the block of
5819 memory returned by __builtin_apply. */
5820 case BUILT_IN_RETURN:
5821 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5822 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5823 NULL_RTX, VOIDmode, 0));
5824 return const0_rtx;
5826 case BUILT_IN_SAVEREGS:
5827 return expand_builtin_saveregs ();
5829 case BUILT_IN_ARGS_INFO:
5830 return expand_builtin_args_info (arglist);
5832 /* Return the address of the first anonymous stack arg. */
5833 case BUILT_IN_NEXT_ARG:
5834 if (fold_builtin_next_arg (arglist))
5835 return const0_rtx;
5836 return expand_builtin_next_arg ();
5838 case BUILT_IN_CLASSIFY_TYPE:
5839 return expand_builtin_classify_type (arglist);
5841 case BUILT_IN_CONSTANT_P:
5842 return const0_rtx;
5844 case BUILT_IN_FRAME_ADDRESS:
5845 case BUILT_IN_RETURN_ADDRESS:
5846 return expand_builtin_frame_address (fndecl, arglist);
5848 /* Returns the address of the area where the structure is returned.
5849 0 otherwise. */
5850 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5851 if (arglist != 0
5852 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5853 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5854 return const0_rtx;
5855 else
5856 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5858 case BUILT_IN_ALLOCA:
5859 target = expand_builtin_alloca (arglist, target);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_STACK_SAVE:
5865 return expand_stack_save ();
5867 case BUILT_IN_STACK_RESTORE:
5868 expand_stack_restore (TREE_VALUE (arglist));
5869 return const0_rtx;
5871 case BUILT_IN_FFS:
5872 case BUILT_IN_FFSL:
5873 case BUILT_IN_FFSLL:
5874 case BUILT_IN_FFSIMAX:
5875 target = expand_builtin_unop (target_mode, arglist, target,
5876 subtarget, ffs_optab);
5877 if (target)
5878 return target;
5879 break;
5881 case BUILT_IN_CLZ:
5882 case BUILT_IN_CLZL:
5883 case BUILT_IN_CLZLL:
5884 case BUILT_IN_CLZIMAX:
5885 target = expand_builtin_unop (target_mode, arglist, target,
5886 subtarget, clz_optab);
5887 if (target)
5888 return target;
5889 break;
5891 case BUILT_IN_CTZ:
5892 case BUILT_IN_CTZL:
5893 case BUILT_IN_CTZLL:
5894 case BUILT_IN_CTZIMAX:
5895 target = expand_builtin_unop (target_mode, arglist, target,
5896 subtarget, ctz_optab);
5897 if (target)
5898 return target;
5899 break;
5901 case BUILT_IN_POPCOUNT:
5902 case BUILT_IN_POPCOUNTL:
5903 case BUILT_IN_POPCOUNTLL:
5904 case BUILT_IN_POPCOUNTIMAX:
5905 target = expand_builtin_unop (target_mode, arglist, target,
5906 subtarget, popcount_optab);
5907 if (target)
5908 return target;
5909 break;
5911 case BUILT_IN_PARITY:
5912 case BUILT_IN_PARITYL:
5913 case BUILT_IN_PARITYLL:
5914 case BUILT_IN_PARITYIMAX:
5915 target = expand_builtin_unop (target_mode, arglist, target,
5916 subtarget, parity_optab);
5917 if (target)
5918 return target;
5919 break;
5921 case BUILT_IN_STRLEN:
5922 target = expand_builtin_strlen (arglist, target, target_mode);
5923 if (target)
5924 return target;
5925 break;
5927 case BUILT_IN_STRCPY:
5928 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5929 if (target)
5930 return target;
5931 break;
5933 case BUILT_IN_STRNCPY:
5934 target = expand_builtin_strncpy (exp, target, mode);
5935 if (target)
5936 return target;
5937 break;
5939 case BUILT_IN_STPCPY:
5940 target = expand_builtin_stpcpy (exp, target, mode);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_STRCAT:
5946 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_STRNCAT:
5952 target = expand_builtin_strncat (arglist, target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_STRSPN:
5958 target = expand_builtin_strspn (arglist, target, mode);
5959 if (target)
5960 return target;
5961 break;
5963 case BUILT_IN_STRCSPN:
5964 target = expand_builtin_strcspn (arglist, target, mode);
5965 if (target)
5966 return target;
5967 break;
5969 case BUILT_IN_STRSTR:
5970 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5971 if (target)
5972 return target;
5973 break;
5975 case BUILT_IN_STRPBRK:
5976 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5977 if (target)
5978 return target;
5979 break;
5981 case BUILT_IN_INDEX:
5982 case BUILT_IN_STRCHR:
5983 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5984 if (target)
5985 return target;
5986 break;
5988 case BUILT_IN_RINDEX:
5989 case BUILT_IN_STRRCHR:
5990 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5991 if (target)
5992 return target;
5993 break;
5995 case BUILT_IN_MEMCPY:
5996 target = expand_builtin_memcpy (exp, target, mode);
5997 if (target)
5998 return target;
5999 break;
6001 case BUILT_IN_MEMPCPY:
6002 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6003 if (target)
6004 return target;
6005 break;
6007 case BUILT_IN_MEMMOVE:
6008 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6009 mode, exp);
6010 if (target)
6011 return target;
6012 break;
6014 case BUILT_IN_BCOPY:
6015 target = expand_builtin_bcopy (exp);
6016 if (target)
6017 return target;
6018 break;
6020 case BUILT_IN_MEMSET:
6021 target = expand_builtin_memset (arglist, target, mode, exp);
6022 if (target)
6023 return target;
6024 break;
6026 case BUILT_IN_BZERO:
6027 target = expand_builtin_bzero (exp);
6028 if (target)
6029 return target;
6030 break;
6032 case BUILT_IN_STRCMP:
6033 target = expand_builtin_strcmp (exp, target, mode);
6034 if (target)
6035 return target;
6036 break;
6038 case BUILT_IN_STRNCMP:
6039 target = expand_builtin_strncmp (exp, target, mode);
6040 if (target)
6041 return target;
6042 break;
6044 case BUILT_IN_BCMP:
6045 case BUILT_IN_MEMCMP:
6046 target = expand_builtin_memcmp (exp, arglist, target, mode);
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_SETJMP:
6052 target = expand_builtin_setjmp (arglist, target);
6053 if (target)
6054 return target;
6055 break;
6057 /* __builtin_longjmp is passed a pointer to an array of five words.
6058 It's similar to the C library longjmp function but works with
6059 __builtin_setjmp above. */
6060 case BUILT_IN_LONGJMP:
6061 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6062 break;
6063 else
6065 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6066 VOIDmode, 0);
6067 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6068 NULL_RTX, VOIDmode, 0);
6070 if (value != const1_rtx)
6072 error ("%<__builtin_longjmp%> second argument must be 1");
6073 return const0_rtx;
6076 expand_builtin_longjmp (buf_addr, value);
6077 return const0_rtx;
6080 case BUILT_IN_NONLOCAL_GOTO:
6081 target = expand_builtin_nonlocal_goto (arglist);
6082 if (target)
6083 return target;
6084 break;
6086 /* This updates the setjmp buffer that is its argument with the value
6087 of the current stack pointer. */
6088 case BUILT_IN_UPDATE_SETJMP_BUF:
6089 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6091 rtx buf_addr
6092 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6094 expand_builtin_update_setjmp_buf (buf_addr);
6095 return const0_rtx;
6097 break;
6099 case BUILT_IN_TRAP:
6100 expand_builtin_trap ();
6101 return const0_rtx;
6103 case BUILT_IN_PRINTF:
6104 target = expand_builtin_printf (exp, target, mode, false);
6105 if (target)
6106 return target;
6107 break;
6109 case BUILT_IN_PRINTF_UNLOCKED:
6110 target = expand_builtin_printf (exp, target, mode, true);
6111 if (target)
6112 return target;
6113 break;
6115 case BUILT_IN_FPUTS:
6116 target = expand_builtin_fputs (arglist, target, false);
6117 if (target)
6118 return target;
6119 break;
6120 case BUILT_IN_FPUTS_UNLOCKED:
6121 target = expand_builtin_fputs (arglist, target, true);
6122 if (target)
6123 return target;
6124 break;
6126 case BUILT_IN_FPRINTF:
6127 target = expand_builtin_fprintf (exp, target, mode, false);
6128 if (target)
6129 return target;
6130 break;
6132 case BUILT_IN_FPRINTF_UNLOCKED:
6133 target = expand_builtin_fprintf (exp, target, mode, true);
6134 if (target)
6135 return target;
6136 break;
6138 case BUILT_IN_SPRINTF:
6139 target = expand_builtin_sprintf (arglist, target, mode);
6140 if (target)
6141 return target;
6142 break;
6144 case BUILT_IN_SIGNBIT:
6145 case BUILT_IN_SIGNBITF:
6146 case BUILT_IN_SIGNBITL:
6147 target = expand_builtin_signbit (exp, target);
6148 if (target)
6149 return target;
6150 break;
6152 /* Various hooks for the DWARF 2 __throw routine. */
6153 case BUILT_IN_UNWIND_INIT:
6154 expand_builtin_unwind_init ();
6155 return const0_rtx;
6156 case BUILT_IN_DWARF_CFA:
6157 return virtual_cfa_rtx;
6158 #ifdef DWARF2_UNWIND_INFO
6159 case BUILT_IN_DWARF_SP_COLUMN:
6160 return expand_builtin_dwarf_sp_column ();
6161 case BUILT_IN_INIT_DWARF_REG_SIZES:
6162 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6163 return const0_rtx;
6164 #endif
6165 case BUILT_IN_FROB_RETURN_ADDR:
6166 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6167 case BUILT_IN_EXTRACT_RETURN_ADDR:
6168 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6169 case BUILT_IN_EH_RETURN:
6170 expand_builtin_eh_return (TREE_VALUE (arglist),
6171 TREE_VALUE (TREE_CHAIN (arglist)));
6172 return const0_rtx;
6173 #ifdef EH_RETURN_DATA_REGNO
6174 case BUILT_IN_EH_RETURN_DATA_REGNO:
6175 return expand_builtin_eh_return_data_regno (arglist);
6176 #endif
6177 case BUILT_IN_EXTEND_POINTER:
6178 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6180 case BUILT_IN_VA_START:
6181 case BUILT_IN_STDARG_START:
6182 return expand_builtin_va_start (arglist);
6183 case BUILT_IN_VA_END:
6184 return expand_builtin_va_end (arglist);
6185 case BUILT_IN_VA_COPY:
6186 return expand_builtin_va_copy (arglist);
6187 case BUILT_IN_EXPECT:
6188 return expand_builtin_expect (arglist, target);
6189 case BUILT_IN_PREFETCH:
6190 expand_builtin_prefetch (arglist);
6191 return const0_rtx;
6193 case BUILT_IN_PROFILE_FUNC_ENTER:
6194 return expand_builtin_profile_func (false);
6195 case BUILT_IN_PROFILE_FUNC_EXIT:
6196 return expand_builtin_profile_func (true);
6198 case BUILT_IN_INIT_TRAMPOLINE:
6199 return expand_builtin_init_trampoline (arglist);
6200 case BUILT_IN_ADJUST_TRAMPOLINE:
6201 return expand_builtin_adjust_trampoline (arglist);
6203 case BUILT_IN_FORK:
6204 case BUILT_IN_EXECL:
6205 case BUILT_IN_EXECV:
6206 case BUILT_IN_EXECLP:
6207 case BUILT_IN_EXECLE:
6208 case BUILT_IN_EXECVP:
6209 case BUILT_IN_EXECVE:
6210 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6211 if (target)
6212 return target;
6213 break;
6215 case BUILT_IN_FETCH_AND_ADD_1:
6216 case BUILT_IN_FETCH_AND_ADD_2:
6217 case BUILT_IN_FETCH_AND_ADD_4:
6218 case BUILT_IN_FETCH_AND_ADD_8:
6219 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6220 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6221 false, target, ignore);
6222 if (target)
6223 return target;
6224 break;
6226 case BUILT_IN_FETCH_AND_SUB_1:
6227 case BUILT_IN_FETCH_AND_SUB_2:
6228 case BUILT_IN_FETCH_AND_SUB_4:
6229 case BUILT_IN_FETCH_AND_SUB_8:
6230 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6231 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6232 false, target, ignore);
6233 if (target)
6234 return target;
6235 break;
6237 case BUILT_IN_FETCH_AND_OR_1:
6238 case BUILT_IN_FETCH_AND_OR_2:
6239 case BUILT_IN_FETCH_AND_OR_4:
6240 case BUILT_IN_FETCH_AND_OR_8:
6241 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6242 target = expand_builtin_sync_operation (mode, arglist, IOR,
6243 false, target, ignore);
6244 if (target)
6245 return target;
6246 break;
6248 case BUILT_IN_FETCH_AND_AND_1:
6249 case BUILT_IN_FETCH_AND_AND_2:
6250 case BUILT_IN_FETCH_AND_AND_4:
6251 case BUILT_IN_FETCH_AND_AND_8:
6252 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6253 target = expand_builtin_sync_operation (mode, arglist, AND,
6254 false, target, ignore);
6255 if (target)
6256 return target;
6257 break;
6259 case BUILT_IN_FETCH_AND_XOR_1:
6260 case BUILT_IN_FETCH_AND_XOR_2:
6261 case BUILT_IN_FETCH_AND_XOR_4:
6262 case BUILT_IN_FETCH_AND_XOR_8:
6263 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6264 target = expand_builtin_sync_operation (mode, arglist, XOR,
6265 false, target, ignore);
6266 if (target)
6267 return target;
6268 break;
6270 case BUILT_IN_FETCH_AND_NAND_1:
6271 case BUILT_IN_FETCH_AND_NAND_2:
6272 case BUILT_IN_FETCH_AND_NAND_4:
6273 case BUILT_IN_FETCH_AND_NAND_8:
6274 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6275 target = expand_builtin_sync_operation (mode, arglist, NOT,
6276 false, target, ignore);
6277 if (target)
6278 return target;
6279 break;
6281 case BUILT_IN_ADD_AND_FETCH_1:
6282 case BUILT_IN_ADD_AND_FETCH_2:
6283 case BUILT_IN_ADD_AND_FETCH_4:
6284 case BUILT_IN_ADD_AND_FETCH_8:
6285 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6286 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6287 true, target, ignore);
6288 if (target)
6289 return target;
6290 break;
6292 case BUILT_IN_SUB_AND_FETCH_1:
6293 case BUILT_IN_SUB_AND_FETCH_2:
6294 case BUILT_IN_SUB_AND_FETCH_4:
6295 case BUILT_IN_SUB_AND_FETCH_8:
6296 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6297 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6298 true, target, ignore);
6299 if (target)
6300 return target;
6301 break;
6303 case BUILT_IN_OR_AND_FETCH_1:
6304 case BUILT_IN_OR_AND_FETCH_2:
6305 case BUILT_IN_OR_AND_FETCH_4:
6306 case BUILT_IN_OR_AND_FETCH_8:
6307 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6308 target = expand_builtin_sync_operation (mode, arglist, IOR,
6309 true, target, ignore);
6310 if (target)
6311 return target;
6312 break;
6314 case BUILT_IN_AND_AND_FETCH_1:
6315 case BUILT_IN_AND_AND_FETCH_2:
6316 case BUILT_IN_AND_AND_FETCH_4:
6317 case BUILT_IN_AND_AND_FETCH_8:
6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6319 target = expand_builtin_sync_operation (mode, arglist, AND,
6320 true, target, ignore);
6321 if (target)
6322 return target;
6323 break;
6325 case BUILT_IN_XOR_AND_FETCH_1:
6326 case BUILT_IN_XOR_AND_FETCH_2:
6327 case BUILT_IN_XOR_AND_FETCH_4:
6328 case BUILT_IN_XOR_AND_FETCH_8:
6329 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6330 target = expand_builtin_sync_operation (mode, arglist, XOR,
6331 true, target, ignore);
6332 if (target)
6333 return target;
6334 break;
6336 case BUILT_IN_NAND_AND_FETCH_1:
6337 case BUILT_IN_NAND_AND_FETCH_2:
6338 case BUILT_IN_NAND_AND_FETCH_4:
6339 case BUILT_IN_NAND_AND_FETCH_8:
6340 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6341 target = expand_builtin_sync_operation (mode, arglist, NOT,
6342 true, target, ignore);
6343 if (target)
6344 return target;
6345 break;
6347 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6348 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6349 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6350 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6351 if (mode == VOIDmode)
6352 mode = TYPE_MODE (boolean_type_node);
6353 if (!target || !register_operand (target, mode))
6354 target = gen_reg_rtx (mode);
6356 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6357 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6358 if (target)
6359 return target;
6360 break;
6362 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6363 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6364 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6365 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6366 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6367 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6368 if (target)
6369 return target;
6370 break;
6372 case BUILT_IN_LOCK_TEST_AND_SET_1:
6373 case BUILT_IN_LOCK_TEST_AND_SET_2:
6374 case BUILT_IN_LOCK_TEST_AND_SET_4:
6375 case BUILT_IN_LOCK_TEST_AND_SET_8:
6376 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6377 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6378 if (target)
6379 return target;
6380 break;
6382 case BUILT_IN_LOCK_RELEASE_1:
6383 case BUILT_IN_LOCK_RELEASE_2:
6384 case BUILT_IN_LOCK_RELEASE_4:
6385 case BUILT_IN_LOCK_RELEASE_8:
6386 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6387 expand_builtin_lock_release (mode, arglist);
6388 return const0_rtx;
6390 case BUILT_IN_SYNCHRONIZE:
6391 expand_builtin_synchronize ();
6392 return const0_rtx;
6394 case BUILT_IN_OBJECT_SIZE:
6395 return expand_builtin_object_size (exp);
6397 case BUILT_IN_MEMCPY_CHK:
6398 case BUILT_IN_MEMPCPY_CHK:
6399 case BUILT_IN_MEMMOVE_CHK:
6400 case BUILT_IN_MEMSET_CHK:
6401 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6402 if (target)
6403 return target;
6404 break;
6406 case BUILT_IN_STRCPY_CHK:
6407 case BUILT_IN_STPCPY_CHK:
6408 case BUILT_IN_STRNCPY_CHK:
6409 case BUILT_IN_STRCAT_CHK:
6410 case BUILT_IN_SNPRINTF_CHK:
6411 case BUILT_IN_VSNPRINTF_CHK:
6412 maybe_emit_chk_warning (exp, fcode);
6413 break;
6415 case BUILT_IN_SPRINTF_CHK:
6416 case BUILT_IN_VSPRINTF_CHK:
6417 maybe_emit_sprintf_chk_warning (exp, fcode);
6418 break;
6420 default: /* just do library call, if unknown builtin */
6421 break;
6424 /* The switch statement above can drop through to cause the function
6425 to be called normally. */
6426 return expand_call (exp, target, ignore);
6429 /* Determine whether a tree node represents a call to a built-in
6430 function. If the tree T is a call to a built-in function with
6431 the right number of arguments of the appropriate types, return
6432 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6433 Otherwise the return value is END_BUILTINS. */
6435 enum built_in_function
6436 builtin_mathfn_code (tree t)
6438 tree fndecl, arglist, parmlist;
6439 tree argtype, parmtype;
6441 if (TREE_CODE (t) != CALL_EXPR
6442 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6443 return END_BUILTINS;
6445 fndecl = get_callee_fndecl (t);
6446 if (fndecl == NULL_TREE
6447 || TREE_CODE (fndecl) != FUNCTION_DECL
6448 || ! DECL_BUILT_IN (fndecl)
6449 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6450 return END_BUILTINS;
6452 arglist = TREE_OPERAND (t, 1);
6453 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6454 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6456 /* If a function doesn't take a variable number of arguments,
6457 the last element in the list will have type `void'. */
6458 parmtype = TREE_VALUE (parmlist);
6459 if (VOID_TYPE_P (parmtype))
6461 if (arglist)
6462 return END_BUILTINS;
6463 return DECL_FUNCTION_CODE (fndecl);
6466 if (! arglist)
6467 return END_BUILTINS;
6469 argtype = TREE_TYPE (TREE_VALUE (arglist));
6471 if (SCALAR_FLOAT_TYPE_P (parmtype))
6473 if (! SCALAR_FLOAT_TYPE_P (argtype))
6474 return END_BUILTINS;
6476 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6478 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6479 return END_BUILTINS;
6481 else if (POINTER_TYPE_P (parmtype))
6483 if (! POINTER_TYPE_P (argtype))
6484 return END_BUILTINS;
6486 else if (INTEGRAL_TYPE_P (parmtype))
6488 if (! INTEGRAL_TYPE_P (argtype))
6489 return END_BUILTINS;
6491 else
6492 return END_BUILTINS;
6494 arglist = TREE_CHAIN (arglist);
6497 /* Variable-length argument list. */
6498 return DECL_FUNCTION_CODE (fndecl);
6501 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6502 constant. ARGLIST is the argument list of the call. */
6504 static tree
6505 fold_builtin_constant_p (tree arglist)
6507 if (arglist == 0)
6508 return 0;
6510 arglist = TREE_VALUE (arglist);
6512 /* We return 1 for a numeric type that's known to be a constant
6513 value at compile-time or for an aggregate type that's a
6514 literal constant. */
6515 STRIP_NOPS (arglist);
6517 /* If we know this is a constant, emit the constant of one. */
6518 if (CONSTANT_CLASS_P (arglist)
6519 || (TREE_CODE (arglist) == CONSTRUCTOR
6520 && TREE_CONSTANT (arglist)))
6521 return integer_one_node;
6522 if (TREE_CODE (arglist) == ADDR_EXPR)
6524 tree op = TREE_OPERAND (arglist, 0);
6525 if (TREE_CODE (op) == STRING_CST
6526 || (TREE_CODE (op) == ARRAY_REF
6527 && integer_zerop (TREE_OPERAND (op, 1))
6528 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6529 return integer_one_node;
6532 /* If this expression has side effects, show we don't know it to be a
6533 constant. Likewise if it's a pointer or aggregate type since in
6534 those case we only want literals, since those are only optimized
6535 when generating RTL, not later.
6536 And finally, if we are compiling an initializer, not code, we
6537 need to return a definite result now; there's not going to be any
6538 more optimization done. */
6539 if (TREE_SIDE_EFFECTS (arglist)
6540 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6541 || POINTER_TYPE_P (TREE_TYPE (arglist))
6542 || cfun == 0)
6543 return integer_zero_node;
6545 return 0;
6548 /* Fold a call to __builtin_expect, if we expect that a comparison against
6549 the argument will fold to a constant. In practice, this means a true
6550 constant or the address of a non-weak symbol. ARGLIST is the argument
6551 list of the call. */
6553 static tree
6554 fold_builtin_expect (tree arglist)
6556 tree arg, inner;
6558 if (arglist == 0)
6559 return 0;
6561 arg = TREE_VALUE (arglist);
6563 /* If the argument isn't invariant, then there's nothing we can do. */
6564 if (!TREE_INVARIANT (arg))
6565 return 0;
6567 /* If we're looking at an address of a weak decl, then do not fold. */
6568 inner = arg;
6569 STRIP_NOPS (inner);
6570 if (TREE_CODE (inner) == ADDR_EXPR)
6574 inner = TREE_OPERAND (inner, 0);
6576 while (TREE_CODE (inner) == COMPONENT_REF
6577 || TREE_CODE (inner) == ARRAY_REF);
6578 if (DECL_P (inner) && DECL_WEAK (inner))
6579 return 0;
6582 /* Otherwise, ARG already has the proper type for the return value. */
6583 return arg;
6586 /* Fold a call to __builtin_classify_type. */
6588 static tree
6589 fold_builtin_classify_type (tree arglist)
6591 if (arglist == 0)
6592 return build_int_cst (NULL_TREE, no_type_class);
6594 return build_int_cst (NULL_TREE,
6595 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6598 /* Fold a call to __builtin_strlen. */
6600 static tree
6601 fold_builtin_strlen (tree arglist)
6603 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6604 return NULL_TREE;
6605 else
6607 tree len = c_strlen (TREE_VALUE (arglist), 0);
6609 if (len)
6611 /* Convert from the internal "sizetype" type to "size_t". */
6612 if (size_type_node)
6613 len = fold_convert (size_type_node, len);
6614 return len;
6617 return NULL_TREE;
6621 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6623 static tree
6624 fold_builtin_inf (tree type, int warn)
6626 REAL_VALUE_TYPE real;
6628 /* __builtin_inff is intended to be usable to define INFINITY on all
6629 targets. If an infinity is not available, INFINITY expands "to a
6630 positive constant of type float that overflows at translation
6631 time", footnote "In this case, using INFINITY will violate the
6632 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6633 Thus we pedwarn to ensure this constraint violation is
6634 diagnosed. */
6635 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6636 pedwarn ("target format does not support infinity");
6638 real_inf (&real);
6639 return build_real (type, real);
6642 /* Fold a call to __builtin_nan or __builtin_nans. */
6644 static tree
6645 fold_builtin_nan (tree arglist, tree type, int quiet)
6647 REAL_VALUE_TYPE real;
6648 const char *str;
6650 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6651 return 0;
6652 str = c_getstr (TREE_VALUE (arglist));
6653 if (!str)
6654 return 0;
6656 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6657 return 0;
6659 return build_real (type, real);
6662 /* Return true if the floating point expression T has an integer value.
6663 We also allow +Inf, -Inf and NaN to be considered integer values. */
6665 static bool
6666 integer_valued_real_p (tree t)
6668 switch (TREE_CODE (t))
6670 case FLOAT_EXPR:
6671 return true;
6673 case ABS_EXPR:
6674 case SAVE_EXPR:
6675 case NON_LVALUE_EXPR:
6676 return integer_valued_real_p (TREE_OPERAND (t, 0));
6678 case COMPOUND_EXPR:
6679 case MODIFY_EXPR:
6680 case BIND_EXPR:
6681 return integer_valued_real_p (TREE_OPERAND (t, 1));
6683 case PLUS_EXPR:
6684 case MINUS_EXPR:
6685 case MULT_EXPR:
6686 case MIN_EXPR:
6687 case MAX_EXPR:
6688 return integer_valued_real_p (TREE_OPERAND (t, 0))
6689 && integer_valued_real_p (TREE_OPERAND (t, 1));
6691 case COND_EXPR:
6692 return integer_valued_real_p (TREE_OPERAND (t, 1))
6693 && integer_valued_real_p (TREE_OPERAND (t, 2));
6695 case REAL_CST:
6696 if (! TREE_CONSTANT_OVERFLOW (t))
6698 REAL_VALUE_TYPE c, cint;
6700 c = TREE_REAL_CST (t);
6701 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6702 return real_identical (&c, &cint);
6705 case NOP_EXPR:
6707 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6708 if (TREE_CODE (type) == INTEGER_TYPE)
6709 return true;
6710 if (TREE_CODE (type) == REAL_TYPE)
6711 return integer_valued_real_p (TREE_OPERAND (t, 0));
6712 break;
6715 case CALL_EXPR:
6716 switch (builtin_mathfn_code (t))
6718 case BUILT_IN_CEIL:
6719 case BUILT_IN_CEILF:
6720 case BUILT_IN_CEILL:
6721 case BUILT_IN_FLOOR:
6722 case BUILT_IN_FLOORF:
6723 case BUILT_IN_FLOORL:
6724 case BUILT_IN_NEARBYINT:
6725 case BUILT_IN_NEARBYINTF:
6726 case BUILT_IN_NEARBYINTL:
6727 case BUILT_IN_RINT:
6728 case BUILT_IN_RINTF:
6729 case BUILT_IN_RINTL:
6730 case BUILT_IN_ROUND:
6731 case BUILT_IN_ROUNDF:
6732 case BUILT_IN_ROUNDL:
6733 case BUILT_IN_TRUNC:
6734 case BUILT_IN_TRUNCF:
6735 case BUILT_IN_TRUNCL:
6736 return true;
6738 default:
6739 break;
6741 break;
6743 default:
6744 break;
6746 return false;
6749 /* EXP is assumed to be builtin call where truncation can be propagated
6750 across (for instance floor((double)f) == (double)floorf (f).
6751 Do the transformation. */
6753 static tree
6754 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6756 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6757 tree arg;
6759 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6760 return 0;
6762 arg = TREE_VALUE (arglist);
6763 /* Integer rounding functions are idempotent. */
6764 if (fcode == builtin_mathfn_code (arg))
6765 return arg;
6767 /* If argument is already integer valued, and we don't need to worry
6768 about setting errno, there's no need to perform rounding. */
6769 if (! flag_errno_math && integer_valued_real_p (arg))
6770 return arg;
6772 if (optimize)
6774 tree arg0 = strip_float_extensions (arg);
6775 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6776 tree newtype = TREE_TYPE (arg0);
6777 tree decl;
6779 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6780 && (decl = mathfn_built_in (newtype, fcode)))
6782 arglist =
6783 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6784 return fold_convert (ftype,
6785 build_function_call_expr (decl, arglist));
6788 return 0;
6791 /* EXP is assumed to be builtin call which can narrow the FP type of
6792 the argument, for instance lround((double)f) -> lroundf (f). */
6794 static tree
6795 fold_fixed_mathfn (tree fndecl, tree arglist)
6797 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6798 tree arg;
6800 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6801 return 0;
6803 arg = TREE_VALUE (arglist);
6805 /* If argument is already integer valued, and we don't need to worry
6806 about setting errno, there's no need to perform rounding. */
6807 if (! flag_errno_math && integer_valued_real_p (arg))
6808 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6810 if (optimize)
6812 tree ftype = TREE_TYPE (arg);
6813 tree arg0 = strip_float_extensions (arg);
6814 tree newtype = TREE_TYPE (arg0);
6815 tree decl;
6817 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6818 && (decl = mathfn_built_in (newtype, fcode)))
6820 arglist =
6821 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6822 return build_function_call_expr (decl, arglist);
6825 return 0;
6828 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6829 is the argument list and TYPE is the return type. Return
6830 NULL_TREE if no if no simplification can be made. */
6832 static tree
6833 fold_builtin_cabs (tree arglist, tree type)
6835 tree arg;
6837 if (!arglist || TREE_CHAIN (arglist))
6838 return NULL_TREE;
6840 arg = TREE_VALUE (arglist);
6841 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6842 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6843 return NULL_TREE;
6845 /* Evaluate cabs of a constant at compile-time. */
6846 if (flag_unsafe_math_optimizations
6847 && TREE_CODE (arg) == COMPLEX_CST
6848 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6849 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6850 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6851 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6853 REAL_VALUE_TYPE r, i;
6855 r = TREE_REAL_CST (TREE_REALPART (arg));
6856 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6858 real_arithmetic (&r, MULT_EXPR, &r, &r);
6859 real_arithmetic (&i, MULT_EXPR, &i, &i);
6860 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6861 if (real_sqrt (&r, TYPE_MODE (type), &r)
6862 || ! flag_trapping_math)
6863 return build_real (type, r);
6866 /* If either part is zero, cabs is fabs of the other. */
6867 if (TREE_CODE (arg) == COMPLEX_EXPR
6868 && real_zerop (TREE_OPERAND (arg, 0)))
6869 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6870 if (TREE_CODE (arg) == COMPLEX_EXPR
6871 && real_zerop (TREE_OPERAND (arg, 1)))
6872 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6874 /* Don't do this when optimizing for size. */
6875 if (flag_unsafe_math_optimizations
6876 && optimize && !optimize_size)
6878 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6880 if (sqrtfn != NULL_TREE)
6882 tree rpart, ipart, result, arglist;
6884 arg = builtin_save_expr (arg);
6886 rpart = fold_build1 (REALPART_EXPR, type, arg);
6887 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6889 rpart = builtin_save_expr (rpart);
6890 ipart = builtin_save_expr (ipart);
6892 result = fold_build2 (PLUS_EXPR, type,
6893 fold_build2 (MULT_EXPR, type,
6894 rpart, rpart),
6895 fold_build2 (MULT_EXPR, type,
6896 ipart, ipart));
6898 arglist = build_tree_list (NULL_TREE, result);
6899 return build_function_call_expr (sqrtfn, arglist);
6903 return NULL_TREE;
6906 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6907 NULL_TREE if no simplification can be made. */
6909 static tree
6910 fold_builtin_sqrt (tree arglist, tree type)
6913 enum built_in_function fcode;
6914 tree arg = TREE_VALUE (arglist);
6916 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6917 return NULL_TREE;
6919 /* Optimize sqrt of constant value. */
6920 if (TREE_CODE (arg) == REAL_CST
6921 && ! TREE_CONSTANT_OVERFLOW (arg))
6923 REAL_VALUE_TYPE r, x;
6925 x = TREE_REAL_CST (arg);
6926 if (real_sqrt (&r, TYPE_MODE (type), &x)
6927 || (!flag_trapping_math && !flag_errno_math))
6928 return build_real (type, r);
6931 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6932 fcode = builtin_mathfn_code (arg);
6933 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6935 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6936 arg = fold_build2 (MULT_EXPR, type,
6937 TREE_VALUE (TREE_OPERAND (arg, 1)),
6938 build_real (type, dconsthalf));
6939 arglist = build_tree_list (NULL_TREE, arg);
6940 return build_function_call_expr (expfn, arglist);
6943 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6944 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6946 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6948 if (powfn)
6950 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6951 tree tree_root;
6952 /* The inner root was either sqrt or cbrt. */
6953 REAL_VALUE_TYPE dconstroot =
6954 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6956 /* Adjust for the outer root. */
6957 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6958 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6959 tree_root = build_real (type, dconstroot);
6960 arglist = tree_cons (NULL_TREE, arg0,
6961 build_tree_list (NULL_TREE, tree_root));
6962 return build_function_call_expr (powfn, arglist);
6966 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6967 if (flag_unsafe_math_optimizations
6968 && (fcode == BUILT_IN_POW
6969 || fcode == BUILT_IN_POWF
6970 || fcode == BUILT_IN_POWL))
6972 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6973 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6974 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6975 tree narg1;
6976 if (!tree_expr_nonnegative_p (arg0))
6977 arg0 = build1 (ABS_EXPR, type, arg0);
6978 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6979 build_real (type, dconsthalf));
6980 arglist = tree_cons (NULL_TREE, arg0,
6981 build_tree_list (NULL_TREE, narg1));
6982 return build_function_call_expr (powfn, arglist);
6985 return NULL_TREE;
6988 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6989 NULL_TREE if no simplification can be made. */
6990 static tree
6991 fold_builtin_cbrt (tree arglist, tree type)
6993 tree arg = TREE_VALUE (arglist);
6994 const enum built_in_function fcode = builtin_mathfn_code (arg);
6996 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6997 return NULL_TREE;
6999 /* Optimize cbrt of constant value. */
7000 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7001 return arg;
7003 if (flag_unsafe_math_optimizations)
7005 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7006 if (BUILTIN_EXPONENT_P (fcode))
7008 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7009 const REAL_VALUE_TYPE third_trunc =
7010 real_value_truncate (TYPE_MODE (type), dconstthird);
7011 arg = fold_build2 (MULT_EXPR, type,
7012 TREE_VALUE (TREE_OPERAND (arg, 1)),
7013 build_real (type, third_trunc));
7014 arglist = build_tree_list (NULL_TREE, arg);
7015 return build_function_call_expr (expfn, arglist);
7018 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7019 if (BUILTIN_SQRT_P (fcode))
7021 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7023 if (powfn)
7025 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7026 tree tree_root;
7027 REAL_VALUE_TYPE dconstroot = dconstthird;
7029 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7030 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7031 tree_root = build_real (type, dconstroot);
7032 arglist = tree_cons (NULL_TREE, arg0,
7033 build_tree_list (NULL_TREE, tree_root));
7034 return build_function_call_expr (powfn, arglist);
7038 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7039 if (BUILTIN_CBRT_P (fcode))
7041 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7042 if (tree_expr_nonnegative_p (arg0))
7044 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7046 if (powfn)
7048 tree tree_root;
7049 REAL_VALUE_TYPE dconstroot;
7051 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7052 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7053 tree_root = build_real (type, dconstroot);
7054 arglist = tree_cons (NULL_TREE, arg0,
7055 build_tree_list (NULL_TREE, tree_root));
7056 return build_function_call_expr (powfn, arglist);
7061 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7062 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7063 || fcode == BUILT_IN_POWL)
7065 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7066 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7067 if (tree_expr_nonnegative_p (arg00))
7069 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7070 const REAL_VALUE_TYPE dconstroot
7071 = real_value_truncate (TYPE_MODE (type), dconstthird);
7072 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7073 build_real (type, dconstroot));
7074 arglist = tree_cons (NULL_TREE, arg00,
7075 build_tree_list (NULL_TREE, narg01));
7076 return build_function_call_expr (powfn, arglist);
7080 return NULL_TREE;
7083 /* Fold function call to builtin sin, sinf, or sinl. Return
7084 NULL_TREE if no simplification can be made. */
7085 static tree
7086 fold_builtin_sin (tree arglist)
7088 tree arg = TREE_VALUE (arglist);
7090 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7091 return NULL_TREE;
7093 /* Optimize sin (0.0) = 0.0. */
7094 if (real_zerop (arg))
7095 return arg;
7097 return NULL_TREE;
7100 /* Fold function call to builtin cos, cosf, or cosl. Return
7101 NULL_TREE if no simplification can be made. */
7102 static tree
7103 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7105 tree arg = TREE_VALUE (arglist);
7107 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7108 return NULL_TREE;
7110 /* Optimize cos (0.0) = 1.0. */
7111 if (real_zerop (arg))
7112 return build_real (type, dconst1);
7114 /* Optimize cos(-x) into cos (x). */
7115 if (TREE_CODE (arg) == NEGATE_EXPR)
7117 tree args = build_tree_list (NULL_TREE,
7118 TREE_OPERAND (arg, 0));
7119 return build_function_call_expr (fndecl, args);
7122 return NULL_TREE;
7125 /* Fold function call to builtin tan, tanf, or tanl. Return
7126 NULL_TREE if no simplification can be made. */
7127 static tree
7128 fold_builtin_tan (tree arglist)
7130 enum built_in_function fcode;
7131 tree arg = TREE_VALUE (arglist);
7133 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7134 return NULL_TREE;
7136 /* Optimize tan(0.0) = 0.0. */
7137 if (real_zerop (arg))
7138 return arg;
7140 /* Optimize tan(atan(x)) = x. */
7141 fcode = builtin_mathfn_code (arg);
7142 if (flag_unsafe_math_optimizations
7143 && (fcode == BUILT_IN_ATAN
7144 || fcode == BUILT_IN_ATANF
7145 || fcode == BUILT_IN_ATANL))
7146 return TREE_VALUE (TREE_OPERAND (arg, 1));
7148 return NULL_TREE;
7151 /* Fold function call to builtin atan, atanf, or atanl. Return
7152 NULL_TREE if no simplification can be made. */
7154 static tree
7155 fold_builtin_atan (tree arglist, tree type)
7158 tree arg = TREE_VALUE (arglist);
7160 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7161 return NULL_TREE;
7163 /* Optimize atan(0.0) = 0.0. */
7164 if (real_zerop (arg))
7165 return arg;
7167 /* Optimize atan(1.0) = pi/4. */
7168 if (real_onep (arg))
7170 REAL_VALUE_TYPE cst;
7172 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7173 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7174 return build_real (type, cst);
7177 return NULL_TREE;
7180 /* Fold function call to builtin trunc, truncf or truncl. Return
7181 NULL_TREE if no simplification can be made. */
7183 static tree
7184 fold_builtin_trunc (tree fndecl, tree arglist)
7186 tree arg;
7188 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7189 return 0;
7191 /* Optimize trunc of constant value. */
7192 arg = TREE_VALUE (arglist);
7193 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7195 REAL_VALUE_TYPE r, x;
7196 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7198 x = TREE_REAL_CST (arg);
7199 real_trunc (&r, TYPE_MODE (type), &x);
7200 return build_real (type, r);
7203 return fold_trunc_transparent_mathfn (fndecl, arglist);
7206 /* Fold function call to builtin floor, floorf or floorl. Return
7207 NULL_TREE if no simplification can be made. */
7209 static tree
7210 fold_builtin_floor (tree fndecl, tree arglist)
7212 tree arg;
7214 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7215 return 0;
7217 /* Optimize floor of constant value. */
7218 arg = TREE_VALUE (arglist);
7219 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7221 REAL_VALUE_TYPE x;
7223 x = TREE_REAL_CST (arg);
7224 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7226 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7227 REAL_VALUE_TYPE r;
7229 real_floor (&r, TYPE_MODE (type), &x);
7230 return build_real (type, r);
7234 return fold_trunc_transparent_mathfn (fndecl, arglist);
7237 /* Fold function call to builtin ceil, ceilf or ceill. Return
7238 NULL_TREE if no simplification can be made. */
7240 static tree
7241 fold_builtin_ceil (tree fndecl, tree arglist)
7243 tree arg;
7245 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7246 return 0;
7248 /* Optimize ceil of constant value. */
7249 arg = TREE_VALUE (arglist);
7250 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7252 REAL_VALUE_TYPE x;
7254 x = TREE_REAL_CST (arg);
7255 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7257 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7258 REAL_VALUE_TYPE r;
7260 real_ceil (&r, TYPE_MODE (type), &x);
7261 return build_real (type, r);
7265 return fold_trunc_transparent_mathfn (fndecl, arglist);
7268 /* Fold function call to builtin round, roundf or roundl. Return
7269 NULL_TREE if no simplification can be made. */
7271 static tree
7272 fold_builtin_round (tree fndecl, tree arglist)
7274 tree arg;
7276 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7277 return 0;
7279 /* Optimize round of constant value. */
7280 arg = TREE_VALUE (arglist);
7281 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7283 REAL_VALUE_TYPE x;
7285 x = TREE_REAL_CST (arg);
7286 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7288 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7289 REAL_VALUE_TYPE r;
7291 real_round (&r, TYPE_MODE (type), &x);
7292 return build_real (type, r);
7296 return fold_trunc_transparent_mathfn (fndecl, arglist);
7299 /* Fold function call to builtin lround, lroundf or lroundl (or the
7300 corresponding long long versions) and other rounding functions.
7301 Return NULL_TREE if no simplification can be made. */
7303 static tree
7304 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7306 tree arg;
7308 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7309 return 0;
7311 /* Optimize lround of constant value. */
7312 arg = TREE_VALUE (arglist);
7313 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7315 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7317 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7319 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7320 tree ftype = TREE_TYPE (arg), result;
7321 HOST_WIDE_INT hi, lo;
7322 REAL_VALUE_TYPE r;
7324 switch (DECL_FUNCTION_CODE (fndecl))
7326 case BUILT_IN_LFLOOR:
7327 case BUILT_IN_LFLOORF:
7328 case BUILT_IN_LFLOORL:
7329 case BUILT_IN_LLFLOOR:
7330 case BUILT_IN_LLFLOORF:
7331 case BUILT_IN_LLFLOORL:
7332 real_floor (&r, TYPE_MODE (ftype), &x);
7333 break;
7335 case BUILT_IN_LCEIL:
7336 case BUILT_IN_LCEILF:
7337 case BUILT_IN_LCEILL:
7338 case BUILT_IN_LLCEIL:
7339 case BUILT_IN_LLCEILF:
7340 case BUILT_IN_LLCEILL:
7341 real_ceil (&r, TYPE_MODE (ftype), &x);
7342 break;
7344 case BUILT_IN_LROUND:
7345 case BUILT_IN_LROUNDF:
7346 case BUILT_IN_LROUNDL:
7347 case BUILT_IN_LLROUND:
7348 case BUILT_IN_LLROUNDF:
7349 case BUILT_IN_LLROUNDL:
7350 real_round (&r, TYPE_MODE (ftype), &x);
7351 break;
7353 default:
7354 gcc_unreachable ();
7357 REAL_VALUE_TO_INT (&lo, &hi, r);
7358 result = build_int_cst_wide (NULL_TREE, lo, hi);
7359 if (int_fits_type_p (result, itype))
7360 return fold_convert (itype, result);
7364 return fold_fixed_mathfn (fndecl, arglist);
7367 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7368 and their long and long long variants (i.e. ffsl and ffsll).
7369 Return NULL_TREE if no simplification can be made. */
7371 static tree
7372 fold_builtin_bitop (tree fndecl, tree arglist)
7374 tree arg;
7376 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7377 return NULL_TREE;
7379 /* Optimize for constant argument. */
7380 arg = TREE_VALUE (arglist);
7381 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7383 HOST_WIDE_INT hi, width, result;
7384 unsigned HOST_WIDE_INT lo;
7385 tree type;
7387 type = TREE_TYPE (arg);
7388 width = TYPE_PRECISION (type);
7389 lo = TREE_INT_CST_LOW (arg);
7391 /* Clear all the bits that are beyond the type's precision. */
7392 if (width > HOST_BITS_PER_WIDE_INT)
7394 hi = TREE_INT_CST_HIGH (arg);
7395 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7396 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7398 else
7400 hi = 0;
7401 if (width < HOST_BITS_PER_WIDE_INT)
7402 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7405 switch (DECL_FUNCTION_CODE (fndecl))
7407 case BUILT_IN_FFS:
7408 case BUILT_IN_FFSL:
7409 case BUILT_IN_FFSLL:
7410 if (lo != 0)
7411 result = exact_log2 (lo & -lo) + 1;
7412 else if (hi != 0)
7413 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7414 else
7415 result = 0;
7416 break;
7418 case BUILT_IN_CLZ:
7419 case BUILT_IN_CLZL:
7420 case BUILT_IN_CLZLL:
7421 if (hi != 0)
7422 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7423 else if (lo != 0)
7424 result = width - floor_log2 (lo) - 1;
7425 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7426 result = width;
7427 break;
7429 case BUILT_IN_CTZ:
7430 case BUILT_IN_CTZL:
7431 case BUILT_IN_CTZLL:
7432 if (lo != 0)
7433 result = exact_log2 (lo & -lo);
7434 else if (hi != 0)
7435 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7436 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7437 result = width;
7438 break;
7440 case BUILT_IN_POPCOUNT:
7441 case BUILT_IN_POPCOUNTL:
7442 case BUILT_IN_POPCOUNTLL:
7443 result = 0;
7444 while (lo)
7445 result++, lo &= lo - 1;
7446 while (hi)
7447 result++, hi &= hi - 1;
7448 break;
7450 case BUILT_IN_PARITY:
7451 case BUILT_IN_PARITYL:
7452 case BUILT_IN_PARITYLL:
7453 result = 0;
7454 while (lo)
7455 result++, lo &= lo - 1;
7456 while (hi)
7457 result++, hi &= hi - 1;
7458 result &= 1;
7459 break;
7461 default:
7462 gcc_unreachable ();
7465 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7468 return NULL_TREE;
7471 /* Return true if EXPR is the real constant contained in VALUE. */
7473 static bool
7474 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7476 STRIP_NOPS (expr);
7478 return ((TREE_CODE (expr) == REAL_CST
7479 && ! TREE_CONSTANT_OVERFLOW (expr)
7480 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7481 || (TREE_CODE (expr) == COMPLEX_CST
7482 && real_dconstp (TREE_REALPART (expr), value)
7483 && real_zerop (TREE_IMAGPART (expr))));
7486 /* A subroutine of fold_builtin to fold the various logarithmic
7487 functions. EXP is the CALL_EXPR of a call to a builtin logN
7488 function. VALUE is the base of the logN function. */
7490 static tree
7491 fold_builtin_logarithm (tree fndecl, tree arglist,
7492 const REAL_VALUE_TYPE *value)
7494 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7496 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7497 tree arg = TREE_VALUE (arglist);
7498 const enum built_in_function fcode = builtin_mathfn_code (arg);
7500 /* Optimize logN(1.0) = 0.0. */
7501 if (real_onep (arg))
7502 return build_real (type, dconst0);
7504 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7505 exactly, then only do this if flag_unsafe_math_optimizations. */
7506 if (exact_real_truncate (TYPE_MODE (type), value)
7507 || flag_unsafe_math_optimizations)
7509 const REAL_VALUE_TYPE value_truncate =
7510 real_value_truncate (TYPE_MODE (type), *value);
7511 if (real_dconstp (arg, &value_truncate))
7512 return build_real (type, dconst1);
7515 /* Special case, optimize logN(expN(x)) = x. */
7516 if (flag_unsafe_math_optimizations
7517 && ((value == &dconste
7518 && (fcode == BUILT_IN_EXP
7519 || fcode == BUILT_IN_EXPF
7520 || fcode == BUILT_IN_EXPL))
7521 || (value == &dconst2
7522 && (fcode == BUILT_IN_EXP2
7523 || fcode == BUILT_IN_EXP2F
7524 || fcode == BUILT_IN_EXP2L))
7525 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7526 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7528 /* Optimize logN(func()) for various exponential functions. We
7529 want to determine the value "x" and the power "exponent" in
7530 order to transform logN(x**exponent) into exponent*logN(x). */
7531 if (flag_unsafe_math_optimizations)
7533 tree exponent = 0, x = 0;
7535 switch (fcode)
7537 case BUILT_IN_EXP:
7538 case BUILT_IN_EXPF:
7539 case BUILT_IN_EXPL:
7540 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7541 x = build_real (type,
7542 real_value_truncate (TYPE_MODE (type), dconste));
7543 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7544 break;
7545 case BUILT_IN_EXP2:
7546 case BUILT_IN_EXP2F:
7547 case BUILT_IN_EXP2L:
7548 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7549 x = build_real (type, dconst2);
7550 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7551 break;
7552 case BUILT_IN_EXP10:
7553 case BUILT_IN_EXP10F:
7554 case BUILT_IN_EXP10L:
7555 case BUILT_IN_POW10:
7556 case BUILT_IN_POW10F:
7557 case BUILT_IN_POW10L:
7558 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7559 x = build_real (type, dconst10);
7560 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7561 break;
7562 case BUILT_IN_SQRT:
7563 case BUILT_IN_SQRTF:
7564 case BUILT_IN_SQRTL:
7565 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7566 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7567 exponent = build_real (type, dconsthalf);
7568 break;
7569 case BUILT_IN_CBRT:
7570 case BUILT_IN_CBRTF:
7571 case BUILT_IN_CBRTL:
7572 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7573 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7574 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7575 dconstthird));
7576 break;
7577 case BUILT_IN_POW:
7578 case BUILT_IN_POWF:
7579 case BUILT_IN_POWL:
7580 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7581 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7582 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7583 break;
7584 default:
7585 break;
7588 /* Now perform the optimization. */
7589 if (x && exponent)
7591 tree logfn;
7592 arglist = build_tree_list (NULL_TREE, x);
7593 logfn = build_function_call_expr (fndecl, arglist);
7594 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7599 return 0;
7602 /* Fold a builtin function call to pow, powf, or powl. Return
7603 NULL_TREE if no simplification can be made. */
7604 static tree
7605 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7607 tree arg0 = TREE_VALUE (arglist);
7608 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7610 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7611 return NULL_TREE;
7613 /* Optimize pow(1.0,y) = 1.0. */
7614 if (real_onep (arg0))
7615 return omit_one_operand (type, build_real (type, dconst1), arg1);
7617 if (TREE_CODE (arg1) == REAL_CST
7618 && ! TREE_CONSTANT_OVERFLOW (arg1))
7620 REAL_VALUE_TYPE cint;
7621 REAL_VALUE_TYPE c;
7622 HOST_WIDE_INT n;
7624 c = TREE_REAL_CST (arg1);
7626 /* Optimize pow(x,0.0) = 1.0. */
7627 if (REAL_VALUES_EQUAL (c, dconst0))
7628 return omit_one_operand (type, build_real (type, dconst1),
7629 arg0);
7631 /* Optimize pow(x,1.0) = x. */
7632 if (REAL_VALUES_EQUAL (c, dconst1))
7633 return arg0;
7635 /* Optimize pow(x,-1.0) = 1.0/x. */
7636 if (REAL_VALUES_EQUAL (c, dconstm1))
7637 return fold_build2 (RDIV_EXPR, type,
7638 build_real (type, dconst1), arg0);
7640 /* Optimize pow(x,0.5) = sqrt(x). */
7641 if (flag_unsafe_math_optimizations
7642 && REAL_VALUES_EQUAL (c, dconsthalf))
7644 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7646 if (sqrtfn != NULL_TREE)
7648 tree arglist = build_tree_list (NULL_TREE, arg0);
7649 return build_function_call_expr (sqrtfn, arglist);
7653 /* Check for an integer exponent. */
7654 n = real_to_integer (&c);
7655 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7656 if (real_identical (&c, &cint))
7658 /* Attempt to evaluate pow at compile-time. */
7659 if (TREE_CODE (arg0) == REAL_CST
7660 && ! TREE_CONSTANT_OVERFLOW (arg0))
7662 REAL_VALUE_TYPE x;
7663 bool inexact;
7665 x = TREE_REAL_CST (arg0);
7666 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7667 if (flag_unsafe_math_optimizations || !inexact)
7668 return build_real (type, x);
7671 /* Strip sign ops from even integer powers. */
7672 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7674 tree narg0 = fold_strip_sign_ops (arg0);
7675 if (narg0)
7677 arglist = build_tree_list (NULL_TREE, arg1);
7678 arglist = tree_cons (NULL_TREE, narg0, arglist);
7679 return build_function_call_expr (fndecl, arglist);
7685 if (flag_unsafe_math_optimizations)
7687 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7689 /* Optimize pow(expN(x),y) = expN(x*y). */
7690 if (BUILTIN_EXPONENT_P (fcode))
7692 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7693 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7694 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7695 arglist = build_tree_list (NULL_TREE, arg);
7696 return build_function_call_expr (expfn, arglist);
7699 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7700 if (BUILTIN_SQRT_P (fcode))
7702 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7703 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7704 build_real (type, dconsthalf));
7706 arglist = tree_cons (NULL_TREE, narg0,
7707 build_tree_list (NULL_TREE, narg1));
7708 return build_function_call_expr (fndecl, arglist);
7711 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7712 if (BUILTIN_CBRT_P (fcode))
7714 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7715 if (tree_expr_nonnegative_p (arg))
7717 const REAL_VALUE_TYPE dconstroot
7718 = real_value_truncate (TYPE_MODE (type), dconstthird);
7719 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7720 build_real (type, dconstroot));
7721 arglist = tree_cons (NULL_TREE, arg,
7722 build_tree_list (NULL_TREE, narg1));
7723 return build_function_call_expr (fndecl, arglist);
7727 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7728 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7729 || fcode == BUILT_IN_POWL)
7731 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7732 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7733 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7734 arglist = tree_cons (NULL_TREE, arg00,
7735 build_tree_list (NULL_TREE, narg1));
7736 return build_function_call_expr (fndecl, arglist);
7740 return NULL_TREE;
7743 /* Fold a builtin function call to powi, powif, or powil. Return
7744 NULL_TREE if no simplification can be made. */
7745 static tree
7746 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7748 tree arg0 = TREE_VALUE (arglist);
7749 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7751 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7752 return NULL_TREE;
7754 /* Optimize pow(1.0,y) = 1.0. */
7755 if (real_onep (arg0))
7756 return omit_one_operand (type, build_real (type, dconst1), arg1);
7758 if (host_integerp (arg1, 0))
7760 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7762 /* Evaluate powi at compile-time. */
7763 if (TREE_CODE (arg0) == REAL_CST
7764 && ! TREE_CONSTANT_OVERFLOW (arg0))
7766 REAL_VALUE_TYPE x;
7767 x = TREE_REAL_CST (arg0);
7768 real_powi (&x, TYPE_MODE (type), &x, c);
7769 return build_real (type, x);
7772 /* Optimize pow(x,0) = 1.0. */
7773 if (c == 0)
7774 return omit_one_operand (type, build_real (type, dconst1),
7775 arg0);
7777 /* Optimize pow(x,1) = x. */
7778 if (c == 1)
7779 return arg0;
7781 /* Optimize pow(x,-1) = 1.0/x. */
7782 if (c == -1)
7783 return fold_build2 (RDIV_EXPR, type,
7784 build_real (type, dconst1), arg0);
7787 return NULL_TREE;
7790 /* A subroutine of fold_builtin to fold the various exponent
7791 functions. EXP is the CALL_EXPR of a call to a builtin function.
7792 VALUE is the value which will be raised to a power. */
7794 static tree
7795 fold_builtin_exponent (tree fndecl, tree arglist,
7796 const REAL_VALUE_TYPE *value)
7798 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7800 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7801 tree arg = TREE_VALUE (arglist);
7803 /* Optimize exp*(0.0) = 1.0. */
7804 if (real_zerop (arg))
7805 return build_real (type, dconst1);
7807 /* Optimize expN(1.0) = N. */
7808 if (real_onep (arg))
7810 REAL_VALUE_TYPE cst;
7812 real_convert (&cst, TYPE_MODE (type), value);
7813 return build_real (type, cst);
7816 /* Attempt to evaluate expN(integer) at compile-time. */
7817 if (flag_unsafe_math_optimizations
7818 && TREE_CODE (arg) == REAL_CST
7819 && ! TREE_CONSTANT_OVERFLOW (arg))
7821 REAL_VALUE_TYPE cint;
7822 REAL_VALUE_TYPE c;
7823 HOST_WIDE_INT n;
7825 c = TREE_REAL_CST (arg);
7826 n = real_to_integer (&c);
7827 real_from_integer (&cint, VOIDmode, n,
7828 n < 0 ? -1 : 0, 0);
7829 if (real_identical (&c, &cint))
7831 REAL_VALUE_TYPE x;
7833 real_powi (&x, TYPE_MODE (type), value, n);
7834 return build_real (type, x);
7838 /* Optimize expN(logN(x)) = x. */
7839 if (flag_unsafe_math_optimizations)
7841 const enum built_in_function fcode = builtin_mathfn_code (arg);
7843 if ((value == &dconste
7844 && (fcode == BUILT_IN_LOG
7845 || fcode == BUILT_IN_LOGF
7846 || fcode == BUILT_IN_LOGL))
7847 || (value == &dconst2
7848 && (fcode == BUILT_IN_LOG2
7849 || fcode == BUILT_IN_LOG2F
7850 || fcode == BUILT_IN_LOG2L))
7851 || (value == &dconst10
7852 && (fcode == BUILT_IN_LOG10
7853 || fcode == BUILT_IN_LOG10F
7854 || fcode == BUILT_IN_LOG10L)))
7855 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7859 return 0;
7862 /* Fold function call to builtin memcpy. Return
7863 NULL_TREE if no simplification can be made. */
7865 static tree
7866 fold_builtin_memcpy (tree fndecl, tree arglist)
7868 tree dest, src, len;
7870 if (!validate_arglist (arglist,
7871 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7872 return 0;
7874 dest = TREE_VALUE (arglist);
7875 src = TREE_VALUE (TREE_CHAIN (arglist));
7876 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7878 /* If the LEN parameter is zero, return DEST. */
7879 if (integer_zerop (len))
7880 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7882 /* If SRC and DEST are the same (and not volatile), return DEST. */
7883 if (operand_equal_p (src, dest, 0))
7884 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7886 return 0;
7889 /* Fold function call to builtin mempcpy. Return
7890 NULL_TREE if no simplification can be made. */
7892 static tree
7893 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7895 if (validate_arglist (arglist,
7896 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7898 tree dest = TREE_VALUE (arglist);
7899 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7900 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7902 /* If the LEN parameter is zero, return DEST. */
7903 if (integer_zerop (len))
7904 return omit_one_operand (type, dest, src);
7906 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7907 if (operand_equal_p (src, dest, 0))
7909 if (endp == 0)
7910 return omit_one_operand (type, dest, len);
7912 if (endp == 2)
7913 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7914 ssize_int (1));
7916 len = fold_convert (TREE_TYPE (dest), len);
7917 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7918 return fold_convert (type, len);
7921 return 0;
7924 /* Fold function call to builtin memmove. Return
7925 NULL_TREE if no simplification can be made. */
7927 static tree
7928 fold_builtin_memmove (tree arglist, tree type)
7930 tree dest, src, len;
7932 if (!validate_arglist (arglist,
7933 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7934 return 0;
7936 dest = TREE_VALUE (arglist);
7937 src = TREE_VALUE (TREE_CHAIN (arglist));
7938 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7940 /* If the LEN parameter is zero, return DEST. */
7941 if (integer_zerop (len))
7942 return omit_one_operand (type, dest, src);
7944 /* If SRC and DEST are the same (and not volatile), return DEST. */
7945 if (operand_equal_p (src, dest, 0))
7946 return omit_one_operand (type, dest, len);
7948 return 0;
7951 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7952 the length of the string to be copied. Return NULL_TREE if no
7953 simplification can be made. */
7955 tree
7956 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7958 tree dest, src, fn;
7960 if (!validate_arglist (arglist,
7961 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7962 return 0;
7964 dest = TREE_VALUE (arglist);
7965 src = TREE_VALUE (TREE_CHAIN (arglist));
7967 /* If SRC and DEST are the same (and not volatile), return DEST. */
7968 if (operand_equal_p (src, dest, 0))
7969 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7971 if (optimize_size)
7972 return 0;
7974 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7975 if (!fn)
7976 return 0;
7978 if (!len)
7980 len = c_strlen (src, 1);
7981 if (! len || TREE_SIDE_EFFECTS (len))
7982 return 0;
7985 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7986 arglist = build_tree_list (NULL_TREE, len);
7987 arglist = tree_cons (NULL_TREE, src, arglist);
7988 arglist = tree_cons (NULL_TREE, dest, arglist);
7989 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7990 build_function_call_expr (fn, arglist));
7993 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7994 the length of the source string. Return NULL_TREE if no simplification
7995 can be made. */
7997 tree
7998 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8000 tree dest, src, len, fn;
8002 if (!validate_arglist (arglist,
8003 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8004 return 0;
8006 dest = TREE_VALUE (arglist);
8007 src = TREE_VALUE (TREE_CHAIN (arglist));
8008 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8010 /* If the LEN parameter is zero, return DEST. */
8011 if (integer_zerop (len))
8012 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8014 /* We can't compare slen with len as constants below if len is not a
8015 constant. */
8016 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8017 return 0;
8019 if (!slen)
8020 slen = c_strlen (src, 1);
8022 /* Now, we must be passed a constant src ptr parameter. */
8023 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8024 return 0;
8026 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8028 /* We do not support simplification of this case, though we do
8029 support it when expanding trees into RTL. */
8030 /* FIXME: generate a call to __builtin_memset. */
8031 if (tree_int_cst_lt (slen, len))
8032 return 0;
8034 /* OK transform into builtin memcpy. */
8035 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8036 if (!fn)
8037 return 0;
8038 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8039 build_function_call_expr (fn, arglist));
8042 /* Fold function call to builtin memcmp. Return
8043 NULL_TREE if no simplification can be made. */
8045 static tree
8046 fold_builtin_memcmp (tree arglist)
8048 tree arg1, arg2, len;
8049 const char *p1, *p2;
8051 if (!validate_arglist (arglist,
8052 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8053 return 0;
8055 arg1 = TREE_VALUE (arglist);
8056 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8057 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8059 /* If the LEN parameter is zero, return zero. */
8060 if (integer_zerop (len))
8061 return omit_two_operands (integer_type_node, integer_zero_node,
8062 arg1, arg2);
8064 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8065 if (operand_equal_p (arg1, arg2, 0))
8066 return omit_one_operand (integer_type_node, integer_zero_node, len);
8068 p1 = c_getstr (arg1);
8069 p2 = c_getstr (arg2);
8071 /* If all arguments are constant, and the value of len is not greater
8072 than the lengths of arg1 and arg2, evaluate at compile-time. */
8073 if (host_integerp (len, 1) && p1 && p2
8074 && compare_tree_int (len, strlen (p1) + 1) <= 0
8075 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8077 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8079 if (r > 0)
8080 return integer_one_node;
8081 else if (r < 0)
8082 return integer_minus_one_node;
8083 else
8084 return integer_zero_node;
8087 /* If len parameter is one, return an expression corresponding to
8088 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8089 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8091 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8092 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8093 tree ind1 = fold_convert (integer_type_node,
8094 build1 (INDIRECT_REF, cst_uchar_node,
8095 fold_convert (cst_uchar_ptr_node,
8096 arg1)));
8097 tree ind2 = fold_convert (integer_type_node,
8098 build1 (INDIRECT_REF, cst_uchar_node,
8099 fold_convert (cst_uchar_ptr_node,
8100 arg2)));
8101 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8104 return 0;
8107 /* Fold function call to builtin strcmp. Return
8108 NULL_TREE if no simplification can be made. */
8110 static tree
8111 fold_builtin_strcmp (tree arglist)
8113 tree arg1, arg2;
8114 const char *p1, *p2;
8116 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8117 return 0;
8119 arg1 = TREE_VALUE (arglist);
8120 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8122 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8123 if (operand_equal_p (arg1, arg2, 0))
8124 return integer_zero_node;
8126 p1 = c_getstr (arg1);
8127 p2 = c_getstr (arg2);
8129 if (p1 && p2)
8131 const int i = strcmp (p1, p2);
8132 if (i < 0)
8133 return integer_minus_one_node;
8134 else if (i > 0)
8135 return integer_one_node;
8136 else
8137 return integer_zero_node;
8140 /* If the second arg is "", return *(const unsigned char*)arg1. */
8141 if (p2 && *p2 == '\0')
8143 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8144 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8145 return fold_convert (integer_type_node,
8146 build1 (INDIRECT_REF, cst_uchar_node,
8147 fold_convert (cst_uchar_ptr_node,
8148 arg1)));
8151 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8152 if (p1 && *p1 == '\0')
8154 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8155 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8156 tree temp = fold_convert (integer_type_node,
8157 build1 (INDIRECT_REF, cst_uchar_node,
8158 fold_convert (cst_uchar_ptr_node,
8159 arg2)));
8160 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8163 return 0;
8166 /* Fold function call to builtin strncmp. Return
8167 NULL_TREE if no simplification can be made. */
8169 static tree
8170 fold_builtin_strncmp (tree arglist)
8172 tree arg1, arg2, len;
8173 const char *p1, *p2;
8175 if (!validate_arglist (arglist,
8176 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8177 return 0;
8179 arg1 = TREE_VALUE (arglist);
8180 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8181 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8183 /* If the LEN parameter is zero, return zero. */
8184 if (integer_zerop (len))
8185 return omit_two_operands (integer_type_node, integer_zero_node,
8186 arg1, arg2);
8188 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8189 if (operand_equal_p (arg1, arg2, 0))
8190 return omit_one_operand (integer_type_node, integer_zero_node, len);
8192 p1 = c_getstr (arg1);
8193 p2 = c_getstr (arg2);
8195 if (host_integerp (len, 1) && p1 && p2)
8197 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8198 if (i > 0)
8199 return integer_one_node;
8200 else if (i < 0)
8201 return integer_minus_one_node;
8202 else
8203 return integer_zero_node;
8206 /* If the second arg is "", and the length is greater than zero,
8207 return *(const unsigned char*)arg1. */
8208 if (p2 && *p2 == '\0'
8209 && TREE_CODE (len) == INTEGER_CST
8210 && tree_int_cst_sgn (len) == 1)
8212 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8213 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8214 return fold_convert (integer_type_node,
8215 build1 (INDIRECT_REF, cst_uchar_node,
8216 fold_convert (cst_uchar_ptr_node,
8217 arg1)));
8220 /* If the first arg is "", and the length is greater than zero,
8221 return -*(const unsigned char*)arg2. */
8222 if (p1 && *p1 == '\0'
8223 && TREE_CODE (len) == INTEGER_CST
8224 && tree_int_cst_sgn (len) == 1)
8226 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8227 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8228 tree temp = fold_convert (integer_type_node,
8229 build1 (INDIRECT_REF, cst_uchar_node,
8230 fold_convert (cst_uchar_ptr_node,
8231 arg2)));
8232 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8235 /* If len parameter is one, return an expression corresponding to
8236 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8237 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8239 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8240 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8241 tree ind1 = fold_convert (integer_type_node,
8242 build1 (INDIRECT_REF, cst_uchar_node,
8243 fold_convert (cst_uchar_ptr_node,
8244 arg1)));
8245 tree ind2 = fold_convert (integer_type_node,
8246 build1 (INDIRECT_REF, cst_uchar_node,
8247 fold_convert (cst_uchar_ptr_node,
8248 arg2)));
8249 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8252 return 0;
8255 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8256 NULL_TREE if no simplification can be made. */
8258 static tree
8259 fold_builtin_signbit (tree fndecl, tree arglist)
8261 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8262 tree arg, temp;
8264 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8265 return NULL_TREE;
8267 arg = TREE_VALUE (arglist);
8269 /* If ARG is a compile-time constant, determine the result. */
8270 if (TREE_CODE (arg) == REAL_CST
8271 && !TREE_CONSTANT_OVERFLOW (arg))
8273 REAL_VALUE_TYPE c;
8275 c = TREE_REAL_CST (arg);
8276 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8277 return fold_convert (type, temp);
8280 /* If ARG is non-negative, the result is always zero. */
8281 if (tree_expr_nonnegative_p (arg))
8282 return omit_one_operand (type, integer_zero_node, arg);
8284 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8285 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8286 return fold_build2 (LT_EXPR, type, arg,
8287 build_real (TREE_TYPE (arg), dconst0));
8289 return NULL_TREE;
8292 /* Fold function call to builtin copysign, copysignf or copysignl.
8293 Return NULL_TREE if no simplification can be made. */
8295 static tree
8296 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8298 tree arg1, arg2, tem;
8300 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8301 return NULL_TREE;
8303 arg1 = TREE_VALUE (arglist);
8304 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8306 /* copysign(X,X) is X. */
8307 if (operand_equal_p (arg1, arg2, 0))
8308 return fold_convert (type, arg1);
8310 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8311 if (TREE_CODE (arg1) == REAL_CST
8312 && TREE_CODE (arg2) == REAL_CST
8313 && !TREE_CONSTANT_OVERFLOW (arg1)
8314 && !TREE_CONSTANT_OVERFLOW (arg2))
8316 REAL_VALUE_TYPE c1, c2;
8318 c1 = TREE_REAL_CST (arg1);
8319 c2 = TREE_REAL_CST (arg2);
8320 real_copysign (&c1, &c2);
8321 return build_real (type, c1);
8322 c1.sign = c2.sign;
8325 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8326 Remember to evaluate Y for side-effects. */
8327 if (tree_expr_nonnegative_p (arg2))
8328 return omit_one_operand (type,
8329 fold_build1 (ABS_EXPR, type, arg1),
8330 arg2);
8332 /* Strip sign changing operations for the first argument. */
8333 tem = fold_strip_sign_ops (arg1);
8334 if (tem)
8336 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8337 return build_function_call_expr (fndecl, arglist);
8340 return NULL_TREE;
8343 /* Fold a call to builtin isascii. */
8345 static tree
8346 fold_builtin_isascii (tree arglist)
8348 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8349 return 0;
8350 else
8352 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8353 tree arg = TREE_VALUE (arglist);
8355 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8356 build_int_cst (NULL_TREE,
8357 ~ (unsigned HOST_WIDE_INT) 0x7f));
8358 arg = fold_build2 (EQ_EXPR, integer_type_node,
8359 arg, integer_zero_node);
8361 if (in_gimple_form && !TREE_CONSTANT (arg))
8362 return NULL_TREE;
8363 else
8364 return arg;
8368 /* Fold a call to builtin toascii. */
8370 static tree
8371 fold_builtin_toascii (tree arglist)
8373 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8374 return 0;
8375 else
8377 /* Transform toascii(c) -> (c & 0x7f). */
8378 tree arg = TREE_VALUE (arglist);
8380 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8381 build_int_cst (NULL_TREE, 0x7f));
8385 /* Fold a call to builtin isdigit. */
8387 static tree
8388 fold_builtin_isdigit (tree arglist)
8390 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8391 return 0;
8392 else
8394 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8395 /* According to the C standard, isdigit is unaffected by locale.
8396 However, it definitely is affected by the target character set. */
8397 tree arg;
8398 unsigned HOST_WIDE_INT target_digit0
8399 = lang_hooks.to_target_charset ('0');
8401 if (target_digit0 == 0)
8402 return NULL_TREE;
8404 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8405 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8406 build_int_cst (unsigned_type_node, target_digit0));
8407 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8408 build_int_cst (unsigned_type_node, 9));
8409 if (in_gimple_form && !TREE_CONSTANT (arg))
8410 return NULL_TREE;
8411 else
8412 return arg;
8416 /* Fold a call to fabs, fabsf or fabsl. */
8418 static tree
8419 fold_builtin_fabs (tree arglist, tree type)
8421 tree arg;
8423 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8424 return 0;
8426 arg = TREE_VALUE (arglist);
8427 arg = fold_convert (type, arg);
8428 if (TREE_CODE (arg) == REAL_CST)
8429 return fold_abs_const (arg, type);
8430 return fold_build1 (ABS_EXPR, type, arg);
8433 /* Fold a call to abs, labs, llabs or imaxabs. */
8435 static tree
8436 fold_builtin_abs (tree arglist, tree type)
8438 tree arg;
8440 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8441 return 0;
8443 arg = TREE_VALUE (arglist);
8444 arg = fold_convert (type, arg);
8445 if (TREE_CODE (arg) == INTEGER_CST)
8446 return fold_abs_const (arg, type);
8447 return fold_build1 (ABS_EXPR, type, arg);
8450 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8451 EXP is the CALL_EXPR for the call. */
8453 static tree
8454 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8456 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8457 tree arg;
8458 REAL_VALUE_TYPE r;
8460 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8462 /* Check that we have exactly one argument. */
8463 if (arglist == 0)
8465 error ("too few arguments to function %qs",
8466 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8467 return error_mark_node;
8469 else if (TREE_CHAIN (arglist) != 0)
8471 error ("too many arguments to function %qs",
8472 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8473 return error_mark_node;
8475 else
8477 error ("non-floating-point argument to function %qs",
8478 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8479 return error_mark_node;
8483 arg = TREE_VALUE (arglist);
8484 switch (builtin_index)
8486 case BUILT_IN_ISINF:
8487 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8488 return omit_one_operand (type, integer_zero_node, arg);
8490 if (TREE_CODE (arg) == REAL_CST)
8492 r = TREE_REAL_CST (arg);
8493 if (real_isinf (&r))
8494 return real_compare (GT_EXPR, &r, &dconst0)
8495 ? integer_one_node : integer_minus_one_node;
8496 else
8497 return integer_zero_node;
8500 return NULL_TREE;
8502 case BUILT_IN_FINITE:
8503 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8504 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8505 return omit_one_operand (type, integer_zero_node, arg);
8507 if (TREE_CODE (arg) == REAL_CST)
8509 r = TREE_REAL_CST (arg);
8510 return real_isinf (&r) || real_isnan (&r)
8511 ? integer_zero_node : integer_one_node;
8514 return NULL_TREE;
8516 case BUILT_IN_ISNAN:
8517 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8518 return omit_one_operand (type, integer_zero_node, arg);
8520 if (TREE_CODE (arg) == REAL_CST)
8522 r = TREE_REAL_CST (arg);
8523 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8526 arg = builtin_save_expr (arg);
8527 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8529 default:
8530 gcc_unreachable ();
8534 /* Fold a call to an unordered comparison function such as
8535 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8536 being called and ARGLIST is the argument list for the call.
8537 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8538 the opposite of the desired result. UNORDERED_CODE is used
8539 for modes that can hold NaNs and ORDERED_CODE is used for
8540 the rest. */
8542 static tree
8543 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8544 enum tree_code unordered_code,
8545 enum tree_code ordered_code)
8547 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8548 enum tree_code code;
8549 tree arg0, arg1;
8550 tree type0, type1;
8551 enum tree_code code0, code1;
8552 tree cmp_type = NULL_TREE;
8554 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8556 /* Check that we have exactly two arguments. */
8557 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8559 error ("too few arguments to function %qs",
8560 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8561 return error_mark_node;
8563 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8565 error ("too many arguments to function %qs",
8566 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8567 return error_mark_node;
8571 arg0 = TREE_VALUE (arglist);
8572 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8574 type0 = TREE_TYPE (arg0);
8575 type1 = TREE_TYPE (arg1);
8577 code0 = TREE_CODE (type0);
8578 code1 = TREE_CODE (type1);
8580 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8581 /* Choose the wider of two real types. */
8582 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8583 ? type0 : type1;
8584 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8585 cmp_type = type0;
8586 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8587 cmp_type = type1;
8588 else
8590 error ("non-floating-point argument to function %qs",
8591 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8592 return error_mark_node;
8595 arg0 = fold_convert (cmp_type, arg0);
8596 arg1 = fold_convert (cmp_type, arg1);
8598 if (unordered_code == UNORDERED_EXPR)
8600 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8601 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8602 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8605 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8606 : ordered_code;
8607 return fold_build1 (TRUTH_NOT_EXPR, type,
8608 fold_build2 (code, type, arg0, arg1));
8611 /* Used by constant folding to simplify calls to builtin functions. EXP is
8612 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8613 result of the function call is ignored. This function returns NULL_TREE
8614 if no simplification was possible. */
8616 static tree
8617 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8619 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8620 enum built_in_function fcode;
8622 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8623 return targetm.fold_builtin (fndecl, arglist, ignore);
8625 fcode = DECL_FUNCTION_CODE (fndecl);
8626 switch (fcode)
8628 case BUILT_IN_FPUTS:
8629 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8631 case BUILT_IN_FPUTS_UNLOCKED:
8632 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8634 case BUILT_IN_STRSTR:
8635 return fold_builtin_strstr (arglist, type);
8637 case BUILT_IN_STRCAT:
8638 return fold_builtin_strcat (arglist);
8640 case BUILT_IN_STRNCAT:
8641 return fold_builtin_strncat (arglist);
8643 case BUILT_IN_STRSPN:
8644 return fold_builtin_strspn (arglist);
8646 case BUILT_IN_STRCSPN:
8647 return fold_builtin_strcspn (arglist);
8649 case BUILT_IN_STRCHR:
8650 case BUILT_IN_INDEX:
8651 return fold_builtin_strchr (arglist, type);
8653 case BUILT_IN_STRRCHR:
8654 case BUILT_IN_RINDEX:
8655 return fold_builtin_strrchr (arglist, type);
8657 case BUILT_IN_STRCPY:
8658 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8660 case BUILT_IN_STRNCPY:
8661 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8663 case BUILT_IN_STRCMP:
8664 return fold_builtin_strcmp (arglist);
8666 case BUILT_IN_STRNCMP:
8667 return fold_builtin_strncmp (arglist);
8669 case BUILT_IN_STRPBRK:
8670 return fold_builtin_strpbrk (arglist, type);
8672 case BUILT_IN_BCMP:
8673 case BUILT_IN_MEMCMP:
8674 return fold_builtin_memcmp (arglist);
8676 case BUILT_IN_SPRINTF:
8677 return fold_builtin_sprintf (arglist, ignore);
8679 case BUILT_IN_CONSTANT_P:
8681 tree val;
8683 val = fold_builtin_constant_p (arglist);
8684 /* Gimplification will pull the CALL_EXPR for the builtin out of
8685 an if condition. When not optimizing, we'll not CSE it back.
8686 To avoid link error types of regressions, return false now. */
8687 if (!val && !optimize)
8688 val = integer_zero_node;
8690 return val;
8693 case BUILT_IN_EXPECT:
8694 return fold_builtin_expect (arglist);
8696 case BUILT_IN_CLASSIFY_TYPE:
8697 return fold_builtin_classify_type (arglist);
8699 case BUILT_IN_STRLEN:
8700 return fold_builtin_strlen (arglist);
8702 case BUILT_IN_FABS:
8703 case BUILT_IN_FABSF:
8704 case BUILT_IN_FABSL:
8705 return fold_builtin_fabs (arglist, type);
8707 case BUILT_IN_ABS:
8708 case BUILT_IN_LABS:
8709 case BUILT_IN_LLABS:
8710 case BUILT_IN_IMAXABS:
8711 return fold_builtin_abs (arglist, type);
8713 case BUILT_IN_CONJ:
8714 case BUILT_IN_CONJF:
8715 case BUILT_IN_CONJL:
8716 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8717 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8718 break;
8720 case BUILT_IN_CREAL:
8721 case BUILT_IN_CREALF:
8722 case BUILT_IN_CREALL:
8723 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8724 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8725 TREE_VALUE (arglist)));
8726 break;
8728 case BUILT_IN_CIMAG:
8729 case BUILT_IN_CIMAGF:
8730 case BUILT_IN_CIMAGL:
8731 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8732 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8733 TREE_VALUE (arglist)));
8734 break;
8736 case BUILT_IN_CABS:
8737 case BUILT_IN_CABSF:
8738 case BUILT_IN_CABSL:
8739 return fold_builtin_cabs (arglist, type);
8741 case BUILT_IN_SQRT:
8742 case BUILT_IN_SQRTF:
8743 case BUILT_IN_SQRTL:
8744 return fold_builtin_sqrt (arglist, type);
8746 case BUILT_IN_CBRT:
8747 case BUILT_IN_CBRTF:
8748 case BUILT_IN_CBRTL:
8749 return fold_builtin_cbrt (arglist, type);
8751 case BUILT_IN_SIN:
8752 case BUILT_IN_SINF:
8753 case BUILT_IN_SINL:
8754 return fold_builtin_sin (arglist);
8756 case BUILT_IN_COS:
8757 case BUILT_IN_COSF:
8758 case BUILT_IN_COSL:
8759 return fold_builtin_cos (arglist, type, fndecl);
8761 case BUILT_IN_EXP:
8762 case BUILT_IN_EXPF:
8763 case BUILT_IN_EXPL:
8764 return fold_builtin_exponent (fndecl, arglist, &dconste);
8766 case BUILT_IN_EXP2:
8767 case BUILT_IN_EXP2F:
8768 case BUILT_IN_EXP2L:
8769 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8771 case BUILT_IN_EXP10:
8772 case BUILT_IN_EXP10F:
8773 case BUILT_IN_EXP10L:
8774 case BUILT_IN_POW10:
8775 case BUILT_IN_POW10F:
8776 case BUILT_IN_POW10L:
8777 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8779 case BUILT_IN_LOG:
8780 case BUILT_IN_LOGF:
8781 case BUILT_IN_LOGL:
8782 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8784 case BUILT_IN_LOG2:
8785 case BUILT_IN_LOG2F:
8786 case BUILT_IN_LOG2L:
8787 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8789 case BUILT_IN_LOG10:
8790 case BUILT_IN_LOG10F:
8791 case BUILT_IN_LOG10L:
8792 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8794 case BUILT_IN_TAN:
8795 case BUILT_IN_TANF:
8796 case BUILT_IN_TANL:
8797 return fold_builtin_tan (arglist);
8799 case BUILT_IN_ATAN:
8800 case BUILT_IN_ATANF:
8801 case BUILT_IN_ATANL:
8802 return fold_builtin_atan (arglist, type);
8804 case BUILT_IN_POW:
8805 case BUILT_IN_POWF:
8806 case BUILT_IN_POWL:
8807 return fold_builtin_pow (fndecl, arglist, type);
8809 case BUILT_IN_POWI:
8810 case BUILT_IN_POWIF:
8811 case BUILT_IN_POWIL:
8812 return fold_builtin_powi (fndecl, arglist, type);
8814 case BUILT_IN_INF:
8815 case BUILT_IN_INFF:
8816 case BUILT_IN_INFL:
8817 return fold_builtin_inf (type, true);
8819 case BUILT_IN_HUGE_VAL:
8820 case BUILT_IN_HUGE_VALF:
8821 case BUILT_IN_HUGE_VALL:
8822 return fold_builtin_inf (type, false);
8824 case BUILT_IN_NAN:
8825 case BUILT_IN_NANF:
8826 case BUILT_IN_NANL:
8827 return fold_builtin_nan (arglist, type, true);
8829 case BUILT_IN_NANS:
8830 case BUILT_IN_NANSF:
8831 case BUILT_IN_NANSL:
8832 return fold_builtin_nan (arglist, type, false);
8834 case BUILT_IN_FLOOR:
8835 case BUILT_IN_FLOORF:
8836 case BUILT_IN_FLOORL:
8837 return fold_builtin_floor (fndecl, arglist);
8839 case BUILT_IN_CEIL:
8840 case BUILT_IN_CEILF:
8841 case BUILT_IN_CEILL:
8842 return fold_builtin_ceil (fndecl, arglist);
8844 case BUILT_IN_TRUNC:
8845 case BUILT_IN_TRUNCF:
8846 case BUILT_IN_TRUNCL:
8847 return fold_builtin_trunc (fndecl, arglist);
8849 case BUILT_IN_ROUND:
8850 case BUILT_IN_ROUNDF:
8851 case BUILT_IN_ROUNDL:
8852 return fold_builtin_round (fndecl, arglist);
8854 case BUILT_IN_NEARBYINT:
8855 case BUILT_IN_NEARBYINTF:
8856 case BUILT_IN_NEARBYINTL:
8857 case BUILT_IN_RINT:
8858 case BUILT_IN_RINTF:
8859 case BUILT_IN_RINTL:
8860 return fold_trunc_transparent_mathfn (fndecl, arglist);
8862 case BUILT_IN_LCEIL:
8863 case BUILT_IN_LCEILF:
8864 case BUILT_IN_LCEILL:
8865 case BUILT_IN_LLCEIL:
8866 case BUILT_IN_LLCEILF:
8867 case BUILT_IN_LLCEILL:
8868 case BUILT_IN_LFLOOR:
8869 case BUILT_IN_LFLOORF:
8870 case BUILT_IN_LFLOORL:
8871 case BUILT_IN_LLFLOOR:
8872 case BUILT_IN_LLFLOORF:
8873 case BUILT_IN_LLFLOORL:
8874 case BUILT_IN_LROUND:
8875 case BUILT_IN_LROUNDF:
8876 case BUILT_IN_LROUNDL:
8877 case BUILT_IN_LLROUND:
8878 case BUILT_IN_LLROUNDF:
8879 case BUILT_IN_LLROUNDL:
8880 return fold_builtin_int_roundingfn (fndecl, arglist);
8882 case BUILT_IN_LRINT:
8883 case BUILT_IN_LRINTF:
8884 case BUILT_IN_LRINTL:
8885 case BUILT_IN_LLRINT:
8886 case BUILT_IN_LLRINTF:
8887 case BUILT_IN_LLRINTL:
8888 return fold_fixed_mathfn (fndecl, arglist);
8890 case BUILT_IN_FFS:
8891 case BUILT_IN_FFSL:
8892 case BUILT_IN_FFSLL:
8893 case BUILT_IN_CLZ:
8894 case BUILT_IN_CLZL:
8895 case BUILT_IN_CLZLL:
8896 case BUILT_IN_CTZ:
8897 case BUILT_IN_CTZL:
8898 case BUILT_IN_CTZLL:
8899 case BUILT_IN_POPCOUNT:
8900 case BUILT_IN_POPCOUNTL:
8901 case BUILT_IN_POPCOUNTLL:
8902 case BUILT_IN_PARITY:
8903 case BUILT_IN_PARITYL:
8904 case BUILT_IN_PARITYLL:
8905 return fold_builtin_bitop (fndecl, arglist);
8907 case BUILT_IN_MEMCPY:
8908 return fold_builtin_memcpy (fndecl, arglist);
8910 case BUILT_IN_MEMPCPY:
8911 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8913 case BUILT_IN_MEMMOVE:
8914 return fold_builtin_memmove (arglist, type);
8916 case BUILT_IN_SIGNBIT:
8917 case BUILT_IN_SIGNBITF:
8918 case BUILT_IN_SIGNBITL:
8919 return fold_builtin_signbit (fndecl, arglist);
8921 case BUILT_IN_ISASCII:
8922 return fold_builtin_isascii (arglist);
8924 case BUILT_IN_TOASCII:
8925 return fold_builtin_toascii (arglist);
8927 case BUILT_IN_ISDIGIT:
8928 return fold_builtin_isdigit (arglist);
8930 case BUILT_IN_COPYSIGN:
8931 case BUILT_IN_COPYSIGNF:
8932 case BUILT_IN_COPYSIGNL:
8933 return fold_builtin_copysign (fndecl, arglist, type);
8935 case BUILT_IN_FINITE:
8936 case BUILT_IN_FINITEF:
8937 case BUILT_IN_FINITEL:
8938 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8940 case BUILT_IN_ISINF:
8941 case BUILT_IN_ISINFF:
8942 case BUILT_IN_ISINFL:
8943 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8945 case BUILT_IN_ISNAN:
8946 case BUILT_IN_ISNANF:
8947 case BUILT_IN_ISNANL:
8948 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8950 case BUILT_IN_ISGREATER:
8951 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8952 case BUILT_IN_ISGREATEREQUAL:
8953 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8954 case BUILT_IN_ISLESS:
8955 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8956 case BUILT_IN_ISLESSEQUAL:
8957 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8958 case BUILT_IN_ISLESSGREATER:
8959 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8960 case BUILT_IN_ISUNORDERED:
8961 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8962 NOP_EXPR);
8964 /* We do the folding for va_start in the expander. */
8965 case BUILT_IN_VA_START:
8966 break;
8968 case BUILT_IN_OBJECT_SIZE:
8969 return fold_builtin_object_size (arglist);
8970 case BUILT_IN_MEMCPY_CHK:
8971 case BUILT_IN_MEMPCPY_CHK:
8972 case BUILT_IN_MEMMOVE_CHK:
8973 case BUILT_IN_MEMSET_CHK:
8974 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8975 DECL_FUNCTION_CODE (fndecl));
8976 case BUILT_IN_STRCPY_CHK:
8977 case BUILT_IN_STPCPY_CHK:
8978 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8979 DECL_FUNCTION_CODE (fndecl));
8980 case BUILT_IN_STRNCPY_CHK:
8981 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8982 case BUILT_IN_STRCAT_CHK:
8983 return fold_builtin_strcat_chk (fndecl, arglist);
8984 case BUILT_IN_STRNCAT_CHK:
8985 return fold_builtin_strncat_chk (fndecl, arglist);
8986 case BUILT_IN_SPRINTF_CHK:
8987 case BUILT_IN_VSPRINTF_CHK:
8988 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8989 case BUILT_IN_SNPRINTF_CHK:
8990 case BUILT_IN_VSNPRINTF_CHK:
8991 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8992 DECL_FUNCTION_CODE (fndecl));
8994 case BUILT_IN_PRINTF:
8995 case BUILT_IN_PRINTF_UNLOCKED:
8996 case BUILT_IN_VPRINTF:
8997 case BUILT_IN_PRINTF_CHK:
8998 case BUILT_IN_VPRINTF_CHK:
8999 return fold_builtin_printf (fndecl, arglist, ignore,
9000 DECL_FUNCTION_CODE (fndecl));
9002 case BUILT_IN_FPRINTF:
9003 case BUILT_IN_FPRINTF_UNLOCKED:
9004 case BUILT_IN_VFPRINTF:
9005 case BUILT_IN_FPRINTF_CHK:
9006 case BUILT_IN_VFPRINTF_CHK:
9007 return fold_builtin_fprintf (fndecl, arglist, ignore,
9008 DECL_FUNCTION_CODE (fndecl));
9010 default:
9011 break;
9014 return 0;
9017 /* A wrapper function for builtin folding that prevents warnings for
9018 "statement without effect" and the like, caused by removing the
9019 call node earlier than the warning is generated. */
9021 tree
9022 fold_builtin (tree fndecl, tree arglist, bool ignore)
9024 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9025 if (exp)
9027 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9028 TREE_NO_WARNING (exp) = 1;
9031 return exp;
9034 /* Conveniently construct a function call expression. */
9036 tree
9037 build_function_call_expr (tree fn, tree arglist)
9039 tree call_expr;
9041 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9042 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9043 call_expr, arglist, NULL_TREE);
9046 /* This function validates the types of a function call argument list
9047 represented as a tree chain of parameters against a specified list
9048 of tree_codes. If the last specifier is a 0, that represents an
9049 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9051 static int
9052 validate_arglist (tree arglist, ...)
9054 enum tree_code code;
9055 int res = 0;
9056 va_list ap;
9058 va_start (ap, arglist);
9062 code = va_arg (ap, enum tree_code);
9063 switch (code)
9065 case 0:
9066 /* This signifies an ellipses, any further arguments are all ok. */
9067 res = 1;
9068 goto end;
9069 case VOID_TYPE:
9070 /* This signifies an endlink, if no arguments remain, return
9071 true, otherwise return false. */
9072 res = arglist == 0;
9073 goto end;
9074 default:
9075 /* If no parameters remain or the parameter's code does not
9076 match the specified code, return false. Otherwise continue
9077 checking any remaining arguments. */
9078 if (arglist == 0)
9079 goto end;
9080 if (code == POINTER_TYPE)
9082 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9083 goto end;
9085 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9086 goto end;
9087 break;
9089 arglist = TREE_CHAIN (arglist);
9091 while (1);
9093 /* We need gotos here since we can only have one VA_CLOSE in a
9094 function. */
9095 end: ;
9096 va_end (ap);
9098 return res;
9101 /* Default target-specific builtin expander that does nothing. */
9104 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9105 rtx target ATTRIBUTE_UNUSED,
9106 rtx subtarget ATTRIBUTE_UNUSED,
9107 enum machine_mode mode ATTRIBUTE_UNUSED,
9108 int ignore ATTRIBUTE_UNUSED)
9110 return NULL_RTX;
9113 /* Returns true is EXP represents data that would potentially reside
9114 in a readonly section. */
9116 static bool
9117 readonly_data_expr (tree exp)
9119 STRIP_NOPS (exp);
9121 if (TREE_CODE (exp) != ADDR_EXPR)
9122 return false;
9124 exp = get_base_address (TREE_OPERAND (exp, 0));
9125 if (!exp)
9126 return false;
9128 /* Make sure we call decl_readonly_section only for trees it
9129 can handle (since it returns true for everything it doesn't
9130 understand). */
9131 if (TREE_CODE (exp) == STRING_CST
9132 || TREE_CODE (exp) == CONSTRUCTOR
9133 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9134 return decl_readonly_section (exp, 0);
9135 else
9136 return false;
9139 /* Simplify a call to the strstr builtin.
9141 Return 0 if no simplification was possible, otherwise return the
9142 simplified form of the call as a tree.
9144 The simplified form may be a constant or other expression which
9145 computes the same value, but in a more efficient manner (including
9146 calls to other builtin functions).
9148 The call may contain arguments which need to be evaluated, but
9149 which are not useful to determine the result of the call. In
9150 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9151 COMPOUND_EXPR will be an argument which must be evaluated.
9152 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9153 COMPOUND_EXPR in the chain will contain the tree for the simplified
9154 form of the builtin function call. */
9156 static tree
9157 fold_builtin_strstr (tree arglist, tree type)
9159 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9160 return 0;
9161 else
9163 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9164 tree fn;
9165 const char *p1, *p2;
9167 p2 = c_getstr (s2);
9168 if (p2 == NULL)
9169 return 0;
9171 p1 = c_getstr (s1);
9172 if (p1 != NULL)
9174 const char *r = strstr (p1, p2);
9175 tree tem;
9177 if (r == NULL)
9178 return build_int_cst (TREE_TYPE (s1), 0);
9180 /* Return an offset into the constant string argument. */
9181 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9182 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9183 return fold_convert (type, tem);
9186 if (p2[0] == '\0')
9187 return s1;
9189 if (p2[1] != '\0')
9190 return 0;
9192 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9193 if (!fn)
9194 return 0;
9196 /* New argument list transforming strstr(s1, s2) to
9197 strchr(s1, s2[0]). */
9198 arglist = build_tree_list (NULL_TREE,
9199 build_int_cst (NULL_TREE, p2[0]));
9200 arglist = tree_cons (NULL_TREE, s1, arglist);
9201 return build_function_call_expr (fn, arglist);
9205 /* Simplify a call to the strchr builtin.
9207 Return 0 if no simplification was possible, otherwise return the
9208 simplified form of the call as a tree.
9210 The simplified form may be a constant or other expression which
9211 computes the same value, but in a more efficient manner (including
9212 calls to other builtin functions).
9214 The call may contain arguments which need to be evaluated, but
9215 which are not useful to determine the result of the call. In
9216 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9217 COMPOUND_EXPR will be an argument which must be evaluated.
9218 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9219 COMPOUND_EXPR in the chain will contain the tree for the simplified
9220 form of the builtin function call. */
9222 static tree
9223 fold_builtin_strchr (tree arglist, tree type)
9225 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9226 return 0;
9227 else
9229 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9230 const char *p1;
9232 if (TREE_CODE (s2) != INTEGER_CST)
9233 return 0;
9235 p1 = c_getstr (s1);
9236 if (p1 != NULL)
9238 char c;
9239 const char *r;
9240 tree tem;
9242 if (target_char_cast (s2, &c))
9243 return 0;
9245 r = strchr (p1, c);
9247 if (r == NULL)
9248 return build_int_cst (TREE_TYPE (s1), 0);
9250 /* Return an offset into the constant string argument. */
9251 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9252 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9253 return fold_convert (type, tem);
9255 return 0;
9259 /* Simplify a call to the strrchr builtin.
9261 Return 0 if no simplification was possible, otherwise return the
9262 simplified form of the call as a tree.
9264 The simplified form may be a constant or other expression which
9265 computes the same value, but in a more efficient manner (including
9266 calls to other builtin functions).
9268 The call may contain arguments which need to be evaluated, but
9269 which are not useful to determine the result of the call. In
9270 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9271 COMPOUND_EXPR will be an argument which must be evaluated.
9272 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9273 COMPOUND_EXPR in the chain will contain the tree for the simplified
9274 form of the builtin function call. */
9276 static tree
9277 fold_builtin_strrchr (tree arglist, tree type)
9279 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9280 return 0;
9281 else
9283 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9284 tree fn;
9285 const char *p1;
9287 if (TREE_CODE (s2) != INTEGER_CST)
9288 return 0;
9290 p1 = c_getstr (s1);
9291 if (p1 != NULL)
9293 char c;
9294 const char *r;
9295 tree tem;
9297 if (target_char_cast (s2, &c))
9298 return 0;
9300 r = strrchr (p1, c);
9302 if (r == NULL)
9303 return build_int_cst (TREE_TYPE (s1), 0);
9305 /* Return an offset into the constant string argument. */
9306 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9307 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9308 return fold_convert (type, tem);
9311 if (! integer_zerop (s2))
9312 return 0;
9314 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9315 if (!fn)
9316 return 0;
9318 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9319 return build_function_call_expr (fn, arglist);
9323 /* Simplify a call to the strpbrk builtin.
9325 Return 0 if no simplification was possible, otherwise return the
9326 simplified form of the call as a tree.
9328 The simplified form may be a constant or other expression which
9329 computes the same value, but in a more efficient manner (including
9330 calls to other builtin functions).
9332 The call may contain arguments which need to be evaluated, but
9333 which are not useful to determine the result of the call. In
9334 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9335 COMPOUND_EXPR will be an argument which must be evaluated.
9336 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9337 COMPOUND_EXPR in the chain will contain the tree for the simplified
9338 form of the builtin function call. */
9340 static tree
9341 fold_builtin_strpbrk (tree arglist, tree type)
9343 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9344 return 0;
9345 else
9347 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9348 tree fn;
9349 const char *p1, *p2;
9351 p2 = c_getstr (s2);
9352 if (p2 == NULL)
9353 return 0;
9355 p1 = c_getstr (s1);
9356 if (p1 != NULL)
9358 const char *r = strpbrk (p1, p2);
9359 tree tem;
9361 if (r == NULL)
9362 return build_int_cst (TREE_TYPE (s1), 0);
9364 /* Return an offset into the constant string argument. */
9365 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9366 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9367 return fold_convert (type, tem);
9370 if (p2[0] == '\0')
9371 /* strpbrk(x, "") == NULL.
9372 Evaluate and ignore s1 in case it had side-effects. */
9373 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9375 if (p2[1] != '\0')
9376 return 0; /* Really call strpbrk. */
9378 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9379 if (!fn)
9380 return 0;
9382 /* New argument list transforming strpbrk(s1, s2) to
9383 strchr(s1, s2[0]). */
9384 arglist = build_tree_list (NULL_TREE,
9385 build_int_cst (NULL_TREE, p2[0]));
9386 arglist = tree_cons (NULL_TREE, s1, arglist);
9387 return build_function_call_expr (fn, arglist);
9391 /* Simplify a call to the strcat builtin.
9393 Return 0 if no simplification was possible, otherwise return the
9394 simplified form of the call as a tree.
9396 The simplified form may be a constant or other expression which
9397 computes the same value, but in a more efficient manner (including
9398 calls to other builtin functions).
9400 The call may contain arguments which need to be evaluated, but
9401 which are not useful to determine the result of the call. In
9402 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9403 COMPOUND_EXPR will be an argument which must be evaluated.
9404 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9405 COMPOUND_EXPR in the chain will contain the tree for the simplified
9406 form of the builtin function call. */
9408 static tree
9409 fold_builtin_strcat (tree arglist)
9411 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9412 return 0;
9413 else
9415 tree dst = TREE_VALUE (arglist),
9416 src = TREE_VALUE (TREE_CHAIN (arglist));
9417 const char *p = c_getstr (src);
9419 /* If the string length is zero, return the dst parameter. */
9420 if (p && *p == '\0')
9421 return dst;
9423 return 0;
9427 /* Simplify a call to the strncat builtin.
9429 Return 0 if no simplification was possible, otherwise return the
9430 simplified form of the call as a tree.
9432 The simplified form may be a constant or other expression which
9433 computes the same value, but in a more efficient manner (including
9434 calls to other builtin functions).
9436 The call may contain arguments which need to be evaluated, but
9437 which are not useful to determine the result of the call. In
9438 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9439 COMPOUND_EXPR will be an argument which must be evaluated.
9440 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9441 COMPOUND_EXPR in the chain will contain the tree for the simplified
9442 form of the builtin function call. */
9444 static tree
9445 fold_builtin_strncat (tree arglist)
9447 if (!validate_arglist (arglist,
9448 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9449 return 0;
9450 else
9452 tree dst = TREE_VALUE (arglist);
9453 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9454 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9455 const char *p = c_getstr (src);
9457 /* If the requested length is zero, or the src parameter string
9458 length is zero, return the dst parameter. */
9459 if (integer_zerop (len) || (p && *p == '\0'))
9460 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9462 /* If the requested len is greater than or equal to the string
9463 length, call strcat. */
9464 if (TREE_CODE (len) == INTEGER_CST && p
9465 && compare_tree_int (len, strlen (p)) >= 0)
9467 tree newarglist
9468 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9469 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9471 /* If the replacement _DECL isn't initialized, don't do the
9472 transformation. */
9473 if (!fn)
9474 return 0;
9476 return build_function_call_expr (fn, newarglist);
9478 return 0;
9482 /* Simplify a call to the strspn builtin.
9484 Return 0 if no simplification was possible, otherwise return the
9485 simplified form of the call as a tree.
9487 The simplified form may be a constant or other expression which
9488 computes the same value, but in a more efficient manner (including
9489 calls to other builtin functions).
9491 The call may contain arguments which need to be evaluated, but
9492 which are not useful to determine the result of the call. In
9493 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9494 COMPOUND_EXPR will be an argument which must be evaluated.
9495 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9496 COMPOUND_EXPR in the chain will contain the tree for the simplified
9497 form of the builtin function call. */
9499 static tree
9500 fold_builtin_strspn (tree arglist)
9502 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9503 return 0;
9504 else
9506 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9507 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9509 /* If both arguments are constants, evaluate at compile-time. */
9510 if (p1 && p2)
9512 const size_t r = strspn (p1, p2);
9513 return size_int (r);
9516 /* If either argument is "", return 0. */
9517 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9518 /* Evaluate and ignore both arguments in case either one has
9519 side-effects. */
9520 return omit_two_operands (integer_type_node, integer_zero_node,
9521 s1, s2);
9522 return 0;
9526 /* Simplify a call to the strcspn builtin.
9528 Return 0 if no simplification was possible, otherwise return the
9529 simplified form of the call as a tree.
9531 The simplified form may be a constant or other expression which
9532 computes the same value, but in a more efficient manner (including
9533 calls to other builtin functions).
9535 The call may contain arguments which need to be evaluated, but
9536 which are not useful to determine the result of the call. In
9537 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9538 COMPOUND_EXPR will be an argument which must be evaluated.
9539 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9540 COMPOUND_EXPR in the chain will contain the tree for the simplified
9541 form of the builtin function call. */
9543 static tree
9544 fold_builtin_strcspn (tree arglist)
9546 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9547 return 0;
9548 else
9550 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9551 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9553 /* If both arguments are constants, evaluate at compile-time. */
9554 if (p1 && p2)
9556 const size_t r = strcspn (p1, p2);
9557 return size_int (r);
9560 /* If the first argument is "", return 0. */
9561 if (p1 && *p1 == '\0')
9563 /* Evaluate and ignore argument s2 in case it has
9564 side-effects. */
9565 return omit_one_operand (integer_type_node,
9566 integer_zero_node, s2);
9569 /* If the second argument is "", return __builtin_strlen(s1). */
9570 if (p2 && *p2 == '\0')
9572 tree newarglist = build_tree_list (NULL_TREE, s1),
9573 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9575 /* If the replacement _DECL isn't initialized, don't do the
9576 transformation. */
9577 if (!fn)
9578 return 0;
9580 return build_function_call_expr (fn, newarglist);
9582 return 0;
9586 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9587 by the builtin will be ignored. UNLOCKED is true is true if this
9588 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9589 the known length of the string. Return NULL_TREE if no simplification
9590 was possible. */
9592 tree
9593 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9595 tree fn;
9596 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9597 : implicit_built_in_decls[BUILT_IN_FPUTC];
9598 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9599 : implicit_built_in_decls[BUILT_IN_FWRITE];
9601 /* If the return value is used, or the replacement _DECL isn't
9602 initialized, don't do the transformation. */
9603 if (!ignore || !fn_fputc || !fn_fwrite)
9604 return 0;
9606 /* Verify the arguments in the original call. */
9607 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9608 return 0;
9610 if (! len)
9611 len = c_strlen (TREE_VALUE (arglist), 0);
9613 /* Get the length of the string passed to fputs. If the length
9614 can't be determined, punt. */
9615 if (!len
9616 || TREE_CODE (len) != INTEGER_CST)
9617 return 0;
9619 switch (compare_tree_int (len, 1))
9621 case -1: /* length is 0, delete the call entirely . */
9622 return omit_one_operand (integer_type_node, integer_zero_node,
9623 TREE_VALUE (TREE_CHAIN (arglist)));
9625 case 0: /* length is 1, call fputc. */
9627 const char *p = c_getstr (TREE_VALUE (arglist));
9629 if (p != NULL)
9631 /* New argument list transforming fputs(string, stream) to
9632 fputc(string[0], stream). */
9633 arglist = build_tree_list (NULL_TREE,
9634 TREE_VALUE (TREE_CHAIN (arglist)));
9635 arglist = tree_cons (NULL_TREE,
9636 build_int_cst (NULL_TREE, p[0]),
9637 arglist);
9638 fn = fn_fputc;
9639 break;
9642 /* FALLTHROUGH */
9643 case 1: /* length is greater than 1, call fwrite. */
9645 tree string_arg;
9647 /* If optimizing for size keep fputs. */
9648 if (optimize_size)
9649 return 0;
9650 string_arg = TREE_VALUE (arglist);
9651 /* New argument list transforming fputs(string, stream) to
9652 fwrite(string, 1, len, stream). */
9653 arglist = build_tree_list (NULL_TREE,
9654 TREE_VALUE (TREE_CHAIN (arglist)));
9655 arglist = tree_cons (NULL_TREE, len, arglist);
9656 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9657 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9658 fn = fn_fwrite;
9659 break;
9661 default:
9662 gcc_unreachable ();
9665 /* These optimizations are only performed when the result is ignored,
9666 hence there's no need to cast the result to integer_type_node. */
9667 return build_function_call_expr (fn, arglist);
9670 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9671 produced. False otherwise. This is done so that we don't output the error
9672 or warning twice or three times. */
9673 bool
9674 fold_builtin_next_arg (tree arglist)
9676 tree fntype = TREE_TYPE (current_function_decl);
9678 if (TYPE_ARG_TYPES (fntype) == 0
9679 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9680 == void_type_node))
9682 error ("%<va_start%> used in function with fixed args");
9683 return true;
9685 else if (!arglist)
9687 /* Evidently an out of date version of <stdarg.h>; can't validate
9688 va_start's second argument, but can still work as intended. */
9689 warning (0, "%<__builtin_next_arg%> called without an argument");
9690 return true;
9692 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9693 when we checked the arguments and if needed issued a warning. */
9694 else if (!TREE_CHAIN (arglist)
9695 || !integer_zerop (TREE_VALUE (arglist))
9696 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9697 || TREE_CHAIN (TREE_CHAIN (arglist)))
9699 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9700 tree arg = TREE_VALUE (arglist);
9702 if (TREE_CHAIN (arglist))
9704 error ("%<va_start%> used with too many arguments");
9705 return true;
9708 /* Strip off all nops for the sake of the comparison. This
9709 is not quite the same as STRIP_NOPS. It does more.
9710 We must also strip off INDIRECT_EXPR for C++ reference
9711 parameters. */
9712 while (TREE_CODE (arg) == NOP_EXPR
9713 || TREE_CODE (arg) == CONVERT_EXPR
9714 || TREE_CODE (arg) == NON_LVALUE_EXPR
9715 || TREE_CODE (arg) == INDIRECT_REF)
9716 arg = TREE_OPERAND (arg, 0);
9717 if (arg != last_parm)
9719 /* FIXME: Sometimes with the tree optimizers we can get the
9720 not the last argument even though the user used the last
9721 argument. We just warn and set the arg to be the last
9722 argument so that we will get wrong-code because of
9723 it. */
9724 warning (0, "second parameter of %<va_start%> not last named argument");
9726 /* We want to verify the second parameter just once before the tree
9727 optimizers are run and then avoid keeping it in the tree,
9728 as otherwise we could warn even for correct code like:
9729 void foo (int i, ...)
9730 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9731 TREE_VALUE (arglist) = integer_zero_node;
9732 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9734 return false;
9738 /* Simplify a call to the sprintf builtin.
9740 Return 0 if no simplification was possible, otherwise return the
9741 simplified form of the call as a tree. If IGNORED is true, it means that
9742 the caller does not use the returned value of the function. */
9744 static tree
9745 fold_builtin_sprintf (tree arglist, int ignored)
9747 tree call, retval, dest, fmt;
9748 const char *fmt_str = NULL;
9750 /* Verify the required arguments in the original call. We deal with two
9751 types of sprintf() calls: 'sprintf (str, fmt)' and
9752 'sprintf (dest, "%s", orig)'. */
9753 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9754 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9755 VOID_TYPE))
9756 return NULL_TREE;
9758 /* Get the destination string and the format specifier. */
9759 dest = TREE_VALUE (arglist);
9760 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9762 /* Check whether the format is a literal string constant. */
9763 fmt_str = c_getstr (fmt);
9764 if (fmt_str == NULL)
9765 return NULL_TREE;
9767 call = NULL_TREE;
9768 retval = NULL_TREE;
9770 /* If the format doesn't contain % args or %%, use strcpy. */
9771 if (strchr (fmt_str, '%') == NULL)
9773 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9775 if (!fn)
9776 return NULL_TREE;
9778 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9779 'format' is known to contain no % formats. */
9780 arglist = build_tree_list (NULL_TREE, fmt);
9781 arglist = tree_cons (NULL_TREE, dest, arglist);
9782 call = build_function_call_expr (fn, arglist);
9783 if (!ignored)
9784 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9787 /* If the format is "%s", use strcpy if the result isn't used. */
9788 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9790 tree fn, orig;
9791 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9793 if (!fn)
9794 return NULL_TREE;
9796 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9797 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9798 arglist = build_tree_list (NULL_TREE, orig);
9799 arglist = tree_cons (NULL_TREE, dest, arglist);
9800 if (!ignored)
9802 retval = c_strlen (orig, 1);
9803 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9804 return NULL_TREE;
9806 call = build_function_call_expr (fn, arglist);
9809 if (call && retval)
9811 retval = convert
9812 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9813 retval);
9814 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9816 else
9817 return call;
9820 /* Expand a call to __builtin_object_size. */
9823 expand_builtin_object_size (tree exp)
9825 tree ost;
9826 int object_size_type;
9827 tree fndecl = get_callee_fndecl (exp);
9828 tree arglist = TREE_OPERAND (exp, 1);
9829 location_t locus = EXPR_LOCATION (exp);
9831 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9833 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9834 &locus, fndecl);
9835 expand_builtin_trap ();
9836 return const0_rtx;
9839 ost = TREE_VALUE (TREE_CHAIN (arglist));
9840 STRIP_NOPS (ost);
9842 if (TREE_CODE (ost) != INTEGER_CST
9843 || tree_int_cst_sgn (ost) < 0
9844 || compare_tree_int (ost, 3) > 0)
9846 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9847 &locus, fndecl);
9848 expand_builtin_trap ();
9849 return const0_rtx;
9852 object_size_type = tree_low_cst (ost, 0);
9854 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9857 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9858 FCODE is the BUILT_IN_* to use.
9859 Return 0 if we failed; the caller should emit a normal call,
9860 otherwise try to get the result in TARGET, if convenient (and in
9861 mode MODE if that's convenient). */
9863 static rtx
9864 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9865 enum built_in_function fcode)
9867 tree arglist = TREE_OPERAND (exp, 1);
9868 tree dest, src, len, size;
9870 if (!validate_arglist (arglist,
9871 POINTER_TYPE,
9872 fcode == BUILT_IN_MEMSET_CHK
9873 ? INTEGER_TYPE : POINTER_TYPE,
9874 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9875 return 0;
9877 dest = TREE_VALUE (arglist);
9878 src = TREE_VALUE (TREE_CHAIN (arglist));
9879 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9880 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9882 if (! host_integerp (size, 1))
9883 return 0;
9885 if (host_integerp (len, 1) || integer_all_onesp (size))
9887 tree fn;
9889 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9891 location_t locus = EXPR_LOCATION (exp);
9892 warning (0, "%Hcall to %D will always overflow destination buffer",
9893 &locus, get_callee_fndecl (exp));
9894 return 0;
9897 arglist = build_tree_list (NULL_TREE, len);
9898 arglist = tree_cons (NULL_TREE, src, arglist);
9899 arglist = tree_cons (NULL_TREE, dest, arglist);
9901 fn = NULL_TREE;
9902 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9903 mem{cpy,pcpy,move,set} is available. */
9904 switch (fcode)
9906 case BUILT_IN_MEMCPY_CHK:
9907 fn = built_in_decls[BUILT_IN_MEMCPY];
9908 break;
9909 case BUILT_IN_MEMPCPY_CHK:
9910 fn = built_in_decls[BUILT_IN_MEMPCPY];
9911 break;
9912 case BUILT_IN_MEMMOVE_CHK:
9913 fn = built_in_decls[BUILT_IN_MEMMOVE];
9914 break;
9915 case BUILT_IN_MEMSET_CHK:
9916 fn = built_in_decls[BUILT_IN_MEMSET];
9917 break;
9918 default:
9919 break;
9922 if (! fn)
9923 return 0;
9925 fn = build_function_call_expr (fn, arglist);
9926 if (TREE_CODE (fn) == CALL_EXPR)
9927 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9928 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9930 else if (fcode == BUILT_IN_MEMSET_CHK)
9931 return 0;
9932 else
9934 unsigned int dest_align
9935 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9937 /* If DEST is not a pointer type, call the normal function. */
9938 if (dest_align == 0)
9939 return 0;
9941 /* If SRC and DEST are the same (and not volatile), do nothing. */
9942 if (operand_equal_p (src, dest, 0))
9944 tree expr;
9946 if (fcode != BUILT_IN_MEMPCPY_CHK)
9948 /* Evaluate and ignore LEN in case it has side-effects. */
9949 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9950 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9953 len = fold_convert (TREE_TYPE (dest), len);
9954 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9955 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9958 /* __memmove_chk special case. */
9959 if (fcode == BUILT_IN_MEMMOVE_CHK)
9961 unsigned int src_align
9962 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9964 if (src_align == 0)
9965 return 0;
9967 /* If src is categorized for a readonly section we can use
9968 normal __memcpy_chk. */
9969 if (readonly_data_expr (src))
9971 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9972 if (!fn)
9973 return 0;
9974 fn = build_function_call_expr (fn, arglist);
9975 if (TREE_CODE (fn) == CALL_EXPR)
9976 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9977 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9980 return 0;
9984 /* Emit warning if a buffer overflow is detected at compile time. */
9986 static void
9987 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9989 int arg_mask, is_strlen = 0;
9990 tree arglist = TREE_OPERAND (exp, 1), a;
9991 tree len, size;
9992 location_t locus;
9994 switch (fcode)
9996 case BUILT_IN_STRCPY_CHK:
9997 case BUILT_IN_STPCPY_CHK:
9998 /* For __strcat_chk the warning will be emitted only if overflowing
9999 by at least strlen (dest) + 1 bytes. */
10000 case BUILT_IN_STRCAT_CHK:
10001 arg_mask = 6;
10002 is_strlen = 1;
10003 break;
10004 case BUILT_IN_STRNCPY_CHK:
10005 arg_mask = 12;
10006 break;
10007 case BUILT_IN_SNPRINTF_CHK:
10008 case BUILT_IN_VSNPRINTF_CHK:
10009 arg_mask = 10;
10010 break;
10011 default:
10012 gcc_unreachable ();
10015 len = NULL_TREE;
10016 size = NULL_TREE;
10017 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10018 if (arg_mask & 1)
10020 if (len)
10021 size = a;
10022 else
10023 len = a;
10026 if (!len || !size)
10027 return;
10029 len = TREE_VALUE (len);
10030 size = TREE_VALUE (size);
10032 if (! host_integerp (size, 1) || integer_all_onesp (size))
10033 return;
10035 if (is_strlen)
10037 len = c_strlen (len, 1);
10038 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10039 return;
10041 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10042 return;
10044 locus = EXPR_LOCATION (exp);
10045 warning (0, "%Hcall to %D will always overflow destination buffer",
10046 &locus, get_callee_fndecl (exp));
10049 /* Emit warning if a buffer overflow is detected at compile time
10050 in __sprintf_chk/__vsprintf_chk calls. */
10052 static void
10053 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10055 tree arglist = TREE_OPERAND (exp, 1);
10056 tree dest, size, len, fmt, flag;
10057 const char *fmt_str;
10059 /* Verify the required arguments in the original call. */
10060 if (! arglist)
10061 return;
10062 dest = TREE_VALUE (arglist);
10063 arglist = TREE_CHAIN (arglist);
10064 if (! arglist)
10065 return;
10066 flag = TREE_VALUE (arglist);
10067 arglist = TREE_CHAIN (arglist);
10068 if (! arglist)
10069 return;
10070 size = TREE_VALUE (arglist);
10071 arglist = TREE_CHAIN (arglist);
10072 if (! arglist)
10073 return;
10074 fmt = TREE_VALUE (arglist);
10075 arglist = TREE_CHAIN (arglist);
10077 if (! host_integerp (size, 1) || integer_all_onesp (size))
10078 return;
10080 /* Check whether the format is a literal string constant. */
10081 fmt_str = c_getstr (fmt);
10082 if (fmt_str == NULL)
10083 return;
10085 /* If the format doesn't contain % args or %%, we know its size. */
10086 if (strchr (fmt_str, '%') == 0)
10087 len = build_int_cstu (size_type_node, strlen (fmt_str));
10088 /* If the format is "%s" and first ... argument is a string literal,
10089 we know it too. */
10090 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10092 tree arg;
10094 if (! arglist)
10095 return;
10096 arg = TREE_VALUE (arglist);
10097 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10098 return;
10100 len = c_strlen (arg, 1);
10101 if (!len || ! host_integerp (len, 1))
10102 return;
10104 else
10105 return;
10107 if (! tree_int_cst_lt (len, size))
10109 location_t locus = EXPR_LOCATION (exp);
10110 warning (0, "%Hcall to %D will always overflow destination buffer",
10111 &locus, get_callee_fndecl (exp));
10115 /* Fold a call to __builtin_object_size, if possible. */
10117 tree
10118 fold_builtin_object_size (tree arglist)
10120 tree ptr, ost, ret = 0;
10121 int object_size_type;
10123 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10124 return 0;
10126 ptr = TREE_VALUE (arglist);
10127 ost = TREE_VALUE (TREE_CHAIN (arglist));
10128 STRIP_NOPS (ost);
10130 if (TREE_CODE (ost) != INTEGER_CST
10131 || tree_int_cst_sgn (ost) < 0
10132 || compare_tree_int (ost, 3) > 0)
10133 return 0;
10135 object_size_type = tree_low_cst (ost, 0);
10137 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10138 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10139 and (size_t) 0 for types 2 and 3. */
10140 if (TREE_SIDE_EFFECTS (ptr))
10141 return fold_convert (size_type_node,
10142 object_size_type < 2
10143 ? integer_minus_one_node : integer_zero_node);
10145 if (TREE_CODE (ptr) == ADDR_EXPR)
10146 ret = build_int_cstu (size_type_node,
10147 compute_builtin_object_size (ptr, object_size_type));
10149 else if (TREE_CODE (ptr) == SSA_NAME)
10151 unsigned HOST_WIDE_INT bytes;
10153 /* If object size is not known yet, delay folding until
10154 later. Maybe subsequent passes will help determining
10155 it. */
10156 bytes = compute_builtin_object_size (ptr, object_size_type);
10157 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10158 ? -1 : 0))
10159 ret = build_int_cstu (size_type_node, bytes);
10162 if (ret)
10164 ret = force_fit_type (ret, -1, false, false);
10165 if (TREE_CONSTANT_OVERFLOW (ret))
10166 ret = 0;
10169 return ret;
10172 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10173 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10174 code of the builtin. If MAXLEN is not NULL, it is maximum length
10175 passed as third argument. */
10177 tree
10178 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10179 enum built_in_function fcode)
10181 tree dest, src, len, size, fn;
10183 if (!validate_arglist (arglist,
10184 POINTER_TYPE,
10185 fcode == BUILT_IN_MEMSET_CHK
10186 ? INTEGER_TYPE : POINTER_TYPE,
10187 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10188 return 0;
10190 dest = TREE_VALUE (arglist);
10191 /* Actually val for __memset_chk, but it doesn't matter. */
10192 src = TREE_VALUE (TREE_CHAIN (arglist));
10193 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10194 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10196 /* If SRC and DEST are the same (and not volatile), return DEST
10197 (resp. DEST+LEN for __mempcpy_chk). */
10198 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10200 if (fcode != BUILT_IN_MEMPCPY_CHK)
10201 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10202 else
10204 tree temp = fold_convert (TREE_TYPE (dest), len);
10205 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10206 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10210 if (! host_integerp (size, 1))
10211 return 0;
10213 if (! integer_all_onesp (size))
10215 if (! host_integerp (len, 1))
10217 /* If LEN is not constant, try MAXLEN too.
10218 For MAXLEN only allow optimizing into non-_ocs function
10219 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10220 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10222 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10224 /* (void) __mempcpy_chk () can be optimized into
10225 (void) __memcpy_chk (). */
10226 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10227 if (!fn)
10228 return 0;
10230 return build_function_call_expr (fn, arglist);
10232 return 0;
10235 else
10236 maxlen = len;
10238 if (tree_int_cst_lt (size, maxlen))
10239 return 0;
10242 arglist = build_tree_list (NULL_TREE, len);
10243 arglist = tree_cons (NULL_TREE, src, arglist);
10244 arglist = tree_cons (NULL_TREE, dest, arglist);
10246 fn = NULL_TREE;
10247 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10248 mem{cpy,pcpy,move,set} is available. */
10249 switch (fcode)
10251 case BUILT_IN_MEMCPY_CHK:
10252 fn = built_in_decls[BUILT_IN_MEMCPY];
10253 break;
10254 case BUILT_IN_MEMPCPY_CHK:
10255 fn = built_in_decls[BUILT_IN_MEMPCPY];
10256 break;
10257 case BUILT_IN_MEMMOVE_CHK:
10258 fn = built_in_decls[BUILT_IN_MEMMOVE];
10259 break;
10260 case BUILT_IN_MEMSET_CHK:
10261 fn = built_in_decls[BUILT_IN_MEMSET];
10262 break;
10263 default:
10264 break;
10267 if (!fn)
10268 return 0;
10270 return build_function_call_expr (fn, arglist);
10273 /* Fold a call to the __st[rp]cpy_chk builtin.
10274 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10275 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10276 strings passed as second argument. */
10278 tree
10279 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10280 enum built_in_function fcode)
10282 tree dest, src, size, len, fn;
10284 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10285 VOID_TYPE))
10286 return 0;
10288 dest = TREE_VALUE (arglist);
10289 src = TREE_VALUE (TREE_CHAIN (arglist));
10290 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10292 /* If SRC and DEST are the same (and not volatile), return DEST. */
10293 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10294 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10296 if (! host_integerp (size, 1))
10297 return 0;
10299 if (! integer_all_onesp (size))
10301 len = c_strlen (src, 1);
10302 if (! len || ! host_integerp (len, 1))
10304 /* If LEN is not constant, try MAXLEN too.
10305 For MAXLEN only allow optimizing into non-_ocs function
10306 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10307 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10309 if (fcode == BUILT_IN_STPCPY_CHK)
10311 if (! ignore)
10312 return 0;
10314 /* If return value of __stpcpy_chk is ignored,
10315 optimize into __strcpy_chk. */
10316 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10317 if (!fn)
10318 return 0;
10320 return build_function_call_expr (fn, arglist);
10323 if (! len || TREE_SIDE_EFFECTS (len))
10324 return 0;
10326 /* If c_strlen returned something, but not a constant,
10327 transform __strcpy_chk into __memcpy_chk. */
10328 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10329 if (!fn)
10330 return 0;
10332 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10333 arglist = build_tree_list (NULL_TREE, size);
10334 arglist = tree_cons (NULL_TREE, len, arglist);
10335 arglist = tree_cons (NULL_TREE, src, arglist);
10336 arglist = tree_cons (NULL_TREE, dest, arglist);
10337 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10338 build_function_call_expr (fn, arglist));
10341 else
10342 maxlen = len;
10344 if (! tree_int_cst_lt (maxlen, size))
10345 return 0;
10348 arglist = build_tree_list (NULL_TREE, src);
10349 arglist = tree_cons (NULL_TREE, dest, arglist);
10351 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10352 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10353 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10354 if (!fn)
10355 return 0;
10357 return build_function_call_expr (fn, arglist);
10360 /* Fold a call to the __strncpy_chk builtin.
10361 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10363 tree
10364 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10366 tree dest, src, size, len, fn;
10368 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10369 INTEGER_TYPE, VOID_TYPE))
10370 return 0;
10372 dest = TREE_VALUE (arglist);
10373 src = TREE_VALUE (TREE_CHAIN (arglist));
10374 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10375 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10377 if (! host_integerp (size, 1))
10378 return 0;
10380 if (! integer_all_onesp (size))
10382 if (! host_integerp (len, 1))
10384 /* If LEN is not constant, try MAXLEN too.
10385 For MAXLEN only allow optimizing into non-_ocs function
10386 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10387 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10388 return 0;
10390 else
10391 maxlen = len;
10393 if (tree_int_cst_lt (size, maxlen))
10394 return 0;
10397 arglist = build_tree_list (NULL_TREE, len);
10398 arglist = tree_cons (NULL_TREE, src, arglist);
10399 arglist = tree_cons (NULL_TREE, dest, arglist);
10401 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10402 fn = built_in_decls[BUILT_IN_STRNCPY];
10403 if (!fn)
10404 return 0;
10406 return build_function_call_expr (fn, arglist);
10409 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10411 static tree
10412 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10414 tree dest, src, size, fn;
10415 const char *p;
10417 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10418 VOID_TYPE))
10419 return 0;
10421 dest = TREE_VALUE (arglist);
10422 src = TREE_VALUE (TREE_CHAIN (arglist));
10423 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10425 p = c_getstr (src);
10426 /* If the SRC parameter is "", return DEST. */
10427 if (p && *p == '\0')
10428 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10430 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10431 return 0;
10433 arglist = build_tree_list (NULL_TREE, src);
10434 arglist = tree_cons (NULL_TREE, dest, arglist);
10436 /* If __builtin_strcat_chk is used, assume strcat is available. */
10437 fn = built_in_decls[BUILT_IN_STRCAT];
10438 if (!fn)
10439 return 0;
10441 return build_function_call_expr (fn, arglist);
10444 /* Fold a call to the __strncat_chk builtin EXP. */
10446 static tree
10447 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10449 tree dest, src, size, len, fn;
10450 const char *p;
10452 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10453 INTEGER_TYPE, VOID_TYPE))
10454 return 0;
10456 dest = TREE_VALUE (arglist);
10457 src = TREE_VALUE (TREE_CHAIN (arglist));
10458 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10459 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10461 p = c_getstr (src);
10462 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10463 if (p && *p == '\0')
10464 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10465 else if (integer_zerop (len))
10466 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10468 if (! host_integerp (size, 1))
10469 return 0;
10471 if (! integer_all_onesp (size))
10473 tree src_len = c_strlen (src, 1);
10474 if (src_len
10475 && host_integerp (src_len, 1)
10476 && host_integerp (len, 1)
10477 && ! tree_int_cst_lt (len, src_len))
10479 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10480 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10481 if (!fn)
10482 return 0;
10484 arglist = build_tree_list (NULL_TREE, size);
10485 arglist = tree_cons (NULL_TREE, src, arglist);
10486 arglist = tree_cons (NULL_TREE, dest, arglist);
10487 return build_function_call_expr (fn, arglist);
10489 return 0;
10492 arglist = build_tree_list (NULL_TREE, len);
10493 arglist = tree_cons (NULL_TREE, src, arglist);
10494 arglist = tree_cons (NULL_TREE, dest, arglist);
10496 /* If __builtin_strncat_chk is used, assume strncat is available. */
10497 fn = built_in_decls[BUILT_IN_STRNCAT];
10498 if (!fn)
10499 return 0;
10501 return build_function_call_expr (fn, arglist);
10504 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10505 a normal call should be emitted rather than expanding the function
10506 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10508 static tree
10509 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10511 tree dest, size, len, fn, fmt, flag;
10512 const char *fmt_str;
10514 /* Verify the required arguments in the original call. */
10515 if (! arglist)
10516 return 0;
10517 dest = TREE_VALUE (arglist);
10518 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10519 return 0;
10520 arglist = TREE_CHAIN (arglist);
10521 if (! arglist)
10522 return 0;
10523 flag = TREE_VALUE (arglist);
10524 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10525 return 0;
10526 arglist = TREE_CHAIN (arglist);
10527 if (! arglist)
10528 return 0;
10529 size = TREE_VALUE (arglist);
10530 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10531 return 0;
10532 arglist = TREE_CHAIN (arglist);
10533 if (! arglist)
10534 return 0;
10535 fmt = TREE_VALUE (arglist);
10536 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10537 return 0;
10538 arglist = TREE_CHAIN (arglist);
10540 if (! host_integerp (size, 1))
10541 return 0;
10543 len = NULL_TREE;
10545 /* Check whether the format is a literal string constant. */
10546 fmt_str = c_getstr (fmt);
10547 if (fmt_str != NULL)
10549 /* If the format doesn't contain % args or %%, we know the size. */
10550 if (strchr (fmt_str, '%') == 0)
10552 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10553 len = build_int_cstu (size_type_node, strlen (fmt_str));
10555 /* If the format is "%s" and first ... argument is a string literal,
10556 we know the size too. */
10557 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10559 tree arg;
10561 if (arglist && !TREE_CHAIN (arglist))
10563 arg = TREE_VALUE (arglist);
10564 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10566 len = c_strlen (arg, 1);
10567 if (! len || ! host_integerp (len, 1))
10568 len = NULL_TREE;
10574 if (! integer_all_onesp (size))
10576 if (! len || ! tree_int_cst_lt (len, size))
10577 return 0;
10580 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10581 or if format doesn't contain % chars or is "%s". */
10582 if (! integer_zerop (flag))
10584 if (fmt_str == NULL)
10585 return 0;
10586 if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10587 return 0;
10590 arglist = tree_cons (NULL_TREE, fmt, arglist);
10591 arglist = tree_cons (NULL_TREE, dest, arglist);
10593 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10594 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10595 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10596 if (!fn)
10597 return 0;
10599 return build_function_call_expr (fn, arglist);
10602 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10603 a normal call should be emitted rather than expanding the function
10604 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10605 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10606 passed as second argument. */
10608 tree
10609 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10610 enum built_in_function fcode)
10612 tree dest, size, len, fn, fmt, flag;
10613 const char *fmt_str;
10615 /* Verify the required arguments in the original call. */
10616 if (! arglist)
10617 return 0;
10618 dest = TREE_VALUE (arglist);
10619 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10620 return 0;
10621 arglist = TREE_CHAIN (arglist);
10622 if (! arglist)
10623 return 0;
10624 len = TREE_VALUE (arglist);
10625 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10626 return 0;
10627 arglist = TREE_CHAIN (arglist);
10628 if (! arglist)
10629 return 0;
10630 flag = TREE_VALUE (arglist);
10631 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10632 return 0;
10633 arglist = TREE_CHAIN (arglist);
10634 if (! arglist)
10635 return 0;
10636 size = TREE_VALUE (arglist);
10637 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10638 return 0;
10639 arglist = TREE_CHAIN (arglist);
10640 if (! arglist)
10641 return 0;
10642 fmt = TREE_VALUE (arglist);
10643 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10644 return 0;
10645 arglist = TREE_CHAIN (arglist);
10647 if (! host_integerp (size, 1))
10648 return 0;
10650 if (! integer_all_onesp (size))
10652 if (! host_integerp (len, 1))
10654 /* If LEN is not constant, try MAXLEN too.
10655 For MAXLEN only allow optimizing into non-_ocs function
10656 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10657 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10658 return 0;
10660 else
10661 maxlen = len;
10663 if (tree_int_cst_lt (size, maxlen))
10664 return 0;
10667 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10668 or if format doesn't contain % chars or is "%s". */
10669 if (! integer_zerop (flag))
10671 fmt_str = c_getstr (fmt);
10672 if (fmt_str == NULL)
10673 return 0;
10674 if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10675 return 0;
10678 arglist = tree_cons (NULL_TREE, fmt, arglist);
10679 arglist = tree_cons (NULL_TREE, len, arglist);
10680 arglist = tree_cons (NULL_TREE, dest, arglist);
10682 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10683 available. */
10684 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10685 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10686 if (!fn)
10687 return 0;
10689 return build_function_call_expr (fn, arglist);
10692 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10694 Return 0 if no simplification was possible, otherwise return the
10695 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10696 code of the function to be simplified. */
10698 static tree
10699 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10700 enum built_in_function fcode)
10702 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10703 const char *fmt_str = NULL;
10705 /* If the return value is used, don't do the transformation. */
10706 if (! ignore)
10707 return 0;
10709 /* Verify the required arguments in the original call. */
10710 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10712 tree flag;
10714 if (! arglist)
10715 return 0;
10716 flag = TREE_VALUE (arglist);
10717 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10718 || TREE_SIDE_EFFECTS (flag))
10719 return 0;
10720 arglist = TREE_CHAIN (arglist);
10723 if (! arglist)
10724 return 0;
10725 fmt = TREE_VALUE (arglist);
10726 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10727 return 0;
10728 arglist = TREE_CHAIN (arglist);
10730 /* Check whether the format is a literal string constant. */
10731 fmt_str = c_getstr (fmt);
10732 if (fmt_str == NULL)
10733 return NULL_TREE;
10735 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10737 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10738 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10740 else
10742 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10743 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10746 if (strcmp (fmt_str, "%s") == 0 || strchr (fmt_str, '%') == NULL)
10748 const char *str;
10750 if (strcmp (fmt_str, "%s") == 0)
10752 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10753 return 0;
10755 if (! arglist
10756 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10757 || TREE_CHAIN (arglist))
10758 return 0;
10760 str = c_getstr (TREE_VALUE (arglist));
10761 if (str == NULL)
10762 return 0;
10764 else
10766 /* The format specifier doesn't contain any '%' characters. */
10767 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10768 && arglist)
10769 return 0;
10770 str = fmt_str;
10773 /* If the string was "", printf does nothing. */
10774 if (str[0] == '\0')
10775 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10777 /* If the string has length of 1, call putchar. */
10778 if (str[1] == '\0')
10780 /* Given printf("c"), (where c is any one character,)
10781 convert "c"[0] to an int and pass that to the replacement
10782 function. */
10783 arg = build_int_cst (NULL_TREE, str[0]);
10784 arglist = build_tree_list (NULL_TREE, arg);
10785 fn = fn_putchar;
10787 else
10789 /* If the string was "string\n", call puts("string"). */
10790 size_t len = strlen (str);
10791 if (str[len - 1] == '\n')
10793 /* Create a NUL-terminated string that's one char shorter
10794 than the original, stripping off the trailing '\n'. */
10795 char *newstr = alloca (len);
10796 memcpy (newstr, str, len - 1);
10797 newstr[len - 1] = 0;
10799 arg = build_string_literal (len, newstr);
10800 arglist = build_tree_list (NULL_TREE, arg);
10801 fn = fn_puts;
10803 else
10804 /* We'd like to arrange to call fputs(string,stdout) here,
10805 but we need stdout and don't have a way to get it yet. */
10806 return 0;
10810 /* The other optimizations can be done only on the non-va_list variants. */
10811 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10812 return 0;
10814 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10815 else if (strcmp (fmt_str, "%s\n") == 0)
10817 if (! arglist
10818 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10819 || TREE_CHAIN (arglist))
10820 return 0;
10821 fn = fn_puts;
10824 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10825 else if (strcmp (fmt_str, "%c") == 0)
10827 if (! arglist
10828 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10829 || TREE_CHAIN (arglist))
10830 return 0;
10831 fn = fn_putchar;
10834 if (!fn)
10835 return 0;
10837 call = build_function_call_expr (fn, arglist);
10838 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10841 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10843 Return 0 if no simplification was possible, otherwise return the
10844 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10845 code of the function to be simplified. */
10847 static tree
10848 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10849 enum built_in_function fcode)
10851 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10852 const char *fmt_str = NULL;
10854 /* If the return value is used, don't do the transformation. */
10855 if (! ignore)
10856 return 0;
10858 /* Verify the required arguments in the original call. */
10859 if (! arglist)
10860 return 0;
10861 fp = TREE_VALUE (arglist);
10862 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10863 return 0;
10864 arglist = TREE_CHAIN (arglist);
10866 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10868 tree flag;
10870 if (! arglist)
10871 return 0;
10872 flag = TREE_VALUE (arglist);
10873 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10874 || TREE_SIDE_EFFECTS (flag))
10875 return 0;
10876 arglist = TREE_CHAIN (arglist);
10879 if (! arglist)
10880 return 0;
10881 fmt = TREE_VALUE (arglist);
10882 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10883 return 0;
10884 arglist = TREE_CHAIN (arglist);
10886 /* Check whether the format is a literal string constant. */
10887 fmt_str = c_getstr (fmt);
10888 if (fmt_str == NULL)
10889 return NULL_TREE;
10891 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10893 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10894 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10896 else
10898 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10899 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10902 /* If the format doesn't contain % args or %%, use strcpy. */
10903 if (strchr (fmt_str, '%') == NULL)
10905 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10906 && arglist)
10907 return 0;
10909 /* If the format specifier was "", fprintf does nothing. */
10910 if (fmt_str[0] == '\0')
10912 /* If FP has side-effects, just wait until gimplification is
10913 done. */
10914 if (TREE_SIDE_EFFECTS (fp))
10915 return 0;
10917 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10920 /* When "string" doesn't contain %, replace all cases of
10921 fprintf (fp, string) with fputs (string, fp). The fputs
10922 builtin will take care of special cases like length == 1. */
10923 arglist = build_tree_list (NULL_TREE, fp);
10924 arglist = tree_cons (NULL_TREE, fmt, arglist);
10925 fn = fn_fputs;
10928 /* The other optimizations can be done only on the non-va_list variants. */
10929 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10930 return 0;
10932 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10933 else if (strcmp (fmt_str, "%s") == 0)
10935 if (! arglist
10936 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10937 || TREE_CHAIN (arglist))
10938 return 0;
10939 arg = TREE_VALUE (arglist);
10940 arglist = build_tree_list (NULL_TREE, fp);
10941 arglist = tree_cons (NULL_TREE, arg, arglist);
10942 fn = fn_fputs;
10945 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10946 else if (strcmp (fmt_str, "%c") == 0)
10948 if (! arglist
10949 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10950 || TREE_CHAIN (arglist))
10951 return 0;
10952 arg = TREE_VALUE (arglist);
10953 arglist = build_tree_list (NULL_TREE, fp);
10954 arglist = tree_cons (NULL_TREE, arg, arglist);
10955 fn = fn_fputc;
10958 if (!fn)
10959 return 0;
10961 call = build_function_call_expr (fn, arglist);
10962 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);