gcj.texi (libgcj Runtime Properties): Document gnu.gcj.runtime.NameFinder.show_raw...
[official-gcc.git] / gcc / builtins.c
blob603106a6751ceffcae657e7df1e25a273769c975
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
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_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_sin (tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_tan (tree);
156 static tree fold_builtin_atan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memcpy (tree, tree);
164 static tree fold_builtin_mempcpy (tree, tree, int);
165 static tree fold_builtin_memmove (tree, tree);
166 static tree fold_builtin_strchr (tree, tree);
167 static tree fold_builtin_memcmp (tree);
168 static tree fold_builtin_strcmp (tree);
169 static tree fold_builtin_strncmp (tree);
170 static tree fold_builtin_signbit (tree, tree);
171 static tree fold_builtin_copysign (tree, tree, tree);
172 static tree fold_builtin_isascii (tree);
173 static tree fold_builtin_toascii (tree);
174 static tree fold_builtin_isdigit (tree);
175 static tree fold_builtin_fabs (tree, tree);
176 static tree fold_builtin_abs (tree, tree);
177 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
178 enum tree_code);
179 static tree fold_builtin_1 (tree, tree, bool);
181 static tree fold_builtin_strpbrk (tree, tree);
182 static tree fold_builtin_strstr (tree, tree);
183 static tree fold_builtin_strrchr (tree, tree);
184 static tree fold_builtin_strcat (tree);
185 static tree fold_builtin_strncat (tree);
186 static tree fold_builtin_strspn (tree);
187 static tree fold_builtin_strcspn (tree);
188 static tree fold_builtin_sprintf (tree, int);
190 static rtx expand_builtin_object_size (tree);
191 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
192 enum built_in_function);
193 static void maybe_emit_chk_warning (tree, enum built_in_function);
194 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
195 static tree fold_builtin_object_size (tree);
196 static tree fold_builtin_strcat_chk (tree, tree);
197 static tree fold_builtin_strncat_chk (tree, tree);
198 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
199 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
200 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
201 static bool init_target_chars (void);
203 static unsigned HOST_WIDE_INT target_newline;
204 static unsigned HOST_WIDE_INT target_percent;
205 static unsigned HOST_WIDE_INT target_c;
206 static unsigned HOST_WIDE_INT target_s;
207 static char target_percent_c[3];
208 static char target_percent_s[3];
209 static char target_percent_s_newline[4];
211 /* Return true if NODE should be considered for inline expansion regardless
212 of the optimization level. This means whenever a function is invoked with
213 its "internal" name, which normally contains the prefix "__builtin". */
215 static bool called_as_built_in (tree node)
217 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
218 if (strncmp (name, "__builtin_", 10) == 0)
219 return true;
220 if (strncmp (name, "__sync_", 7) == 0)
221 return true;
222 return false;
225 /* Return the alignment in bits of EXP, a pointer valued expression.
226 But don't return more than MAX_ALIGN no matter what.
227 The alignment returned is, by default, the alignment of the thing that
228 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
230 Otherwise, look at the expression to see if we can do better, i.e., if the
231 expression is actually pointing at an object whose alignment is tighter. */
233 static int
234 get_pointer_alignment (tree exp, unsigned int max_align)
236 unsigned int align, inner;
238 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
239 return 0;
241 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
242 align = MIN (align, max_align);
244 while (1)
246 switch (TREE_CODE (exp))
248 case NOP_EXPR:
249 case CONVERT_EXPR:
250 case NON_LVALUE_EXPR:
251 exp = TREE_OPERAND (exp, 0);
252 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
253 return align;
255 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
256 align = MIN (inner, max_align);
257 break;
259 case PLUS_EXPR:
260 /* If sum of pointer + int, restrict our maximum alignment to that
261 imposed by the integer. If not, we can't do any better than
262 ALIGN. */
263 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
264 return align;
266 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
267 & (max_align / BITS_PER_UNIT - 1))
268 != 0)
269 max_align >>= 1;
271 exp = TREE_OPERAND (exp, 0);
272 break;
274 case ADDR_EXPR:
275 /* See what we are pointing at and look at its alignment. */
276 exp = TREE_OPERAND (exp, 0);
277 inner = max_align;
278 while (handled_component_p (exp))
280 /* Fields in a structure can be packed, honor DECL_ALIGN
281 of the FIELD_DECL. For all other references the conservative
282 alignment is the element type alignment. */
283 if (TREE_CODE (exp) == COMPONENT_REF)
284 inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
285 else
286 inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
287 exp = TREE_OPERAND (exp, 0);
289 if (TREE_CODE (exp) == FUNCTION_DECL)
290 align = FUNCTION_BOUNDARY;
291 else if (DECL_P (exp))
292 align = MIN (inner, DECL_ALIGN (exp));
293 #ifdef CONSTANT_ALIGNMENT
294 else if (CONSTANT_CLASS_P (exp))
295 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
296 #endif
297 else
298 align = MIN (align, inner);
299 return MIN (align, max_align);
301 default:
302 return align;
307 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
308 way, because it could contain a zero byte in the middle.
309 TREE_STRING_LENGTH is the size of the character array, not the string.
311 ONLY_VALUE should be nonzero if the result is not going to be emitted
312 into the instruction stream and zero if it is going to be expanded.
313 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
314 is returned, otherwise NULL, since
315 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
316 evaluate the side-effects.
318 The value returned is of type `ssizetype'.
320 Unfortunately, string_constant can't access the values of const char
321 arrays with initializers, so neither can we do so here. */
323 tree
324 c_strlen (tree src, int only_value)
326 tree offset_node;
327 HOST_WIDE_INT offset;
328 int max;
329 const char *ptr;
331 STRIP_NOPS (src);
332 if (TREE_CODE (src) == COND_EXPR
333 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
335 tree len1, len2;
337 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
338 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
339 if (tree_int_cst_equal (len1, len2))
340 return len1;
343 if (TREE_CODE (src) == COMPOUND_EXPR
344 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
345 return c_strlen (TREE_OPERAND (src, 1), only_value);
347 src = string_constant (src, &offset_node);
348 if (src == 0)
349 return 0;
351 max = TREE_STRING_LENGTH (src) - 1;
352 ptr = TREE_STRING_POINTER (src);
354 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
356 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
357 compute the offset to the following null if we don't know where to
358 start searching for it. */
359 int i;
361 for (i = 0; i < max; i++)
362 if (ptr[i] == 0)
363 return 0;
365 /* We don't know the starting offset, but we do know that the string
366 has no internal zero bytes. We can assume that the offset falls
367 within the bounds of the string; otherwise, the programmer deserves
368 what he gets. Subtract the offset from the length of the string,
369 and return that. This would perhaps not be valid if we were dealing
370 with named arrays in addition to literal string constants. */
372 return size_diffop (size_int (max), offset_node);
375 /* We have a known offset into the string. Start searching there for
376 a null character if we can represent it as a single HOST_WIDE_INT. */
377 if (offset_node == 0)
378 offset = 0;
379 else if (! host_integerp (offset_node, 0))
380 offset = -1;
381 else
382 offset = tree_low_cst (offset_node, 0);
384 /* If the offset is known to be out of bounds, warn, and call strlen at
385 runtime. */
386 if (offset < 0 || offset > max)
388 warning (0, "offset outside bounds of constant string");
389 return 0;
392 /* Use strlen to search for the first zero byte. Since any strings
393 constructed with build_string will have nulls appended, we win even
394 if we get handed something like (char[4])"abcd".
396 Since OFFSET is our starting index into the string, no further
397 calculation is needed. */
398 return ssize_int (strlen (ptr + offset));
401 /* Return a char pointer for a C string if it is a string constant
402 or sum of string constant and integer constant. */
404 static const char *
405 c_getstr (tree src)
407 tree offset_node;
409 src = string_constant (src, &offset_node);
410 if (src == 0)
411 return 0;
413 if (offset_node == 0)
414 return TREE_STRING_POINTER (src);
415 else if (!host_integerp (offset_node, 1)
416 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
417 return 0;
419 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
422 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
423 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
425 static rtx
426 c_readstr (const char *str, enum machine_mode mode)
428 HOST_WIDE_INT c[2];
429 HOST_WIDE_INT ch;
430 unsigned int i, j;
432 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
434 c[0] = 0;
435 c[1] = 0;
436 ch = 1;
437 for (i = 0; i < GET_MODE_SIZE (mode); i++)
439 j = i;
440 if (WORDS_BIG_ENDIAN)
441 j = GET_MODE_SIZE (mode) - i - 1;
442 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
443 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
444 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
445 j *= BITS_PER_UNIT;
446 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
448 if (ch)
449 ch = (unsigned char) str[i];
450 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
452 return immed_double_const (c[0], c[1], mode);
455 /* Cast a target constant CST to target CHAR and if that value fits into
456 host char type, return zero and put that value into variable pointed to by
457 P. */
459 static int
460 target_char_cast (tree cst, char *p)
462 unsigned HOST_WIDE_INT val, hostval;
464 if (!host_integerp (cst, 1)
465 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
466 return 1;
468 val = tree_low_cst (cst, 1);
469 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
470 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
472 hostval = val;
473 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
474 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
476 if (val != hostval)
477 return 1;
479 *p = hostval;
480 return 0;
483 /* Similar to save_expr, but assumes that arbitrary code is not executed
484 in between the multiple evaluations. In particular, we assume that a
485 non-addressable local variable will not be modified. */
487 static tree
488 builtin_save_expr (tree exp)
490 if (TREE_ADDRESSABLE (exp) == 0
491 && (TREE_CODE (exp) == PARM_DECL
492 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
493 return exp;
495 return save_expr (exp);
498 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
499 times to get the address of either a higher stack frame, or a return
500 address located within it (depending on FNDECL_CODE). */
502 static rtx
503 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
505 int i;
507 #ifdef INITIAL_FRAME_ADDRESS_RTX
508 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
509 #else
510 rtx tem;
512 /* For a zero count, we don't care what frame address we return, so frame
513 pointer elimination is OK, and using the soft frame pointer is OK.
514 For a nonzero count, we require a stable offset from the current frame
515 pointer to the previous one, so we must use the hard frame pointer, and
516 we must disable frame pointer elimination. */
517 if (count == 0)
518 tem = frame_pointer_rtx;
519 else
521 tem = hard_frame_pointer_rtx;
523 /* Tell reload not to eliminate the frame pointer. */
524 current_function_accesses_prior_frames = 1;
526 #endif
528 /* Some machines need special handling before we can access
529 arbitrary frames. For example, on the sparc, we must first flush
530 all register windows to the stack. */
531 #ifdef SETUP_FRAME_ADDRESSES
532 if (count > 0)
533 SETUP_FRAME_ADDRESSES ();
534 #endif
536 /* On the sparc, the return address is not in the frame, it is in a
537 register. There is no way to access it off of the current frame
538 pointer, but it can be accessed off the previous frame pointer by
539 reading the value from the register window save area. */
540 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
541 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
542 count--;
543 #endif
545 /* Scan back COUNT frames to the specified frame. */
546 for (i = 0; i < count; i++)
548 /* Assume the dynamic chain pointer is in the word that the
549 frame address points to, unless otherwise specified. */
550 #ifdef DYNAMIC_CHAIN_ADDRESS
551 tem = DYNAMIC_CHAIN_ADDRESS (tem);
552 #endif
553 tem = memory_address (Pmode, tem);
554 tem = gen_frame_mem (Pmode, tem);
555 tem = copy_to_reg (tem);
558 /* For __builtin_frame_address, return what we've got. */
559 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
560 return tem;
562 /* For __builtin_return_address, Get the return address from that
563 frame. */
564 #ifdef RETURN_ADDR_RTX
565 tem = RETURN_ADDR_RTX (count, tem);
566 #else
567 tem = memory_address (Pmode,
568 plus_constant (tem, GET_MODE_SIZE (Pmode)));
569 tem = gen_frame_mem (Pmode, tem);
570 #endif
571 return tem;
574 /* Alias set used for setjmp buffer. */
575 static HOST_WIDE_INT setjmp_alias_set = -1;
577 /* Construct the leading half of a __builtin_setjmp call. Control will
578 return to RECEIVER_LABEL. This is used directly by sjlj exception
579 handling code. */
581 void
582 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
584 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
585 rtx stack_save;
586 rtx mem;
588 if (setjmp_alias_set == -1)
589 setjmp_alias_set = new_alias_set ();
591 buf_addr = convert_memory_address (Pmode, buf_addr);
593 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
595 /* We store the frame pointer and the address of receiver_label in
596 the buffer and use the rest of it for the stack save area, which
597 is machine-dependent. */
599 mem = gen_rtx_MEM (Pmode, buf_addr);
600 set_mem_alias_set (mem, setjmp_alias_set);
601 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
603 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
604 set_mem_alias_set (mem, setjmp_alias_set);
606 emit_move_insn (validize_mem (mem),
607 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
609 stack_save = gen_rtx_MEM (sa_mode,
610 plus_constant (buf_addr,
611 2 * GET_MODE_SIZE (Pmode)));
612 set_mem_alias_set (stack_save, setjmp_alias_set);
613 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
615 /* If there is further processing to do, do it. */
616 #ifdef HAVE_builtin_setjmp_setup
617 if (HAVE_builtin_setjmp_setup)
618 emit_insn (gen_builtin_setjmp_setup (buf_addr));
619 #endif
621 /* Tell optimize_save_area_alloca that extra work is going to
622 need to go on during alloca. */
623 current_function_calls_setjmp = 1;
625 /* Set this so all the registers get saved in our frame; we need to be
626 able to copy the saved values for any registers from frames we unwind. */
627 current_function_has_nonlocal_label = 1;
630 /* Construct the trailing part of a __builtin_setjmp call.
631 This is used directly by sjlj exception handling code. */
633 void
634 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
636 /* Clobber the FP when we get here, so we have to make sure it's
637 marked as used by this function. */
638 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
640 /* Mark the static chain as clobbered here so life information
641 doesn't get messed up for it. */
642 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
644 /* Now put in the code to restore the frame pointer, and argument
645 pointer, if needed. */
646 #ifdef HAVE_nonlocal_goto
647 if (! HAVE_nonlocal_goto)
648 #endif
649 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
651 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
652 if (fixed_regs[ARG_POINTER_REGNUM])
654 #ifdef ELIMINABLE_REGS
655 size_t i;
656 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
658 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
659 if (elim_regs[i].from == ARG_POINTER_REGNUM
660 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
661 break;
663 if (i == ARRAY_SIZE (elim_regs))
664 #endif
666 /* Now restore our arg pointer from the address at which it
667 was saved in our stack frame. */
668 emit_move_insn (virtual_incoming_args_rtx,
669 copy_to_reg (get_arg_pointer_save_area (cfun)));
672 #endif
674 #ifdef HAVE_builtin_setjmp_receiver
675 if (HAVE_builtin_setjmp_receiver)
676 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
677 else
678 #endif
679 #ifdef HAVE_nonlocal_goto_receiver
680 if (HAVE_nonlocal_goto_receiver)
681 emit_insn (gen_nonlocal_goto_receiver ());
682 else
683 #endif
684 { /* Nothing */ }
686 /* @@@ This is a kludge. Not all machine descriptions define a blockage
687 insn, but we must not allow the code we just generated to be reordered
688 by scheduling. Specifically, the update of the frame pointer must
689 happen immediately, not later. So emit an ASM_INPUT to act as blockage
690 insn. */
691 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
694 /* __builtin_setjmp is passed a pointer to an array of five words (not
695 all will be used on all machines). It operates similarly to the C
696 library function of the same name, but is more efficient. Much of
697 the code below (and for longjmp) is copied from the handling of
698 non-local gotos.
700 NOTE: This is intended for use by GNAT and the exception handling
701 scheme in the compiler and will only work in the method used by
702 them. */
704 static rtx
705 expand_builtin_setjmp (tree arglist, rtx target)
707 rtx buf_addr, next_lab, cont_lab;
709 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
710 return NULL_RTX;
712 if (target == 0 || !REG_P (target)
713 || REGNO (target) < FIRST_PSEUDO_REGISTER)
714 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
716 buf_addr = expand_normal (TREE_VALUE (arglist));
718 next_lab = gen_label_rtx ();
719 cont_lab = gen_label_rtx ();
721 expand_builtin_setjmp_setup (buf_addr, next_lab);
723 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
724 ensure that pending stack adjustments are flushed. */
725 emit_move_insn (target, const0_rtx);
726 emit_jump (cont_lab);
728 emit_label (next_lab);
730 expand_builtin_setjmp_receiver (next_lab);
732 /* Set TARGET to one. */
733 emit_move_insn (target, const1_rtx);
734 emit_label (cont_lab);
736 /* Tell flow about the strange goings on. Putting `next_lab' on
737 `nonlocal_goto_handler_labels' to indicates that function
738 calls may traverse the arc back to this label. */
740 current_function_has_nonlocal_label = 1;
741 nonlocal_goto_handler_labels
742 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
744 return target;
747 /* __builtin_longjmp is passed a pointer to an array of five words (not
748 all will be used on all machines). It operates similarly to the C
749 library function of the same name, but is more efficient. Much of
750 the code below is copied from the handling of non-local gotos.
752 NOTE: This is intended for use by GNAT and the exception handling
753 scheme in the compiler and will only work in the method used by
754 them. */
756 static void
757 expand_builtin_longjmp (rtx buf_addr, rtx value)
759 rtx fp, lab, stack, insn, last;
760 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
762 if (setjmp_alias_set == -1)
763 setjmp_alias_set = new_alias_set ();
765 buf_addr = convert_memory_address (Pmode, buf_addr);
767 buf_addr = force_reg (Pmode, buf_addr);
769 /* We used to store value in static_chain_rtx, but that fails if pointers
770 are smaller than integers. We instead require that the user must pass
771 a second argument of 1, because that is what builtin_setjmp will
772 return. This also makes EH slightly more efficient, since we are no
773 longer copying around a value that we don't care about. */
774 gcc_assert (value == const1_rtx);
776 last = get_last_insn ();
777 #ifdef HAVE_builtin_longjmp
778 if (HAVE_builtin_longjmp)
779 emit_insn (gen_builtin_longjmp (buf_addr));
780 else
781 #endif
783 fp = gen_rtx_MEM (Pmode, buf_addr);
784 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
785 GET_MODE_SIZE (Pmode)));
787 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
788 2 * GET_MODE_SIZE (Pmode)));
789 set_mem_alias_set (fp, setjmp_alias_set);
790 set_mem_alias_set (lab, setjmp_alias_set);
791 set_mem_alias_set (stack, setjmp_alias_set);
793 /* Pick up FP, label, and SP from the block and jump. This code is
794 from expand_goto in stmt.c; see there for detailed comments. */
795 #ifdef HAVE_nonlocal_goto
796 if (HAVE_nonlocal_goto)
797 /* We have to pass a value to the nonlocal_goto pattern that will
798 get copied into the static_chain pointer, but it does not matter
799 what that value is, because builtin_setjmp does not use it. */
800 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
801 else
802 #endif
804 lab = copy_to_reg (lab);
806 emit_insn (gen_rtx_CLOBBER (VOIDmode,
807 gen_rtx_MEM (BLKmode,
808 gen_rtx_SCRATCH (VOIDmode))));
809 emit_insn (gen_rtx_CLOBBER (VOIDmode,
810 gen_rtx_MEM (BLKmode,
811 hard_frame_pointer_rtx)));
813 emit_move_insn (hard_frame_pointer_rtx, fp);
814 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
816 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
817 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
818 emit_indirect_jump (lab);
822 /* Search backwards and mark the jump insn as a non-local goto.
823 Note that this precludes the use of __builtin_longjmp to a
824 __builtin_setjmp target in the same function. However, we've
825 already cautioned the user that these functions are for
826 internal exception handling use only. */
827 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
829 gcc_assert (insn != last);
831 if (JUMP_P (insn))
833 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
834 REG_NOTES (insn));
835 break;
837 else if (CALL_P (insn))
838 break;
842 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
843 and the address of the save area. */
845 static rtx
846 expand_builtin_nonlocal_goto (tree arglist)
848 tree t_label, t_save_area;
849 rtx r_label, r_save_area, r_fp, r_sp, insn;
851 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
852 return NULL_RTX;
854 t_label = TREE_VALUE (arglist);
855 arglist = TREE_CHAIN (arglist);
856 t_save_area = TREE_VALUE (arglist);
858 r_label = expand_normal (t_label);
859 r_label = convert_memory_address (Pmode, r_label);
860 r_save_area = expand_normal (t_save_area);
861 r_save_area = convert_memory_address (Pmode, r_save_area);
862 r_fp = gen_rtx_MEM (Pmode, r_save_area);
863 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
864 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
866 current_function_has_nonlocal_goto = 1;
868 #ifdef HAVE_nonlocal_goto
869 /* ??? We no longer need to pass the static chain value, afaik. */
870 if (HAVE_nonlocal_goto)
871 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
872 else
873 #endif
875 r_label = copy_to_reg (r_label);
877 emit_insn (gen_rtx_CLOBBER (VOIDmode,
878 gen_rtx_MEM (BLKmode,
879 gen_rtx_SCRATCH (VOIDmode))));
881 emit_insn (gen_rtx_CLOBBER (VOIDmode,
882 gen_rtx_MEM (BLKmode,
883 hard_frame_pointer_rtx)));
885 /* Restore frame pointer for containing function.
886 This sets the actual hard register used for the frame pointer
887 to the location of the function's incoming static chain info.
888 The non-local goto handler will then adjust it to contain the
889 proper value and reload the argument pointer, if needed. */
890 emit_move_insn (hard_frame_pointer_rtx, r_fp);
891 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
893 /* USE of hard_frame_pointer_rtx added for consistency;
894 not clear if really needed. */
895 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
896 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
897 emit_indirect_jump (r_label);
900 /* Search backwards to the jump insn and mark it as a
901 non-local goto. */
902 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
904 if (JUMP_P (insn))
906 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
907 const0_rtx, REG_NOTES (insn));
908 break;
910 else if (CALL_P (insn))
911 break;
914 return const0_rtx;
917 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
918 (not all will be used on all machines) that was passed to __builtin_setjmp.
919 It updates the stack pointer in that block to correspond to the current
920 stack pointer. */
922 static void
923 expand_builtin_update_setjmp_buf (rtx buf_addr)
925 enum machine_mode sa_mode = Pmode;
926 rtx stack_save;
929 #ifdef HAVE_save_stack_nonlocal
930 if (HAVE_save_stack_nonlocal)
931 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
932 #endif
933 #ifdef STACK_SAVEAREA_MODE
934 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
935 #endif
937 stack_save
938 = gen_rtx_MEM (sa_mode,
939 memory_address
940 (sa_mode,
941 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
943 #ifdef HAVE_setjmp
944 if (HAVE_setjmp)
945 emit_insn (gen_setjmp ());
946 #endif
948 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
951 /* Expand a call to __builtin_prefetch. For a target that does not support
952 data prefetch, evaluate the memory address argument in case it has side
953 effects. */
955 static void
956 expand_builtin_prefetch (tree arglist)
958 tree arg0, arg1, arg2;
959 rtx op0, op1, op2;
961 if (!validate_arglist (arglist, POINTER_TYPE, 0))
962 return;
964 arg0 = TREE_VALUE (arglist);
965 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
966 zero (read) and argument 2 (locality) defaults to 3 (high degree of
967 locality). */
968 if (TREE_CHAIN (arglist))
970 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
971 if (TREE_CHAIN (TREE_CHAIN (arglist)))
972 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
973 else
974 arg2 = build_int_cst (NULL_TREE, 3);
976 else
978 arg1 = integer_zero_node;
979 arg2 = build_int_cst (NULL_TREE, 3);
982 /* Argument 0 is an address. */
983 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
985 /* Argument 1 (read/write flag) must be a compile-time constant int. */
986 if (TREE_CODE (arg1) != INTEGER_CST)
988 error ("second argument to %<__builtin_prefetch%> must be a constant");
989 arg1 = integer_zero_node;
991 op1 = expand_normal (arg1);
992 /* Argument 1 must be either zero or one. */
993 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
995 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
996 " using zero");
997 op1 = const0_rtx;
1000 /* Argument 2 (locality) must be a compile-time constant int. */
1001 if (TREE_CODE (arg2) != INTEGER_CST)
1003 error ("third argument to %<__builtin_prefetch%> must be a constant");
1004 arg2 = integer_zero_node;
1006 op2 = expand_normal (arg2);
1007 /* Argument 2 must be 0, 1, 2, or 3. */
1008 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1010 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1011 op2 = const0_rtx;
1014 #ifdef HAVE_prefetch
1015 if (HAVE_prefetch)
1017 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1018 (op0,
1019 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1020 || (GET_MODE (op0) != Pmode))
1022 op0 = convert_memory_address (Pmode, op0);
1023 op0 = force_reg (Pmode, op0);
1025 emit_insn (gen_prefetch (op0, op1, op2));
1027 #endif
1029 /* Don't do anything with direct references to volatile memory, but
1030 generate code to handle other side effects. */
1031 if (!MEM_P (op0) && side_effects_p (op0))
1032 emit_insn (op0);
1035 /* Get a MEM rtx for expression EXP which is the address of an operand
1036 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1037 the maximum length of the block of memory that might be accessed or
1038 NULL if unknown. */
1040 static rtx
1041 get_memory_rtx (tree exp, tree len)
1043 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1044 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1046 /* Get an expression we can use to find the attributes to assign to MEM.
1047 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1048 we can. First remove any nops. */
1049 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1050 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1051 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1052 exp = TREE_OPERAND (exp, 0);
1054 if (TREE_CODE (exp) == ADDR_EXPR)
1055 exp = TREE_OPERAND (exp, 0);
1056 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1057 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1058 else
1059 exp = NULL;
1061 /* Honor attributes derived from exp, except for the alias set
1062 (as builtin stringops may alias with anything) and the size
1063 (as stringops may access multiple array elements). */
1064 if (exp)
1066 set_mem_attributes (mem, exp, 0);
1068 /* Allow the string and memory builtins to overflow from one
1069 field into another, see http://gcc.gnu.org/PR23561.
1070 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1071 memory accessed by the string or memory builtin will fit
1072 within the field. */
1073 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1075 tree mem_expr = MEM_EXPR (mem);
1076 HOST_WIDE_INT offset = -1, length = -1;
1077 tree inner = exp;
1079 while (TREE_CODE (inner) == ARRAY_REF
1080 || TREE_CODE (inner) == NOP_EXPR
1081 || TREE_CODE (inner) == CONVERT_EXPR
1082 || TREE_CODE (inner) == NON_LVALUE_EXPR
1083 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1084 || TREE_CODE (inner) == SAVE_EXPR)
1085 inner = TREE_OPERAND (inner, 0);
1087 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1089 if (MEM_OFFSET (mem)
1090 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1091 offset = INTVAL (MEM_OFFSET (mem));
1093 if (offset >= 0 && len && host_integerp (len, 0))
1094 length = tree_low_cst (len, 0);
1096 while (TREE_CODE (inner) == COMPONENT_REF)
1098 tree field = TREE_OPERAND (inner, 1);
1099 gcc_assert (! DECL_BIT_FIELD (field));
1100 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1101 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1103 if (length >= 0
1104 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1105 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1107 HOST_WIDE_INT size
1108 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1109 /* If we can prove the memory starting at XEXP (mem, 0)
1110 and ending at XEXP (mem, 0) + LENGTH will fit into
1111 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1112 if (offset <= size
1113 && length <= size
1114 && offset + length <= size)
1115 break;
1118 if (offset >= 0
1119 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1120 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1121 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1122 / BITS_PER_UNIT;
1123 else
1125 offset = -1;
1126 length = -1;
1129 mem_expr = TREE_OPERAND (mem_expr, 0);
1130 inner = TREE_OPERAND (inner, 0);
1133 if (mem_expr == NULL)
1134 offset = -1;
1135 if (mem_expr != MEM_EXPR (mem))
1137 set_mem_expr (mem, mem_expr);
1138 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1141 set_mem_alias_set (mem, 0);
1142 set_mem_size (mem, NULL_RTX);
1145 return mem;
1148 /* Built-in functions to perform an untyped call and return. */
1150 /* For each register that may be used for calling a function, this
1151 gives a mode used to copy the register's value. VOIDmode indicates
1152 the register is not used for calling a function. If the machine
1153 has register windows, this gives only the outbound registers.
1154 INCOMING_REGNO gives the corresponding inbound register. */
1155 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1157 /* For each register that may be used for returning values, this gives
1158 a mode used to copy the register's value. VOIDmode indicates the
1159 register is not used for returning values. If the machine has
1160 register windows, this gives only the outbound registers.
1161 INCOMING_REGNO gives the corresponding inbound register. */
1162 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1164 /* For each register that may be used for calling a function, this
1165 gives the offset of that register into the block returned by
1166 __builtin_apply_args. 0 indicates that the register is not
1167 used for calling a function. */
1168 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1170 /* Return the size required for the block returned by __builtin_apply_args,
1171 and initialize apply_args_mode. */
1173 static int
1174 apply_args_size (void)
1176 static int size = -1;
1177 int align;
1178 unsigned int regno;
1179 enum machine_mode mode;
1181 /* The values computed by this function never change. */
1182 if (size < 0)
1184 /* The first value is the incoming arg-pointer. */
1185 size = GET_MODE_SIZE (Pmode);
1187 /* The second value is the structure value address unless this is
1188 passed as an "invisible" first argument. */
1189 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1190 size += GET_MODE_SIZE (Pmode);
1192 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1193 if (FUNCTION_ARG_REGNO_P (regno))
1195 mode = reg_raw_mode[regno];
1197 gcc_assert (mode != VOIDmode);
1199 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1200 if (size % align != 0)
1201 size = CEIL (size, align) * align;
1202 apply_args_reg_offset[regno] = size;
1203 size += GET_MODE_SIZE (mode);
1204 apply_args_mode[regno] = mode;
1206 else
1208 apply_args_mode[regno] = VOIDmode;
1209 apply_args_reg_offset[regno] = 0;
1212 return size;
1215 /* Return the size required for the block returned by __builtin_apply,
1216 and initialize apply_result_mode. */
1218 static int
1219 apply_result_size (void)
1221 static int size = -1;
1222 int align, regno;
1223 enum machine_mode mode;
1225 /* The values computed by this function never change. */
1226 if (size < 0)
1228 size = 0;
1230 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1231 if (FUNCTION_VALUE_REGNO_P (regno))
1233 mode = reg_raw_mode[regno];
1235 gcc_assert (mode != VOIDmode);
1237 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1238 if (size % align != 0)
1239 size = CEIL (size, align) * align;
1240 size += GET_MODE_SIZE (mode);
1241 apply_result_mode[regno] = mode;
1243 else
1244 apply_result_mode[regno] = VOIDmode;
1246 /* Allow targets that use untyped_call and untyped_return to override
1247 the size so that machine-specific information can be stored here. */
1248 #ifdef APPLY_RESULT_SIZE
1249 size = APPLY_RESULT_SIZE;
1250 #endif
1252 return size;
1255 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1256 /* Create a vector describing the result block RESULT. If SAVEP is true,
1257 the result block is used to save the values; otherwise it is used to
1258 restore the values. */
1260 static rtx
1261 result_vector (int savep, rtx result)
1263 int regno, size, align, nelts;
1264 enum machine_mode mode;
1265 rtx reg, mem;
1266 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1268 size = nelts = 0;
1269 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1270 if ((mode = apply_result_mode[regno]) != VOIDmode)
1272 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1273 if (size % align != 0)
1274 size = CEIL (size, align) * align;
1275 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1276 mem = adjust_address (result, mode, size);
1277 savevec[nelts++] = (savep
1278 ? gen_rtx_SET (VOIDmode, mem, reg)
1279 : gen_rtx_SET (VOIDmode, reg, mem));
1280 size += GET_MODE_SIZE (mode);
1282 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1284 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1286 /* Save the state required to perform an untyped call with the same
1287 arguments as were passed to the current function. */
1289 static rtx
1290 expand_builtin_apply_args_1 (void)
1292 rtx registers, tem;
1293 int size, align, regno;
1294 enum machine_mode mode;
1295 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1297 /* Create a block where the arg-pointer, structure value address,
1298 and argument registers can be saved. */
1299 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1301 /* Walk past the arg-pointer and structure value address. */
1302 size = GET_MODE_SIZE (Pmode);
1303 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1304 size += GET_MODE_SIZE (Pmode);
1306 /* Save each register used in calling a function to the block. */
1307 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1308 if ((mode = apply_args_mode[regno]) != VOIDmode)
1310 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1311 if (size % align != 0)
1312 size = CEIL (size, align) * align;
1314 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1316 emit_move_insn (adjust_address (registers, mode, size), tem);
1317 size += GET_MODE_SIZE (mode);
1320 /* Save the arg pointer to the block. */
1321 tem = copy_to_reg (virtual_incoming_args_rtx);
1322 #ifdef STACK_GROWS_DOWNWARD
1323 /* We need the pointer as the caller actually passed them to us, not
1324 as we might have pretended they were passed. Make sure it's a valid
1325 operand, as emit_move_insn isn't expected to handle a PLUS. */
1327 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1328 NULL_RTX);
1329 #endif
1330 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1332 size = GET_MODE_SIZE (Pmode);
1334 /* Save the structure value address unless this is passed as an
1335 "invisible" first argument. */
1336 if (struct_incoming_value)
1338 emit_move_insn (adjust_address (registers, Pmode, size),
1339 copy_to_reg (struct_incoming_value));
1340 size += GET_MODE_SIZE (Pmode);
1343 /* Return the address of the block. */
1344 return copy_addr_to_reg (XEXP (registers, 0));
1347 /* __builtin_apply_args returns block of memory allocated on
1348 the stack into which is stored the arg pointer, structure
1349 value address, static chain, and all the registers that might
1350 possibly be used in performing a function call. The code is
1351 moved to the start of the function so the incoming values are
1352 saved. */
1354 static rtx
1355 expand_builtin_apply_args (void)
1357 /* Don't do __builtin_apply_args more than once in a function.
1358 Save the result of the first call and reuse it. */
1359 if (apply_args_value != 0)
1360 return apply_args_value;
1362 /* When this function is called, it means that registers must be
1363 saved on entry to this function. So we migrate the
1364 call to the first insn of this function. */
1365 rtx temp;
1366 rtx seq;
1368 start_sequence ();
1369 temp = expand_builtin_apply_args_1 ();
1370 seq = get_insns ();
1371 end_sequence ();
1373 apply_args_value = temp;
1375 /* Put the insns after the NOTE that starts the function.
1376 If this is inside a start_sequence, make the outer-level insn
1377 chain current, so the code is placed at the start of the
1378 function. */
1379 push_topmost_sequence ();
1380 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1381 pop_topmost_sequence ();
1382 return temp;
1386 /* Perform an untyped call and save the state required to perform an
1387 untyped return of whatever value was returned by the given function. */
1389 static rtx
1390 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1392 int size, align, regno;
1393 enum machine_mode mode;
1394 rtx incoming_args, result, reg, dest, src, call_insn;
1395 rtx old_stack_level = 0;
1396 rtx call_fusage = 0;
1397 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1399 arguments = convert_memory_address (Pmode, arguments);
1401 /* Create a block where the return registers can be saved. */
1402 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1404 /* Fetch the arg pointer from the ARGUMENTS block. */
1405 incoming_args = gen_reg_rtx (Pmode);
1406 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1407 #ifndef STACK_GROWS_DOWNWARD
1408 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1409 incoming_args, 0, OPTAB_LIB_WIDEN);
1410 #endif
1412 /* Push a new argument block and copy the arguments. Do not allow
1413 the (potential) memcpy call below to interfere with our stack
1414 manipulations. */
1415 do_pending_stack_adjust ();
1416 NO_DEFER_POP;
1418 /* Save the stack with nonlocal if available. */
1419 #ifdef HAVE_save_stack_nonlocal
1420 if (HAVE_save_stack_nonlocal)
1421 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1422 else
1423 #endif
1424 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1426 /* Allocate a block of memory onto the stack and copy the memory
1427 arguments to the outgoing arguments address. */
1428 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1429 dest = virtual_outgoing_args_rtx;
1430 #ifndef STACK_GROWS_DOWNWARD
1431 if (GET_CODE (argsize) == CONST_INT)
1432 dest = plus_constant (dest, -INTVAL (argsize));
1433 else
1434 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1435 #endif
1436 dest = gen_rtx_MEM (BLKmode, dest);
1437 set_mem_align (dest, PARM_BOUNDARY);
1438 src = gen_rtx_MEM (BLKmode, incoming_args);
1439 set_mem_align (src, PARM_BOUNDARY);
1440 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1442 /* Refer to the argument block. */
1443 apply_args_size ();
1444 arguments = gen_rtx_MEM (BLKmode, arguments);
1445 set_mem_align (arguments, PARM_BOUNDARY);
1447 /* Walk past the arg-pointer and structure value address. */
1448 size = GET_MODE_SIZE (Pmode);
1449 if (struct_value)
1450 size += GET_MODE_SIZE (Pmode);
1452 /* Restore each of the registers previously saved. Make USE insns
1453 for each of these registers for use in making the call. */
1454 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1455 if ((mode = apply_args_mode[regno]) != VOIDmode)
1457 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1458 if (size % align != 0)
1459 size = CEIL (size, align) * align;
1460 reg = gen_rtx_REG (mode, regno);
1461 emit_move_insn (reg, adjust_address (arguments, mode, size));
1462 use_reg (&call_fusage, reg);
1463 size += GET_MODE_SIZE (mode);
1466 /* Restore the structure value address unless this is passed as an
1467 "invisible" first argument. */
1468 size = GET_MODE_SIZE (Pmode);
1469 if (struct_value)
1471 rtx value = gen_reg_rtx (Pmode);
1472 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1473 emit_move_insn (struct_value, value);
1474 if (REG_P (struct_value))
1475 use_reg (&call_fusage, struct_value);
1476 size += GET_MODE_SIZE (Pmode);
1479 /* All arguments and registers used for the call are set up by now! */
1480 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1482 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1483 and we don't want to load it into a register as an optimization,
1484 because prepare_call_address already did it if it should be done. */
1485 if (GET_CODE (function) != SYMBOL_REF)
1486 function = memory_address (FUNCTION_MODE, function);
1488 /* Generate the actual call instruction and save the return value. */
1489 #ifdef HAVE_untyped_call
1490 if (HAVE_untyped_call)
1491 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1492 result, result_vector (1, result)));
1493 else
1494 #endif
1495 #ifdef HAVE_call_value
1496 if (HAVE_call_value)
1498 rtx valreg = 0;
1500 /* Locate the unique return register. It is not possible to
1501 express a call that sets more than one return register using
1502 call_value; use untyped_call for that. In fact, untyped_call
1503 only needs to save the return registers in the given block. */
1504 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1505 if ((mode = apply_result_mode[regno]) != VOIDmode)
1507 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1509 valreg = gen_rtx_REG (mode, regno);
1512 emit_call_insn (GEN_CALL_VALUE (valreg,
1513 gen_rtx_MEM (FUNCTION_MODE, function),
1514 const0_rtx, NULL_RTX, const0_rtx));
1516 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1518 else
1519 #endif
1520 gcc_unreachable ();
1522 /* Find the CALL insn we just emitted, and attach the register usage
1523 information. */
1524 call_insn = last_call_insn ();
1525 add_function_usage_to (call_insn, call_fusage);
1527 /* Restore the stack. */
1528 #ifdef HAVE_save_stack_nonlocal
1529 if (HAVE_save_stack_nonlocal)
1530 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1531 else
1532 #endif
1533 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1535 OK_DEFER_POP;
1537 /* Return the address of the result block. */
1538 result = copy_addr_to_reg (XEXP (result, 0));
1539 return convert_memory_address (ptr_mode, result);
1542 /* Perform an untyped return. */
1544 static void
1545 expand_builtin_return (rtx result)
1547 int size, align, regno;
1548 enum machine_mode mode;
1549 rtx reg;
1550 rtx call_fusage = 0;
1552 result = convert_memory_address (Pmode, result);
1554 apply_result_size ();
1555 result = gen_rtx_MEM (BLKmode, result);
1557 #ifdef HAVE_untyped_return
1558 if (HAVE_untyped_return)
1560 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1561 emit_barrier ();
1562 return;
1564 #endif
1566 /* Restore the return value and note that each value is used. */
1567 size = 0;
1568 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1569 if ((mode = apply_result_mode[regno]) != VOIDmode)
1571 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1572 if (size % align != 0)
1573 size = CEIL (size, align) * align;
1574 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1575 emit_move_insn (reg, adjust_address (result, mode, size));
1577 push_to_sequence (call_fusage);
1578 emit_insn (gen_rtx_USE (VOIDmode, reg));
1579 call_fusage = get_insns ();
1580 end_sequence ();
1581 size += GET_MODE_SIZE (mode);
1584 /* Put the USE insns before the return. */
1585 emit_insn (call_fusage);
1587 /* Return whatever values was restored by jumping directly to the end
1588 of the function. */
1589 expand_naked_return ();
1592 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1594 static enum type_class
1595 type_to_class (tree type)
1597 switch (TREE_CODE (type))
1599 case VOID_TYPE: return void_type_class;
1600 case INTEGER_TYPE: return integer_type_class;
1601 case ENUMERAL_TYPE: return enumeral_type_class;
1602 case BOOLEAN_TYPE: return boolean_type_class;
1603 case POINTER_TYPE: return pointer_type_class;
1604 case REFERENCE_TYPE: return reference_type_class;
1605 case OFFSET_TYPE: return offset_type_class;
1606 case REAL_TYPE: return real_type_class;
1607 case COMPLEX_TYPE: return complex_type_class;
1608 case FUNCTION_TYPE: return function_type_class;
1609 case METHOD_TYPE: return method_type_class;
1610 case RECORD_TYPE: return record_type_class;
1611 case UNION_TYPE:
1612 case QUAL_UNION_TYPE: return union_type_class;
1613 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1614 ? string_type_class : array_type_class);
1615 case LANG_TYPE: return lang_type_class;
1616 default: return no_type_class;
1620 /* Expand a call to __builtin_classify_type with arguments found in
1621 ARGLIST. */
1623 static rtx
1624 expand_builtin_classify_type (tree arglist)
1626 if (arglist != 0)
1627 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1628 return GEN_INT (no_type_class);
1631 /* This helper macro, meant to be used in mathfn_built_in below,
1632 determines which among a set of three builtin math functions is
1633 appropriate for a given type mode. The `F' and `L' cases are
1634 automatically generated from the `double' case. */
1635 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1636 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1637 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1638 fcodel = BUILT_IN_MATHFN##L ; break;
1640 /* Return mathematic function equivalent to FN but operating directly
1641 on TYPE, if available. If we can't do the conversion, return zero. */
1642 tree
1643 mathfn_built_in (tree type, enum built_in_function fn)
1645 enum built_in_function fcode, fcodef, fcodel;
1647 switch (fn)
1649 CASE_MATHFN (BUILT_IN_ACOS)
1650 CASE_MATHFN (BUILT_IN_ACOSH)
1651 CASE_MATHFN (BUILT_IN_ASIN)
1652 CASE_MATHFN (BUILT_IN_ASINH)
1653 CASE_MATHFN (BUILT_IN_ATAN)
1654 CASE_MATHFN (BUILT_IN_ATAN2)
1655 CASE_MATHFN (BUILT_IN_ATANH)
1656 CASE_MATHFN (BUILT_IN_CBRT)
1657 CASE_MATHFN (BUILT_IN_CEIL)
1658 CASE_MATHFN (BUILT_IN_COPYSIGN)
1659 CASE_MATHFN (BUILT_IN_COS)
1660 CASE_MATHFN (BUILT_IN_COSH)
1661 CASE_MATHFN (BUILT_IN_DREM)
1662 CASE_MATHFN (BUILT_IN_ERF)
1663 CASE_MATHFN (BUILT_IN_ERFC)
1664 CASE_MATHFN (BUILT_IN_EXP)
1665 CASE_MATHFN (BUILT_IN_EXP10)
1666 CASE_MATHFN (BUILT_IN_EXP2)
1667 CASE_MATHFN (BUILT_IN_EXPM1)
1668 CASE_MATHFN (BUILT_IN_FABS)
1669 CASE_MATHFN (BUILT_IN_FDIM)
1670 CASE_MATHFN (BUILT_IN_FLOOR)
1671 CASE_MATHFN (BUILT_IN_FMA)
1672 CASE_MATHFN (BUILT_IN_FMAX)
1673 CASE_MATHFN (BUILT_IN_FMIN)
1674 CASE_MATHFN (BUILT_IN_FMOD)
1675 CASE_MATHFN (BUILT_IN_FREXP)
1676 CASE_MATHFN (BUILT_IN_GAMMA)
1677 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1678 CASE_MATHFN (BUILT_IN_HYPOT)
1679 CASE_MATHFN (BUILT_IN_ILOGB)
1680 CASE_MATHFN (BUILT_IN_INF)
1681 CASE_MATHFN (BUILT_IN_J0)
1682 CASE_MATHFN (BUILT_IN_J1)
1683 CASE_MATHFN (BUILT_IN_JN)
1684 CASE_MATHFN (BUILT_IN_LCEIL)
1685 CASE_MATHFN (BUILT_IN_LDEXP)
1686 CASE_MATHFN (BUILT_IN_LFLOOR)
1687 CASE_MATHFN (BUILT_IN_LGAMMA)
1688 CASE_MATHFN (BUILT_IN_LLCEIL)
1689 CASE_MATHFN (BUILT_IN_LLFLOOR)
1690 CASE_MATHFN (BUILT_IN_LLRINT)
1691 CASE_MATHFN (BUILT_IN_LLROUND)
1692 CASE_MATHFN (BUILT_IN_LOG)
1693 CASE_MATHFN (BUILT_IN_LOG10)
1694 CASE_MATHFN (BUILT_IN_LOG1P)
1695 CASE_MATHFN (BUILT_IN_LOG2)
1696 CASE_MATHFN (BUILT_IN_LOGB)
1697 CASE_MATHFN (BUILT_IN_LRINT)
1698 CASE_MATHFN (BUILT_IN_LROUND)
1699 CASE_MATHFN (BUILT_IN_MODF)
1700 CASE_MATHFN (BUILT_IN_NAN)
1701 CASE_MATHFN (BUILT_IN_NANS)
1702 CASE_MATHFN (BUILT_IN_NEARBYINT)
1703 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1704 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1705 CASE_MATHFN (BUILT_IN_POW)
1706 CASE_MATHFN (BUILT_IN_POWI)
1707 CASE_MATHFN (BUILT_IN_POW10)
1708 CASE_MATHFN (BUILT_IN_REMAINDER)
1709 CASE_MATHFN (BUILT_IN_REMQUO)
1710 CASE_MATHFN (BUILT_IN_RINT)
1711 CASE_MATHFN (BUILT_IN_ROUND)
1712 CASE_MATHFN (BUILT_IN_SCALB)
1713 CASE_MATHFN (BUILT_IN_SCALBLN)
1714 CASE_MATHFN (BUILT_IN_SCALBN)
1715 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1716 CASE_MATHFN (BUILT_IN_SIN)
1717 CASE_MATHFN (BUILT_IN_SINCOS)
1718 CASE_MATHFN (BUILT_IN_SINH)
1719 CASE_MATHFN (BUILT_IN_SQRT)
1720 CASE_MATHFN (BUILT_IN_TAN)
1721 CASE_MATHFN (BUILT_IN_TANH)
1722 CASE_MATHFN (BUILT_IN_TGAMMA)
1723 CASE_MATHFN (BUILT_IN_TRUNC)
1724 CASE_MATHFN (BUILT_IN_Y0)
1725 CASE_MATHFN (BUILT_IN_Y1)
1726 CASE_MATHFN (BUILT_IN_YN)
1728 default:
1729 return 0;
1732 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1733 return implicit_built_in_decls[fcode];
1734 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1735 return implicit_built_in_decls[fcodef];
1736 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1737 return implicit_built_in_decls[fcodel];
1738 else
1739 return 0;
1742 /* If errno must be maintained, expand the RTL to check if the result,
1743 TARGET, of a built-in function call, EXP, is NaN, and if so set
1744 errno to EDOM. */
1746 static void
1747 expand_errno_check (tree exp, rtx target)
1749 rtx lab = gen_label_rtx ();
1751 /* Test the result; if it is NaN, set errno=EDOM because
1752 the argument was not in the domain. */
1753 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1754 0, lab);
1756 #ifdef TARGET_EDOM
1757 /* If this built-in doesn't throw an exception, set errno directly. */
1758 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1760 #ifdef GEN_ERRNO_RTX
1761 rtx errno_rtx = GEN_ERRNO_RTX;
1762 #else
1763 rtx errno_rtx
1764 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1765 #endif
1766 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1767 emit_label (lab);
1768 return;
1770 #endif
1772 /* We can't set errno=EDOM directly; let the library call do it.
1773 Pop the arguments right away in case the call gets deleted. */
1774 NO_DEFER_POP;
1775 expand_call (exp, target, 0);
1776 OK_DEFER_POP;
1777 emit_label (lab);
1781 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1782 Return 0 if a normal call should be emitted rather than expanding the
1783 function in-line. EXP is the expression that is a call to the builtin
1784 function; if convenient, the result should be placed in TARGET.
1785 SUBTARGET may be used as the target for computing one of EXP's operands. */
1787 static rtx
1788 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1790 optab builtin_optab;
1791 rtx op0, insns, before_call;
1792 tree fndecl = get_callee_fndecl (exp);
1793 tree arglist = TREE_OPERAND (exp, 1);
1794 enum machine_mode mode;
1795 bool errno_set = false;
1796 tree arg, narg;
1798 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1799 return 0;
1801 arg = TREE_VALUE (arglist);
1803 switch (DECL_FUNCTION_CODE (fndecl))
1805 CASE_FLT_FN (BUILT_IN_SQRT):
1806 errno_set = ! tree_expr_nonnegative_p (arg);
1807 builtin_optab = sqrt_optab;
1808 break;
1809 CASE_FLT_FN (BUILT_IN_EXP):
1810 errno_set = true; builtin_optab = exp_optab; break;
1811 CASE_FLT_FN (BUILT_IN_EXP10):
1812 CASE_FLT_FN (BUILT_IN_POW10):
1813 errno_set = true; builtin_optab = exp10_optab; break;
1814 CASE_FLT_FN (BUILT_IN_EXP2):
1815 errno_set = true; builtin_optab = exp2_optab; break;
1816 CASE_FLT_FN (BUILT_IN_EXPM1):
1817 errno_set = true; builtin_optab = expm1_optab; break;
1818 CASE_FLT_FN (BUILT_IN_LOGB):
1819 errno_set = true; builtin_optab = logb_optab; break;
1820 CASE_FLT_FN (BUILT_IN_ILOGB):
1821 errno_set = true; builtin_optab = ilogb_optab; break;
1822 CASE_FLT_FN (BUILT_IN_LOG):
1823 errno_set = true; builtin_optab = log_optab; break;
1824 CASE_FLT_FN (BUILT_IN_LOG10):
1825 errno_set = true; builtin_optab = log10_optab; break;
1826 CASE_FLT_FN (BUILT_IN_LOG2):
1827 errno_set = true; builtin_optab = log2_optab; break;
1828 CASE_FLT_FN (BUILT_IN_LOG1P):
1829 errno_set = true; builtin_optab = log1p_optab; break;
1830 CASE_FLT_FN (BUILT_IN_ASIN):
1831 builtin_optab = asin_optab; break;
1832 CASE_FLT_FN (BUILT_IN_ACOS):
1833 builtin_optab = acos_optab; break;
1834 CASE_FLT_FN (BUILT_IN_TAN):
1835 builtin_optab = tan_optab; break;
1836 CASE_FLT_FN (BUILT_IN_ATAN):
1837 builtin_optab = atan_optab; break;
1838 CASE_FLT_FN (BUILT_IN_FLOOR):
1839 builtin_optab = floor_optab; break;
1840 CASE_FLT_FN (BUILT_IN_CEIL):
1841 builtin_optab = ceil_optab; break;
1842 CASE_FLT_FN (BUILT_IN_TRUNC):
1843 builtin_optab = btrunc_optab; break;
1844 CASE_FLT_FN (BUILT_IN_ROUND):
1845 builtin_optab = round_optab; break;
1846 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1847 builtin_optab = nearbyint_optab; break;
1848 CASE_FLT_FN (BUILT_IN_RINT):
1849 builtin_optab = rint_optab; break;
1850 CASE_FLT_FN (BUILT_IN_LRINT):
1851 CASE_FLT_FN (BUILT_IN_LLRINT):
1852 builtin_optab = lrint_optab; break;
1853 default:
1854 gcc_unreachable ();
1857 /* Make a suitable register to place result in. */
1858 mode = TYPE_MODE (TREE_TYPE (exp));
1860 if (! flag_errno_math || ! HONOR_NANS (mode))
1861 errno_set = false;
1863 /* Before working hard, check whether the instruction is available. */
1864 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1866 target = gen_reg_rtx (mode);
1868 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1869 need to expand the argument again. This way, we will not perform
1870 side-effects more the once. */
1871 narg = builtin_save_expr (arg);
1872 if (narg != arg)
1874 arg = narg;
1875 arglist = build_tree_list (NULL_TREE, arg);
1876 exp = build_function_call_expr (fndecl, arglist);
1879 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1881 start_sequence ();
1883 /* Compute into TARGET.
1884 Set TARGET to wherever the result comes back. */
1885 target = expand_unop (mode, builtin_optab, op0, target, 0);
1887 if (target != 0)
1889 if (errno_set)
1890 expand_errno_check (exp, target);
1892 /* Output the entire sequence. */
1893 insns = get_insns ();
1894 end_sequence ();
1895 emit_insn (insns);
1896 return target;
1899 /* If we were unable to expand via the builtin, stop the sequence
1900 (without outputting the insns) and call to the library function
1901 with the stabilized argument list. */
1902 end_sequence ();
1905 before_call = get_last_insn ();
1907 target = expand_call (exp, target, target == const0_rtx);
1909 /* If this is a sqrt operation and we don't care about errno, try to
1910 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1911 This allows the semantics of the libcall to be visible to the RTL
1912 optimizers. */
1913 if (builtin_optab == sqrt_optab && !errno_set)
1915 /* Search backwards through the insns emitted by expand_call looking
1916 for the instruction with the REG_RETVAL note. */
1917 rtx last = get_last_insn ();
1918 while (last != before_call)
1920 if (find_reg_note (last, REG_RETVAL, NULL))
1922 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1923 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1924 two elements, i.e. symbol_ref(sqrt) and the operand. */
1925 if (note
1926 && GET_CODE (note) == EXPR_LIST
1927 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1928 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1929 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1931 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1932 /* Check operand is a register with expected mode. */
1933 if (operand
1934 && REG_P (operand)
1935 && GET_MODE (operand) == mode)
1937 /* Replace the REG_EQUAL note with a SQRT rtx. */
1938 rtx equiv = gen_rtx_SQRT (mode, operand);
1939 set_unique_reg_note (last, REG_EQUAL, equiv);
1942 break;
1944 last = PREV_INSN (last);
1948 return target;
1951 /* Expand a call to the builtin binary math functions (pow and atan2).
1952 Return 0 if a normal call should be emitted rather than expanding the
1953 function in-line. EXP is the expression that is a call to the builtin
1954 function; if convenient, the result should be placed in TARGET.
1955 SUBTARGET may be used as the target for computing one of EXP's
1956 operands. */
1958 static rtx
1959 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1961 optab builtin_optab;
1962 rtx op0, op1, insns;
1963 int op1_type = REAL_TYPE;
1964 tree fndecl = get_callee_fndecl (exp);
1965 tree arglist = TREE_OPERAND (exp, 1);
1966 tree arg0, arg1, temp, narg;
1967 enum machine_mode mode;
1968 bool errno_set = true;
1969 bool stable = true;
1971 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1972 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1973 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1974 op1_type = INTEGER_TYPE;
1976 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1977 return 0;
1979 arg0 = TREE_VALUE (arglist);
1980 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1982 switch (DECL_FUNCTION_CODE (fndecl))
1984 CASE_FLT_FN (BUILT_IN_POW):
1985 builtin_optab = pow_optab; break;
1986 CASE_FLT_FN (BUILT_IN_ATAN2):
1987 builtin_optab = atan2_optab; break;
1988 CASE_FLT_FN (BUILT_IN_LDEXP):
1989 builtin_optab = ldexp_optab; break;
1990 CASE_FLT_FN (BUILT_IN_FMOD):
1991 builtin_optab = fmod_optab; break;
1992 CASE_FLT_FN (BUILT_IN_DREM):
1993 builtin_optab = drem_optab; break;
1994 default:
1995 gcc_unreachable ();
1998 /* Make a suitable register to place result in. */
1999 mode = TYPE_MODE (TREE_TYPE (exp));
2001 /* Before working hard, check whether the instruction is available. */
2002 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2003 return 0;
2005 target = gen_reg_rtx (mode);
2007 if (! flag_errno_math || ! HONOR_NANS (mode))
2008 errno_set = false;
2010 /* Always stabilize the argument list. */
2011 narg = builtin_save_expr (arg1);
2012 if (narg != arg1)
2014 arg1 = narg;
2015 temp = build_tree_list (NULL_TREE, narg);
2016 stable = false;
2018 else
2019 temp = TREE_CHAIN (arglist);
2021 narg = builtin_save_expr (arg0);
2022 if (narg != arg0)
2024 arg0 = narg;
2025 arglist = tree_cons (NULL_TREE, narg, temp);
2026 stable = false;
2028 else if (! stable)
2029 arglist = tree_cons (NULL_TREE, arg0, temp);
2031 if (! stable)
2032 exp = build_function_call_expr (fndecl, arglist);
2034 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2035 op1 = expand_normal (arg1);
2037 start_sequence ();
2039 /* Compute into TARGET.
2040 Set TARGET to wherever the result comes back. */
2041 target = expand_binop (mode, builtin_optab, op0, op1,
2042 target, 0, OPTAB_DIRECT);
2044 /* If we were unable to expand via the builtin, stop the sequence
2045 (without outputting the insns) and call to the library function
2046 with the stabilized argument list. */
2047 if (target == 0)
2049 end_sequence ();
2050 return expand_call (exp, target, target == const0_rtx);
2053 if (errno_set)
2054 expand_errno_check (exp, target);
2056 /* Output the entire sequence. */
2057 insns = get_insns ();
2058 end_sequence ();
2059 emit_insn (insns);
2061 return target;
2064 /* Expand a call to the builtin sin and cos math functions.
2065 Return 0 if a normal call should be emitted rather than expanding the
2066 function in-line. EXP is the expression that is a call to the builtin
2067 function; if convenient, the result should be placed in TARGET.
2068 SUBTARGET may be used as the target for computing one of EXP's
2069 operands. */
2071 static rtx
2072 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2074 optab builtin_optab;
2075 rtx op0, insns;
2076 tree fndecl = get_callee_fndecl (exp);
2077 tree arglist = TREE_OPERAND (exp, 1);
2078 enum machine_mode mode;
2079 tree arg, narg;
2081 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2082 return 0;
2084 arg = TREE_VALUE (arglist);
2086 switch (DECL_FUNCTION_CODE (fndecl))
2088 CASE_FLT_FN (BUILT_IN_SIN):
2089 CASE_FLT_FN (BUILT_IN_COS):
2090 builtin_optab = sincos_optab; break;
2091 default:
2092 gcc_unreachable ();
2095 /* Make a suitable register to place result in. */
2096 mode = TYPE_MODE (TREE_TYPE (exp));
2098 /* Check if sincos insn is available, otherwise fallback
2099 to sin or cos insn. */
2100 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2101 switch (DECL_FUNCTION_CODE (fndecl))
2103 CASE_FLT_FN (BUILT_IN_SIN):
2104 builtin_optab = sin_optab; break;
2105 CASE_FLT_FN (BUILT_IN_COS):
2106 builtin_optab = cos_optab; break;
2107 default:
2108 gcc_unreachable ();
2112 /* Before working hard, check whether the instruction is available. */
2113 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2115 target = gen_reg_rtx (mode);
2117 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2118 need to expand the argument again. This way, we will not perform
2119 side-effects more the once. */
2120 narg = save_expr (arg);
2121 if (narg != arg)
2123 arg = narg;
2124 arglist = build_tree_list (NULL_TREE, arg);
2125 exp = build_function_call_expr (fndecl, arglist);
2128 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2130 start_sequence ();
2132 /* Compute into TARGET.
2133 Set TARGET to wherever the result comes back. */
2134 if (builtin_optab == sincos_optab)
2136 int result;
2138 switch (DECL_FUNCTION_CODE (fndecl))
2140 CASE_FLT_FN (BUILT_IN_SIN):
2141 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2142 break;
2143 CASE_FLT_FN (BUILT_IN_COS):
2144 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2145 break;
2146 default:
2147 gcc_unreachable ();
2149 gcc_assert (result);
2151 else
2153 target = expand_unop (mode, builtin_optab, op0, target, 0);
2156 if (target != 0)
2158 /* Output the entire sequence. */
2159 insns = get_insns ();
2160 end_sequence ();
2161 emit_insn (insns);
2162 return target;
2165 /* If we were unable to expand via the builtin, stop the sequence
2166 (without outputting the insns) and call to the library function
2167 with the stabilized argument list. */
2168 end_sequence ();
2171 target = expand_call (exp, target, target == const0_rtx);
2173 return target;
2176 /* Expand a call to the builtin sincos math function.
2177 Return 0 if a normal call should be emitted rather than expanding the
2178 function in-line. EXP is the expression that is a call to the builtin
2179 function. */
2181 static rtx
2182 expand_builtin_sincos (tree exp)
2184 rtx op0, op1, op2, target1, target2;
2185 tree arglist = TREE_OPERAND (exp, 1);
2186 enum machine_mode mode;
2187 tree arg, sinp, cosp;
2188 int result;
2190 if (!validate_arglist (arglist, REAL_TYPE,
2191 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2192 return 0;
2194 arg = TREE_VALUE (arglist);
2195 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2196 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2198 /* Make a suitable register to place result in. */
2199 mode = TYPE_MODE (TREE_TYPE (arg));
2201 /* Check if sincos insn is available, otherwise emit the call. */
2202 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2203 return NULL_RTX;
2205 target1 = gen_reg_rtx (mode);
2206 target2 = gen_reg_rtx (mode);
2208 op0 = expand_normal (arg);
2209 op1 = expand_normal (build_fold_indirect_ref (sinp));
2210 op2 = expand_normal (build_fold_indirect_ref (cosp));
2212 /* Compute into target1 and target2.
2213 Set TARGET to wherever the result comes back. */
2214 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2215 gcc_assert (result);
2217 /* Move target1 and target2 to the memory locations indicated
2218 by op1 and op2. */
2219 emit_move_insn (op1, target1);
2220 emit_move_insn (op2, target2);
2222 return const0_rtx;
2225 /* Expand a call to one of the builtin rounding functions (lfloor).
2226 If expanding via optab fails, lower expression to (int)(floor(x)).
2227 EXP is the expression that is a call to the builtin function;
2228 if convenient, the result should be placed in TARGET. SUBTARGET may
2229 be used as the target for computing one of EXP's operands. */
2231 static rtx
2232 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2234 optab builtin_optab;
2235 rtx op0, insns, tmp;
2236 tree fndecl = get_callee_fndecl (exp);
2237 tree arglist = TREE_OPERAND (exp, 1);
2238 enum built_in_function fallback_fn;
2239 tree fallback_fndecl;
2240 enum machine_mode mode;
2241 tree arg, narg;
2243 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2244 gcc_unreachable ();
2246 arg = TREE_VALUE (arglist);
2248 switch (DECL_FUNCTION_CODE (fndecl))
2250 CASE_FLT_FN (BUILT_IN_LCEIL):
2251 CASE_FLT_FN (BUILT_IN_LLCEIL):
2252 builtin_optab = lceil_optab;
2253 fallback_fn = BUILT_IN_CEIL;
2254 break;
2256 CASE_FLT_FN (BUILT_IN_LFLOOR):
2257 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2258 builtin_optab = lfloor_optab;
2259 fallback_fn = BUILT_IN_FLOOR;
2260 break;
2262 default:
2263 gcc_unreachable ();
2266 /* Make a suitable register to place result in. */
2267 mode = TYPE_MODE (TREE_TYPE (exp));
2269 /* Before working hard, check whether the instruction is available. */
2270 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2272 target = gen_reg_rtx (mode);
2274 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2275 need to expand the argument again. This way, we will not perform
2276 side-effects more the once. */
2277 narg = builtin_save_expr (arg);
2278 if (narg != arg)
2280 arg = narg;
2281 arglist = build_tree_list (NULL_TREE, arg);
2282 exp = build_function_call_expr (fndecl, arglist);
2285 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2287 start_sequence ();
2289 /* Compute into TARGET.
2290 Set TARGET to wherever the result comes back. */
2291 target = expand_unop (mode, builtin_optab, op0, target, 0);
2293 if (target != 0)
2295 /* Output the entire sequence. */
2296 insns = get_insns ();
2297 end_sequence ();
2298 emit_insn (insns);
2299 return target;
2302 /* If we were unable to expand via the builtin, stop the sequence
2303 (without outputting the insns). */
2304 end_sequence ();
2307 /* Fall back to floating point rounding optab. */
2308 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2309 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2310 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2311 gcc_assert (fallback_fndecl != NULL_TREE);
2312 exp = build_function_call_expr (fallback_fndecl, arglist);
2314 tmp = expand_normal (exp);
2316 /* Truncate the result of floating point optab to integer
2317 via expand_fix (). */
2318 target = gen_reg_rtx (mode);
2319 expand_fix (target, tmp, 0);
2321 return target;
2324 /* To evaluate powi(x,n), the floating point value x raised to the
2325 constant integer exponent n, we use a hybrid algorithm that
2326 combines the "window method" with look-up tables. For an
2327 introduction to exponentiation algorithms and "addition chains",
2328 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2329 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2330 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2331 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2333 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2334 multiplications to inline before calling the system library's pow
2335 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2336 so this default never requires calling pow, powf or powl. */
2338 #ifndef POWI_MAX_MULTS
2339 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2340 #endif
2342 /* The size of the "optimal power tree" lookup table. All
2343 exponents less than this value are simply looked up in the
2344 powi_table below. This threshold is also used to size the
2345 cache of pseudo registers that hold intermediate results. */
2346 #define POWI_TABLE_SIZE 256
2348 /* The size, in bits of the window, used in the "window method"
2349 exponentiation algorithm. This is equivalent to a radix of
2350 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2351 #define POWI_WINDOW_SIZE 3
2353 /* The following table is an efficient representation of an
2354 "optimal power tree". For each value, i, the corresponding
2355 value, j, in the table states than an optimal evaluation
2356 sequence for calculating pow(x,i) can be found by evaluating
2357 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2358 100 integers is given in Knuth's "Seminumerical algorithms". */
2360 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2362 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2363 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2364 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2365 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2366 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2367 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2368 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2369 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2370 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2371 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2372 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2373 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2374 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2375 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2376 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2377 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2378 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2379 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2380 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2381 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2382 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2383 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2384 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2385 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2386 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2387 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2388 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2389 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2390 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2391 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2392 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2393 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2397 /* Return the number of multiplications required to calculate
2398 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2399 subroutine of powi_cost. CACHE is an array indicating
2400 which exponents have already been calculated. */
2402 static int
2403 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2405 /* If we've already calculated this exponent, then this evaluation
2406 doesn't require any additional multiplications. */
2407 if (cache[n])
2408 return 0;
2410 cache[n] = true;
2411 return powi_lookup_cost (n - powi_table[n], cache)
2412 + powi_lookup_cost (powi_table[n], cache) + 1;
2415 /* Return the number of multiplications required to calculate
2416 powi(x,n) for an arbitrary x, given the exponent N. This
2417 function needs to be kept in sync with expand_powi below. */
2419 static int
2420 powi_cost (HOST_WIDE_INT n)
2422 bool cache[POWI_TABLE_SIZE];
2423 unsigned HOST_WIDE_INT digit;
2424 unsigned HOST_WIDE_INT val;
2425 int result;
2427 if (n == 0)
2428 return 0;
2430 /* Ignore the reciprocal when calculating the cost. */
2431 val = (n < 0) ? -n : n;
2433 /* Initialize the exponent cache. */
2434 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2435 cache[1] = true;
2437 result = 0;
2439 while (val >= POWI_TABLE_SIZE)
2441 if (val & 1)
2443 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2444 result += powi_lookup_cost (digit, cache)
2445 + POWI_WINDOW_SIZE + 1;
2446 val >>= POWI_WINDOW_SIZE;
2448 else
2450 val >>= 1;
2451 result++;
2455 return result + powi_lookup_cost (val, cache);
2458 /* Recursive subroutine of expand_powi. This function takes the array,
2459 CACHE, of already calculated exponents and an exponent N and returns
2460 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2462 static rtx
2463 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2465 unsigned HOST_WIDE_INT digit;
2466 rtx target, result;
2467 rtx op0, op1;
2469 if (n < POWI_TABLE_SIZE)
2471 if (cache[n])
2472 return cache[n];
2474 target = gen_reg_rtx (mode);
2475 cache[n] = target;
2477 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2478 op1 = expand_powi_1 (mode, powi_table[n], cache);
2480 else if (n & 1)
2482 target = gen_reg_rtx (mode);
2483 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2484 op0 = expand_powi_1 (mode, n - digit, cache);
2485 op1 = expand_powi_1 (mode, digit, cache);
2487 else
2489 target = gen_reg_rtx (mode);
2490 op0 = expand_powi_1 (mode, n >> 1, cache);
2491 op1 = op0;
2494 result = expand_mult (mode, op0, op1, target, 0);
2495 if (result != target)
2496 emit_move_insn (target, result);
2497 return target;
2500 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2501 floating point operand in mode MODE, and N is the exponent. This
2502 function needs to be kept in sync with powi_cost above. */
2504 static rtx
2505 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2507 unsigned HOST_WIDE_INT val;
2508 rtx cache[POWI_TABLE_SIZE];
2509 rtx result;
2511 if (n == 0)
2512 return CONST1_RTX (mode);
2514 val = (n < 0) ? -n : n;
2516 memset (cache, 0, sizeof (cache));
2517 cache[1] = x;
2519 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2521 /* If the original exponent was negative, reciprocate the result. */
2522 if (n < 0)
2523 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2524 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2526 return result;
2529 /* Expand a call to the pow built-in mathematical function. Return 0 if
2530 a normal call should be emitted rather than expanding the function
2531 in-line. EXP is the expression that is a call to the builtin
2532 function; if convenient, the result should be placed in TARGET. */
2534 static rtx
2535 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2537 tree arglist = TREE_OPERAND (exp, 1);
2538 tree arg0, arg1;
2540 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2541 return 0;
2543 arg0 = TREE_VALUE (arglist);
2544 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2546 if (TREE_CODE (arg1) == REAL_CST
2547 && ! TREE_CONSTANT_OVERFLOW (arg1))
2549 REAL_VALUE_TYPE cint;
2550 REAL_VALUE_TYPE c;
2551 HOST_WIDE_INT n;
2553 c = TREE_REAL_CST (arg1);
2554 n = real_to_integer (&c);
2555 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2556 if (real_identical (&c, &cint))
2558 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2559 Otherwise, check the number of multiplications required.
2560 Note that pow never sets errno for an integer exponent. */
2561 if ((n >= -1 && n <= 2)
2562 || (flag_unsafe_math_optimizations
2563 && ! optimize_size
2564 && powi_cost (n) <= POWI_MAX_MULTS))
2566 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2567 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2568 op = force_reg (mode, op);
2569 return expand_powi (op, mode, n);
2574 if (! flag_unsafe_math_optimizations)
2575 return NULL_RTX;
2576 return expand_builtin_mathfn_2 (exp, target, subtarget);
2579 /* Expand a call to the powi built-in mathematical function. Return 0 if
2580 a normal call should be emitted rather than expanding the function
2581 in-line. EXP is the expression that is a call to the builtin
2582 function; if convenient, the result should be placed in TARGET. */
2584 static rtx
2585 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2587 tree arglist = TREE_OPERAND (exp, 1);
2588 tree arg0, arg1;
2589 rtx op0, op1;
2590 enum machine_mode mode;
2591 enum machine_mode mode2;
2593 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2594 return 0;
2596 arg0 = TREE_VALUE (arglist);
2597 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2598 mode = TYPE_MODE (TREE_TYPE (exp));
2600 /* Handle constant power. */
2602 if (TREE_CODE (arg1) == INTEGER_CST
2603 && ! TREE_CONSTANT_OVERFLOW (arg1))
2605 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2607 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2608 Otherwise, check the number of multiplications required. */
2609 if ((TREE_INT_CST_HIGH (arg1) == 0
2610 || TREE_INT_CST_HIGH (arg1) == -1)
2611 && ((n >= -1 && n <= 2)
2612 || (! optimize_size
2613 && powi_cost (n) <= POWI_MAX_MULTS)))
2615 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2616 op0 = force_reg (mode, op0);
2617 return expand_powi (op0, mode, n);
2621 /* Emit a libcall to libgcc. */
2623 /* Mode of the 2nd argument must match that of an int. */
2624 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2626 if (target == NULL_RTX)
2627 target = gen_reg_rtx (mode);
2629 op0 = expand_expr (arg0, subtarget, mode, 0);
2630 if (GET_MODE (op0) != mode)
2631 op0 = convert_to_mode (mode, op0, 0);
2632 op1 = expand_expr (arg1, 0, mode2, 0);
2633 if (GET_MODE (op1) != mode2)
2634 op1 = convert_to_mode (mode2, op1, 0);
2636 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2637 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2638 op0, mode, op1, mode2);
2640 return target;
2643 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2644 if we failed the caller should emit a normal call, otherwise
2645 try to get the result in TARGET, if convenient. */
2647 static rtx
2648 expand_builtin_strlen (tree arglist, rtx target,
2649 enum machine_mode target_mode)
2651 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2652 return 0;
2653 else
2655 rtx pat;
2656 tree len, src = TREE_VALUE (arglist);
2657 rtx result, src_reg, char_rtx, before_strlen;
2658 enum machine_mode insn_mode = target_mode, char_mode;
2659 enum insn_code icode = CODE_FOR_nothing;
2660 int align;
2662 /* If the length can be computed at compile-time, return it. */
2663 len = c_strlen (src, 0);
2664 if (len)
2665 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2667 /* If the length can be computed at compile-time and is constant
2668 integer, but there are side-effects in src, evaluate
2669 src for side-effects, then return len.
2670 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2671 can be optimized into: i++; x = 3; */
2672 len = c_strlen (src, 1);
2673 if (len && TREE_CODE (len) == INTEGER_CST)
2675 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2676 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2679 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2681 /* If SRC is not a pointer type, don't do this operation inline. */
2682 if (align == 0)
2683 return 0;
2685 /* Bail out if we can't compute strlen in the right mode. */
2686 while (insn_mode != VOIDmode)
2688 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2689 if (icode != CODE_FOR_nothing)
2690 break;
2692 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2694 if (insn_mode == VOIDmode)
2695 return 0;
2697 /* Make a place to write the result of the instruction. */
2698 result = target;
2699 if (! (result != 0
2700 && REG_P (result)
2701 && GET_MODE (result) == insn_mode
2702 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2703 result = gen_reg_rtx (insn_mode);
2705 /* Make a place to hold the source address. We will not expand
2706 the actual source until we are sure that the expansion will
2707 not fail -- there are trees that cannot be expanded twice. */
2708 src_reg = gen_reg_rtx (Pmode);
2710 /* Mark the beginning of the strlen sequence so we can emit the
2711 source operand later. */
2712 before_strlen = get_last_insn ();
2714 char_rtx = const0_rtx;
2715 char_mode = insn_data[(int) icode].operand[2].mode;
2716 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2717 char_mode))
2718 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2720 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2721 char_rtx, GEN_INT (align));
2722 if (! pat)
2723 return 0;
2724 emit_insn (pat);
2726 /* Now that we are assured of success, expand the source. */
2727 start_sequence ();
2728 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2729 if (pat != src_reg)
2730 emit_move_insn (src_reg, pat);
2731 pat = get_insns ();
2732 end_sequence ();
2734 if (before_strlen)
2735 emit_insn_after (pat, before_strlen);
2736 else
2737 emit_insn_before (pat, get_insns ());
2739 /* Return the value in the proper mode for this function. */
2740 if (GET_MODE (result) == target_mode)
2741 target = result;
2742 else if (target != 0)
2743 convert_move (target, result, 0);
2744 else
2745 target = convert_to_mode (target_mode, result, 0);
2747 return target;
2751 /* Expand a call to the strstr builtin. Return 0 if we failed the
2752 caller should emit a normal call, otherwise try to get the result
2753 in TARGET, if convenient (and in mode MODE if that's convenient). */
2755 static rtx
2756 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2758 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2760 tree result = fold_builtin_strstr (arglist, type);
2761 if (result)
2762 return expand_expr (result, target, mode, EXPAND_NORMAL);
2764 return 0;
2767 /* Expand a call to the strchr builtin. Return 0 if we failed the
2768 caller should emit a normal call, otherwise try to get the result
2769 in TARGET, if convenient (and in mode MODE if that's convenient). */
2771 static rtx
2772 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2774 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2776 tree result = fold_builtin_strchr (arglist, type);
2777 if (result)
2778 return expand_expr (result, target, mode, EXPAND_NORMAL);
2780 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2782 return 0;
2785 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2786 caller should emit a normal call, otherwise try to get the result
2787 in TARGET, if convenient (and in mode MODE if that's convenient). */
2789 static rtx
2790 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2792 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2794 tree result = fold_builtin_strrchr (arglist, type);
2795 if (result)
2796 return expand_expr (result, target, mode, EXPAND_NORMAL);
2798 return 0;
2801 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2802 caller should emit a normal call, otherwise try to get the result
2803 in TARGET, if convenient (and in mode MODE if that's convenient). */
2805 static rtx
2806 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2808 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2810 tree result = fold_builtin_strpbrk (arglist, type);
2811 if (result)
2812 return expand_expr (result, target, mode, EXPAND_NORMAL);
2814 return 0;
2817 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2818 bytes from constant string DATA + OFFSET and return it as target
2819 constant. */
2821 static rtx
2822 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2823 enum machine_mode mode)
2825 const char *str = (const char *) data;
2827 gcc_assert (offset >= 0
2828 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2829 <= strlen (str) + 1));
2831 return c_readstr (str + offset, mode);
2834 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2835 Return 0 if we failed, the caller should emit a normal call,
2836 otherwise try to get the result in TARGET, if convenient (and in
2837 mode MODE if that's convenient). */
2838 static rtx
2839 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2841 tree fndecl = get_callee_fndecl (exp);
2842 tree arglist = TREE_OPERAND (exp, 1);
2843 if (!validate_arglist (arglist,
2844 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2845 return 0;
2846 else
2848 tree dest = TREE_VALUE (arglist);
2849 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2850 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2851 const char *src_str;
2852 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2853 unsigned int dest_align
2854 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2855 rtx dest_mem, src_mem, dest_addr, len_rtx;
2856 tree result = fold_builtin_memcpy (fndecl, arglist);
2858 if (result)
2859 return expand_expr (result, target, mode, EXPAND_NORMAL);
2861 /* If DEST is not a pointer type, call the normal function. */
2862 if (dest_align == 0)
2863 return 0;
2865 /* If either SRC is not a pointer type, don't do this
2866 operation in-line. */
2867 if (src_align == 0)
2868 return 0;
2870 dest_mem = get_memory_rtx (dest, len);
2871 set_mem_align (dest_mem, dest_align);
2872 len_rtx = expand_normal (len);
2873 src_str = c_getstr (src);
2875 /* If SRC is a string constant and block move would be done
2876 by pieces, we can avoid loading the string from memory
2877 and only stored the computed constants. */
2878 if (src_str
2879 && GET_CODE (len_rtx) == CONST_INT
2880 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2881 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2882 (void *) src_str, dest_align))
2884 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2885 builtin_memcpy_read_str,
2886 (void *) src_str, dest_align, 0);
2887 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2888 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2889 return dest_mem;
2892 src_mem = get_memory_rtx (src, len);
2893 set_mem_align (src_mem, src_align);
2895 /* Copy word part most expediently. */
2896 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2897 CALL_EXPR_TAILCALL (exp)
2898 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2900 if (dest_addr == 0)
2902 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2903 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2905 return dest_addr;
2909 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2910 Return 0 if we failed; the caller should emit a normal call,
2911 otherwise try to get the result in TARGET, if convenient (and in
2912 mode MODE if that's convenient). If ENDP is 0 return the
2913 destination pointer, if ENDP is 1 return the end pointer ala
2914 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2915 stpcpy. */
2917 static rtx
2918 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2919 int endp)
2921 if (!validate_arglist (arglist,
2922 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2923 return 0;
2924 /* If return value is ignored, transform mempcpy into memcpy. */
2925 else if (target == const0_rtx)
2927 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2929 if (!fn)
2930 return 0;
2932 return expand_expr (build_function_call_expr (fn, arglist),
2933 target, mode, EXPAND_NORMAL);
2935 else
2937 tree dest = TREE_VALUE (arglist);
2938 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2939 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2940 const char *src_str;
2941 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2942 unsigned int dest_align
2943 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2944 rtx dest_mem, src_mem, len_rtx;
2945 tree result = fold_builtin_mempcpy (arglist, type, endp);
2947 if (result)
2948 return expand_expr (result, target, mode, EXPAND_NORMAL);
2950 /* If either SRC or DEST is not a pointer type, don't do this
2951 operation in-line. */
2952 if (dest_align == 0 || src_align == 0)
2953 return 0;
2955 /* If LEN is not constant, call the normal function. */
2956 if (! host_integerp (len, 1))
2957 return 0;
2959 len_rtx = expand_normal (len);
2960 src_str = c_getstr (src);
2962 /* If SRC is a string constant and block move would be done
2963 by pieces, we can avoid loading the string from memory
2964 and only stored the computed constants. */
2965 if (src_str
2966 && GET_CODE (len_rtx) == CONST_INT
2967 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2968 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2969 (void *) src_str, dest_align))
2971 dest_mem = get_memory_rtx (dest, len);
2972 set_mem_align (dest_mem, dest_align);
2973 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2974 builtin_memcpy_read_str,
2975 (void *) src_str, dest_align, endp);
2976 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2977 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2978 return dest_mem;
2981 if (GET_CODE (len_rtx) == CONST_INT
2982 && can_move_by_pieces (INTVAL (len_rtx),
2983 MIN (dest_align, src_align)))
2985 dest_mem = get_memory_rtx (dest, len);
2986 set_mem_align (dest_mem, dest_align);
2987 src_mem = get_memory_rtx (src, len);
2988 set_mem_align (src_mem, src_align);
2989 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2990 MIN (dest_align, src_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 return 0;
3000 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3001 if we failed; the caller should emit a normal call. */
3003 static rtx
3004 expand_builtin_memmove (tree arglist, tree type, rtx target,
3005 enum machine_mode mode, tree orig_exp)
3007 if (!validate_arglist (arglist,
3008 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3009 return 0;
3010 else
3012 tree dest = TREE_VALUE (arglist);
3013 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3014 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3016 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3017 unsigned int dest_align
3018 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3019 tree result = fold_builtin_memmove (arglist, type);
3021 if (result)
3022 return expand_expr (result, target, mode, EXPAND_NORMAL);
3024 /* If DEST is not a pointer type, call the normal function. */
3025 if (dest_align == 0)
3026 return 0;
3028 /* If either SRC is not a pointer type, don't do this
3029 operation in-line. */
3030 if (src_align == 0)
3031 return 0;
3033 /* If src is categorized for a readonly section we can use
3034 normal memcpy. */
3035 if (readonly_data_expr (src))
3037 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3038 if (!fn)
3039 return 0;
3040 fn = build_function_call_expr (fn, arglist);
3041 if (TREE_CODE (fn) == CALL_EXPR)
3042 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3043 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3046 /* If length is 1 and we can expand memcpy call inline,
3047 it is ok to use memcpy as well. */
3048 if (integer_onep (len))
3050 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3051 /*endp=*/0);
3052 if (ret)
3053 return ret;
3056 /* Otherwise, call the normal function. */
3057 return 0;
3061 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3062 if we failed the caller should emit a normal call. */
3064 static rtx
3065 expand_builtin_bcopy (tree exp)
3067 tree arglist = TREE_OPERAND (exp, 1);
3068 tree type = TREE_TYPE (exp);
3069 tree src, dest, size, newarglist;
3071 if (!validate_arglist (arglist,
3072 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3073 return NULL_RTX;
3075 src = TREE_VALUE (arglist);
3076 dest = TREE_VALUE (TREE_CHAIN (arglist));
3077 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3079 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3080 memmove(ptr y, ptr x, size_t z). This is done this way
3081 so that if it isn't expanded inline, we fallback to
3082 calling bcopy instead of memmove. */
3084 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3085 newarglist = tree_cons (NULL_TREE, src, newarglist);
3086 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3088 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3091 #ifndef HAVE_movstr
3092 # define HAVE_movstr 0
3093 # define CODE_FOR_movstr CODE_FOR_nothing
3094 #endif
3096 /* Expand into a movstr instruction, if one is available. Return 0 if
3097 we failed, the caller should emit a normal call, otherwise try to
3098 get the result in TARGET, if convenient. If ENDP is 0 return the
3099 destination pointer, if ENDP is 1 return the end pointer ala
3100 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3101 stpcpy. */
3103 static rtx
3104 expand_movstr (tree dest, tree src, rtx target, int endp)
3106 rtx end;
3107 rtx dest_mem;
3108 rtx src_mem;
3109 rtx insn;
3110 const struct insn_data * data;
3112 if (!HAVE_movstr)
3113 return 0;
3115 dest_mem = get_memory_rtx (dest, NULL);
3116 src_mem = get_memory_rtx (src, NULL);
3117 if (!endp)
3119 target = force_reg (Pmode, XEXP (dest_mem, 0));
3120 dest_mem = replace_equiv_address (dest_mem, target);
3121 end = gen_reg_rtx (Pmode);
3123 else
3125 if (target == 0 || target == const0_rtx)
3127 end = gen_reg_rtx (Pmode);
3128 if (target == 0)
3129 target = end;
3131 else
3132 end = target;
3135 data = insn_data + CODE_FOR_movstr;
3137 if (data->operand[0].mode != VOIDmode)
3138 end = gen_lowpart (data->operand[0].mode, end);
3140 insn = data->genfun (end, dest_mem, src_mem);
3142 gcc_assert (insn);
3144 emit_insn (insn);
3146 /* movstr is supposed to set end to the address of the NUL
3147 terminator. If the caller requested a mempcpy-like return value,
3148 adjust it. */
3149 if (endp == 1 && target != const0_rtx)
3151 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3152 emit_move_insn (target, force_operand (tem, NULL_RTX));
3155 return target;
3158 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3159 if we failed the caller should emit a normal call, otherwise try to get
3160 the result in TARGET, if convenient (and in mode MODE if that's
3161 convenient). */
3163 static rtx
3164 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3166 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3168 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3169 if (result)
3170 return expand_expr (result, target, mode, EXPAND_NORMAL);
3172 return expand_movstr (TREE_VALUE (arglist),
3173 TREE_VALUE (TREE_CHAIN (arglist)),
3174 target, /*endp=*/0);
3176 return 0;
3179 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3180 Return 0 if we failed the caller should emit a normal call,
3181 otherwise try to get the result in TARGET, if convenient (and in
3182 mode MODE if that's convenient). */
3184 static rtx
3185 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3187 tree arglist = TREE_OPERAND (exp, 1);
3188 /* If return value is ignored, transform stpcpy into strcpy. */
3189 if (target == const0_rtx)
3191 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3192 if (!fn)
3193 return 0;
3195 return expand_expr (build_function_call_expr (fn, arglist),
3196 target, mode, EXPAND_NORMAL);
3199 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3200 return 0;
3201 else
3203 tree dst, src, len, lenp1;
3204 tree narglist;
3205 rtx ret;
3207 /* Ensure we get an actual string whose length can be evaluated at
3208 compile-time, not an expression containing a string. This is
3209 because the latter will potentially produce pessimized code
3210 when used to produce the return value. */
3211 src = TREE_VALUE (TREE_CHAIN (arglist));
3212 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3213 return expand_movstr (TREE_VALUE (arglist),
3214 TREE_VALUE (TREE_CHAIN (arglist)),
3215 target, /*endp=*/2);
3217 dst = TREE_VALUE (arglist);
3218 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3219 narglist = build_tree_list (NULL_TREE, lenp1);
3220 narglist = tree_cons (NULL_TREE, src, narglist);
3221 narglist = tree_cons (NULL_TREE, dst, narglist);
3222 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3223 target, mode, /*endp=*/2);
3225 if (ret)
3226 return ret;
3228 if (TREE_CODE (len) == INTEGER_CST)
3230 rtx len_rtx = expand_normal (len);
3232 if (GET_CODE (len_rtx) == CONST_INT)
3234 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3235 arglist, target, mode);
3237 if (ret)
3239 if (! target)
3241 if (mode != VOIDmode)
3242 target = gen_reg_rtx (mode);
3243 else
3244 target = gen_reg_rtx (GET_MODE (ret));
3246 if (GET_MODE (target) != GET_MODE (ret))
3247 ret = gen_lowpart (GET_MODE (target), ret);
3249 ret = plus_constant (ret, INTVAL (len_rtx));
3250 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3251 gcc_assert (ret);
3253 return target;
3258 return expand_movstr (TREE_VALUE (arglist),
3259 TREE_VALUE (TREE_CHAIN (arglist)),
3260 target, /*endp=*/2);
3264 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3265 bytes from constant string DATA + OFFSET and return it as target
3266 constant. */
3268 static rtx
3269 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3270 enum machine_mode mode)
3272 const char *str = (const char *) data;
3274 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3275 return const0_rtx;
3277 return c_readstr (str + offset, mode);
3280 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3281 if we failed the caller should emit a normal call. */
3283 static rtx
3284 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3286 tree fndecl = get_callee_fndecl (exp);
3287 tree arglist = TREE_OPERAND (exp, 1);
3288 if (validate_arglist (arglist,
3289 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3291 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3292 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3293 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3295 if (result)
3296 return expand_expr (result, target, mode, EXPAND_NORMAL);
3298 /* We must be passed a constant len and src parameter. */
3299 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3300 return 0;
3302 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3304 /* We're required to pad with trailing zeros if the requested
3305 len is greater than strlen(s2)+1. In that case try to
3306 use store_by_pieces, if it fails, punt. */
3307 if (tree_int_cst_lt (slen, len))
3309 tree dest = TREE_VALUE (arglist);
3310 unsigned int dest_align
3311 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3312 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3313 rtx dest_mem;
3315 if (!p || dest_align == 0 || !host_integerp (len, 1)
3316 || !can_store_by_pieces (tree_low_cst (len, 1),
3317 builtin_strncpy_read_str,
3318 (void *) p, dest_align))
3319 return 0;
3321 dest_mem = get_memory_rtx (dest, len);
3322 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3323 builtin_strncpy_read_str,
3324 (void *) p, dest_align, 0);
3325 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3326 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3327 return dest_mem;
3330 return 0;
3333 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3334 bytes from constant string DATA + OFFSET and return it as target
3335 constant. */
3337 static rtx
3338 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3339 enum machine_mode mode)
3341 const char *c = (const char *) data;
3342 char *p = alloca (GET_MODE_SIZE (mode));
3344 memset (p, *c, GET_MODE_SIZE (mode));
3346 return c_readstr (p, mode);
3349 /* Callback routine for store_by_pieces. Return the RTL of a register
3350 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3351 char value given in the RTL register data. For example, if mode is
3352 4 bytes wide, return the RTL for 0x01010101*data. */
3354 static rtx
3355 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3356 enum machine_mode mode)
3358 rtx target, coeff;
3359 size_t size;
3360 char *p;
3362 size = GET_MODE_SIZE (mode);
3363 if (size == 1)
3364 return (rtx) data;
3366 p = alloca (size);
3367 memset (p, 1, size);
3368 coeff = c_readstr (p, mode);
3370 target = convert_to_mode (mode, (rtx) data, 1);
3371 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3372 return force_reg (mode, target);
3375 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3376 if we failed the caller should emit a normal call, otherwise try to get
3377 the result in TARGET, if convenient (and in mode MODE if that's
3378 convenient). */
3380 static rtx
3381 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3382 tree orig_exp)
3384 if (!validate_arglist (arglist,
3385 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3386 return 0;
3387 else
3389 tree dest = TREE_VALUE (arglist);
3390 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3391 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3392 tree fndecl, fn;
3393 enum built_in_function fcode;
3394 char c;
3395 unsigned int dest_align;
3396 rtx dest_mem, dest_addr, len_rtx;
3398 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3400 /* If DEST is not a pointer type, don't do this
3401 operation in-line. */
3402 if (dest_align == 0)
3403 return 0;
3405 /* If the LEN parameter is zero, return DEST. */
3406 if (integer_zerop (len))
3408 /* Evaluate and ignore VAL in case it has side-effects. */
3409 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3410 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3413 /* Stabilize the arguments in case we fail. */
3414 dest = builtin_save_expr (dest);
3415 val = builtin_save_expr (val);
3416 len = builtin_save_expr (len);
3418 len_rtx = expand_normal (len);
3419 dest_mem = get_memory_rtx (dest, len);
3421 if (TREE_CODE (val) != INTEGER_CST)
3423 rtx val_rtx;
3425 val_rtx = expand_normal (val);
3426 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3427 val_rtx, 0);
3429 /* Assume that we can memset by pieces if we can store the
3430 * the coefficients by pieces (in the required modes).
3431 * We can't pass builtin_memset_gen_str as that emits RTL. */
3432 c = 1;
3433 if (host_integerp (len, 1)
3434 && !(optimize_size && tree_low_cst (len, 1) > 1)
3435 && can_store_by_pieces (tree_low_cst (len, 1),
3436 builtin_memset_read_str, &c, dest_align))
3438 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3439 val_rtx);
3440 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3441 builtin_memset_gen_str, val_rtx, dest_align, 0);
3443 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3444 dest_align))
3445 goto do_libcall;
3447 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3448 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3449 return dest_mem;
3452 if (target_char_cast (val, &c))
3453 goto do_libcall;
3455 if (c)
3457 if (host_integerp (len, 1)
3458 && !(optimize_size && tree_low_cst (len, 1) > 1)
3459 && can_store_by_pieces (tree_low_cst (len, 1),
3460 builtin_memset_read_str, &c, dest_align))
3461 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3462 builtin_memset_read_str, &c, dest_align, 0);
3463 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3464 dest_align))
3465 goto do_libcall;
3467 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3468 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3469 return dest_mem;
3472 set_mem_align (dest_mem, dest_align);
3473 dest_addr = clear_storage (dest_mem, len_rtx,
3474 CALL_EXPR_TAILCALL (orig_exp)
3475 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3477 if (dest_addr == 0)
3479 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3480 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3483 return dest_addr;
3485 do_libcall:
3486 fndecl = get_callee_fndecl (orig_exp);
3487 fcode = DECL_FUNCTION_CODE (fndecl);
3488 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3489 arglist = build_tree_list (NULL_TREE, len);
3490 if (fcode == BUILT_IN_MEMSET)
3491 arglist = tree_cons (NULL_TREE, val, arglist);
3492 arglist = tree_cons (NULL_TREE, dest, arglist);
3493 fn = build_function_call_expr (fndecl, arglist);
3494 if (TREE_CODE (fn) == CALL_EXPR)
3495 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3496 return expand_call (fn, target, target == const0_rtx);
3500 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3501 if we failed the caller should emit a normal call. */
3503 static rtx
3504 expand_builtin_bzero (tree exp)
3506 tree arglist = TREE_OPERAND (exp, 1);
3507 tree dest, size, newarglist;
3509 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3510 return NULL_RTX;
3512 dest = TREE_VALUE (arglist);
3513 size = TREE_VALUE (TREE_CHAIN (arglist));
3515 /* New argument list transforming bzero(ptr x, int y) to
3516 memset(ptr x, int 0, size_t y). This is done this way
3517 so that if it isn't expanded inline, we fallback to
3518 calling bzero instead of memset. */
3520 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3521 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3522 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3524 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3527 /* Expand expression EXP, which is a call to the memcmp built-in function.
3528 ARGLIST is the argument list for this call. Return 0 if we failed and the
3529 caller should emit a normal call, otherwise try to get the result in
3530 TARGET, if convenient (and in mode MODE, if that's convenient). */
3532 static rtx
3533 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3534 enum machine_mode mode)
3536 if (!validate_arglist (arglist,
3537 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3538 return 0;
3539 else
3541 tree result = fold_builtin_memcmp (arglist);
3542 if (result)
3543 return expand_expr (result, target, mode, EXPAND_NORMAL);
3546 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3548 tree arg1 = TREE_VALUE (arglist);
3549 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3550 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3551 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3552 rtx result;
3553 rtx insn;
3555 int arg1_align
3556 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3557 int arg2_align
3558 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3559 enum machine_mode insn_mode;
3561 #ifdef HAVE_cmpmemsi
3562 if (HAVE_cmpmemsi)
3563 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3564 else
3565 #endif
3566 #ifdef HAVE_cmpstrnsi
3567 if (HAVE_cmpstrnsi)
3568 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3569 else
3570 #endif
3571 return 0;
3573 /* If we don't have POINTER_TYPE, call the function. */
3574 if (arg1_align == 0 || arg2_align == 0)
3575 return 0;
3577 /* Make a place to write the result of the instruction. */
3578 result = target;
3579 if (! (result != 0
3580 && REG_P (result) && GET_MODE (result) == insn_mode
3581 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3582 result = gen_reg_rtx (insn_mode);
3584 arg1_rtx = get_memory_rtx (arg1, len);
3585 arg2_rtx = get_memory_rtx (arg2, len);
3586 arg3_rtx = expand_normal (len);
3588 /* Set MEM_SIZE as appropriate. */
3589 if (GET_CODE (arg3_rtx) == CONST_INT)
3591 set_mem_size (arg1_rtx, arg3_rtx);
3592 set_mem_size (arg2_rtx, arg3_rtx);
3595 #ifdef HAVE_cmpmemsi
3596 if (HAVE_cmpmemsi)
3597 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3598 GEN_INT (MIN (arg1_align, arg2_align)));
3599 else
3600 #endif
3601 #ifdef HAVE_cmpstrnsi
3602 if (HAVE_cmpstrnsi)
3603 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3604 GEN_INT (MIN (arg1_align, arg2_align)));
3605 else
3606 #endif
3607 gcc_unreachable ();
3609 if (insn)
3610 emit_insn (insn);
3611 else
3612 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3613 TYPE_MODE (integer_type_node), 3,
3614 XEXP (arg1_rtx, 0), Pmode,
3615 XEXP (arg2_rtx, 0), Pmode,
3616 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3617 TYPE_UNSIGNED (sizetype)),
3618 TYPE_MODE (sizetype));
3620 /* Return the value in the proper mode for this function. */
3621 mode = TYPE_MODE (TREE_TYPE (exp));
3622 if (GET_MODE (result) == mode)
3623 return result;
3624 else if (target != 0)
3626 convert_move (target, result, 0);
3627 return target;
3629 else
3630 return convert_to_mode (mode, result, 0);
3632 #endif
3634 return 0;
3637 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3638 if we failed the caller should emit a normal call, otherwise try to get
3639 the result in TARGET, if convenient. */
3641 static rtx
3642 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3644 tree arglist = TREE_OPERAND (exp, 1);
3646 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3647 return 0;
3648 else
3650 tree result = fold_builtin_strcmp (arglist);
3651 if (result)
3652 return expand_expr (result, target, mode, EXPAND_NORMAL);
3655 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3656 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3657 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3659 rtx arg1_rtx, arg2_rtx;
3660 rtx result, insn = NULL_RTX;
3661 tree fndecl, fn;
3663 tree arg1 = TREE_VALUE (arglist);
3664 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3665 int arg1_align
3666 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3667 int arg2_align
3668 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3670 /* If we don't have POINTER_TYPE, call the function. */
3671 if (arg1_align == 0 || arg2_align == 0)
3672 return 0;
3674 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3675 arg1 = builtin_save_expr (arg1);
3676 arg2 = builtin_save_expr (arg2);
3678 arg1_rtx = get_memory_rtx (arg1, NULL);
3679 arg2_rtx = get_memory_rtx (arg2, NULL);
3681 #ifdef HAVE_cmpstrsi
3682 /* Try to call cmpstrsi. */
3683 if (HAVE_cmpstrsi)
3685 enum machine_mode insn_mode
3686 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3688 /* Make a place to write the result of the instruction. */
3689 result = target;
3690 if (! (result != 0
3691 && REG_P (result) && GET_MODE (result) == insn_mode
3692 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3693 result = gen_reg_rtx (insn_mode);
3695 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3696 GEN_INT (MIN (arg1_align, arg2_align)));
3698 #endif
3699 #ifdef HAVE_cmpstrnsi
3700 /* Try to determine at least one length and call cmpstrnsi. */
3701 if (!insn && HAVE_cmpstrnsi)
3703 tree len;
3704 rtx arg3_rtx;
3706 enum machine_mode insn_mode
3707 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3708 tree len1 = c_strlen (arg1, 1);
3709 tree len2 = c_strlen (arg2, 1);
3711 if (len1)
3712 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3713 if (len2)
3714 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3716 /* If we don't have a constant length for the first, use the length
3717 of the second, if we know it. We don't require a constant for
3718 this case; some cost analysis could be done if both are available
3719 but neither is constant. For now, assume they're equally cheap,
3720 unless one has side effects. If both strings have constant lengths,
3721 use the smaller. */
3723 if (!len1)
3724 len = len2;
3725 else if (!len2)
3726 len = len1;
3727 else if (TREE_SIDE_EFFECTS (len1))
3728 len = len2;
3729 else if (TREE_SIDE_EFFECTS (len2))
3730 len = len1;
3731 else if (TREE_CODE (len1) != INTEGER_CST)
3732 len = len2;
3733 else if (TREE_CODE (len2) != INTEGER_CST)
3734 len = len1;
3735 else if (tree_int_cst_lt (len1, len2))
3736 len = len1;
3737 else
3738 len = len2;
3740 /* If both arguments have side effects, we cannot optimize. */
3741 if (!len || TREE_SIDE_EFFECTS (len))
3742 goto do_libcall;
3744 arg3_rtx = expand_normal (len);
3746 /* Make a place to write the result of the instruction. */
3747 result = target;
3748 if (! (result != 0
3749 && REG_P (result) && GET_MODE (result) == insn_mode
3750 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3751 result = gen_reg_rtx (insn_mode);
3753 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3754 GEN_INT (MIN (arg1_align, arg2_align)));
3756 #endif
3758 if (insn)
3760 emit_insn (insn);
3762 /* Return the value in the proper mode for this function. */
3763 mode = TYPE_MODE (TREE_TYPE (exp));
3764 if (GET_MODE (result) == mode)
3765 return result;
3766 if (target == 0)
3767 return convert_to_mode (mode, result, 0);
3768 convert_move (target, result, 0);
3769 return target;
3772 /* Expand the library call ourselves using a stabilized argument
3773 list to avoid re-evaluating the function's arguments twice. */
3774 #ifdef HAVE_cmpstrnsi
3775 do_libcall:
3776 #endif
3777 arglist = build_tree_list (NULL_TREE, arg2);
3778 arglist = tree_cons (NULL_TREE, arg1, arglist);
3779 fndecl = get_callee_fndecl (exp);
3780 fn = build_function_call_expr (fndecl, arglist);
3781 if (TREE_CODE (fn) == CALL_EXPR)
3782 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3783 return expand_call (fn, target, target == const0_rtx);
3785 #endif
3786 return 0;
3789 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3790 if we failed the caller should emit a normal call, otherwise try to get
3791 the result in TARGET, if convenient. */
3793 static rtx
3794 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3796 tree arglist = TREE_OPERAND (exp, 1);
3798 if (!validate_arglist (arglist,
3799 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3800 return 0;
3801 else
3803 tree result = fold_builtin_strncmp (arglist);
3804 if (result)
3805 return expand_expr (result, target, mode, EXPAND_NORMAL);
3808 /* If c_strlen can determine an expression for one of the string
3809 lengths, and it doesn't have side effects, then emit cmpstrnsi
3810 using length MIN(strlen(string)+1, arg3). */
3811 #ifdef HAVE_cmpstrnsi
3812 if (HAVE_cmpstrnsi)
3814 tree arg1 = TREE_VALUE (arglist);
3815 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3816 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3817 tree len, len1, len2;
3818 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3819 rtx result, insn;
3820 tree fndecl, fn;
3822 int arg1_align
3823 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3824 int arg2_align
3825 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3826 enum machine_mode insn_mode
3827 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3829 len1 = c_strlen (arg1, 1);
3830 len2 = c_strlen (arg2, 1);
3832 if (len1)
3833 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3834 if (len2)
3835 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3837 /* If we don't have a constant length for the first, use the length
3838 of the second, if we know it. We don't require a constant for
3839 this case; some cost analysis could be done if both are available
3840 but neither is constant. For now, assume they're equally cheap,
3841 unless one has side effects. If both strings have constant lengths,
3842 use the smaller. */
3844 if (!len1)
3845 len = len2;
3846 else if (!len2)
3847 len = len1;
3848 else if (TREE_SIDE_EFFECTS (len1))
3849 len = len2;
3850 else if (TREE_SIDE_EFFECTS (len2))
3851 len = len1;
3852 else if (TREE_CODE (len1) != INTEGER_CST)
3853 len = len2;
3854 else if (TREE_CODE (len2) != INTEGER_CST)
3855 len = len1;
3856 else if (tree_int_cst_lt (len1, len2))
3857 len = len1;
3858 else
3859 len = len2;
3861 /* If both arguments have side effects, we cannot optimize. */
3862 if (!len || TREE_SIDE_EFFECTS (len))
3863 return 0;
3865 /* The actual new length parameter is MIN(len,arg3). */
3866 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3867 fold_convert (TREE_TYPE (len), arg3));
3869 /* If we don't have POINTER_TYPE, call the function. */
3870 if (arg1_align == 0 || arg2_align == 0)
3871 return 0;
3873 /* Make a place to write the result of the instruction. */
3874 result = target;
3875 if (! (result != 0
3876 && REG_P (result) && GET_MODE (result) == insn_mode
3877 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3878 result = gen_reg_rtx (insn_mode);
3880 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3881 arg1 = builtin_save_expr (arg1);
3882 arg2 = builtin_save_expr (arg2);
3883 len = builtin_save_expr (len);
3885 arg1_rtx = get_memory_rtx (arg1, len);
3886 arg2_rtx = get_memory_rtx (arg2, len);
3887 arg3_rtx = expand_normal (len);
3888 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3889 GEN_INT (MIN (arg1_align, arg2_align)));
3890 if (insn)
3892 emit_insn (insn);
3894 /* Return the value in the proper mode for this function. */
3895 mode = TYPE_MODE (TREE_TYPE (exp));
3896 if (GET_MODE (result) == mode)
3897 return result;
3898 if (target == 0)
3899 return convert_to_mode (mode, result, 0);
3900 convert_move (target, result, 0);
3901 return target;
3904 /* Expand the library call ourselves using a stabilized argument
3905 list to avoid re-evaluating the function's arguments twice. */
3906 arglist = build_tree_list (NULL_TREE, len);
3907 arglist = tree_cons (NULL_TREE, arg2, arglist);
3908 arglist = tree_cons (NULL_TREE, arg1, arglist);
3909 fndecl = get_callee_fndecl (exp);
3910 fn = build_function_call_expr (fndecl, arglist);
3911 if (TREE_CODE (fn) == CALL_EXPR)
3912 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3913 return expand_call (fn, target, target == const0_rtx);
3915 #endif
3916 return 0;
3919 /* Expand expression EXP, which is a call to the strcat builtin.
3920 Return 0 if we failed the caller should emit a normal call,
3921 otherwise try to get the result in TARGET, if convenient. */
3923 static rtx
3924 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3926 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3927 return 0;
3928 else
3930 tree dst = TREE_VALUE (arglist),
3931 src = TREE_VALUE (TREE_CHAIN (arglist));
3932 const char *p = c_getstr (src);
3934 /* If the string length is zero, return the dst parameter. */
3935 if (p && *p == '\0')
3936 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3938 if (!optimize_size)
3940 /* See if we can store by pieces into (dst + strlen(dst)). */
3941 tree newsrc, newdst,
3942 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3943 rtx insns;
3945 /* Stabilize the argument list. */
3946 newsrc = builtin_save_expr (src);
3947 if (newsrc != src)
3948 arglist = build_tree_list (NULL_TREE, newsrc);
3949 else
3950 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3952 dst = builtin_save_expr (dst);
3954 start_sequence ();
3956 /* Create strlen (dst). */
3957 newdst =
3958 build_function_call_expr (strlen_fn,
3959 build_tree_list (NULL_TREE, dst));
3960 /* Create (dst + (cast) strlen (dst)). */
3961 newdst = fold_convert (TREE_TYPE (dst), newdst);
3962 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3964 newdst = builtin_save_expr (newdst);
3965 arglist = tree_cons (NULL_TREE, newdst, arglist);
3967 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3969 end_sequence (); /* Stop sequence. */
3970 return 0;
3973 /* Output the entire sequence. */
3974 insns = get_insns ();
3975 end_sequence ();
3976 emit_insn (insns);
3978 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3981 return 0;
3985 /* Expand expression EXP, which is a call to the strncat builtin.
3986 Return 0 if we failed the caller should emit a normal call,
3987 otherwise try to get the result in TARGET, if convenient. */
3989 static rtx
3990 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3992 if (validate_arglist (arglist,
3993 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3995 tree result = fold_builtin_strncat (arglist);
3996 if (result)
3997 return expand_expr (result, target, mode, EXPAND_NORMAL);
3999 return 0;
4002 /* Expand expression EXP, which is a call to the strspn builtin.
4003 Return 0 if we failed the caller should emit a normal call,
4004 otherwise try to get the result in TARGET, if convenient. */
4006 static rtx
4007 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4009 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4011 tree result = fold_builtin_strspn (arglist);
4012 if (result)
4013 return expand_expr (result, target, mode, EXPAND_NORMAL);
4015 return 0;
4018 /* Expand expression EXP, which is a call to the strcspn builtin.
4019 Return 0 if we failed the caller should emit a normal call,
4020 otherwise try to get the result in TARGET, if convenient. */
4022 static rtx
4023 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4025 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4027 tree result = fold_builtin_strcspn (arglist);
4028 if (result)
4029 return expand_expr (result, target, mode, EXPAND_NORMAL);
4031 return 0;
4034 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4035 if that's convenient. */
4038 expand_builtin_saveregs (void)
4040 rtx val, seq;
4042 /* Don't do __builtin_saveregs more than once in a function.
4043 Save the result of the first call and reuse it. */
4044 if (saveregs_value != 0)
4045 return saveregs_value;
4047 /* When this function is called, it means that registers must be
4048 saved on entry to this function. So we migrate the call to the
4049 first insn of this function. */
4051 start_sequence ();
4053 /* Do whatever the machine needs done in this case. */
4054 val = targetm.calls.expand_builtin_saveregs ();
4056 seq = get_insns ();
4057 end_sequence ();
4059 saveregs_value = val;
4061 /* Put the insns after the NOTE that starts the function. If this
4062 is inside a start_sequence, make the outer-level insn chain current, so
4063 the code is placed at the start of the function. */
4064 push_topmost_sequence ();
4065 emit_insn_after (seq, entry_of_function ());
4066 pop_topmost_sequence ();
4068 return val;
4071 /* __builtin_args_info (N) returns word N of the arg space info
4072 for the current function. The number and meanings of words
4073 is controlled by the definition of CUMULATIVE_ARGS. */
4075 static rtx
4076 expand_builtin_args_info (tree arglist)
4078 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4079 int *word_ptr = (int *) &current_function_args_info;
4081 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4083 if (arglist != 0)
4085 if (!host_integerp (TREE_VALUE (arglist), 0))
4086 error ("argument of %<__builtin_args_info%> must be constant");
4087 else
4089 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4091 if (wordnum < 0 || wordnum >= nwords)
4092 error ("argument of %<__builtin_args_info%> out of range");
4093 else
4094 return GEN_INT (word_ptr[wordnum]);
4097 else
4098 error ("missing argument in %<__builtin_args_info%>");
4100 return const0_rtx;
4103 /* Expand a call to __builtin_next_arg. */
4105 static rtx
4106 expand_builtin_next_arg (void)
4108 /* Checking arguments is already done in fold_builtin_next_arg
4109 that must be called before this function. */
4110 return expand_binop (Pmode, add_optab,
4111 current_function_internal_arg_pointer,
4112 current_function_arg_offset_rtx,
4113 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4116 /* Make it easier for the backends by protecting the valist argument
4117 from multiple evaluations. */
4119 static tree
4120 stabilize_va_list (tree valist, int needs_lvalue)
4122 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4124 if (TREE_SIDE_EFFECTS (valist))
4125 valist = save_expr (valist);
4127 /* For this case, the backends will be expecting a pointer to
4128 TREE_TYPE (va_list_type_node), but it's possible we've
4129 actually been given an array (an actual va_list_type_node).
4130 So fix it. */
4131 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4133 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4134 valist = build_fold_addr_expr_with_type (valist, p1);
4137 else
4139 tree pt;
4141 if (! needs_lvalue)
4143 if (! TREE_SIDE_EFFECTS (valist))
4144 return valist;
4146 pt = build_pointer_type (va_list_type_node);
4147 valist = fold_build1 (ADDR_EXPR, pt, valist);
4148 TREE_SIDE_EFFECTS (valist) = 1;
4151 if (TREE_SIDE_EFFECTS (valist))
4152 valist = save_expr (valist);
4153 valist = build_fold_indirect_ref (valist);
4156 return valist;
4159 /* The "standard" definition of va_list is void*. */
4161 tree
4162 std_build_builtin_va_list (void)
4164 return ptr_type_node;
4167 /* The "standard" implementation of va_start: just assign `nextarg' to
4168 the variable. */
4170 void
4171 std_expand_builtin_va_start (tree valist, rtx nextarg)
4173 tree t;
4175 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4176 make_tree (ptr_type_node, nextarg));
4177 TREE_SIDE_EFFECTS (t) = 1;
4179 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4182 /* Expand ARGLIST, from a call to __builtin_va_start. */
4184 static rtx
4185 expand_builtin_va_start (tree arglist)
4187 rtx nextarg;
4188 tree chain, valist;
4190 chain = TREE_CHAIN (arglist);
4192 if (!chain)
4194 error ("too few arguments to function %<va_start%>");
4195 return const0_rtx;
4198 if (fold_builtin_next_arg (chain))
4199 return const0_rtx;
4201 nextarg = expand_builtin_next_arg ();
4202 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4204 #ifdef EXPAND_BUILTIN_VA_START
4205 EXPAND_BUILTIN_VA_START (valist, nextarg);
4206 #else
4207 std_expand_builtin_va_start (valist, nextarg);
4208 #endif
4210 return const0_rtx;
4213 /* The "standard" implementation of va_arg: read the value from the
4214 current (padded) address and increment by the (padded) size. */
4216 tree
4217 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4219 tree addr, t, type_size, rounded_size, valist_tmp;
4220 unsigned HOST_WIDE_INT align, boundary;
4221 bool indirect;
4223 #ifdef ARGS_GROW_DOWNWARD
4224 /* All of the alignment and movement below is for args-grow-up machines.
4225 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4226 implement their own specialized gimplify_va_arg_expr routines. */
4227 gcc_unreachable ();
4228 #endif
4230 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4231 if (indirect)
4232 type = build_pointer_type (type);
4234 align = PARM_BOUNDARY / BITS_PER_UNIT;
4235 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4237 /* Hoist the valist value into a temporary for the moment. */
4238 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4240 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4241 requires greater alignment, we must perform dynamic alignment. */
4242 if (boundary > align
4243 && !integer_zerop (TYPE_SIZE (type)))
4245 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4246 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4247 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4248 gimplify_and_add (t, pre_p);
4250 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4251 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4252 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4253 gimplify_and_add (t, pre_p);
4255 else
4256 boundary = align;
4258 /* If the actual alignment is less than the alignment of the type,
4259 adjust the type accordingly so that we don't assume strict alignment
4260 when deferencing the pointer. */
4261 boundary *= BITS_PER_UNIT;
4262 if (boundary < TYPE_ALIGN (type))
4264 type = build_variant_type_copy (type);
4265 TYPE_ALIGN (type) = boundary;
4268 /* Compute the rounded size of the type. */
4269 type_size = size_in_bytes (type);
4270 rounded_size = round_up (type_size, align);
4272 /* Reduce rounded_size so it's sharable with the postqueue. */
4273 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4275 /* Get AP. */
4276 addr = valist_tmp;
4277 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4279 /* Small args are padded downward. */
4280 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4281 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4282 size_binop (MINUS_EXPR, rounded_size, type_size));
4283 t = fold_convert (TREE_TYPE (addr), t);
4284 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4287 /* Compute new value for AP. */
4288 t = fold_convert (TREE_TYPE (valist), rounded_size);
4289 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4290 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4291 gimplify_and_add (t, pre_p);
4293 addr = fold_convert (build_pointer_type (type), addr);
4295 if (indirect)
4296 addr = build_va_arg_indirect_ref (addr);
4298 return build_va_arg_indirect_ref (addr);
4301 /* Build an indirect-ref expression over the given TREE, which represents a
4302 piece of a va_arg() expansion. */
4303 tree
4304 build_va_arg_indirect_ref (tree addr)
4306 addr = build_fold_indirect_ref (addr);
4308 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4309 mf_mark (addr);
4311 return addr;
4314 /* Return a dummy expression of type TYPE in order to keep going after an
4315 error. */
4317 static tree
4318 dummy_object (tree type)
4320 tree t = build_int_cst (build_pointer_type (type), 0);
4321 return build1 (INDIRECT_REF, type, t);
4324 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4325 builtin function, but a very special sort of operator. */
4327 enum gimplify_status
4328 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4330 tree promoted_type, want_va_type, have_va_type;
4331 tree valist = TREE_OPERAND (*expr_p, 0);
4332 tree type = TREE_TYPE (*expr_p);
4333 tree t;
4335 /* Verify that valist is of the proper type. */
4336 want_va_type = va_list_type_node;
4337 have_va_type = TREE_TYPE (valist);
4339 if (have_va_type == error_mark_node)
4340 return GS_ERROR;
4342 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4344 /* If va_list is an array type, the argument may have decayed
4345 to a pointer type, e.g. by being passed to another function.
4346 In that case, unwrap both types so that we can compare the
4347 underlying records. */
4348 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4349 || POINTER_TYPE_P (have_va_type))
4351 want_va_type = TREE_TYPE (want_va_type);
4352 have_va_type = TREE_TYPE (have_va_type);
4356 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4358 error ("first argument to %<va_arg%> not of type %<va_list%>");
4359 return GS_ERROR;
4362 /* Generate a diagnostic for requesting data of a type that cannot
4363 be passed through `...' due to type promotion at the call site. */
4364 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4365 != type)
4367 static bool gave_help;
4369 /* Unfortunately, this is merely undefined, rather than a constraint
4370 violation, so we cannot make this an error. If this call is never
4371 executed, the program is still strictly conforming. */
4372 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4373 type, promoted_type);
4374 if (! gave_help)
4376 gave_help = true;
4377 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4378 promoted_type, type);
4381 /* We can, however, treat "undefined" any way we please.
4382 Call abort to encourage the user to fix the program. */
4383 inform ("if this code is reached, the program will abort");
4384 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4385 NULL);
4386 append_to_statement_list (t, pre_p);
4388 /* This is dead code, but go ahead and finish so that the
4389 mode of the result comes out right. */
4390 *expr_p = dummy_object (type);
4391 return GS_ALL_DONE;
4393 else
4395 /* Make it easier for the backends by protecting the valist argument
4396 from multiple evaluations. */
4397 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4399 /* For this case, the backends will be expecting a pointer to
4400 TREE_TYPE (va_list_type_node), but it's possible we've
4401 actually been given an array (an actual va_list_type_node).
4402 So fix it. */
4403 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4405 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4406 valist = build_fold_addr_expr_with_type (valist, p1);
4408 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4410 else
4411 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4413 if (!targetm.gimplify_va_arg_expr)
4414 /* FIXME:Once most targets are converted we should merely
4415 assert this is non-null. */
4416 return GS_ALL_DONE;
4418 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4419 return GS_OK;
4423 /* Expand ARGLIST, from a call to __builtin_va_end. */
4425 static rtx
4426 expand_builtin_va_end (tree arglist)
4428 tree valist = TREE_VALUE (arglist);
4430 /* Evaluate for side effects, if needed. I hate macros that don't
4431 do that. */
4432 if (TREE_SIDE_EFFECTS (valist))
4433 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4435 return const0_rtx;
4438 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4439 builtin rather than just as an assignment in stdarg.h because of the
4440 nastiness of array-type va_list types. */
4442 static rtx
4443 expand_builtin_va_copy (tree arglist)
4445 tree dst, src, t;
4447 dst = TREE_VALUE (arglist);
4448 src = TREE_VALUE (TREE_CHAIN (arglist));
4450 dst = stabilize_va_list (dst, 1);
4451 src = stabilize_va_list (src, 0);
4453 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4455 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4456 TREE_SIDE_EFFECTS (t) = 1;
4457 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4459 else
4461 rtx dstb, srcb, size;
4463 /* Evaluate to pointers. */
4464 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4465 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4466 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4467 VOIDmode, EXPAND_NORMAL);
4469 dstb = convert_memory_address (Pmode, dstb);
4470 srcb = convert_memory_address (Pmode, srcb);
4472 /* "Dereference" to BLKmode memories. */
4473 dstb = gen_rtx_MEM (BLKmode, dstb);
4474 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4475 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4476 srcb = gen_rtx_MEM (BLKmode, srcb);
4477 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4478 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4480 /* Copy. */
4481 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4484 return const0_rtx;
4487 /* Expand a call to one of the builtin functions __builtin_frame_address or
4488 __builtin_return_address. */
4490 static rtx
4491 expand_builtin_frame_address (tree fndecl, tree arglist)
4493 /* The argument must be a nonnegative integer constant.
4494 It counts the number of frames to scan up the stack.
4495 The value is the return address saved in that frame. */
4496 if (arglist == 0)
4497 /* Warning about missing arg was already issued. */
4498 return const0_rtx;
4499 else if (! host_integerp (TREE_VALUE (arglist), 1))
4501 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4502 error ("invalid argument to %<__builtin_frame_address%>");
4503 else
4504 error ("invalid argument to %<__builtin_return_address%>");
4505 return const0_rtx;
4507 else
4509 rtx tem
4510 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4511 tree_low_cst (TREE_VALUE (arglist), 1));
4513 /* Some ports cannot access arbitrary stack frames. */
4514 if (tem == NULL)
4516 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4517 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4518 else
4519 warning (0, "unsupported argument to %<__builtin_return_address%>");
4520 return const0_rtx;
4523 /* For __builtin_frame_address, return what we've got. */
4524 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4525 return tem;
4527 if (!REG_P (tem)
4528 && ! CONSTANT_P (tem))
4529 tem = copy_to_mode_reg (Pmode, tem);
4530 return tem;
4534 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4535 we failed and the caller should emit a normal call, otherwise try to get
4536 the result in TARGET, if convenient. */
4538 static rtx
4539 expand_builtin_alloca (tree arglist, rtx target)
4541 rtx op0;
4542 rtx result;
4544 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4545 should always expand to function calls. These can be intercepted
4546 in libmudflap. */
4547 if (flag_mudflap)
4548 return 0;
4550 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4551 return 0;
4553 /* Compute the argument. */
4554 op0 = expand_normal (TREE_VALUE (arglist));
4556 /* Allocate the desired space. */
4557 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4558 result = convert_memory_address (ptr_mode, result);
4560 return result;
4563 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4564 Return 0 if a normal call should be emitted rather than expanding the
4565 function in-line. If convenient, the result should be placed in TARGET.
4566 SUBTARGET may be used as the target for computing one of EXP's operands. */
4568 static rtx
4569 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4570 rtx subtarget, optab op_optab)
4572 rtx op0;
4573 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4574 return 0;
4576 /* Compute the argument. */
4577 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4578 /* Compute op, into TARGET if possible.
4579 Set TARGET to wherever the result comes back. */
4580 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4581 op_optab, op0, target, 1);
4582 gcc_assert (target);
4584 return convert_to_mode (target_mode, target, 0);
4587 /* If the string passed to fputs is a constant and is one character
4588 long, we attempt to transform this call into __builtin_fputc(). */
4590 static rtx
4591 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4593 /* Verify the arguments in the original call. */
4594 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4596 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4597 unlocked, NULL_TREE);
4598 if (result)
4599 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4601 return 0;
4604 /* Expand a call to __builtin_expect. We return our argument and emit a
4605 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4606 a non-jump context. */
4608 static rtx
4609 expand_builtin_expect (tree arglist, rtx target)
4611 tree exp, c;
4612 rtx note, rtx_c;
4614 if (arglist == NULL_TREE
4615 || TREE_CHAIN (arglist) == NULL_TREE)
4616 return const0_rtx;
4617 exp = TREE_VALUE (arglist);
4618 c = TREE_VALUE (TREE_CHAIN (arglist));
4620 if (TREE_CODE (c) != INTEGER_CST)
4622 error ("second argument to %<__builtin_expect%> must be a constant");
4623 c = integer_zero_node;
4626 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4628 /* Don't bother with expected value notes for integral constants. */
4629 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4631 /* We do need to force this into a register so that we can be
4632 moderately sure to be able to correctly interpret the branch
4633 condition later. */
4634 target = force_reg (GET_MODE (target), target);
4636 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4638 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4639 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4642 return target;
4645 /* Like expand_builtin_expect, except do this in a jump context. This is
4646 called from do_jump if the conditional is a __builtin_expect. Return either
4647 a list of insns to emit the jump or NULL if we cannot optimize
4648 __builtin_expect. We need to optimize this at jump time so that machines
4649 like the PowerPC don't turn the test into a SCC operation, and then jump
4650 based on the test being 0/1. */
4653 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4655 tree arglist = TREE_OPERAND (exp, 1);
4656 tree arg0 = TREE_VALUE (arglist);
4657 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4658 rtx ret = NULL_RTX;
4660 /* Only handle __builtin_expect (test, 0) and
4661 __builtin_expect (test, 1). */
4662 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4663 && (integer_zerop (arg1) || integer_onep (arg1)))
4665 rtx insn, drop_through_label, temp;
4667 /* Expand the jump insns. */
4668 start_sequence ();
4669 do_jump (arg0, if_false_label, if_true_label);
4670 ret = get_insns ();
4672 drop_through_label = get_last_insn ();
4673 if (drop_through_label && NOTE_P (drop_through_label))
4674 drop_through_label = prev_nonnote_insn (drop_through_label);
4675 if (drop_through_label && !LABEL_P (drop_through_label))
4676 drop_through_label = NULL_RTX;
4677 end_sequence ();
4679 if (! if_true_label)
4680 if_true_label = drop_through_label;
4681 if (! if_false_label)
4682 if_false_label = drop_through_label;
4684 /* Go through and add the expect's to each of the conditional jumps. */
4685 insn = ret;
4686 while (insn != NULL_RTX)
4688 rtx next = NEXT_INSN (insn);
4690 if (JUMP_P (insn) && any_condjump_p (insn))
4692 rtx ifelse = SET_SRC (pc_set (insn));
4693 rtx then_dest = XEXP (ifelse, 1);
4694 rtx else_dest = XEXP (ifelse, 2);
4695 int taken = -1;
4697 /* First check if we recognize any of the labels. */
4698 if (GET_CODE (then_dest) == LABEL_REF
4699 && XEXP (then_dest, 0) == if_true_label)
4700 taken = 1;
4701 else if (GET_CODE (then_dest) == LABEL_REF
4702 && XEXP (then_dest, 0) == if_false_label)
4703 taken = 0;
4704 else if (GET_CODE (else_dest) == LABEL_REF
4705 && XEXP (else_dest, 0) == if_false_label)
4706 taken = 1;
4707 else if (GET_CODE (else_dest) == LABEL_REF
4708 && XEXP (else_dest, 0) == if_true_label)
4709 taken = 0;
4710 /* Otherwise check where we drop through. */
4711 else if (else_dest == pc_rtx)
4713 if (next && NOTE_P (next))
4714 next = next_nonnote_insn (next);
4716 if (next && JUMP_P (next)
4717 && any_uncondjump_p (next))
4718 temp = XEXP (SET_SRC (pc_set (next)), 0);
4719 else
4720 temp = next;
4722 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4723 else that can't possibly match either target label. */
4724 if (temp == if_false_label)
4725 taken = 1;
4726 else if (temp == if_true_label)
4727 taken = 0;
4729 else if (then_dest == pc_rtx)
4731 if (next && NOTE_P (next))
4732 next = next_nonnote_insn (next);
4734 if (next && JUMP_P (next)
4735 && any_uncondjump_p (next))
4736 temp = XEXP (SET_SRC (pc_set (next)), 0);
4737 else
4738 temp = next;
4740 if (temp == if_false_label)
4741 taken = 0;
4742 else if (temp == if_true_label)
4743 taken = 1;
4746 if (taken != -1)
4748 /* If the test is expected to fail, reverse the
4749 probabilities. */
4750 if (integer_zerop (arg1))
4751 taken = 1 - taken;
4752 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4756 insn = next;
4760 return ret;
4763 void
4764 expand_builtin_trap (void)
4766 #ifdef HAVE_trap
4767 if (HAVE_trap)
4768 emit_insn (gen_trap ());
4769 else
4770 #endif
4771 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4772 emit_barrier ();
4775 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4776 Return 0 if a normal call should be emitted rather than expanding
4777 the function inline. If convenient, the result should be placed
4778 in TARGET. SUBTARGET may be used as the target for computing
4779 the operand. */
4781 static rtx
4782 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4784 enum machine_mode mode;
4785 tree arg;
4786 rtx op0;
4788 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4789 return 0;
4791 arg = TREE_VALUE (arglist);
4792 mode = TYPE_MODE (TREE_TYPE (arg));
4793 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4794 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4797 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4798 Return NULL is a normal call should be emitted rather than expanding the
4799 function inline. If convenient, the result should be placed in TARGET.
4800 SUBTARGET may be used as the target for computing the operand. */
4802 static rtx
4803 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4805 rtx op0, op1;
4806 tree arg;
4808 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4809 return 0;
4811 arg = TREE_VALUE (arglist);
4812 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4814 arg = TREE_VALUE (TREE_CHAIN (arglist));
4815 op1 = expand_normal (arg);
4817 return expand_copysign (op0, op1, target);
4820 /* Create a new constant string literal and return a char* pointer to it.
4821 The STRING_CST value is the LEN characters at STR. */
4822 tree
4823 build_string_literal (int len, const char *str)
4825 tree t, elem, index, type;
4827 t = build_string (len, str);
4828 elem = build_type_variant (char_type_node, 1, 0);
4829 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4830 type = build_array_type (elem, index);
4831 TREE_TYPE (t) = type;
4832 TREE_CONSTANT (t) = 1;
4833 TREE_INVARIANT (t) = 1;
4834 TREE_READONLY (t) = 1;
4835 TREE_STATIC (t) = 1;
4837 type = build_pointer_type (type);
4838 t = build1 (ADDR_EXPR, type, t);
4840 type = build_pointer_type (elem);
4841 t = build1 (NOP_EXPR, type, t);
4842 return t;
4845 /* Expand EXP, a call to printf or printf_unlocked.
4846 Return 0 if a normal call should be emitted rather than transforming
4847 the function inline. If convenient, the result should be placed in
4848 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4849 call. */
4850 static rtx
4851 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4852 bool unlocked)
4854 tree arglist = TREE_OPERAND (exp, 1);
4855 /* If we're using an unlocked function, assume the other unlocked
4856 functions exist explicitly. */
4857 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4858 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4859 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4860 : implicit_built_in_decls[BUILT_IN_PUTS];
4861 const char *fmt_str;
4862 tree fn, fmt, arg;
4864 /* If the return value is used, don't do the transformation. */
4865 if (target != const0_rtx)
4866 return 0;
4868 /* Verify the required arguments in the original call. */
4869 if (! arglist)
4870 return 0;
4871 fmt = TREE_VALUE (arglist);
4872 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4873 return 0;
4874 arglist = TREE_CHAIN (arglist);
4876 /* Check whether the format is a literal string constant. */
4877 fmt_str = c_getstr (fmt);
4878 if (fmt_str == NULL)
4879 return 0;
4881 if (!init_target_chars())
4882 return 0;
4884 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4885 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4887 if (! arglist
4888 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4889 || TREE_CHAIN (arglist))
4890 return 0;
4891 fn = fn_puts;
4893 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4894 else if (strcmp (fmt_str, target_percent_c) == 0)
4896 if (! arglist
4897 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4898 || TREE_CHAIN (arglist))
4899 return 0;
4900 fn = fn_putchar;
4902 else
4904 /* We can't handle anything else with % args or %% ... yet. */
4905 if (strchr (fmt_str, target_percent))
4906 return 0;
4908 if (arglist)
4909 return 0;
4911 /* If the format specifier was "", printf does nothing. */
4912 if (fmt_str[0] == '\0')
4913 return const0_rtx;
4914 /* If the format specifier has length of 1, call putchar. */
4915 if (fmt_str[1] == '\0')
4917 /* Given printf("c"), (where c is any one character,)
4918 convert "c"[0] to an int and pass that to the replacement
4919 function. */
4920 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4921 arglist = build_tree_list (NULL_TREE, arg);
4922 fn = fn_putchar;
4924 else
4926 /* If the format specifier was "string\n", call puts("string"). */
4927 size_t len = strlen (fmt_str);
4928 if ((unsigned char)fmt_str[len - 1] == target_newline)
4930 /* Create a NUL-terminated string that's one char shorter
4931 than the original, stripping off the trailing '\n'. */
4932 char *newstr = alloca (len);
4933 memcpy (newstr, fmt_str, len - 1);
4934 newstr[len - 1] = 0;
4936 arg = build_string_literal (len, newstr);
4937 arglist = build_tree_list (NULL_TREE, arg);
4938 fn = fn_puts;
4940 else
4941 /* We'd like to arrange to call fputs(string,stdout) here,
4942 but we need stdout and don't have a way to get it yet. */
4943 return 0;
4947 if (!fn)
4948 return 0;
4949 fn = build_function_call_expr (fn, arglist);
4950 if (TREE_CODE (fn) == CALL_EXPR)
4951 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4952 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4955 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4956 Return 0 if a normal call should be emitted rather than transforming
4957 the function inline. If convenient, the result should be placed in
4958 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4959 call. */
4960 static rtx
4961 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4962 bool unlocked)
4964 tree arglist = TREE_OPERAND (exp, 1);
4965 /* If we're using an unlocked function, assume the other unlocked
4966 functions exist explicitly. */
4967 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4968 : implicit_built_in_decls[BUILT_IN_FPUTC];
4969 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4970 : implicit_built_in_decls[BUILT_IN_FPUTS];
4971 const char *fmt_str;
4972 tree fn, fmt, fp, arg;
4974 /* If the return value is used, don't do the transformation. */
4975 if (target != const0_rtx)
4976 return 0;
4978 /* Verify the required arguments in the original call. */
4979 if (! arglist)
4980 return 0;
4981 fp = TREE_VALUE (arglist);
4982 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4983 return 0;
4984 arglist = TREE_CHAIN (arglist);
4985 if (! arglist)
4986 return 0;
4987 fmt = TREE_VALUE (arglist);
4988 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4989 return 0;
4990 arglist = TREE_CHAIN (arglist);
4992 /* Check whether the format is a literal string constant. */
4993 fmt_str = c_getstr (fmt);
4994 if (fmt_str == NULL)
4995 return 0;
4997 if (!init_target_chars())
4998 return 0;
5000 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5001 if (strcmp (fmt_str, target_percent_s) == 0)
5003 if (! arglist
5004 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5005 || TREE_CHAIN (arglist))
5006 return 0;
5007 arg = TREE_VALUE (arglist);
5008 arglist = build_tree_list (NULL_TREE, fp);
5009 arglist = tree_cons (NULL_TREE, arg, arglist);
5010 fn = fn_fputs;
5012 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5013 else if (strcmp (fmt_str, target_percent_c) == 0)
5015 if (! arglist
5016 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5017 || TREE_CHAIN (arglist))
5018 return 0;
5019 arg = TREE_VALUE (arglist);
5020 arglist = build_tree_list (NULL_TREE, fp);
5021 arglist = tree_cons (NULL_TREE, arg, arglist);
5022 fn = fn_fputc;
5024 else
5026 /* We can't handle anything else with % args or %% ... yet. */
5027 if (strchr (fmt_str, target_percent))
5028 return 0;
5030 if (arglist)
5031 return 0;
5033 /* If the format specifier was "", fprintf does nothing. */
5034 if (fmt_str[0] == '\0')
5036 /* Evaluate and ignore FILE* argument for side-effects. */
5037 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5038 return const0_rtx;
5041 /* When "string" doesn't contain %, replace all cases of
5042 fprintf(stream,string) with fputs(string,stream). The fputs
5043 builtin will take care of special cases like length == 1. */
5044 arglist = build_tree_list (NULL_TREE, fp);
5045 arglist = tree_cons (NULL_TREE, fmt, arglist);
5046 fn = fn_fputs;
5049 if (!fn)
5050 return 0;
5051 fn = build_function_call_expr (fn, arglist);
5052 if (TREE_CODE (fn) == CALL_EXPR)
5053 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5054 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5057 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5058 a normal call should be emitted rather than expanding the function
5059 inline. If convenient, the result should be placed in TARGET with
5060 mode MODE. */
5062 static rtx
5063 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5065 tree orig_arglist, dest, fmt;
5066 const char *fmt_str;
5068 orig_arglist = arglist;
5070 /* Verify the required arguments in the original call. */
5071 if (! arglist)
5072 return 0;
5073 dest = TREE_VALUE (arglist);
5074 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5075 return 0;
5076 arglist = TREE_CHAIN (arglist);
5077 if (! arglist)
5078 return 0;
5079 fmt = TREE_VALUE (arglist);
5080 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5081 return 0;
5082 arglist = TREE_CHAIN (arglist);
5084 /* Check whether the format is a literal string constant. */
5085 fmt_str = c_getstr (fmt);
5086 if (fmt_str == NULL)
5087 return 0;
5089 if (!init_target_chars())
5090 return 0;
5092 /* If the format doesn't contain % args or %%, use strcpy. */
5093 if (strchr (fmt_str, target_percent) == 0)
5095 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5096 tree exp;
5098 if (arglist || ! fn)
5099 return 0;
5100 expand_expr (build_function_call_expr (fn, orig_arglist),
5101 const0_rtx, VOIDmode, EXPAND_NORMAL);
5102 if (target == const0_rtx)
5103 return const0_rtx;
5104 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5105 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5107 /* If the format is "%s", use strcpy if the result isn't used. */
5108 else if (strcmp (fmt_str, target_percent_s) == 0)
5110 tree fn, arg, len;
5111 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5113 if (! fn)
5114 return 0;
5116 if (! arglist || TREE_CHAIN (arglist))
5117 return 0;
5118 arg = TREE_VALUE (arglist);
5119 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5120 return 0;
5122 if (target != const0_rtx)
5124 len = c_strlen (arg, 1);
5125 if (! len || TREE_CODE (len) != INTEGER_CST)
5126 return 0;
5128 else
5129 len = NULL_TREE;
5131 arglist = build_tree_list (NULL_TREE, arg);
5132 arglist = tree_cons (NULL_TREE, dest, arglist);
5133 expand_expr (build_function_call_expr (fn, arglist),
5134 const0_rtx, VOIDmode, EXPAND_NORMAL);
5136 if (target == const0_rtx)
5137 return const0_rtx;
5138 return expand_expr (len, target, mode, EXPAND_NORMAL);
5141 return 0;
5144 /* Expand a call to either the entry or exit function profiler. */
5146 static rtx
5147 expand_builtin_profile_func (bool exitp)
5149 rtx this, which;
5151 this = DECL_RTL (current_function_decl);
5152 gcc_assert (MEM_P (this));
5153 this = XEXP (this, 0);
5155 if (exitp)
5156 which = profile_function_exit_libfunc;
5157 else
5158 which = profile_function_entry_libfunc;
5160 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5161 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5163 Pmode);
5165 return const0_rtx;
5168 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5170 static rtx
5171 round_trampoline_addr (rtx tramp)
5173 rtx temp, addend, mask;
5175 /* If we don't need too much alignment, we'll have been guaranteed
5176 proper alignment by get_trampoline_type. */
5177 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5178 return tramp;
5180 /* Round address up to desired boundary. */
5181 temp = gen_reg_rtx (Pmode);
5182 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5183 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5185 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5186 temp, 0, OPTAB_LIB_WIDEN);
5187 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5188 temp, 0, OPTAB_LIB_WIDEN);
5190 return tramp;
5193 static rtx
5194 expand_builtin_init_trampoline (tree arglist)
5196 tree t_tramp, t_func, t_chain;
5197 rtx r_tramp, r_func, r_chain;
5198 #ifdef TRAMPOLINE_TEMPLATE
5199 rtx blktramp;
5200 #endif
5202 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5203 POINTER_TYPE, VOID_TYPE))
5204 return NULL_RTX;
5206 t_tramp = TREE_VALUE (arglist);
5207 arglist = TREE_CHAIN (arglist);
5208 t_func = TREE_VALUE (arglist);
5209 arglist = TREE_CHAIN (arglist);
5210 t_chain = TREE_VALUE (arglist);
5212 r_tramp = expand_normal (t_tramp);
5213 r_func = expand_normal (t_func);
5214 r_chain = expand_normal (t_chain);
5216 /* Generate insns to initialize the trampoline. */
5217 r_tramp = round_trampoline_addr (r_tramp);
5218 #ifdef TRAMPOLINE_TEMPLATE
5219 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5220 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5221 emit_block_move (blktramp, assemble_trampoline_template (),
5222 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5223 #endif
5224 trampolines_created = 1;
5225 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5227 return const0_rtx;
5230 static rtx
5231 expand_builtin_adjust_trampoline (tree arglist)
5233 rtx tramp;
5235 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5236 return NULL_RTX;
5238 tramp = expand_normal (TREE_VALUE (arglist));
5239 tramp = round_trampoline_addr (tramp);
5240 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5241 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5242 #endif
5244 return tramp;
5247 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5248 Return NULL_RTX if a normal call should be emitted rather than expanding
5249 the function in-line. EXP is the expression that is a call to the builtin
5250 function; if convenient, the result should be placed in TARGET. */
5252 static rtx
5253 expand_builtin_signbit (tree exp, rtx target)
5255 const struct real_format *fmt;
5256 enum machine_mode fmode, imode, rmode;
5257 HOST_WIDE_INT hi, lo;
5258 tree arg, arglist;
5259 int word, bitpos;
5260 rtx temp;
5262 arglist = TREE_OPERAND (exp, 1);
5263 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5264 return 0;
5266 arg = TREE_VALUE (arglist);
5267 fmode = TYPE_MODE (TREE_TYPE (arg));
5268 rmode = TYPE_MODE (TREE_TYPE (exp));
5269 fmt = REAL_MODE_FORMAT (fmode);
5271 /* For floating point formats without a sign bit, implement signbit
5272 as "ARG < 0.0". */
5273 bitpos = fmt->signbit_ro;
5274 if (bitpos < 0)
5276 /* But we can't do this if the format supports signed zero. */
5277 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5278 return 0;
5280 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5281 build_real (TREE_TYPE (arg), dconst0));
5282 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5285 temp = expand_normal (arg);
5286 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5288 imode = int_mode_for_mode (fmode);
5289 if (imode == BLKmode)
5290 return 0;
5291 temp = gen_lowpart (imode, temp);
5293 else
5295 imode = word_mode;
5296 /* Handle targets with different FP word orders. */
5297 if (FLOAT_WORDS_BIG_ENDIAN)
5298 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5299 else
5300 word = bitpos / BITS_PER_WORD;
5301 temp = operand_subword_force (temp, word, fmode);
5302 bitpos = bitpos % BITS_PER_WORD;
5305 /* Force the intermediate word_mode (or narrower) result into a
5306 register. This avoids attempting to create paradoxical SUBREGs
5307 of floating point modes below. */
5308 temp = force_reg (imode, temp);
5310 /* If the bitpos is within the "result mode" lowpart, the operation
5311 can be implement with a single bitwise AND. Otherwise, we need
5312 a right shift and an AND. */
5314 if (bitpos < GET_MODE_BITSIZE (rmode))
5316 if (bitpos < HOST_BITS_PER_WIDE_INT)
5318 hi = 0;
5319 lo = (HOST_WIDE_INT) 1 << bitpos;
5321 else
5323 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5324 lo = 0;
5327 if (imode != rmode)
5328 temp = gen_lowpart (rmode, temp);
5329 temp = expand_binop (rmode, and_optab, temp,
5330 immed_double_const (lo, hi, rmode),
5331 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5333 else
5335 /* Perform a logical right shift to place the signbit in the least
5336 significant bit, then truncate the result to the desired mode
5337 and mask just this bit. */
5338 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5339 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5340 temp = gen_lowpart (rmode, temp);
5341 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5342 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5345 return temp;
5348 /* Expand fork or exec calls. TARGET is the desired target of the
5349 call. ARGLIST is the list of arguments of the call. FN is the
5350 identificator of the actual function. IGNORE is nonzero if the
5351 value is to be ignored. */
5353 static rtx
5354 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5356 tree id, decl;
5357 tree call;
5359 /* If we are not profiling, just call the function. */
5360 if (!profile_arc_flag)
5361 return NULL_RTX;
5363 /* Otherwise call the wrapper. This should be equivalent for the rest of
5364 compiler, so the code does not diverge, and the wrapper may run the
5365 code necessary for keeping the profiling sane. */
5367 switch (DECL_FUNCTION_CODE (fn))
5369 case BUILT_IN_FORK:
5370 id = get_identifier ("__gcov_fork");
5371 break;
5373 case BUILT_IN_EXECL:
5374 id = get_identifier ("__gcov_execl");
5375 break;
5377 case BUILT_IN_EXECV:
5378 id = get_identifier ("__gcov_execv");
5379 break;
5381 case BUILT_IN_EXECLP:
5382 id = get_identifier ("__gcov_execlp");
5383 break;
5385 case BUILT_IN_EXECLE:
5386 id = get_identifier ("__gcov_execle");
5387 break;
5389 case BUILT_IN_EXECVP:
5390 id = get_identifier ("__gcov_execvp");
5391 break;
5393 case BUILT_IN_EXECVE:
5394 id = get_identifier ("__gcov_execve");
5395 break;
5397 default:
5398 gcc_unreachable ();
5401 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5402 DECL_EXTERNAL (decl) = 1;
5403 TREE_PUBLIC (decl) = 1;
5404 DECL_ARTIFICIAL (decl) = 1;
5405 TREE_NOTHROW (decl) = 1;
5406 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5407 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5408 call = build_function_call_expr (decl, arglist);
5410 return expand_call (call, target, ignore);
5414 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5415 the pointer in these functions is void*, the tree optimizers may remove
5416 casts. The mode computed in expand_builtin isn't reliable either, due
5417 to __sync_bool_compare_and_swap.
5419 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5420 group of builtins. This gives us log2 of the mode size. */
5422 static inline enum machine_mode
5423 get_builtin_sync_mode (int fcode_diff)
5425 /* The size is not negotiable, so ask not to get BLKmode in return
5426 if the target indicates that a smaller size would be better. */
5427 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5430 /* Expand the memory expression LOC and return the appropriate memory operand
5431 for the builtin_sync operations. */
5433 static rtx
5434 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5436 rtx addr, mem;
5438 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5440 /* Note that we explicitly do not want any alias information for this
5441 memory, so that we kill all other live memories. Otherwise we don't
5442 satisfy the full barrier semantics of the intrinsic. */
5443 mem = validize_mem (gen_rtx_MEM (mode, addr));
5445 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5446 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5447 MEM_VOLATILE_P (mem) = 1;
5449 return mem;
5452 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5453 ARGLIST is the operands list to the function. CODE is the rtx code
5454 that corresponds to the arithmetic or logical operation from the name;
5455 an exception here is that NOT actually means NAND. TARGET is an optional
5456 place for us to store the results; AFTER is true if this is the
5457 fetch_and_xxx form. IGNORE is true if we don't actually care about
5458 the result of the operation at all. */
5460 static rtx
5461 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5462 enum rtx_code code, bool after,
5463 rtx target, bool ignore)
5465 rtx val, mem;
5467 /* Expand the operands. */
5468 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5470 arglist = TREE_CHAIN (arglist);
5471 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5473 if (ignore)
5474 return expand_sync_operation (mem, val, code);
5475 else
5476 return expand_sync_fetch_operation (mem, val, code, after, target);
5479 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5480 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5481 true if this is the boolean form. TARGET is a place for us to store the
5482 results; this is NOT optional if IS_BOOL is true. */
5484 static rtx
5485 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5486 bool is_bool, rtx target)
5488 rtx old_val, new_val, mem;
5490 /* Expand the operands. */
5491 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5493 arglist = TREE_CHAIN (arglist);
5494 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5496 arglist = TREE_CHAIN (arglist);
5497 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5499 if (is_bool)
5500 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5501 else
5502 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5505 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5506 general form is actually an atomic exchange, and some targets only
5507 support a reduced form with the second argument being a constant 1.
5508 ARGLIST is the operands list to the function; TARGET is an optional
5509 place for us to store the results. */
5511 static rtx
5512 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5513 rtx target)
5515 rtx val, mem;
5517 /* Expand the operands. */
5518 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5520 arglist = TREE_CHAIN (arglist);
5521 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5523 return expand_sync_lock_test_and_set (mem, val, target);
5526 /* Expand the __sync_synchronize intrinsic. */
5528 static void
5529 expand_builtin_synchronize (void)
5531 tree x;
5533 #ifdef HAVE_memory_barrier
5534 if (HAVE_memory_barrier)
5536 emit_insn (gen_memory_barrier ());
5537 return;
5539 #endif
5541 /* If no explicit memory barrier instruction is available, create an
5542 empty asm stmt with a memory clobber. */
5543 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5544 tree_cons (NULL, build_string (6, "memory"), NULL));
5545 ASM_VOLATILE_P (x) = 1;
5546 expand_asm_expr (x);
5549 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5550 to the function. */
5552 static void
5553 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5555 enum insn_code icode;
5556 rtx mem, insn;
5557 rtx val = const0_rtx;
5559 /* Expand the operands. */
5560 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5562 /* If there is an explicit operation in the md file, use it. */
5563 icode = sync_lock_release[mode];
5564 if (icode != CODE_FOR_nothing)
5566 if (!insn_data[icode].operand[1].predicate (val, mode))
5567 val = force_reg (mode, val);
5569 insn = GEN_FCN (icode) (mem, val);
5570 if (insn)
5572 emit_insn (insn);
5573 return;
5577 /* Otherwise we can implement this operation by emitting a barrier
5578 followed by a store of zero. */
5579 expand_builtin_synchronize ();
5580 emit_move_insn (mem, val);
5583 /* Expand an expression EXP that calls a built-in function,
5584 with result going to TARGET if that's convenient
5585 (and in mode MODE if that's convenient).
5586 SUBTARGET may be used as the target for computing one of EXP's operands.
5587 IGNORE is nonzero if the value is to be ignored. */
5590 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5591 int ignore)
5593 tree fndecl = get_callee_fndecl (exp);
5594 tree arglist = TREE_OPERAND (exp, 1);
5595 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5596 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5598 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5599 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5601 /* When not optimizing, generate calls to library functions for a certain
5602 set of builtins. */
5603 if (!optimize
5604 && !called_as_built_in (fndecl)
5605 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5606 && fcode != BUILT_IN_ALLOCA)
5607 return expand_call (exp, target, ignore);
5609 /* The built-in function expanders test for target == const0_rtx
5610 to determine whether the function's result will be ignored. */
5611 if (ignore)
5612 target = const0_rtx;
5614 /* If the result of a pure or const built-in function is ignored, and
5615 none of its arguments are volatile, we can avoid expanding the
5616 built-in call and just evaluate the arguments for side-effects. */
5617 if (target == const0_rtx
5618 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5620 bool volatilep = false;
5621 tree arg;
5623 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5624 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5626 volatilep = true;
5627 break;
5630 if (! volatilep)
5632 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5633 expand_expr (TREE_VALUE (arg), const0_rtx,
5634 VOIDmode, EXPAND_NORMAL);
5635 return const0_rtx;
5639 switch (fcode)
5641 CASE_FLT_FN (BUILT_IN_FABS):
5642 target = expand_builtin_fabs (arglist, target, subtarget);
5643 if (target)
5644 return target;
5645 break;
5647 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5648 target = expand_builtin_copysign (arglist, target, subtarget);
5649 if (target)
5650 return target;
5651 break;
5653 /* Just do a normal library call if we were unable to fold
5654 the values. */
5655 CASE_FLT_FN (BUILT_IN_CABS):
5656 break;
5658 CASE_FLT_FN (BUILT_IN_EXP):
5659 CASE_FLT_FN (BUILT_IN_EXP10):
5660 CASE_FLT_FN (BUILT_IN_POW10):
5661 CASE_FLT_FN (BUILT_IN_EXP2):
5662 CASE_FLT_FN (BUILT_IN_EXPM1):
5663 CASE_FLT_FN (BUILT_IN_LOGB):
5664 CASE_FLT_FN (BUILT_IN_ILOGB):
5665 CASE_FLT_FN (BUILT_IN_LOG):
5666 CASE_FLT_FN (BUILT_IN_LOG10):
5667 CASE_FLT_FN (BUILT_IN_LOG2):
5668 CASE_FLT_FN (BUILT_IN_LOG1P):
5669 CASE_FLT_FN (BUILT_IN_TAN):
5670 CASE_FLT_FN (BUILT_IN_ASIN):
5671 CASE_FLT_FN (BUILT_IN_ACOS):
5672 CASE_FLT_FN (BUILT_IN_ATAN):
5673 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5674 because of possible accuracy problems. */
5675 if (! flag_unsafe_math_optimizations)
5676 break;
5677 CASE_FLT_FN (BUILT_IN_SQRT):
5678 CASE_FLT_FN (BUILT_IN_FLOOR):
5679 CASE_FLT_FN (BUILT_IN_CEIL):
5680 CASE_FLT_FN (BUILT_IN_TRUNC):
5681 CASE_FLT_FN (BUILT_IN_ROUND):
5682 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5683 CASE_FLT_FN (BUILT_IN_RINT):
5684 CASE_FLT_FN (BUILT_IN_LRINT):
5685 CASE_FLT_FN (BUILT_IN_LLRINT):
5686 target = expand_builtin_mathfn (exp, target, subtarget);
5687 if (target)
5688 return target;
5689 break;
5691 CASE_FLT_FN (BUILT_IN_LCEIL):
5692 CASE_FLT_FN (BUILT_IN_LLCEIL):
5693 CASE_FLT_FN (BUILT_IN_LFLOOR):
5694 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5695 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5696 if (target)
5697 return target;
5698 break;
5700 CASE_FLT_FN (BUILT_IN_POW):
5701 target = expand_builtin_pow (exp, target, subtarget);
5702 if (target)
5703 return target;
5704 break;
5706 CASE_FLT_FN (BUILT_IN_POWI):
5707 target = expand_builtin_powi (exp, target, subtarget);
5708 if (target)
5709 return target;
5710 break;
5712 CASE_FLT_FN (BUILT_IN_ATAN2):
5713 CASE_FLT_FN (BUILT_IN_LDEXP):
5714 CASE_FLT_FN (BUILT_IN_FMOD):
5715 CASE_FLT_FN (BUILT_IN_DREM):
5716 if (! flag_unsafe_math_optimizations)
5717 break;
5718 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5719 if (target)
5720 return target;
5721 break;
5723 CASE_FLT_FN (BUILT_IN_SIN):
5724 CASE_FLT_FN (BUILT_IN_COS):
5725 if (! flag_unsafe_math_optimizations)
5726 break;
5727 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5728 if (target)
5729 return target;
5730 break;
5732 CASE_FLT_FN (BUILT_IN_SINCOS):
5733 if (! flag_unsafe_math_optimizations)
5734 break;
5735 target = expand_builtin_sincos (exp);
5736 if (target)
5737 return target;
5738 break;
5740 case BUILT_IN_APPLY_ARGS:
5741 return expand_builtin_apply_args ();
5743 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5744 FUNCTION with a copy of the parameters described by
5745 ARGUMENTS, and ARGSIZE. It returns a block of memory
5746 allocated on the stack into which is stored all the registers
5747 that might possibly be used for returning the result of a
5748 function. ARGUMENTS is the value returned by
5749 __builtin_apply_args. ARGSIZE is the number of bytes of
5750 arguments that must be copied. ??? How should this value be
5751 computed? We'll also need a safe worst case value for varargs
5752 functions. */
5753 case BUILT_IN_APPLY:
5754 if (!validate_arglist (arglist, POINTER_TYPE,
5755 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5756 && !validate_arglist (arglist, REFERENCE_TYPE,
5757 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5758 return const0_rtx;
5759 else
5761 int i;
5762 tree t;
5763 rtx ops[3];
5765 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5766 ops[i] = expand_normal (TREE_VALUE (t));
5768 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5771 /* __builtin_return (RESULT) causes the function to return the
5772 value described by RESULT. RESULT is address of the block of
5773 memory returned by __builtin_apply. */
5774 case BUILT_IN_RETURN:
5775 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5776 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5777 return const0_rtx;
5779 case BUILT_IN_SAVEREGS:
5780 return expand_builtin_saveregs ();
5782 case BUILT_IN_ARGS_INFO:
5783 return expand_builtin_args_info (arglist);
5785 /* Return the address of the first anonymous stack arg. */
5786 case BUILT_IN_NEXT_ARG:
5787 if (fold_builtin_next_arg (arglist))
5788 return const0_rtx;
5789 return expand_builtin_next_arg ();
5791 case BUILT_IN_CLASSIFY_TYPE:
5792 return expand_builtin_classify_type (arglist);
5794 case BUILT_IN_CONSTANT_P:
5795 return const0_rtx;
5797 case BUILT_IN_FRAME_ADDRESS:
5798 case BUILT_IN_RETURN_ADDRESS:
5799 return expand_builtin_frame_address (fndecl, arglist);
5801 /* Returns the address of the area where the structure is returned.
5802 0 otherwise. */
5803 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5804 if (arglist != 0
5805 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5806 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5807 return const0_rtx;
5808 else
5809 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5811 case BUILT_IN_ALLOCA:
5812 target = expand_builtin_alloca (arglist, target);
5813 if (target)
5814 return target;
5815 break;
5817 case BUILT_IN_STACK_SAVE:
5818 return expand_stack_save ();
5820 case BUILT_IN_STACK_RESTORE:
5821 expand_stack_restore (TREE_VALUE (arglist));
5822 return const0_rtx;
5824 CASE_INT_FN (BUILT_IN_FFS):
5825 case BUILT_IN_FFSIMAX:
5826 target = expand_builtin_unop (target_mode, arglist, target,
5827 subtarget, ffs_optab);
5828 if (target)
5829 return target;
5830 break;
5832 CASE_INT_FN (BUILT_IN_CLZ):
5833 case BUILT_IN_CLZIMAX:
5834 target = expand_builtin_unop (target_mode, arglist, target,
5835 subtarget, clz_optab);
5836 if (target)
5837 return target;
5838 break;
5840 CASE_INT_FN (BUILT_IN_CTZ):
5841 case BUILT_IN_CTZIMAX:
5842 target = expand_builtin_unop (target_mode, arglist, target,
5843 subtarget, ctz_optab);
5844 if (target)
5845 return target;
5846 break;
5848 CASE_INT_FN (BUILT_IN_POPCOUNT):
5849 case BUILT_IN_POPCOUNTIMAX:
5850 target = expand_builtin_unop (target_mode, arglist, target,
5851 subtarget, popcount_optab);
5852 if (target)
5853 return target;
5854 break;
5856 CASE_INT_FN (BUILT_IN_PARITY):
5857 case BUILT_IN_PARITYIMAX:
5858 target = expand_builtin_unop (target_mode, arglist, target,
5859 subtarget, parity_optab);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_STRLEN:
5865 target = expand_builtin_strlen (arglist, target, target_mode);
5866 if (target)
5867 return target;
5868 break;
5870 case BUILT_IN_STRCPY:
5871 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5872 if (target)
5873 return target;
5874 break;
5876 case BUILT_IN_STRNCPY:
5877 target = expand_builtin_strncpy (exp, target, mode);
5878 if (target)
5879 return target;
5880 break;
5882 case BUILT_IN_STPCPY:
5883 target = expand_builtin_stpcpy (exp, target, mode);
5884 if (target)
5885 return target;
5886 break;
5888 case BUILT_IN_STRCAT:
5889 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5890 if (target)
5891 return target;
5892 break;
5894 case BUILT_IN_STRNCAT:
5895 target = expand_builtin_strncat (arglist, target, mode);
5896 if (target)
5897 return target;
5898 break;
5900 case BUILT_IN_STRSPN:
5901 target = expand_builtin_strspn (arglist, target, mode);
5902 if (target)
5903 return target;
5904 break;
5906 case BUILT_IN_STRCSPN:
5907 target = expand_builtin_strcspn (arglist, target, mode);
5908 if (target)
5909 return target;
5910 break;
5912 case BUILT_IN_STRSTR:
5913 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5914 if (target)
5915 return target;
5916 break;
5918 case BUILT_IN_STRPBRK:
5919 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5920 if (target)
5921 return target;
5922 break;
5924 case BUILT_IN_INDEX:
5925 case BUILT_IN_STRCHR:
5926 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5927 if (target)
5928 return target;
5929 break;
5931 case BUILT_IN_RINDEX:
5932 case BUILT_IN_STRRCHR:
5933 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_MEMCPY:
5939 target = expand_builtin_memcpy (exp, target, mode);
5940 if (target)
5941 return target;
5942 break;
5944 case BUILT_IN_MEMPCPY:
5945 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5946 if (target)
5947 return target;
5948 break;
5950 case BUILT_IN_MEMMOVE:
5951 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5952 mode, exp);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_BCOPY:
5958 target = expand_builtin_bcopy (exp);
5959 if (target)
5960 return target;
5961 break;
5963 case BUILT_IN_MEMSET:
5964 target = expand_builtin_memset (arglist, target, mode, exp);
5965 if (target)
5966 return target;
5967 break;
5969 case BUILT_IN_BZERO:
5970 target = expand_builtin_bzero (exp);
5971 if (target)
5972 return target;
5973 break;
5975 case BUILT_IN_STRCMP:
5976 target = expand_builtin_strcmp (exp, target, mode);
5977 if (target)
5978 return target;
5979 break;
5981 case BUILT_IN_STRNCMP:
5982 target = expand_builtin_strncmp (exp, target, mode);
5983 if (target)
5984 return target;
5985 break;
5987 case BUILT_IN_BCMP:
5988 case BUILT_IN_MEMCMP:
5989 target = expand_builtin_memcmp (exp, arglist, target, mode);
5990 if (target)
5991 return target;
5992 break;
5994 case BUILT_IN_SETJMP:
5995 target = expand_builtin_setjmp (arglist, target);
5996 if (target)
5997 return target;
5998 break;
6000 /* __builtin_longjmp is passed a pointer to an array of five words.
6001 It's similar to the C library longjmp function but works with
6002 __builtin_setjmp above. */
6003 case BUILT_IN_LONGJMP:
6004 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6005 break;
6006 else
6008 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6009 VOIDmode, EXPAND_NORMAL);
6010 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6012 if (value != const1_rtx)
6014 error ("%<__builtin_longjmp%> second argument must be 1");
6015 return const0_rtx;
6018 expand_builtin_longjmp (buf_addr, value);
6019 return const0_rtx;
6022 case BUILT_IN_NONLOCAL_GOTO:
6023 target = expand_builtin_nonlocal_goto (arglist);
6024 if (target)
6025 return target;
6026 break;
6028 /* This updates the setjmp buffer that is its argument with the value
6029 of the current stack pointer. */
6030 case BUILT_IN_UPDATE_SETJMP_BUF:
6031 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6033 rtx buf_addr
6034 = expand_normal (TREE_VALUE (arglist));
6036 expand_builtin_update_setjmp_buf (buf_addr);
6037 return const0_rtx;
6039 break;
6041 case BUILT_IN_TRAP:
6042 expand_builtin_trap ();
6043 return const0_rtx;
6045 case BUILT_IN_PRINTF:
6046 target = expand_builtin_printf (exp, target, mode, false);
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_PRINTF_UNLOCKED:
6052 target = expand_builtin_printf (exp, target, mode, true);
6053 if (target)
6054 return target;
6055 break;
6057 case BUILT_IN_FPUTS:
6058 target = expand_builtin_fputs (arglist, target, false);
6059 if (target)
6060 return target;
6061 break;
6062 case BUILT_IN_FPUTS_UNLOCKED:
6063 target = expand_builtin_fputs (arglist, target, true);
6064 if (target)
6065 return target;
6066 break;
6068 case BUILT_IN_FPRINTF:
6069 target = expand_builtin_fprintf (exp, target, mode, false);
6070 if (target)
6071 return target;
6072 break;
6074 case BUILT_IN_FPRINTF_UNLOCKED:
6075 target = expand_builtin_fprintf (exp, target, mode, true);
6076 if (target)
6077 return target;
6078 break;
6080 case BUILT_IN_SPRINTF:
6081 target = expand_builtin_sprintf (arglist, target, mode);
6082 if (target)
6083 return target;
6084 break;
6086 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6087 target = expand_builtin_signbit (exp, target);
6088 if (target)
6089 return target;
6090 break;
6092 /* Various hooks for the DWARF 2 __throw routine. */
6093 case BUILT_IN_UNWIND_INIT:
6094 expand_builtin_unwind_init ();
6095 return const0_rtx;
6096 case BUILT_IN_DWARF_CFA:
6097 return virtual_cfa_rtx;
6098 #ifdef DWARF2_UNWIND_INFO
6099 case BUILT_IN_DWARF_SP_COLUMN:
6100 return expand_builtin_dwarf_sp_column ();
6101 case BUILT_IN_INIT_DWARF_REG_SIZES:
6102 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6103 return const0_rtx;
6104 #endif
6105 case BUILT_IN_FROB_RETURN_ADDR:
6106 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6107 case BUILT_IN_EXTRACT_RETURN_ADDR:
6108 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6109 case BUILT_IN_EH_RETURN:
6110 expand_builtin_eh_return (TREE_VALUE (arglist),
6111 TREE_VALUE (TREE_CHAIN (arglist)));
6112 return const0_rtx;
6113 #ifdef EH_RETURN_DATA_REGNO
6114 case BUILT_IN_EH_RETURN_DATA_REGNO:
6115 return expand_builtin_eh_return_data_regno (arglist);
6116 #endif
6117 case BUILT_IN_EXTEND_POINTER:
6118 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6120 case BUILT_IN_VA_START:
6121 case BUILT_IN_STDARG_START:
6122 return expand_builtin_va_start (arglist);
6123 case BUILT_IN_VA_END:
6124 return expand_builtin_va_end (arglist);
6125 case BUILT_IN_VA_COPY:
6126 return expand_builtin_va_copy (arglist);
6127 case BUILT_IN_EXPECT:
6128 return expand_builtin_expect (arglist, target);
6129 case BUILT_IN_PREFETCH:
6130 expand_builtin_prefetch (arglist);
6131 return const0_rtx;
6133 case BUILT_IN_PROFILE_FUNC_ENTER:
6134 return expand_builtin_profile_func (false);
6135 case BUILT_IN_PROFILE_FUNC_EXIT:
6136 return expand_builtin_profile_func (true);
6138 case BUILT_IN_INIT_TRAMPOLINE:
6139 return expand_builtin_init_trampoline (arglist);
6140 case BUILT_IN_ADJUST_TRAMPOLINE:
6141 return expand_builtin_adjust_trampoline (arglist);
6143 case BUILT_IN_FORK:
6144 case BUILT_IN_EXECL:
6145 case BUILT_IN_EXECV:
6146 case BUILT_IN_EXECLP:
6147 case BUILT_IN_EXECLE:
6148 case BUILT_IN_EXECVP:
6149 case BUILT_IN_EXECVE:
6150 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6151 if (target)
6152 return target;
6153 break;
6155 case BUILT_IN_FETCH_AND_ADD_1:
6156 case BUILT_IN_FETCH_AND_ADD_2:
6157 case BUILT_IN_FETCH_AND_ADD_4:
6158 case BUILT_IN_FETCH_AND_ADD_8:
6159 case BUILT_IN_FETCH_AND_ADD_16:
6160 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6161 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6162 false, target, ignore);
6163 if (target)
6164 return target;
6165 break;
6167 case BUILT_IN_FETCH_AND_SUB_1:
6168 case BUILT_IN_FETCH_AND_SUB_2:
6169 case BUILT_IN_FETCH_AND_SUB_4:
6170 case BUILT_IN_FETCH_AND_SUB_8:
6171 case BUILT_IN_FETCH_AND_SUB_16:
6172 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6173 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6174 false, target, ignore);
6175 if (target)
6176 return target;
6177 break;
6179 case BUILT_IN_FETCH_AND_OR_1:
6180 case BUILT_IN_FETCH_AND_OR_2:
6181 case BUILT_IN_FETCH_AND_OR_4:
6182 case BUILT_IN_FETCH_AND_OR_8:
6183 case BUILT_IN_FETCH_AND_OR_16:
6184 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6185 target = expand_builtin_sync_operation (mode, arglist, IOR,
6186 false, target, ignore);
6187 if (target)
6188 return target;
6189 break;
6191 case BUILT_IN_FETCH_AND_AND_1:
6192 case BUILT_IN_FETCH_AND_AND_2:
6193 case BUILT_IN_FETCH_AND_AND_4:
6194 case BUILT_IN_FETCH_AND_AND_8:
6195 case BUILT_IN_FETCH_AND_AND_16:
6196 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6197 target = expand_builtin_sync_operation (mode, arglist, AND,
6198 false, target, ignore);
6199 if (target)
6200 return target;
6201 break;
6203 case BUILT_IN_FETCH_AND_XOR_1:
6204 case BUILT_IN_FETCH_AND_XOR_2:
6205 case BUILT_IN_FETCH_AND_XOR_4:
6206 case BUILT_IN_FETCH_AND_XOR_8:
6207 case BUILT_IN_FETCH_AND_XOR_16:
6208 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6209 target = expand_builtin_sync_operation (mode, arglist, XOR,
6210 false, target, ignore);
6211 if (target)
6212 return target;
6213 break;
6215 case BUILT_IN_FETCH_AND_NAND_1:
6216 case BUILT_IN_FETCH_AND_NAND_2:
6217 case BUILT_IN_FETCH_AND_NAND_4:
6218 case BUILT_IN_FETCH_AND_NAND_8:
6219 case BUILT_IN_FETCH_AND_NAND_16:
6220 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6221 target = expand_builtin_sync_operation (mode, arglist, NOT,
6222 false, target, ignore);
6223 if (target)
6224 return target;
6225 break;
6227 case BUILT_IN_ADD_AND_FETCH_1:
6228 case BUILT_IN_ADD_AND_FETCH_2:
6229 case BUILT_IN_ADD_AND_FETCH_4:
6230 case BUILT_IN_ADD_AND_FETCH_8:
6231 case BUILT_IN_ADD_AND_FETCH_16:
6232 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6233 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6234 true, target, ignore);
6235 if (target)
6236 return target;
6237 break;
6239 case BUILT_IN_SUB_AND_FETCH_1:
6240 case BUILT_IN_SUB_AND_FETCH_2:
6241 case BUILT_IN_SUB_AND_FETCH_4:
6242 case BUILT_IN_SUB_AND_FETCH_8:
6243 case BUILT_IN_SUB_AND_FETCH_16:
6244 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6245 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6246 true, target, ignore);
6247 if (target)
6248 return target;
6249 break;
6251 case BUILT_IN_OR_AND_FETCH_1:
6252 case BUILT_IN_OR_AND_FETCH_2:
6253 case BUILT_IN_OR_AND_FETCH_4:
6254 case BUILT_IN_OR_AND_FETCH_8:
6255 case BUILT_IN_OR_AND_FETCH_16:
6256 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6257 target = expand_builtin_sync_operation (mode, arglist, IOR,
6258 true, target, ignore);
6259 if (target)
6260 return target;
6261 break;
6263 case BUILT_IN_AND_AND_FETCH_1:
6264 case BUILT_IN_AND_AND_FETCH_2:
6265 case BUILT_IN_AND_AND_FETCH_4:
6266 case BUILT_IN_AND_AND_FETCH_8:
6267 case BUILT_IN_AND_AND_FETCH_16:
6268 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6269 target = expand_builtin_sync_operation (mode, arglist, AND,
6270 true, target, ignore);
6271 if (target)
6272 return target;
6273 break;
6275 case BUILT_IN_XOR_AND_FETCH_1:
6276 case BUILT_IN_XOR_AND_FETCH_2:
6277 case BUILT_IN_XOR_AND_FETCH_4:
6278 case BUILT_IN_XOR_AND_FETCH_8:
6279 case BUILT_IN_XOR_AND_FETCH_16:
6280 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6281 target = expand_builtin_sync_operation (mode, arglist, XOR,
6282 true, target, ignore);
6283 if (target)
6284 return target;
6285 break;
6287 case BUILT_IN_NAND_AND_FETCH_1:
6288 case BUILT_IN_NAND_AND_FETCH_2:
6289 case BUILT_IN_NAND_AND_FETCH_4:
6290 case BUILT_IN_NAND_AND_FETCH_8:
6291 case BUILT_IN_NAND_AND_FETCH_16:
6292 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6293 target = expand_builtin_sync_operation (mode, arglist, NOT,
6294 true, target, ignore);
6295 if (target)
6296 return target;
6297 break;
6299 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6300 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6301 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6302 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6303 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6304 if (mode == VOIDmode)
6305 mode = TYPE_MODE (boolean_type_node);
6306 if (!target || !register_operand (target, mode))
6307 target = gen_reg_rtx (mode);
6309 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6310 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6311 if (target)
6312 return target;
6313 break;
6315 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6316 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6317 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6318 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6319 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6320 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6321 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6322 if (target)
6323 return target;
6324 break;
6326 case BUILT_IN_LOCK_TEST_AND_SET_1:
6327 case BUILT_IN_LOCK_TEST_AND_SET_2:
6328 case BUILT_IN_LOCK_TEST_AND_SET_4:
6329 case BUILT_IN_LOCK_TEST_AND_SET_8:
6330 case BUILT_IN_LOCK_TEST_AND_SET_16:
6331 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6332 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6333 if (target)
6334 return target;
6335 break;
6337 case BUILT_IN_LOCK_RELEASE_1:
6338 case BUILT_IN_LOCK_RELEASE_2:
6339 case BUILT_IN_LOCK_RELEASE_4:
6340 case BUILT_IN_LOCK_RELEASE_8:
6341 case BUILT_IN_LOCK_RELEASE_16:
6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6343 expand_builtin_lock_release (mode, arglist);
6344 return const0_rtx;
6346 case BUILT_IN_SYNCHRONIZE:
6347 expand_builtin_synchronize ();
6348 return const0_rtx;
6350 case BUILT_IN_OBJECT_SIZE:
6351 return expand_builtin_object_size (exp);
6353 case BUILT_IN_MEMCPY_CHK:
6354 case BUILT_IN_MEMPCPY_CHK:
6355 case BUILT_IN_MEMMOVE_CHK:
6356 case BUILT_IN_MEMSET_CHK:
6357 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6358 if (target)
6359 return target;
6360 break;
6362 case BUILT_IN_STRCPY_CHK:
6363 case BUILT_IN_STPCPY_CHK:
6364 case BUILT_IN_STRNCPY_CHK:
6365 case BUILT_IN_STRCAT_CHK:
6366 case BUILT_IN_SNPRINTF_CHK:
6367 case BUILT_IN_VSNPRINTF_CHK:
6368 maybe_emit_chk_warning (exp, fcode);
6369 break;
6371 case BUILT_IN_SPRINTF_CHK:
6372 case BUILT_IN_VSPRINTF_CHK:
6373 maybe_emit_sprintf_chk_warning (exp, fcode);
6374 break;
6376 default: /* just do library call, if unknown builtin */
6377 break;
6380 /* The switch statement above can drop through to cause the function
6381 to be called normally. */
6382 return expand_call (exp, target, ignore);
6385 /* Determine whether a tree node represents a call to a built-in
6386 function. If the tree T is a call to a built-in function with
6387 the right number of arguments of the appropriate types, return
6388 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6389 Otherwise the return value is END_BUILTINS. */
6391 enum built_in_function
6392 builtin_mathfn_code (tree t)
6394 tree fndecl, arglist, parmlist;
6395 tree argtype, parmtype;
6397 if (TREE_CODE (t) != CALL_EXPR
6398 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6399 return END_BUILTINS;
6401 fndecl = get_callee_fndecl (t);
6402 if (fndecl == NULL_TREE
6403 || TREE_CODE (fndecl) != FUNCTION_DECL
6404 || ! DECL_BUILT_IN (fndecl)
6405 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6406 return END_BUILTINS;
6408 arglist = TREE_OPERAND (t, 1);
6409 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6410 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6412 /* If a function doesn't take a variable number of arguments,
6413 the last element in the list will have type `void'. */
6414 parmtype = TREE_VALUE (parmlist);
6415 if (VOID_TYPE_P (parmtype))
6417 if (arglist)
6418 return END_BUILTINS;
6419 return DECL_FUNCTION_CODE (fndecl);
6422 if (! arglist)
6423 return END_BUILTINS;
6425 argtype = TREE_TYPE (TREE_VALUE (arglist));
6427 if (SCALAR_FLOAT_TYPE_P (parmtype))
6429 if (! SCALAR_FLOAT_TYPE_P (argtype))
6430 return END_BUILTINS;
6432 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6434 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6435 return END_BUILTINS;
6437 else if (POINTER_TYPE_P (parmtype))
6439 if (! POINTER_TYPE_P (argtype))
6440 return END_BUILTINS;
6442 else if (INTEGRAL_TYPE_P (parmtype))
6444 if (! INTEGRAL_TYPE_P (argtype))
6445 return END_BUILTINS;
6447 else
6448 return END_BUILTINS;
6450 arglist = TREE_CHAIN (arglist);
6453 /* Variable-length argument list. */
6454 return DECL_FUNCTION_CODE (fndecl);
6457 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6458 constant. ARGLIST is the argument list of the call. */
6460 static tree
6461 fold_builtin_constant_p (tree arglist)
6463 if (arglist == 0)
6464 return 0;
6466 arglist = TREE_VALUE (arglist);
6468 /* We return 1 for a numeric type that's known to be a constant
6469 value at compile-time or for an aggregate type that's a
6470 literal constant. */
6471 STRIP_NOPS (arglist);
6473 /* If we know this is a constant, emit the constant of one. */
6474 if (CONSTANT_CLASS_P (arglist)
6475 || (TREE_CODE (arglist) == CONSTRUCTOR
6476 && TREE_CONSTANT (arglist)))
6477 return integer_one_node;
6478 if (TREE_CODE (arglist) == ADDR_EXPR)
6480 tree op = TREE_OPERAND (arglist, 0);
6481 if (TREE_CODE (op) == STRING_CST
6482 || (TREE_CODE (op) == ARRAY_REF
6483 && integer_zerop (TREE_OPERAND (op, 1))
6484 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6485 return integer_one_node;
6488 /* If this expression has side effects, show we don't know it to be a
6489 constant. Likewise if it's a pointer or aggregate type since in
6490 those case we only want literals, since those are only optimized
6491 when generating RTL, not later.
6492 And finally, if we are compiling an initializer, not code, we
6493 need to return a definite result now; there's not going to be any
6494 more optimization done. */
6495 if (TREE_SIDE_EFFECTS (arglist)
6496 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6497 || POINTER_TYPE_P (TREE_TYPE (arglist))
6498 || cfun == 0
6499 || folding_initializer)
6500 return integer_zero_node;
6502 return 0;
6505 /* Fold a call to __builtin_expect, if we expect that a comparison against
6506 the argument will fold to a constant. In practice, this means a true
6507 constant or the address of a non-weak symbol. ARGLIST is the argument
6508 list of the call. */
6510 static tree
6511 fold_builtin_expect (tree arglist)
6513 tree arg, inner;
6515 if (arglist == 0)
6516 return 0;
6518 arg = TREE_VALUE (arglist);
6520 /* If the argument isn't invariant, then there's nothing we can do. */
6521 if (!TREE_INVARIANT (arg))
6522 return 0;
6524 /* If we're looking at an address of a weak decl, then do not fold. */
6525 inner = arg;
6526 STRIP_NOPS (inner);
6527 if (TREE_CODE (inner) == ADDR_EXPR)
6531 inner = TREE_OPERAND (inner, 0);
6533 while (TREE_CODE (inner) == COMPONENT_REF
6534 || TREE_CODE (inner) == ARRAY_REF);
6535 if (DECL_P (inner) && DECL_WEAK (inner))
6536 return 0;
6539 /* Otherwise, ARG already has the proper type for the return value. */
6540 return arg;
6543 /* Fold a call to __builtin_classify_type. */
6545 static tree
6546 fold_builtin_classify_type (tree arglist)
6548 if (arglist == 0)
6549 return build_int_cst (NULL_TREE, no_type_class);
6551 return build_int_cst (NULL_TREE,
6552 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6555 /* Fold a call to __builtin_strlen. */
6557 static tree
6558 fold_builtin_strlen (tree arglist)
6560 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6561 return NULL_TREE;
6562 else
6564 tree len = c_strlen (TREE_VALUE (arglist), 0);
6566 if (len)
6568 /* Convert from the internal "sizetype" type to "size_t". */
6569 if (size_type_node)
6570 len = fold_convert (size_type_node, len);
6571 return len;
6574 return NULL_TREE;
6578 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6580 static tree
6581 fold_builtin_inf (tree type, int warn)
6583 REAL_VALUE_TYPE real;
6585 /* __builtin_inff is intended to be usable to define INFINITY on all
6586 targets. If an infinity is not available, INFINITY expands "to a
6587 positive constant of type float that overflows at translation
6588 time", footnote "In this case, using INFINITY will violate the
6589 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6590 Thus we pedwarn to ensure this constraint violation is
6591 diagnosed. */
6592 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6593 pedwarn ("target format does not support infinity");
6595 real_inf (&real);
6596 return build_real (type, real);
6599 /* Fold a call to __builtin_nan or __builtin_nans. */
6601 static tree
6602 fold_builtin_nan (tree arglist, tree type, int quiet)
6604 REAL_VALUE_TYPE real;
6605 const char *str;
6607 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6608 return 0;
6609 str = c_getstr (TREE_VALUE (arglist));
6610 if (!str)
6611 return 0;
6613 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6614 return 0;
6616 return build_real (type, real);
6619 /* Return true if the floating point expression T has an integer value.
6620 We also allow +Inf, -Inf and NaN to be considered integer values. */
6622 static bool
6623 integer_valued_real_p (tree t)
6625 switch (TREE_CODE (t))
6627 case FLOAT_EXPR:
6628 return true;
6630 case ABS_EXPR:
6631 case SAVE_EXPR:
6632 case NON_LVALUE_EXPR:
6633 return integer_valued_real_p (TREE_OPERAND (t, 0));
6635 case COMPOUND_EXPR:
6636 case MODIFY_EXPR:
6637 case BIND_EXPR:
6638 return integer_valued_real_p (TREE_OPERAND (t, 1));
6640 case PLUS_EXPR:
6641 case MINUS_EXPR:
6642 case MULT_EXPR:
6643 case MIN_EXPR:
6644 case MAX_EXPR:
6645 return integer_valued_real_p (TREE_OPERAND (t, 0))
6646 && integer_valued_real_p (TREE_OPERAND (t, 1));
6648 case COND_EXPR:
6649 return integer_valued_real_p (TREE_OPERAND (t, 1))
6650 && integer_valued_real_p (TREE_OPERAND (t, 2));
6652 case REAL_CST:
6653 if (! TREE_CONSTANT_OVERFLOW (t))
6655 REAL_VALUE_TYPE c, cint;
6657 c = TREE_REAL_CST (t);
6658 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6659 return real_identical (&c, &cint);
6661 break;
6663 case NOP_EXPR:
6665 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6666 if (TREE_CODE (type) == INTEGER_TYPE)
6667 return true;
6668 if (TREE_CODE (type) == REAL_TYPE)
6669 return integer_valued_real_p (TREE_OPERAND (t, 0));
6670 break;
6673 case CALL_EXPR:
6674 switch (builtin_mathfn_code (t))
6676 CASE_FLT_FN (BUILT_IN_CEIL):
6677 CASE_FLT_FN (BUILT_IN_FLOOR):
6678 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6679 CASE_FLT_FN (BUILT_IN_RINT):
6680 CASE_FLT_FN (BUILT_IN_ROUND):
6681 CASE_FLT_FN (BUILT_IN_TRUNC):
6682 return true;
6684 default:
6685 break;
6687 break;
6689 default:
6690 break;
6692 return false;
6695 /* EXP is assumed to be builtin call where truncation can be propagated
6696 across (for instance floor((double)f) == (double)floorf (f).
6697 Do the transformation. */
6699 static tree
6700 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6702 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6703 tree arg;
6705 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6706 return 0;
6708 arg = TREE_VALUE (arglist);
6709 /* Integer rounding functions are idempotent. */
6710 if (fcode == builtin_mathfn_code (arg))
6711 return arg;
6713 /* If argument is already integer valued, and we don't need to worry
6714 about setting errno, there's no need to perform rounding. */
6715 if (! flag_errno_math && integer_valued_real_p (arg))
6716 return arg;
6718 if (optimize)
6720 tree arg0 = strip_float_extensions (arg);
6721 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6722 tree newtype = TREE_TYPE (arg0);
6723 tree decl;
6725 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6726 && (decl = mathfn_built_in (newtype, fcode)))
6728 arglist =
6729 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6730 return fold_convert (ftype,
6731 build_function_call_expr (decl, arglist));
6734 return 0;
6737 /* EXP is assumed to be builtin call which can narrow the FP type of
6738 the argument, for instance lround((double)f) -> lroundf (f). */
6740 static tree
6741 fold_fixed_mathfn (tree fndecl, tree arglist)
6743 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6744 tree arg;
6746 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6747 return 0;
6749 arg = TREE_VALUE (arglist);
6751 /* If argument is already integer valued, and we don't need to worry
6752 about setting errno, there's no need to perform rounding. */
6753 if (! flag_errno_math && integer_valued_real_p (arg))
6754 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6756 if (optimize)
6758 tree ftype = TREE_TYPE (arg);
6759 tree arg0 = strip_float_extensions (arg);
6760 tree newtype = TREE_TYPE (arg0);
6761 tree decl;
6763 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6764 && (decl = mathfn_built_in (newtype, fcode)))
6766 arglist =
6767 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6768 return build_function_call_expr (decl, arglist);
6771 return 0;
6774 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6775 is the argument list, TYPE is the return type and FNDECL is the
6776 original function DECL. Return NULL_TREE if no if no simplification
6777 can be made. */
6779 static tree
6780 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6782 tree arg;
6784 if (!arglist || TREE_CHAIN (arglist))
6785 return NULL_TREE;
6787 arg = TREE_VALUE (arglist);
6788 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6789 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6790 return NULL_TREE;
6792 /* Evaluate cabs of a constant at compile-time. */
6793 if (flag_unsafe_math_optimizations
6794 && TREE_CODE (arg) == COMPLEX_CST
6795 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6796 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6797 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6798 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6800 REAL_VALUE_TYPE r, i;
6802 r = TREE_REAL_CST (TREE_REALPART (arg));
6803 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6805 real_arithmetic (&r, MULT_EXPR, &r, &r);
6806 real_arithmetic (&i, MULT_EXPR, &i, &i);
6807 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6808 if (real_sqrt (&r, TYPE_MODE (type), &r)
6809 || ! flag_trapping_math)
6810 return build_real (type, r);
6813 /* If either part is zero, cabs is fabs of the other. */
6814 if (TREE_CODE (arg) == COMPLEX_EXPR
6815 && real_zerop (TREE_OPERAND (arg, 0)))
6816 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6817 if (TREE_CODE (arg) == COMPLEX_EXPR
6818 && real_zerop (TREE_OPERAND (arg, 1)))
6819 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6821 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6822 if (TREE_CODE (arg) == NEGATE_EXPR
6823 || TREE_CODE (arg) == CONJ_EXPR)
6825 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6826 return build_function_call_expr (fndecl, arglist);
6829 /* Don't do this when optimizing for size. */
6830 if (flag_unsafe_math_optimizations
6831 && optimize && !optimize_size)
6833 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6835 if (sqrtfn != NULL_TREE)
6837 tree rpart, ipart, result, arglist;
6839 arg = builtin_save_expr (arg);
6841 rpart = fold_build1 (REALPART_EXPR, type, arg);
6842 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6844 rpart = builtin_save_expr (rpart);
6845 ipart = builtin_save_expr (ipart);
6847 result = fold_build2 (PLUS_EXPR, type,
6848 fold_build2 (MULT_EXPR, type,
6849 rpart, rpart),
6850 fold_build2 (MULT_EXPR, type,
6851 ipart, ipart));
6853 arglist = build_tree_list (NULL_TREE, result);
6854 return build_function_call_expr (sqrtfn, arglist);
6858 return NULL_TREE;
6861 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6862 NULL_TREE if no simplification can be made. */
6864 static tree
6865 fold_builtin_sqrt (tree arglist, tree type)
6868 enum built_in_function fcode;
6869 tree arg = TREE_VALUE (arglist);
6871 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6872 return NULL_TREE;
6874 /* Optimize sqrt of constant value. */
6875 if (TREE_CODE (arg) == REAL_CST
6876 && ! TREE_CONSTANT_OVERFLOW (arg))
6878 REAL_VALUE_TYPE r, x;
6880 x = TREE_REAL_CST (arg);
6881 if (real_sqrt (&r, TYPE_MODE (type), &x)
6882 || (!flag_trapping_math && !flag_errno_math))
6883 return build_real (type, r);
6886 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6887 fcode = builtin_mathfn_code (arg);
6888 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6890 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6891 arg = fold_build2 (MULT_EXPR, type,
6892 TREE_VALUE (TREE_OPERAND (arg, 1)),
6893 build_real (type, dconsthalf));
6894 arglist = build_tree_list (NULL_TREE, arg);
6895 return build_function_call_expr (expfn, arglist);
6898 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6899 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6901 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6903 if (powfn)
6905 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6906 tree tree_root;
6907 /* The inner root was either sqrt or cbrt. */
6908 REAL_VALUE_TYPE dconstroot =
6909 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6911 /* Adjust for the outer root. */
6912 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6913 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6914 tree_root = build_real (type, dconstroot);
6915 arglist = tree_cons (NULL_TREE, arg0,
6916 build_tree_list (NULL_TREE, tree_root));
6917 return build_function_call_expr (powfn, arglist);
6921 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6922 if (flag_unsafe_math_optimizations
6923 && (fcode == BUILT_IN_POW
6924 || fcode == BUILT_IN_POWF
6925 || fcode == BUILT_IN_POWL))
6927 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6928 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6929 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6930 tree narg1;
6931 if (!tree_expr_nonnegative_p (arg0))
6932 arg0 = build1 (ABS_EXPR, type, arg0);
6933 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6934 build_real (type, dconsthalf));
6935 arglist = tree_cons (NULL_TREE, arg0,
6936 build_tree_list (NULL_TREE, narg1));
6937 return build_function_call_expr (powfn, arglist);
6940 return NULL_TREE;
6943 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6944 NULL_TREE if no simplification can be made. */
6945 static tree
6946 fold_builtin_cbrt (tree arglist, tree type)
6948 tree arg = TREE_VALUE (arglist);
6949 const enum built_in_function fcode = builtin_mathfn_code (arg);
6951 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6952 return NULL_TREE;
6954 /* Optimize cbrt of constant value. */
6955 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6956 return arg;
6958 if (flag_unsafe_math_optimizations)
6960 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6961 if (BUILTIN_EXPONENT_P (fcode))
6963 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6964 const REAL_VALUE_TYPE third_trunc =
6965 real_value_truncate (TYPE_MODE (type), dconstthird);
6966 arg = fold_build2 (MULT_EXPR, type,
6967 TREE_VALUE (TREE_OPERAND (arg, 1)),
6968 build_real (type, third_trunc));
6969 arglist = build_tree_list (NULL_TREE, arg);
6970 return build_function_call_expr (expfn, arglist);
6973 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6974 if (BUILTIN_SQRT_P (fcode))
6976 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6978 if (powfn)
6980 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6981 tree tree_root;
6982 REAL_VALUE_TYPE dconstroot = dconstthird;
6984 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6985 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6986 tree_root = build_real (type, dconstroot);
6987 arglist = tree_cons (NULL_TREE, arg0,
6988 build_tree_list (NULL_TREE, tree_root));
6989 return build_function_call_expr (powfn, arglist);
6993 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6994 if (BUILTIN_CBRT_P (fcode))
6996 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6997 if (tree_expr_nonnegative_p (arg0))
6999 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7001 if (powfn)
7003 tree tree_root;
7004 REAL_VALUE_TYPE dconstroot;
7006 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7007 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7008 tree_root = build_real (type, dconstroot);
7009 arglist = tree_cons (NULL_TREE, arg0,
7010 build_tree_list (NULL_TREE, tree_root));
7011 return build_function_call_expr (powfn, arglist);
7016 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7017 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7018 || fcode == BUILT_IN_POWL)
7020 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7021 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7022 if (tree_expr_nonnegative_p (arg00))
7024 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7025 const REAL_VALUE_TYPE dconstroot
7026 = real_value_truncate (TYPE_MODE (type), dconstthird);
7027 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7028 build_real (type, dconstroot));
7029 arglist = tree_cons (NULL_TREE, arg00,
7030 build_tree_list (NULL_TREE, narg01));
7031 return build_function_call_expr (powfn, arglist);
7035 return NULL_TREE;
7038 /* Fold function call to builtin sin, sinf, or sinl. Return
7039 NULL_TREE if no simplification can be made. */
7040 static tree
7041 fold_builtin_sin (tree arglist)
7043 tree arg = TREE_VALUE (arglist);
7045 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7046 return NULL_TREE;
7048 /* Optimize sin (0.0) = 0.0. */
7049 if (real_zerop (arg))
7050 return arg;
7052 return NULL_TREE;
7055 /* Fold function call to builtin cos, cosf, or cosl. Return
7056 NULL_TREE if no simplification can be made. */
7057 static tree
7058 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7060 tree arg = TREE_VALUE (arglist);
7062 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7063 return NULL_TREE;
7065 /* Optimize cos (0.0) = 1.0. */
7066 if (real_zerop (arg))
7067 return build_real (type, dconst1);
7069 /* Optimize cos(-x) into cos (x). */
7070 if (TREE_CODE (arg) == NEGATE_EXPR)
7072 tree args = build_tree_list (NULL_TREE,
7073 TREE_OPERAND (arg, 0));
7074 return build_function_call_expr (fndecl, args);
7077 return NULL_TREE;
7080 /* Fold function call to builtin tan, tanf, or tanl. Return
7081 NULL_TREE if no simplification can be made. */
7082 static tree
7083 fold_builtin_tan (tree arglist)
7085 enum built_in_function fcode;
7086 tree arg = TREE_VALUE (arglist);
7088 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7089 return NULL_TREE;
7091 /* Optimize tan(0.0) = 0.0. */
7092 if (real_zerop (arg))
7093 return arg;
7095 /* Optimize tan(atan(x)) = x. */
7096 fcode = builtin_mathfn_code (arg);
7097 if (flag_unsafe_math_optimizations
7098 && (fcode == BUILT_IN_ATAN
7099 || fcode == BUILT_IN_ATANF
7100 || fcode == BUILT_IN_ATANL))
7101 return TREE_VALUE (TREE_OPERAND (arg, 1));
7103 return NULL_TREE;
7106 /* Fold function call to builtin atan, atanf, or atanl. Return
7107 NULL_TREE if no simplification can be made. */
7109 static tree
7110 fold_builtin_atan (tree arglist, tree type)
7113 tree arg = TREE_VALUE (arglist);
7115 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7116 return NULL_TREE;
7118 /* Optimize atan(0.0) = 0.0. */
7119 if (real_zerop (arg))
7120 return arg;
7122 /* Optimize atan(1.0) = pi/4. */
7123 if (real_onep (arg))
7125 REAL_VALUE_TYPE cst;
7127 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7128 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7129 return build_real (type, cst);
7132 return NULL_TREE;
7135 /* Fold function call to builtin trunc, truncf or truncl. Return
7136 NULL_TREE if no simplification can be made. */
7138 static tree
7139 fold_builtin_trunc (tree fndecl, tree arglist)
7141 tree arg;
7143 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7144 return 0;
7146 /* Optimize trunc of constant value. */
7147 arg = TREE_VALUE (arglist);
7148 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7150 REAL_VALUE_TYPE r, x;
7151 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7153 x = TREE_REAL_CST (arg);
7154 real_trunc (&r, TYPE_MODE (type), &x);
7155 return build_real (type, r);
7158 return fold_trunc_transparent_mathfn (fndecl, arglist);
7161 /* Fold function call to builtin floor, floorf or floorl. Return
7162 NULL_TREE if no simplification can be made. */
7164 static tree
7165 fold_builtin_floor (tree fndecl, tree arglist)
7167 tree arg;
7169 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7170 return 0;
7172 /* Optimize floor of constant value. */
7173 arg = TREE_VALUE (arglist);
7174 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7176 REAL_VALUE_TYPE x;
7178 x = TREE_REAL_CST (arg);
7179 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7181 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7182 REAL_VALUE_TYPE r;
7184 real_floor (&r, TYPE_MODE (type), &x);
7185 return build_real (type, r);
7189 return fold_trunc_transparent_mathfn (fndecl, arglist);
7192 /* Fold function call to builtin ceil, ceilf or ceill. Return
7193 NULL_TREE if no simplification can be made. */
7195 static tree
7196 fold_builtin_ceil (tree fndecl, tree arglist)
7198 tree arg;
7200 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7201 return 0;
7203 /* Optimize ceil of constant value. */
7204 arg = TREE_VALUE (arglist);
7205 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7207 REAL_VALUE_TYPE x;
7209 x = TREE_REAL_CST (arg);
7210 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7212 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7213 REAL_VALUE_TYPE r;
7215 real_ceil (&r, TYPE_MODE (type), &x);
7216 return build_real (type, r);
7220 return fold_trunc_transparent_mathfn (fndecl, arglist);
7223 /* Fold function call to builtin round, roundf or roundl. Return
7224 NULL_TREE if no simplification can be made. */
7226 static tree
7227 fold_builtin_round (tree fndecl, tree arglist)
7229 tree arg;
7231 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7232 return 0;
7234 /* Optimize round of constant value. */
7235 arg = TREE_VALUE (arglist);
7236 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7238 REAL_VALUE_TYPE x;
7240 x = TREE_REAL_CST (arg);
7241 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7243 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7244 REAL_VALUE_TYPE r;
7246 real_round (&r, TYPE_MODE (type), &x);
7247 return build_real (type, r);
7251 return fold_trunc_transparent_mathfn (fndecl, arglist);
7254 /* Fold function call to builtin lround, lroundf or lroundl (or the
7255 corresponding long long versions) and other rounding functions.
7256 Return NULL_TREE if no simplification can be made. */
7258 static tree
7259 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7261 tree arg;
7263 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7264 return 0;
7266 /* Optimize lround of constant value. */
7267 arg = TREE_VALUE (arglist);
7268 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7270 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7272 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7274 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7275 tree ftype = TREE_TYPE (arg), result;
7276 HOST_WIDE_INT hi, lo;
7277 REAL_VALUE_TYPE r;
7279 switch (DECL_FUNCTION_CODE (fndecl))
7281 CASE_FLT_FN (BUILT_IN_LFLOOR):
7282 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7283 real_floor (&r, TYPE_MODE (ftype), &x);
7284 break;
7286 CASE_FLT_FN (BUILT_IN_LCEIL):
7287 CASE_FLT_FN (BUILT_IN_LLCEIL):
7288 real_ceil (&r, TYPE_MODE (ftype), &x);
7289 break;
7291 CASE_FLT_FN (BUILT_IN_LROUND):
7292 CASE_FLT_FN (BUILT_IN_LLROUND):
7293 real_round (&r, TYPE_MODE (ftype), &x);
7294 break;
7296 default:
7297 gcc_unreachable ();
7300 REAL_VALUE_TO_INT (&lo, &hi, r);
7301 result = build_int_cst_wide (NULL_TREE, lo, hi);
7302 if (int_fits_type_p (result, itype))
7303 return fold_convert (itype, result);
7307 return fold_fixed_mathfn (fndecl, arglist);
7310 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7311 and their long and long long variants (i.e. ffsl and ffsll).
7312 Return NULL_TREE if no simplification can be made. */
7314 static tree
7315 fold_builtin_bitop (tree fndecl, tree arglist)
7317 tree arg;
7319 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7320 return NULL_TREE;
7322 /* Optimize for constant argument. */
7323 arg = TREE_VALUE (arglist);
7324 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7326 HOST_WIDE_INT hi, width, result;
7327 unsigned HOST_WIDE_INT lo;
7328 tree type;
7330 type = TREE_TYPE (arg);
7331 width = TYPE_PRECISION (type);
7332 lo = TREE_INT_CST_LOW (arg);
7334 /* Clear all the bits that are beyond the type's precision. */
7335 if (width > HOST_BITS_PER_WIDE_INT)
7337 hi = TREE_INT_CST_HIGH (arg);
7338 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7339 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7341 else
7343 hi = 0;
7344 if (width < HOST_BITS_PER_WIDE_INT)
7345 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7348 switch (DECL_FUNCTION_CODE (fndecl))
7350 CASE_INT_FN (BUILT_IN_FFS):
7351 if (lo != 0)
7352 result = exact_log2 (lo & -lo) + 1;
7353 else if (hi != 0)
7354 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7355 else
7356 result = 0;
7357 break;
7359 CASE_INT_FN (BUILT_IN_CLZ):
7360 if (hi != 0)
7361 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7362 else if (lo != 0)
7363 result = width - floor_log2 (lo) - 1;
7364 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7365 result = width;
7366 break;
7368 CASE_INT_FN (BUILT_IN_CTZ):
7369 if (lo != 0)
7370 result = exact_log2 (lo & -lo);
7371 else if (hi != 0)
7372 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7373 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7374 result = width;
7375 break;
7377 CASE_INT_FN (BUILT_IN_POPCOUNT):
7378 result = 0;
7379 while (lo)
7380 result++, lo &= lo - 1;
7381 while (hi)
7382 result++, hi &= hi - 1;
7383 break;
7385 CASE_INT_FN (BUILT_IN_PARITY):
7386 result = 0;
7387 while (lo)
7388 result++, lo &= lo - 1;
7389 while (hi)
7390 result++, hi &= hi - 1;
7391 result &= 1;
7392 break;
7394 default:
7395 gcc_unreachable ();
7398 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7401 return NULL_TREE;
7404 /* Return true if EXPR is the real constant contained in VALUE. */
7406 static bool
7407 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7409 STRIP_NOPS (expr);
7411 return ((TREE_CODE (expr) == REAL_CST
7412 && ! TREE_CONSTANT_OVERFLOW (expr)
7413 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7414 || (TREE_CODE (expr) == COMPLEX_CST
7415 && real_dconstp (TREE_REALPART (expr), value)
7416 && real_zerop (TREE_IMAGPART (expr))));
7419 /* A subroutine of fold_builtin to fold the various logarithmic
7420 functions. EXP is the CALL_EXPR of a call to a builtin logN
7421 function. VALUE is the base of the logN function. */
7423 static tree
7424 fold_builtin_logarithm (tree fndecl, tree arglist,
7425 const REAL_VALUE_TYPE *value)
7427 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7429 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7430 tree arg = TREE_VALUE (arglist);
7431 const enum built_in_function fcode = builtin_mathfn_code (arg);
7433 /* Optimize logN(1.0) = 0.0. */
7434 if (real_onep (arg))
7435 return build_real (type, dconst0);
7437 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7438 exactly, then only do this if flag_unsafe_math_optimizations. */
7439 if (exact_real_truncate (TYPE_MODE (type), value)
7440 || flag_unsafe_math_optimizations)
7442 const REAL_VALUE_TYPE value_truncate =
7443 real_value_truncate (TYPE_MODE (type), *value);
7444 if (real_dconstp (arg, &value_truncate))
7445 return build_real (type, dconst1);
7448 /* Special case, optimize logN(expN(x)) = x. */
7449 if (flag_unsafe_math_optimizations
7450 && ((value == &dconste
7451 && (fcode == BUILT_IN_EXP
7452 || fcode == BUILT_IN_EXPF
7453 || fcode == BUILT_IN_EXPL))
7454 || (value == &dconst2
7455 && (fcode == BUILT_IN_EXP2
7456 || fcode == BUILT_IN_EXP2F
7457 || fcode == BUILT_IN_EXP2L))
7458 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7459 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7461 /* Optimize logN(func()) for various exponential functions. We
7462 want to determine the value "x" and the power "exponent" in
7463 order to transform logN(x**exponent) into exponent*logN(x). */
7464 if (flag_unsafe_math_optimizations)
7466 tree exponent = 0, x = 0;
7468 switch (fcode)
7470 CASE_FLT_FN (BUILT_IN_EXP):
7471 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7472 x = build_real (type,
7473 real_value_truncate (TYPE_MODE (type), dconste));
7474 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7475 break;
7476 CASE_FLT_FN (BUILT_IN_EXP2):
7477 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7478 x = build_real (type, dconst2);
7479 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7480 break;
7481 CASE_FLT_FN (BUILT_IN_EXP10):
7482 CASE_FLT_FN (BUILT_IN_POW10):
7483 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7484 x = build_real (type, dconst10);
7485 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7486 break;
7487 CASE_FLT_FN (BUILT_IN_SQRT):
7488 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7489 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7490 exponent = build_real (type, dconsthalf);
7491 break;
7492 CASE_FLT_FN (BUILT_IN_CBRT):
7493 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7494 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7495 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7496 dconstthird));
7497 break;
7498 CASE_FLT_FN (BUILT_IN_POW):
7499 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7500 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7501 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7502 break;
7503 default:
7504 break;
7507 /* Now perform the optimization. */
7508 if (x && exponent)
7510 tree logfn;
7511 arglist = build_tree_list (NULL_TREE, x);
7512 logfn = build_function_call_expr (fndecl, arglist);
7513 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7518 return 0;
7521 /* Fold a builtin function call to pow, powf, or powl. Return
7522 NULL_TREE if no simplification can be made. */
7523 static tree
7524 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7526 tree arg0 = TREE_VALUE (arglist);
7527 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7529 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7530 return NULL_TREE;
7532 /* Optimize pow(1.0,y) = 1.0. */
7533 if (real_onep (arg0))
7534 return omit_one_operand (type, build_real (type, dconst1), arg1);
7536 if (TREE_CODE (arg1) == REAL_CST
7537 && ! TREE_CONSTANT_OVERFLOW (arg1))
7539 REAL_VALUE_TYPE cint;
7540 REAL_VALUE_TYPE c;
7541 HOST_WIDE_INT n;
7543 c = TREE_REAL_CST (arg1);
7545 /* Optimize pow(x,0.0) = 1.0. */
7546 if (REAL_VALUES_EQUAL (c, dconst0))
7547 return omit_one_operand (type, build_real (type, dconst1),
7548 arg0);
7550 /* Optimize pow(x,1.0) = x. */
7551 if (REAL_VALUES_EQUAL (c, dconst1))
7552 return arg0;
7554 /* Optimize pow(x,-1.0) = 1.0/x. */
7555 if (REAL_VALUES_EQUAL (c, dconstm1))
7556 return fold_build2 (RDIV_EXPR, type,
7557 build_real (type, dconst1), arg0);
7559 /* Optimize pow(x,0.5) = sqrt(x). */
7560 if (flag_unsafe_math_optimizations
7561 && REAL_VALUES_EQUAL (c, dconsthalf))
7563 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7565 if (sqrtfn != NULL_TREE)
7567 tree arglist = build_tree_list (NULL_TREE, arg0);
7568 return build_function_call_expr (sqrtfn, arglist);
7572 /* Check for an integer exponent. */
7573 n = real_to_integer (&c);
7574 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7575 if (real_identical (&c, &cint))
7577 /* Attempt to evaluate pow at compile-time. */
7578 if (TREE_CODE (arg0) == REAL_CST
7579 && ! TREE_CONSTANT_OVERFLOW (arg0))
7581 REAL_VALUE_TYPE x;
7582 bool inexact;
7584 x = TREE_REAL_CST (arg0);
7585 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7586 if (flag_unsafe_math_optimizations || !inexact)
7587 return build_real (type, x);
7590 /* Strip sign ops from even integer powers. */
7591 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7593 tree narg0 = fold_strip_sign_ops (arg0);
7594 if (narg0)
7596 arglist = build_tree_list (NULL_TREE, arg1);
7597 arglist = tree_cons (NULL_TREE, narg0, arglist);
7598 return build_function_call_expr (fndecl, arglist);
7604 if (flag_unsafe_math_optimizations)
7606 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7608 /* Optimize pow(expN(x),y) = expN(x*y). */
7609 if (BUILTIN_EXPONENT_P (fcode))
7611 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7612 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7613 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7614 arglist = build_tree_list (NULL_TREE, arg);
7615 return build_function_call_expr (expfn, arglist);
7618 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7619 if (BUILTIN_SQRT_P (fcode))
7621 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7622 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7623 build_real (type, dconsthalf));
7625 arglist = tree_cons (NULL_TREE, narg0,
7626 build_tree_list (NULL_TREE, narg1));
7627 return build_function_call_expr (fndecl, arglist);
7630 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7631 if (BUILTIN_CBRT_P (fcode))
7633 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7634 if (tree_expr_nonnegative_p (arg))
7636 const REAL_VALUE_TYPE dconstroot
7637 = real_value_truncate (TYPE_MODE (type), dconstthird);
7638 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7639 build_real (type, dconstroot));
7640 arglist = tree_cons (NULL_TREE, arg,
7641 build_tree_list (NULL_TREE, narg1));
7642 return build_function_call_expr (fndecl, arglist);
7646 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7647 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7648 || fcode == BUILT_IN_POWL)
7650 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7651 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7652 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7653 arglist = tree_cons (NULL_TREE, arg00,
7654 build_tree_list (NULL_TREE, narg1));
7655 return build_function_call_expr (fndecl, arglist);
7659 return NULL_TREE;
7662 /* Fold a builtin function call to powi, powif, or powil. Return
7663 NULL_TREE if no simplification can be made. */
7664 static tree
7665 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7667 tree arg0 = TREE_VALUE (arglist);
7668 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7670 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7671 return NULL_TREE;
7673 /* Optimize pow(1.0,y) = 1.0. */
7674 if (real_onep (arg0))
7675 return omit_one_operand (type, build_real (type, dconst1), arg1);
7677 if (host_integerp (arg1, 0))
7679 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7681 /* Evaluate powi at compile-time. */
7682 if (TREE_CODE (arg0) == REAL_CST
7683 && ! TREE_CONSTANT_OVERFLOW (arg0))
7685 REAL_VALUE_TYPE x;
7686 x = TREE_REAL_CST (arg0);
7687 real_powi (&x, TYPE_MODE (type), &x, c);
7688 return build_real (type, x);
7691 /* Optimize pow(x,0) = 1.0. */
7692 if (c == 0)
7693 return omit_one_operand (type, build_real (type, dconst1),
7694 arg0);
7696 /* Optimize pow(x,1) = x. */
7697 if (c == 1)
7698 return arg0;
7700 /* Optimize pow(x,-1) = 1.0/x. */
7701 if (c == -1)
7702 return fold_build2 (RDIV_EXPR, type,
7703 build_real (type, dconst1), arg0);
7706 return NULL_TREE;
7709 /* A subroutine of fold_builtin to fold the various exponent
7710 functions. EXP is the CALL_EXPR of a call to a builtin function.
7711 VALUE is the value which will be raised to a power. */
7713 static tree
7714 fold_builtin_exponent (tree fndecl, tree arglist,
7715 const REAL_VALUE_TYPE *value)
7717 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7719 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7720 tree arg = TREE_VALUE (arglist);
7722 /* Optimize exp*(0.0) = 1.0. */
7723 if (real_zerop (arg))
7724 return build_real (type, dconst1);
7726 /* Optimize expN(1.0) = N. */
7727 if (real_onep (arg))
7729 REAL_VALUE_TYPE cst;
7731 real_convert (&cst, TYPE_MODE (type), value);
7732 return build_real (type, cst);
7735 /* Attempt to evaluate expN(integer) at compile-time. */
7736 if (flag_unsafe_math_optimizations
7737 && TREE_CODE (arg) == REAL_CST
7738 && ! TREE_CONSTANT_OVERFLOW (arg))
7740 REAL_VALUE_TYPE cint;
7741 REAL_VALUE_TYPE c;
7742 HOST_WIDE_INT n;
7744 c = TREE_REAL_CST (arg);
7745 n = real_to_integer (&c);
7746 real_from_integer (&cint, VOIDmode, n,
7747 n < 0 ? -1 : 0, 0);
7748 if (real_identical (&c, &cint))
7750 REAL_VALUE_TYPE x;
7752 real_powi (&x, TYPE_MODE (type), value, n);
7753 return build_real (type, x);
7757 /* Optimize expN(logN(x)) = x. */
7758 if (flag_unsafe_math_optimizations)
7760 const enum built_in_function fcode = builtin_mathfn_code (arg);
7762 if ((value == &dconste
7763 && (fcode == BUILT_IN_LOG
7764 || fcode == BUILT_IN_LOGF
7765 || fcode == BUILT_IN_LOGL))
7766 || (value == &dconst2
7767 && (fcode == BUILT_IN_LOG2
7768 || fcode == BUILT_IN_LOG2F
7769 || fcode == BUILT_IN_LOG2L))
7770 || (value == &dconst10
7771 && (fcode == BUILT_IN_LOG10
7772 || fcode == BUILT_IN_LOG10F
7773 || fcode == BUILT_IN_LOG10L)))
7774 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7778 return 0;
7781 /* Fold function call to builtin memcpy. Return
7782 NULL_TREE if no simplification can be made. */
7784 static tree
7785 fold_builtin_memcpy (tree fndecl, tree arglist)
7787 tree dest, src, len;
7789 if (!validate_arglist (arglist,
7790 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7791 return 0;
7793 dest = TREE_VALUE (arglist);
7794 src = TREE_VALUE (TREE_CHAIN (arglist));
7795 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7797 /* If the LEN parameter is zero, return DEST. */
7798 if (integer_zerop (len))
7799 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7801 /* If SRC and DEST are the same (and not volatile), return DEST. */
7802 if (operand_equal_p (src, dest, 0))
7803 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7805 return 0;
7808 /* Fold function call to builtin mempcpy. Return
7809 NULL_TREE if no simplification can be made. */
7811 static tree
7812 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7814 if (validate_arglist (arglist,
7815 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7817 tree dest = TREE_VALUE (arglist);
7818 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7819 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7821 /* If the LEN parameter is zero, return DEST. */
7822 if (integer_zerop (len))
7823 return omit_one_operand (type, dest, src);
7825 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7826 if (operand_equal_p (src, dest, 0))
7828 if (endp == 0)
7829 return omit_one_operand (type, dest, len);
7831 if (endp == 2)
7832 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7833 ssize_int (1));
7835 len = fold_convert (TREE_TYPE (dest), len);
7836 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7837 return fold_convert (type, len);
7840 return 0;
7843 /* Fold function call to builtin memmove. Return
7844 NULL_TREE if no simplification can be made. */
7846 static tree
7847 fold_builtin_memmove (tree arglist, tree type)
7849 tree dest, src, len;
7851 if (!validate_arglist (arglist,
7852 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7853 return 0;
7855 dest = TREE_VALUE (arglist);
7856 src = TREE_VALUE (TREE_CHAIN (arglist));
7857 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7859 /* If the LEN parameter is zero, return DEST. */
7860 if (integer_zerop (len))
7861 return omit_one_operand (type, dest, src);
7863 /* If SRC and DEST are the same (and not volatile), return DEST. */
7864 if (operand_equal_p (src, dest, 0))
7865 return omit_one_operand (type, dest, len);
7867 return 0;
7870 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7871 the length of the string to be copied. Return NULL_TREE if no
7872 simplification can be made. */
7874 tree
7875 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7877 tree dest, src, fn;
7879 if (!validate_arglist (arglist,
7880 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7881 return 0;
7883 dest = TREE_VALUE (arglist);
7884 src = TREE_VALUE (TREE_CHAIN (arglist));
7886 /* If SRC and DEST are the same (and not volatile), return DEST. */
7887 if (operand_equal_p (src, dest, 0))
7888 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7890 if (optimize_size)
7891 return 0;
7893 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7894 if (!fn)
7895 return 0;
7897 if (!len)
7899 len = c_strlen (src, 1);
7900 if (! len || TREE_SIDE_EFFECTS (len))
7901 return 0;
7904 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7905 arglist = build_tree_list (NULL_TREE, len);
7906 arglist = tree_cons (NULL_TREE, src, arglist);
7907 arglist = tree_cons (NULL_TREE, dest, arglist);
7908 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7909 build_function_call_expr (fn, arglist));
7912 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7913 the length of the source string. Return NULL_TREE if no simplification
7914 can be made. */
7916 tree
7917 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7919 tree dest, src, len, fn;
7921 if (!validate_arglist (arglist,
7922 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7923 return 0;
7925 dest = TREE_VALUE (arglist);
7926 src = TREE_VALUE (TREE_CHAIN (arglist));
7927 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7929 /* If the LEN parameter is zero, return DEST. */
7930 if (integer_zerop (len))
7931 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7933 /* We can't compare slen with len as constants below if len is not a
7934 constant. */
7935 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7936 return 0;
7938 if (!slen)
7939 slen = c_strlen (src, 1);
7941 /* Now, we must be passed a constant src ptr parameter. */
7942 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7943 return 0;
7945 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7947 /* We do not support simplification of this case, though we do
7948 support it when expanding trees into RTL. */
7949 /* FIXME: generate a call to __builtin_memset. */
7950 if (tree_int_cst_lt (slen, len))
7951 return 0;
7953 /* OK transform into builtin memcpy. */
7954 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7955 if (!fn)
7956 return 0;
7957 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7958 build_function_call_expr (fn, arglist));
7961 /* Fold function call to builtin memcmp. Return
7962 NULL_TREE if no simplification can be made. */
7964 static tree
7965 fold_builtin_memcmp (tree arglist)
7967 tree arg1, arg2, len;
7968 const char *p1, *p2;
7970 if (!validate_arglist (arglist,
7971 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7972 return 0;
7974 arg1 = TREE_VALUE (arglist);
7975 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7976 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7978 /* If the LEN parameter is zero, return zero. */
7979 if (integer_zerop (len))
7980 return omit_two_operands (integer_type_node, integer_zero_node,
7981 arg1, arg2);
7983 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7984 if (operand_equal_p (arg1, arg2, 0))
7985 return omit_one_operand (integer_type_node, integer_zero_node, len);
7987 p1 = c_getstr (arg1);
7988 p2 = c_getstr (arg2);
7990 /* If all arguments are constant, and the value of len is not greater
7991 than the lengths of arg1 and arg2, evaluate at compile-time. */
7992 if (host_integerp (len, 1) && p1 && p2
7993 && compare_tree_int (len, strlen (p1) + 1) <= 0
7994 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7996 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7998 if (r > 0)
7999 return integer_one_node;
8000 else if (r < 0)
8001 return integer_minus_one_node;
8002 else
8003 return integer_zero_node;
8006 /* If len parameter is one, return an expression corresponding to
8007 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8008 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8010 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8011 tree cst_uchar_ptr_node
8012 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8014 tree ind1 = fold_convert (integer_type_node,
8015 build1 (INDIRECT_REF, cst_uchar_node,
8016 fold_convert (cst_uchar_ptr_node,
8017 arg1)));
8018 tree ind2 = fold_convert (integer_type_node,
8019 build1 (INDIRECT_REF, cst_uchar_node,
8020 fold_convert (cst_uchar_ptr_node,
8021 arg2)));
8022 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8025 return 0;
8028 /* Fold function call to builtin strcmp. Return
8029 NULL_TREE if no simplification can be made. */
8031 static tree
8032 fold_builtin_strcmp (tree arglist)
8034 tree arg1, arg2;
8035 const char *p1, *p2;
8037 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8038 return 0;
8040 arg1 = TREE_VALUE (arglist);
8041 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8043 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8044 if (operand_equal_p (arg1, arg2, 0))
8045 return integer_zero_node;
8047 p1 = c_getstr (arg1);
8048 p2 = c_getstr (arg2);
8050 if (p1 && p2)
8052 const int i = strcmp (p1, p2);
8053 if (i < 0)
8054 return integer_minus_one_node;
8055 else if (i > 0)
8056 return integer_one_node;
8057 else
8058 return integer_zero_node;
8061 /* If the second arg is "", return *(const unsigned char*)arg1. */
8062 if (p2 && *p2 == '\0')
8064 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8065 tree cst_uchar_ptr_node
8066 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8068 return fold_convert (integer_type_node,
8069 build1 (INDIRECT_REF, cst_uchar_node,
8070 fold_convert (cst_uchar_ptr_node,
8071 arg1)));
8074 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8075 if (p1 && *p1 == '\0')
8077 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8078 tree cst_uchar_ptr_node
8079 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8081 tree temp = fold_convert (integer_type_node,
8082 build1 (INDIRECT_REF, cst_uchar_node,
8083 fold_convert (cst_uchar_ptr_node,
8084 arg2)));
8085 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8088 return 0;
8091 /* Fold function call to builtin strncmp. Return
8092 NULL_TREE if no simplification can be made. */
8094 static tree
8095 fold_builtin_strncmp (tree arglist)
8097 tree arg1, arg2, len;
8098 const char *p1, *p2;
8100 if (!validate_arglist (arglist,
8101 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8102 return 0;
8104 arg1 = TREE_VALUE (arglist);
8105 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8106 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8108 /* If the LEN parameter is zero, return zero. */
8109 if (integer_zerop (len))
8110 return omit_two_operands (integer_type_node, integer_zero_node,
8111 arg1, arg2);
8113 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8114 if (operand_equal_p (arg1, arg2, 0))
8115 return omit_one_operand (integer_type_node, integer_zero_node, len);
8117 p1 = c_getstr (arg1);
8118 p2 = c_getstr (arg2);
8120 if (host_integerp (len, 1) && p1 && p2)
8122 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8123 if (i > 0)
8124 return integer_one_node;
8125 else if (i < 0)
8126 return integer_minus_one_node;
8127 else
8128 return integer_zero_node;
8131 /* If the second arg is "", and the length is greater than zero,
8132 return *(const unsigned char*)arg1. */
8133 if (p2 && *p2 == '\0'
8134 && TREE_CODE (len) == INTEGER_CST
8135 && tree_int_cst_sgn (len) == 1)
8137 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8138 tree cst_uchar_ptr_node
8139 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8141 return fold_convert (integer_type_node,
8142 build1 (INDIRECT_REF, cst_uchar_node,
8143 fold_convert (cst_uchar_ptr_node,
8144 arg1)));
8147 /* If the first arg is "", and the length is greater than zero,
8148 return -*(const unsigned char*)arg2. */
8149 if (p1 && *p1 == '\0'
8150 && TREE_CODE (len) == INTEGER_CST
8151 && tree_int_cst_sgn (len) == 1)
8153 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8154 tree cst_uchar_ptr_node
8155 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8157 tree temp = fold_convert (integer_type_node,
8158 build1 (INDIRECT_REF, cst_uchar_node,
8159 fold_convert (cst_uchar_ptr_node,
8160 arg2)));
8161 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8164 /* If len parameter is one, return an expression corresponding to
8165 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8166 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8168 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8169 tree cst_uchar_ptr_node
8170 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8172 tree ind1 = fold_convert (integer_type_node,
8173 build1 (INDIRECT_REF, cst_uchar_node,
8174 fold_convert (cst_uchar_ptr_node,
8175 arg1)));
8176 tree ind2 = fold_convert (integer_type_node,
8177 build1 (INDIRECT_REF, cst_uchar_node,
8178 fold_convert (cst_uchar_ptr_node,
8179 arg2)));
8180 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8183 return 0;
8186 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8187 NULL_TREE if no simplification can be made. */
8189 static tree
8190 fold_builtin_signbit (tree fndecl, tree arglist)
8192 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8193 tree arg, temp;
8195 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8196 return NULL_TREE;
8198 arg = TREE_VALUE (arglist);
8200 /* If ARG is a compile-time constant, determine the result. */
8201 if (TREE_CODE (arg) == REAL_CST
8202 && !TREE_CONSTANT_OVERFLOW (arg))
8204 REAL_VALUE_TYPE c;
8206 c = TREE_REAL_CST (arg);
8207 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8208 return fold_convert (type, temp);
8211 /* If ARG is non-negative, the result is always zero. */
8212 if (tree_expr_nonnegative_p (arg))
8213 return omit_one_operand (type, integer_zero_node, arg);
8215 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8216 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8217 return fold_build2 (LT_EXPR, type, arg,
8218 build_real (TREE_TYPE (arg), dconst0));
8220 return NULL_TREE;
8223 /* Fold function call to builtin copysign, copysignf or copysignl.
8224 Return NULL_TREE if no simplification can be made. */
8226 static tree
8227 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8229 tree arg1, arg2, tem;
8231 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8232 return NULL_TREE;
8234 arg1 = TREE_VALUE (arglist);
8235 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8237 /* copysign(X,X) is X. */
8238 if (operand_equal_p (arg1, arg2, 0))
8239 return fold_convert (type, arg1);
8241 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8242 if (TREE_CODE (arg1) == REAL_CST
8243 && TREE_CODE (arg2) == REAL_CST
8244 && !TREE_CONSTANT_OVERFLOW (arg1)
8245 && !TREE_CONSTANT_OVERFLOW (arg2))
8247 REAL_VALUE_TYPE c1, c2;
8249 c1 = TREE_REAL_CST (arg1);
8250 c2 = TREE_REAL_CST (arg2);
8251 /* c1.sign := c2.sign. */
8252 real_copysign (&c1, &c2);
8253 return build_real (type, c1);
8256 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8257 Remember to evaluate Y for side-effects. */
8258 if (tree_expr_nonnegative_p (arg2))
8259 return omit_one_operand (type,
8260 fold_build1 (ABS_EXPR, type, arg1),
8261 arg2);
8263 /* Strip sign changing operations for the first argument. */
8264 tem = fold_strip_sign_ops (arg1);
8265 if (tem)
8267 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8268 return build_function_call_expr (fndecl, arglist);
8271 return NULL_TREE;
8274 /* Fold a call to builtin isascii. */
8276 static tree
8277 fold_builtin_isascii (tree arglist)
8279 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8280 return 0;
8281 else
8283 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8284 tree arg = TREE_VALUE (arglist);
8286 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8287 build_int_cst (NULL_TREE,
8288 ~ (unsigned HOST_WIDE_INT) 0x7f));
8289 arg = fold_build2 (EQ_EXPR, integer_type_node,
8290 arg, integer_zero_node);
8292 if (in_gimple_form && !TREE_CONSTANT (arg))
8293 return NULL_TREE;
8294 else
8295 return arg;
8299 /* Fold a call to builtin toascii. */
8301 static tree
8302 fold_builtin_toascii (tree arglist)
8304 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8305 return 0;
8306 else
8308 /* Transform toascii(c) -> (c & 0x7f). */
8309 tree arg = TREE_VALUE (arglist);
8311 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8312 build_int_cst (NULL_TREE, 0x7f));
8316 /* Fold a call to builtin isdigit. */
8318 static tree
8319 fold_builtin_isdigit (tree arglist)
8321 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8322 return 0;
8323 else
8325 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8326 /* According to the C standard, isdigit is unaffected by locale.
8327 However, it definitely is affected by the target character set. */
8328 tree arg;
8329 unsigned HOST_WIDE_INT target_digit0
8330 = lang_hooks.to_target_charset ('0');
8332 if (target_digit0 == 0)
8333 return NULL_TREE;
8335 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8336 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8337 build_int_cst (unsigned_type_node, target_digit0));
8338 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8339 build_int_cst (unsigned_type_node, 9));
8340 if (in_gimple_form && !TREE_CONSTANT (arg))
8341 return NULL_TREE;
8342 else
8343 return arg;
8347 /* Fold a call to fabs, fabsf or fabsl. */
8349 static tree
8350 fold_builtin_fabs (tree arglist, tree type)
8352 tree arg;
8354 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8355 return 0;
8357 arg = TREE_VALUE (arglist);
8358 arg = fold_convert (type, arg);
8359 if (TREE_CODE (arg) == REAL_CST)
8360 return fold_abs_const (arg, type);
8361 return fold_build1 (ABS_EXPR, type, arg);
8364 /* Fold a call to abs, labs, llabs or imaxabs. */
8366 static tree
8367 fold_builtin_abs (tree arglist, tree type)
8369 tree arg;
8371 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8372 return 0;
8374 arg = TREE_VALUE (arglist);
8375 arg = fold_convert (type, arg);
8376 if (TREE_CODE (arg) == INTEGER_CST)
8377 return fold_abs_const (arg, type);
8378 return fold_build1 (ABS_EXPR, type, arg);
8381 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8382 EXP is the CALL_EXPR for the call. */
8384 static tree
8385 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8387 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8388 tree arg;
8389 REAL_VALUE_TYPE r;
8391 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8393 /* Check that we have exactly one argument. */
8394 if (arglist == 0)
8396 error ("too few arguments to function %qs",
8397 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8398 return error_mark_node;
8400 else if (TREE_CHAIN (arglist) != 0)
8402 error ("too many arguments to function %qs",
8403 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8404 return error_mark_node;
8406 else
8408 error ("non-floating-point argument to function %qs",
8409 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8410 return error_mark_node;
8414 arg = TREE_VALUE (arglist);
8415 switch (builtin_index)
8417 case BUILT_IN_ISINF:
8418 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8419 return omit_one_operand (type, integer_zero_node, arg);
8421 if (TREE_CODE (arg) == REAL_CST)
8423 r = TREE_REAL_CST (arg);
8424 if (real_isinf (&r))
8425 return real_compare (GT_EXPR, &r, &dconst0)
8426 ? integer_one_node : integer_minus_one_node;
8427 else
8428 return integer_zero_node;
8431 return NULL_TREE;
8433 case BUILT_IN_FINITE:
8434 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8435 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8436 return omit_one_operand (type, integer_zero_node, arg);
8438 if (TREE_CODE (arg) == REAL_CST)
8440 r = TREE_REAL_CST (arg);
8441 return real_isinf (&r) || real_isnan (&r)
8442 ? integer_zero_node : integer_one_node;
8445 return NULL_TREE;
8447 case BUILT_IN_ISNAN:
8448 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8449 return omit_one_operand (type, integer_zero_node, arg);
8451 if (TREE_CODE (arg) == REAL_CST)
8453 r = TREE_REAL_CST (arg);
8454 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8457 arg = builtin_save_expr (arg);
8458 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8460 default:
8461 gcc_unreachable ();
8465 /* Fold a call to an unordered comparison function such as
8466 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8467 being called and ARGLIST is the argument list for the call.
8468 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8469 the opposite of the desired result. UNORDERED_CODE is used
8470 for modes that can hold NaNs and ORDERED_CODE is used for
8471 the rest. */
8473 static tree
8474 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8475 enum tree_code unordered_code,
8476 enum tree_code ordered_code)
8478 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8479 enum tree_code code;
8480 tree arg0, arg1;
8481 tree type0, type1;
8482 enum tree_code code0, code1;
8483 tree cmp_type = NULL_TREE;
8485 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8487 /* Check that we have exactly two arguments. */
8488 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8490 error ("too few arguments to function %qs",
8491 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8492 return error_mark_node;
8494 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8496 error ("too many arguments to function %qs",
8497 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8498 return error_mark_node;
8502 arg0 = TREE_VALUE (arglist);
8503 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8505 type0 = TREE_TYPE (arg0);
8506 type1 = TREE_TYPE (arg1);
8508 code0 = TREE_CODE (type0);
8509 code1 = TREE_CODE (type1);
8511 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8512 /* Choose the wider of two real types. */
8513 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8514 ? type0 : type1;
8515 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8516 cmp_type = type0;
8517 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8518 cmp_type = type1;
8519 else
8521 error ("non-floating-point argument to function %qs",
8522 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8523 return error_mark_node;
8526 arg0 = fold_convert (cmp_type, arg0);
8527 arg1 = fold_convert (cmp_type, arg1);
8529 if (unordered_code == UNORDERED_EXPR)
8531 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8532 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8533 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8536 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8537 : ordered_code;
8538 return fold_build1 (TRUTH_NOT_EXPR, type,
8539 fold_build2 (code, type, arg0, arg1));
8542 /* Used by constant folding to simplify calls to builtin functions. EXP is
8543 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8544 result of the function call is ignored. This function returns NULL_TREE
8545 if no simplification was possible. */
8547 static tree
8548 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8550 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8551 enum built_in_function fcode;
8553 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8554 return targetm.fold_builtin (fndecl, arglist, ignore);
8556 fcode = DECL_FUNCTION_CODE (fndecl);
8557 switch (fcode)
8559 case BUILT_IN_FPUTS:
8560 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8562 case BUILT_IN_FPUTS_UNLOCKED:
8563 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8565 case BUILT_IN_STRSTR:
8566 return fold_builtin_strstr (arglist, type);
8568 case BUILT_IN_STRCAT:
8569 return fold_builtin_strcat (arglist);
8571 case BUILT_IN_STRNCAT:
8572 return fold_builtin_strncat (arglist);
8574 case BUILT_IN_STRSPN:
8575 return fold_builtin_strspn (arglist);
8577 case BUILT_IN_STRCSPN:
8578 return fold_builtin_strcspn (arglist);
8580 case BUILT_IN_STRCHR:
8581 case BUILT_IN_INDEX:
8582 return fold_builtin_strchr (arglist, type);
8584 case BUILT_IN_STRRCHR:
8585 case BUILT_IN_RINDEX:
8586 return fold_builtin_strrchr (arglist, type);
8588 case BUILT_IN_STRCPY:
8589 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8591 case BUILT_IN_STRNCPY:
8592 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8594 case BUILT_IN_STRCMP:
8595 return fold_builtin_strcmp (arglist);
8597 case BUILT_IN_STRNCMP:
8598 return fold_builtin_strncmp (arglist);
8600 case BUILT_IN_STRPBRK:
8601 return fold_builtin_strpbrk (arglist, type);
8603 case BUILT_IN_BCMP:
8604 case BUILT_IN_MEMCMP:
8605 return fold_builtin_memcmp (arglist);
8607 case BUILT_IN_SPRINTF:
8608 return fold_builtin_sprintf (arglist, ignore);
8610 case BUILT_IN_CONSTANT_P:
8612 tree val;
8614 val = fold_builtin_constant_p (arglist);
8615 /* Gimplification will pull the CALL_EXPR for the builtin out of
8616 an if condition. When not optimizing, we'll not CSE it back.
8617 To avoid link error types of regressions, return false now. */
8618 if (!val && !optimize)
8619 val = integer_zero_node;
8621 return val;
8624 case BUILT_IN_EXPECT:
8625 return fold_builtin_expect (arglist);
8627 case BUILT_IN_CLASSIFY_TYPE:
8628 return fold_builtin_classify_type (arglist);
8630 case BUILT_IN_STRLEN:
8631 return fold_builtin_strlen (arglist);
8633 CASE_FLT_FN (BUILT_IN_FABS):
8634 return fold_builtin_fabs (arglist, type);
8636 case BUILT_IN_ABS:
8637 case BUILT_IN_LABS:
8638 case BUILT_IN_LLABS:
8639 case BUILT_IN_IMAXABS:
8640 return fold_builtin_abs (arglist, type);
8642 CASE_FLT_FN (BUILT_IN_CONJ):
8643 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8644 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8645 break;
8647 CASE_FLT_FN (BUILT_IN_CREAL):
8648 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8649 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8650 TREE_VALUE (arglist)));
8651 break;
8653 CASE_FLT_FN (BUILT_IN_CIMAG):
8654 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8655 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8656 TREE_VALUE (arglist)));
8657 break;
8659 CASE_FLT_FN (BUILT_IN_CABS):
8660 return fold_builtin_cabs (arglist, type, fndecl);
8662 CASE_FLT_FN (BUILT_IN_SQRT):
8663 return fold_builtin_sqrt (arglist, type);
8665 CASE_FLT_FN (BUILT_IN_CBRT):
8666 return fold_builtin_cbrt (arglist, type);
8668 CASE_FLT_FN (BUILT_IN_SIN):
8669 return fold_builtin_sin (arglist);
8671 CASE_FLT_FN (BUILT_IN_COS):
8672 return fold_builtin_cos (arglist, type, fndecl);
8674 CASE_FLT_FN (BUILT_IN_EXP):
8675 return fold_builtin_exponent (fndecl, arglist, &dconste);
8677 CASE_FLT_FN (BUILT_IN_EXP2):
8678 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8680 CASE_FLT_FN (BUILT_IN_EXP10):
8681 CASE_FLT_FN (BUILT_IN_POW10):
8682 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8684 CASE_FLT_FN (BUILT_IN_LOG):
8685 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8687 CASE_FLT_FN (BUILT_IN_LOG2):
8688 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8690 CASE_FLT_FN (BUILT_IN_LOG10):
8691 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8693 CASE_FLT_FN (BUILT_IN_TAN):
8694 return fold_builtin_tan (arglist);
8696 CASE_FLT_FN (BUILT_IN_ATAN):
8697 return fold_builtin_atan (arglist, type);
8699 CASE_FLT_FN (BUILT_IN_POW):
8700 return fold_builtin_pow (fndecl, arglist, type);
8702 CASE_FLT_FN (BUILT_IN_POWI):
8703 return fold_builtin_powi (fndecl, arglist, type);
8705 CASE_FLT_FN (BUILT_IN_INF):
8706 case BUILT_IN_INFD32:
8707 case BUILT_IN_INFD64:
8708 case BUILT_IN_INFD128:
8709 return fold_builtin_inf (type, true);
8711 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8712 return fold_builtin_inf (type, false);
8714 CASE_FLT_FN (BUILT_IN_NAN):
8715 case BUILT_IN_NAND32:
8716 case BUILT_IN_NAND64:
8717 case BUILT_IN_NAND128:
8718 return fold_builtin_nan (arglist, type, true);
8720 CASE_FLT_FN (BUILT_IN_NANS):
8721 return fold_builtin_nan (arglist, type, false);
8723 CASE_FLT_FN (BUILT_IN_FLOOR):
8724 return fold_builtin_floor (fndecl, arglist);
8726 CASE_FLT_FN (BUILT_IN_CEIL):
8727 return fold_builtin_ceil (fndecl, arglist);
8729 CASE_FLT_FN (BUILT_IN_TRUNC):
8730 return fold_builtin_trunc (fndecl, arglist);
8732 CASE_FLT_FN (BUILT_IN_ROUND):
8733 return fold_builtin_round (fndecl, arglist);
8735 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8736 CASE_FLT_FN (BUILT_IN_RINT):
8737 return fold_trunc_transparent_mathfn (fndecl, arglist);
8739 CASE_FLT_FN (BUILT_IN_LCEIL):
8740 CASE_FLT_FN (BUILT_IN_LLCEIL):
8741 CASE_FLT_FN (BUILT_IN_LFLOOR):
8742 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8743 CASE_FLT_FN (BUILT_IN_LROUND):
8744 CASE_FLT_FN (BUILT_IN_LLROUND):
8745 return fold_builtin_int_roundingfn (fndecl, arglist);
8747 CASE_FLT_FN (BUILT_IN_LRINT):
8748 CASE_FLT_FN (BUILT_IN_LLRINT):
8749 return fold_fixed_mathfn (fndecl, arglist);
8751 CASE_INT_FN (BUILT_IN_FFS):
8752 CASE_INT_FN (BUILT_IN_CLZ):
8753 CASE_INT_FN (BUILT_IN_CTZ):
8754 CASE_INT_FN (BUILT_IN_POPCOUNT):
8755 CASE_INT_FN (BUILT_IN_PARITY):
8756 return fold_builtin_bitop (fndecl, arglist);
8758 case BUILT_IN_MEMCPY:
8759 return fold_builtin_memcpy (fndecl, arglist);
8761 case BUILT_IN_MEMPCPY:
8762 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8764 case BUILT_IN_MEMMOVE:
8765 return fold_builtin_memmove (arglist, type);
8767 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8768 return fold_builtin_signbit (fndecl, arglist);
8770 case BUILT_IN_ISASCII:
8771 return fold_builtin_isascii (arglist);
8773 case BUILT_IN_TOASCII:
8774 return fold_builtin_toascii (arglist);
8776 case BUILT_IN_ISDIGIT:
8777 return fold_builtin_isdigit (arglist);
8779 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8780 return fold_builtin_copysign (fndecl, arglist, type);
8782 CASE_FLT_FN (BUILT_IN_FINITE):
8783 case BUILT_IN_FINITED32:
8784 case BUILT_IN_FINITED64:
8785 case BUILT_IN_FINITED128:
8786 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8788 CASE_FLT_FN (BUILT_IN_ISINF):
8789 case BUILT_IN_ISINFD32:
8790 case BUILT_IN_ISINFD64:
8791 case BUILT_IN_ISINFD128:
8792 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8794 CASE_FLT_FN (BUILT_IN_ISNAN):
8795 case BUILT_IN_ISNAND32:
8796 case BUILT_IN_ISNAND64:
8797 case BUILT_IN_ISNAND128:
8798 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8800 case BUILT_IN_ISGREATER:
8801 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8802 case BUILT_IN_ISGREATEREQUAL:
8803 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8804 case BUILT_IN_ISLESS:
8805 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8806 case BUILT_IN_ISLESSEQUAL:
8807 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8808 case BUILT_IN_ISLESSGREATER:
8809 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8810 case BUILT_IN_ISUNORDERED:
8811 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8812 NOP_EXPR);
8814 /* We do the folding for va_start in the expander. */
8815 case BUILT_IN_VA_START:
8816 break;
8818 case BUILT_IN_OBJECT_SIZE:
8819 return fold_builtin_object_size (arglist);
8820 case BUILT_IN_MEMCPY_CHK:
8821 case BUILT_IN_MEMPCPY_CHK:
8822 case BUILT_IN_MEMMOVE_CHK:
8823 case BUILT_IN_MEMSET_CHK:
8824 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8825 DECL_FUNCTION_CODE (fndecl));
8826 case BUILT_IN_STRCPY_CHK:
8827 case BUILT_IN_STPCPY_CHK:
8828 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8829 DECL_FUNCTION_CODE (fndecl));
8830 case BUILT_IN_STRNCPY_CHK:
8831 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8832 case BUILT_IN_STRCAT_CHK:
8833 return fold_builtin_strcat_chk (fndecl, arglist);
8834 case BUILT_IN_STRNCAT_CHK:
8835 return fold_builtin_strncat_chk (fndecl, arglist);
8836 case BUILT_IN_SPRINTF_CHK:
8837 case BUILT_IN_VSPRINTF_CHK:
8838 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8839 case BUILT_IN_SNPRINTF_CHK:
8840 case BUILT_IN_VSNPRINTF_CHK:
8841 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8842 DECL_FUNCTION_CODE (fndecl));
8844 case BUILT_IN_PRINTF:
8845 case BUILT_IN_PRINTF_UNLOCKED:
8846 case BUILT_IN_VPRINTF:
8847 case BUILT_IN_PRINTF_CHK:
8848 case BUILT_IN_VPRINTF_CHK:
8849 return fold_builtin_printf (fndecl, arglist, ignore,
8850 DECL_FUNCTION_CODE (fndecl));
8852 case BUILT_IN_FPRINTF:
8853 case BUILT_IN_FPRINTF_UNLOCKED:
8854 case BUILT_IN_VFPRINTF:
8855 case BUILT_IN_FPRINTF_CHK:
8856 case BUILT_IN_VFPRINTF_CHK:
8857 return fold_builtin_fprintf (fndecl, arglist, ignore,
8858 DECL_FUNCTION_CODE (fndecl));
8860 default:
8861 break;
8864 return 0;
8867 /* A wrapper function for builtin folding that prevents warnings for
8868 "statement without effect" and the like, caused by removing the
8869 call node earlier than the warning is generated. */
8871 tree
8872 fold_builtin (tree fndecl, tree arglist, bool ignore)
8874 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8875 if (exp)
8877 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8878 TREE_NO_WARNING (exp) = 1;
8881 return exp;
8884 /* Conveniently construct a function call expression. */
8886 tree
8887 build_function_call_expr (tree fn, tree arglist)
8889 tree call_expr;
8891 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8892 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8893 call_expr, arglist, NULL_TREE);
8896 /* This function validates the types of a function call argument list
8897 represented as a tree chain of parameters against a specified list
8898 of tree_codes. If the last specifier is a 0, that represents an
8899 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8901 static int
8902 validate_arglist (tree arglist, ...)
8904 enum tree_code code;
8905 int res = 0;
8906 va_list ap;
8908 va_start (ap, arglist);
8912 code = va_arg (ap, enum tree_code);
8913 switch (code)
8915 case 0:
8916 /* This signifies an ellipses, any further arguments are all ok. */
8917 res = 1;
8918 goto end;
8919 case VOID_TYPE:
8920 /* This signifies an endlink, if no arguments remain, return
8921 true, otherwise return false. */
8922 res = arglist == 0;
8923 goto end;
8924 default:
8925 /* If no parameters remain or the parameter's code does not
8926 match the specified code, return false. Otherwise continue
8927 checking any remaining arguments. */
8928 if (arglist == 0)
8929 goto end;
8930 if (code == POINTER_TYPE)
8932 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8933 goto end;
8935 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8936 goto end;
8937 break;
8939 arglist = TREE_CHAIN (arglist);
8941 while (1);
8943 /* We need gotos here since we can only have one VA_CLOSE in a
8944 function. */
8945 end: ;
8946 va_end (ap);
8948 return res;
8951 /* Default target-specific builtin expander that does nothing. */
8954 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8955 rtx target ATTRIBUTE_UNUSED,
8956 rtx subtarget ATTRIBUTE_UNUSED,
8957 enum machine_mode mode ATTRIBUTE_UNUSED,
8958 int ignore ATTRIBUTE_UNUSED)
8960 return NULL_RTX;
8963 /* Returns true is EXP represents data that would potentially reside
8964 in a readonly section. */
8966 static bool
8967 readonly_data_expr (tree exp)
8969 STRIP_NOPS (exp);
8971 if (TREE_CODE (exp) != ADDR_EXPR)
8972 return false;
8974 exp = get_base_address (TREE_OPERAND (exp, 0));
8975 if (!exp)
8976 return false;
8978 /* Make sure we call decl_readonly_section only for trees it
8979 can handle (since it returns true for everything it doesn't
8980 understand). */
8981 if (TREE_CODE (exp) == STRING_CST
8982 || TREE_CODE (exp) == CONSTRUCTOR
8983 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8984 return decl_readonly_section (exp, 0);
8985 else
8986 return false;
8989 /* Simplify a call to the strstr builtin.
8991 Return 0 if no simplification was possible, otherwise return the
8992 simplified form of the call as a tree.
8994 The simplified form may be a constant or other expression which
8995 computes the same value, but in a more efficient manner (including
8996 calls to other builtin functions).
8998 The call may contain arguments which need to be evaluated, but
8999 which are not useful to determine the result of the call. In
9000 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9001 COMPOUND_EXPR will be an argument which must be evaluated.
9002 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9003 COMPOUND_EXPR in the chain will contain the tree for the simplified
9004 form of the builtin function call. */
9006 static tree
9007 fold_builtin_strstr (tree arglist, tree type)
9009 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9010 return 0;
9011 else
9013 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9014 tree fn;
9015 const char *p1, *p2;
9017 p2 = c_getstr (s2);
9018 if (p2 == NULL)
9019 return 0;
9021 p1 = c_getstr (s1);
9022 if (p1 != NULL)
9024 const char *r = strstr (p1, p2);
9025 tree tem;
9027 if (r == NULL)
9028 return build_int_cst (TREE_TYPE (s1), 0);
9030 /* Return an offset into the constant string argument. */
9031 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9032 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9033 return fold_convert (type, tem);
9036 /* The argument is const char *, and the result is char *, so we need
9037 a type conversion here to avoid a warning. */
9038 if (p2[0] == '\0')
9039 return fold_convert (type, s1);
9041 if (p2[1] != '\0')
9042 return 0;
9044 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9045 if (!fn)
9046 return 0;
9048 /* New argument list transforming strstr(s1, s2) to
9049 strchr(s1, s2[0]). */
9050 arglist = build_tree_list (NULL_TREE,
9051 build_int_cst (NULL_TREE, p2[0]));
9052 arglist = tree_cons (NULL_TREE, s1, arglist);
9053 return build_function_call_expr (fn, arglist);
9057 /* Simplify a call to the strchr builtin.
9059 Return 0 if no simplification was possible, otherwise return the
9060 simplified form of the call as a tree.
9062 The simplified form may be a constant or other expression which
9063 computes the same value, but in a more efficient manner (including
9064 calls to other builtin functions).
9066 The call may contain arguments which need to be evaluated, but
9067 which are not useful to determine the result of the call. In
9068 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9069 COMPOUND_EXPR will be an argument which must be evaluated.
9070 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9071 COMPOUND_EXPR in the chain will contain the tree for the simplified
9072 form of the builtin function call. */
9074 static tree
9075 fold_builtin_strchr (tree arglist, tree type)
9077 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9078 return 0;
9079 else
9081 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9082 const char *p1;
9084 if (TREE_CODE (s2) != INTEGER_CST)
9085 return 0;
9087 p1 = c_getstr (s1);
9088 if (p1 != NULL)
9090 char c;
9091 const char *r;
9092 tree tem;
9094 if (target_char_cast (s2, &c))
9095 return 0;
9097 r = strchr (p1, c);
9099 if (r == NULL)
9100 return build_int_cst (TREE_TYPE (s1), 0);
9102 /* Return an offset into the constant string argument. */
9103 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9104 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9105 return fold_convert (type, tem);
9107 return 0;
9111 /* Simplify a call to the strrchr builtin.
9113 Return 0 if no simplification was possible, otherwise return the
9114 simplified form of the call as a tree.
9116 The simplified form may be a constant or other expression which
9117 computes the same value, but in a more efficient manner (including
9118 calls to other builtin functions).
9120 The call may contain arguments which need to be evaluated, but
9121 which are not useful to determine the result of the call. In
9122 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9123 COMPOUND_EXPR will be an argument which must be evaluated.
9124 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9125 COMPOUND_EXPR in the chain will contain the tree for the simplified
9126 form of the builtin function call. */
9128 static tree
9129 fold_builtin_strrchr (tree arglist, tree type)
9131 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9132 return 0;
9133 else
9135 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9136 tree fn;
9137 const char *p1;
9139 if (TREE_CODE (s2) != INTEGER_CST)
9140 return 0;
9142 p1 = c_getstr (s1);
9143 if (p1 != NULL)
9145 char c;
9146 const char *r;
9147 tree tem;
9149 if (target_char_cast (s2, &c))
9150 return 0;
9152 r = strrchr (p1, c);
9154 if (r == NULL)
9155 return build_int_cst (TREE_TYPE (s1), 0);
9157 /* Return an offset into the constant string argument. */
9158 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9159 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9160 return fold_convert (type, tem);
9163 if (! integer_zerop (s2))
9164 return 0;
9166 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9167 if (!fn)
9168 return 0;
9170 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9171 return build_function_call_expr (fn, arglist);
9175 /* Simplify a call to the strpbrk builtin.
9177 Return 0 if no simplification was possible, otherwise return the
9178 simplified form of the call as a tree.
9180 The simplified form may be a constant or other expression which
9181 computes the same value, but in a more efficient manner (including
9182 calls to other builtin functions).
9184 The call may contain arguments which need to be evaluated, but
9185 which are not useful to determine the result of the call. In
9186 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9187 COMPOUND_EXPR will be an argument which must be evaluated.
9188 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9189 COMPOUND_EXPR in the chain will contain the tree for the simplified
9190 form of the builtin function call. */
9192 static tree
9193 fold_builtin_strpbrk (tree arglist, tree type)
9195 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9196 return 0;
9197 else
9199 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9200 tree fn;
9201 const char *p1, *p2;
9203 p2 = c_getstr (s2);
9204 if (p2 == NULL)
9205 return 0;
9207 p1 = c_getstr (s1);
9208 if (p1 != NULL)
9210 const char *r = strpbrk (p1, p2);
9211 tree tem;
9213 if (r == NULL)
9214 return build_int_cst (TREE_TYPE (s1), 0);
9216 /* Return an offset into the constant string argument. */
9217 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9218 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9219 return fold_convert (type, tem);
9222 if (p2[0] == '\0')
9223 /* strpbrk(x, "") == NULL.
9224 Evaluate and ignore s1 in case it had side-effects. */
9225 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9227 if (p2[1] != '\0')
9228 return 0; /* Really call strpbrk. */
9230 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9231 if (!fn)
9232 return 0;
9234 /* New argument list transforming strpbrk(s1, s2) to
9235 strchr(s1, s2[0]). */
9236 arglist = build_tree_list (NULL_TREE,
9237 build_int_cst (NULL_TREE, p2[0]));
9238 arglist = tree_cons (NULL_TREE, s1, arglist);
9239 return build_function_call_expr (fn, arglist);
9243 /* Simplify a call to the strcat builtin.
9245 Return 0 if no simplification was possible, otherwise return the
9246 simplified form of the call as a tree.
9248 The simplified form may be a constant or other expression which
9249 computes the same value, but in a more efficient manner (including
9250 calls to other builtin functions).
9252 The call may contain arguments which need to be evaluated, but
9253 which are not useful to determine the result of the call. In
9254 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9255 COMPOUND_EXPR will be an argument which must be evaluated.
9256 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9257 COMPOUND_EXPR in the chain will contain the tree for the simplified
9258 form of the builtin function call. */
9260 static tree
9261 fold_builtin_strcat (tree arglist)
9263 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9264 return 0;
9265 else
9267 tree dst = TREE_VALUE (arglist),
9268 src = TREE_VALUE (TREE_CHAIN (arglist));
9269 const char *p = c_getstr (src);
9271 /* If the string length is zero, return the dst parameter. */
9272 if (p && *p == '\0')
9273 return dst;
9275 return 0;
9279 /* Simplify a call to the strncat builtin.
9281 Return 0 if no simplification was possible, otherwise return the
9282 simplified form of the call as a tree.
9284 The simplified form may be a constant or other expression which
9285 computes the same value, but in a more efficient manner (including
9286 calls to other builtin functions).
9288 The call may contain arguments which need to be evaluated, but
9289 which are not useful to determine the result of the call. In
9290 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9291 COMPOUND_EXPR will be an argument which must be evaluated.
9292 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9293 COMPOUND_EXPR in the chain will contain the tree for the simplified
9294 form of the builtin function call. */
9296 static tree
9297 fold_builtin_strncat (tree arglist)
9299 if (!validate_arglist (arglist,
9300 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9301 return 0;
9302 else
9304 tree dst = TREE_VALUE (arglist);
9305 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9306 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9307 const char *p = c_getstr (src);
9309 /* If the requested length is zero, or the src parameter string
9310 length is zero, return the dst parameter. */
9311 if (integer_zerop (len) || (p && *p == '\0'))
9312 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9314 /* If the requested len is greater than or equal to the string
9315 length, call strcat. */
9316 if (TREE_CODE (len) == INTEGER_CST && p
9317 && compare_tree_int (len, strlen (p)) >= 0)
9319 tree newarglist
9320 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9321 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9323 /* If the replacement _DECL isn't initialized, don't do the
9324 transformation. */
9325 if (!fn)
9326 return 0;
9328 return build_function_call_expr (fn, newarglist);
9330 return 0;
9334 /* Simplify a call to the strspn builtin.
9336 Return 0 if no simplification was possible, otherwise return the
9337 simplified form of the call as a tree.
9339 The simplified form may be a constant or other expression which
9340 computes the same value, but in a more efficient manner (including
9341 calls to other builtin functions).
9343 The call may contain arguments which need to be evaluated, but
9344 which are not useful to determine the result of the call. In
9345 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9346 COMPOUND_EXPR will be an argument which must be evaluated.
9347 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9348 COMPOUND_EXPR in the chain will contain the tree for the simplified
9349 form of the builtin function call. */
9351 static tree
9352 fold_builtin_strspn (tree arglist)
9354 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9355 return 0;
9356 else
9358 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9359 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9361 /* If both arguments are constants, evaluate at compile-time. */
9362 if (p1 && p2)
9364 const size_t r = strspn (p1, p2);
9365 return size_int (r);
9368 /* If either argument is "", return 0. */
9369 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9370 /* Evaluate and ignore both arguments in case either one has
9371 side-effects. */
9372 return omit_two_operands (integer_type_node, integer_zero_node,
9373 s1, s2);
9374 return 0;
9378 /* Simplify a call to the strcspn builtin.
9380 Return 0 if no simplification was possible, otherwise return the
9381 simplified form of the call as a tree.
9383 The simplified form may be a constant or other expression which
9384 computes the same value, but in a more efficient manner (including
9385 calls to other builtin functions).
9387 The call may contain arguments which need to be evaluated, but
9388 which are not useful to determine the result of the call. In
9389 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9390 COMPOUND_EXPR will be an argument which must be evaluated.
9391 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9392 COMPOUND_EXPR in the chain will contain the tree for the simplified
9393 form of the builtin function call. */
9395 static tree
9396 fold_builtin_strcspn (tree arglist)
9398 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9399 return 0;
9400 else
9402 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9403 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9405 /* If both arguments are constants, evaluate at compile-time. */
9406 if (p1 && p2)
9408 const size_t r = strcspn (p1, p2);
9409 return size_int (r);
9412 /* If the first argument is "", return 0. */
9413 if (p1 && *p1 == '\0')
9415 /* Evaluate and ignore argument s2 in case it has
9416 side-effects. */
9417 return omit_one_operand (integer_type_node,
9418 integer_zero_node, s2);
9421 /* If the second argument is "", return __builtin_strlen(s1). */
9422 if (p2 && *p2 == '\0')
9424 tree newarglist = build_tree_list (NULL_TREE, s1),
9425 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9427 /* If the replacement _DECL isn't initialized, don't do the
9428 transformation. */
9429 if (!fn)
9430 return 0;
9432 return build_function_call_expr (fn, newarglist);
9434 return 0;
9438 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9439 by the builtin will be ignored. UNLOCKED is true is true if this
9440 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9441 the known length of the string. Return NULL_TREE if no simplification
9442 was possible. */
9444 tree
9445 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9447 tree fn;
9448 /* If we're using an unlocked function, assume the other unlocked
9449 functions exist explicitly. */
9450 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9451 : implicit_built_in_decls[BUILT_IN_FPUTC];
9452 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9453 : implicit_built_in_decls[BUILT_IN_FWRITE];
9455 /* If the return value is used, don't do the transformation. */
9456 if (!ignore)
9457 return 0;
9459 /* Verify the arguments in the original call. */
9460 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9461 return 0;
9463 if (! len)
9464 len = c_strlen (TREE_VALUE (arglist), 0);
9466 /* Get the length of the string passed to fputs. If the length
9467 can't be determined, punt. */
9468 if (!len
9469 || TREE_CODE (len) != INTEGER_CST)
9470 return 0;
9472 switch (compare_tree_int (len, 1))
9474 case -1: /* length is 0, delete the call entirely . */
9475 return omit_one_operand (integer_type_node, integer_zero_node,
9476 TREE_VALUE (TREE_CHAIN (arglist)));
9478 case 0: /* length is 1, call fputc. */
9480 const char *p = c_getstr (TREE_VALUE (arglist));
9482 if (p != NULL)
9484 /* New argument list transforming fputs(string, stream) to
9485 fputc(string[0], stream). */
9486 arglist = build_tree_list (NULL_TREE,
9487 TREE_VALUE (TREE_CHAIN (arglist)));
9488 arglist = tree_cons (NULL_TREE,
9489 build_int_cst (NULL_TREE, p[0]),
9490 arglist);
9491 fn = fn_fputc;
9492 break;
9495 /* FALLTHROUGH */
9496 case 1: /* length is greater than 1, call fwrite. */
9498 tree string_arg;
9500 /* If optimizing for size keep fputs. */
9501 if (optimize_size)
9502 return 0;
9503 string_arg = TREE_VALUE (arglist);
9504 /* New argument list transforming fputs(string, stream) to
9505 fwrite(string, 1, len, stream). */
9506 arglist = build_tree_list (NULL_TREE,
9507 TREE_VALUE (TREE_CHAIN (arglist)));
9508 arglist = tree_cons (NULL_TREE, len, arglist);
9509 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9510 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9511 fn = fn_fwrite;
9512 break;
9514 default:
9515 gcc_unreachable ();
9518 /* If the replacement _DECL isn't initialized, don't do the
9519 transformation. */
9520 if (!fn)
9521 return 0;
9523 /* These optimizations are only performed when the result is ignored,
9524 hence there's no need to cast the result to integer_type_node. */
9525 return build_function_call_expr (fn, arglist);
9528 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9529 produced. False otherwise. This is done so that we don't output the error
9530 or warning twice or three times. */
9531 bool
9532 fold_builtin_next_arg (tree arglist)
9534 tree fntype = TREE_TYPE (current_function_decl);
9536 if (TYPE_ARG_TYPES (fntype) == 0
9537 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9538 == void_type_node))
9540 error ("%<va_start%> used in function with fixed args");
9541 return true;
9543 else if (!arglist)
9545 /* Evidently an out of date version of <stdarg.h>; can't validate
9546 va_start's second argument, but can still work as intended. */
9547 warning (0, "%<__builtin_next_arg%> called without an argument");
9548 return true;
9550 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9551 when we checked the arguments and if needed issued a warning. */
9552 else if (!TREE_CHAIN (arglist)
9553 || !integer_zerop (TREE_VALUE (arglist))
9554 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9555 || TREE_CHAIN (TREE_CHAIN (arglist)))
9557 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9558 tree arg = TREE_VALUE (arglist);
9560 if (TREE_CHAIN (arglist))
9562 error ("%<va_start%> used with too many arguments");
9563 return true;
9566 /* Strip off all nops for the sake of the comparison. This
9567 is not quite the same as STRIP_NOPS. It does more.
9568 We must also strip off INDIRECT_EXPR for C++ reference
9569 parameters. */
9570 while (TREE_CODE (arg) == NOP_EXPR
9571 || TREE_CODE (arg) == CONVERT_EXPR
9572 || TREE_CODE (arg) == NON_LVALUE_EXPR
9573 || TREE_CODE (arg) == INDIRECT_REF)
9574 arg = TREE_OPERAND (arg, 0);
9575 if (arg != last_parm)
9577 /* FIXME: Sometimes with the tree optimizers we can get the
9578 not the last argument even though the user used the last
9579 argument. We just warn and set the arg to be the last
9580 argument so that we will get wrong-code because of
9581 it. */
9582 warning (0, "second parameter of %<va_start%> not last named argument");
9584 /* We want to verify the second parameter just once before the tree
9585 optimizers are run and then avoid keeping it in the tree,
9586 as otherwise we could warn even for correct code like:
9587 void foo (int i, ...)
9588 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9589 TREE_VALUE (arglist) = integer_zero_node;
9590 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9592 return false;
9596 /* Simplify a call to the sprintf builtin.
9598 Return 0 if no simplification was possible, otherwise return the
9599 simplified form of the call as a tree. If IGNORED is true, it means that
9600 the caller does not use the returned value of the function. */
9602 static tree
9603 fold_builtin_sprintf (tree arglist, int ignored)
9605 tree call, retval, dest, fmt;
9606 const char *fmt_str = NULL;
9608 /* Verify the required arguments in the original call. We deal with two
9609 types of sprintf() calls: 'sprintf (str, fmt)' and
9610 'sprintf (dest, "%s", orig)'. */
9611 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9612 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9613 VOID_TYPE))
9614 return NULL_TREE;
9616 /* Get the destination string and the format specifier. */
9617 dest = TREE_VALUE (arglist);
9618 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9620 /* Check whether the format is a literal string constant. */
9621 fmt_str = c_getstr (fmt);
9622 if (fmt_str == NULL)
9623 return NULL_TREE;
9625 call = NULL_TREE;
9626 retval = NULL_TREE;
9628 if (!init_target_chars())
9629 return 0;
9631 /* If the format doesn't contain % args or %%, use strcpy. */
9632 if (strchr (fmt_str, target_percent) == NULL)
9634 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9636 if (!fn)
9637 return NULL_TREE;
9639 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9640 'format' is known to contain no % formats. */
9641 arglist = build_tree_list (NULL_TREE, fmt);
9642 arglist = tree_cons (NULL_TREE, dest, arglist);
9643 call = build_function_call_expr (fn, arglist);
9644 if (!ignored)
9645 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9648 /* If the format is "%s", use strcpy if the result isn't used. */
9649 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9651 tree fn, orig;
9652 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9654 if (!fn)
9655 return NULL_TREE;
9657 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9658 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9659 arglist = build_tree_list (NULL_TREE, orig);
9660 arglist = tree_cons (NULL_TREE, dest, arglist);
9661 if (!ignored)
9663 retval = c_strlen (orig, 1);
9664 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9665 return NULL_TREE;
9667 call = build_function_call_expr (fn, arglist);
9670 if (call && retval)
9672 retval = fold_convert
9673 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9674 retval);
9675 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9677 else
9678 return call;
9681 /* Expand a call to __builtin_object_size. */
9684 expand_builtin_object_size (tree exp)
9686 tree ost;
9687 int object_size_type;
9688 tree fndecl = get_callee_fndecl (exp);
9689 tree arglist = TREE_OPERAND (exp, 1);
9690 location_t locus = EXPR_LOCATION (exp);
9692 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9694 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9695 &locus, fndecl);
9696 expand_builtin_trap ();
9697 return const0_rtx;
9700 ost = TREE_VALUE (TREE_CHAIN (arglist));
9701 STRIP_NOPS (ost);
9703 if (TREE_CODE (ost) != INTEGER_CST
9704 || tree_int_cst_sgn (ost) < 0
9705 || compare_tree_int (ost, 3) > 0)
9707 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9708 &locus, fndecl);
9709 expand_builtin_trap ();
9710 return const0_rtx;
9713 object_size_type = tree_low_cst (ost, 0);
9715 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9718 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9719 FCODE is the BUILT_IN_* to use.
9720 Return 0 if we failed; the caller should emit a normal call,
9721 otherwise try to get the result in TARGET, if convenient (and in
9722 mode MODE if that's convenient). */
9724 static rtx
9725 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9726 enum built_in_function fcode)
9728 tree arglist = TREE_OPERAND (exp, 1);
9729 tree dest, src, len, size;
9731 if (!validate_arglist (arglist,
9732 POINTER_TYPE,
9733 fcode == BUILT_IN_MEMSET_CHK
9734 ? INTEGER_TYPE : POINTER_TYPE,
9735 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9736 return 0;
9738 dest = TREE_VALUE (arglist);
9739 src = TREE_VALUE (TREE_CHAIN (arglist));
9740 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9741 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9743 if (! host_integerp (size, 1))
9744 return 0;
9746 if (host_integerp (len, 1) || integer_all_onesp (size))
9748 tree fn;
9750 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9752 location_t locus = EXPR_LOCATION (exp);
9753 warning (0, "%Hcall to %D will always overflow destination buffer",
9754 &locus, get_callee_fndecl (exp));
9755 return 0;
9758 arglist = build_tree_list (NULL_TREE, len);
9759 arglist = tree_cons (NULL_TREE, src, arglist);
9760 arglist = tree_cons (NULL_TREE, dest, arglist);
9762 fn = NULL_TREE;
9763 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9764 mem{cpy,pcpy,move,set} is available. */
9765 switch (fcode)
9767 case BUILT_IN_MEMCPY_CHK:
9768 fn = built_in_decls[BUILT_IN_MEMCPY];
9769 break;
9770 case BUILT_IN_MEMPCPY_CHK:
9771 fn = built_in_decls[BUILT_IN_MEMPCPY];
9772 break;
9773 case BUILT_IN_MEMMOVE_CHK:
9774 fn = built_in_decls[BUILT_IN_MEMMOVE];
9775 break;
9776 case BUILT_IN_MEMSET_CHK:
9777 fn = built_in_decls[BUILT_IN_MEMSET];
9778 break;
9779 default:
9780 break;
9783 if (! fn)
9784 return 0;
9786 fn = build_function_call_expr (fn, arglist);
9787 if (TREE_CODE (fn) == CALL_EXPR)
9788 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9789 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9791 else if (fcode == BUILT_IN_MEMSET_CHK)
9792 return 0;
9793 else
9795 unsigned int dest_align
9796 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9798 /* If DEST is not a pointer type, call the normal function. */
9799 if (dest_align == 0)
9800 return 0;
9802 /* If SRC and DEST are the same (and not volatile), do nothing. */
9803 if (operand_equal_p (src, dest, 0))
9805 tree expr;
9807 if (fcode != BUILT_IN_MEMPCPY_CHK)
9809 /* Evaluate and ignore LEN in case it has side-effects. */
9810 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9811 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9814 len = fold_convert (TREE_TYPE (dest), len);
9815 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9816 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9819 /* __memmove_chk special case. */
9820 if (fcode == BUILT_IN_MEMMOVE_CHK)
9822 unsigned int src_align
9823 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9825 if (src_align == 0)
9826 return 0;
9828 /* If src is categorized for a readonly section we can use
9829 normal __memcpy_chk. */
9830 if (readonly_data_expr (src))
9832 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9833 if (!fn)
9834 return 0;
9835 fn = build_function_call_expr (fn, arglist);
9836 if (TREE_CODE (fn) == CALL_EXPR)
9837 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9838 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9841 return 0;
9845 /* Emit warning if a buffer overflow is detected at compile time. */
9847 static void
9848 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9850 int arg_mask, is_strlen = 0;
9851 tree arglist = TREE_OPERAND (exp, 1), a;
9852 tree len, size;
9853 location_t locus;
9855 switch (fcode)
9857 case BUILT_IN_STRCPY_CHK:
9858 case BUILT_IN_STPCPY_CHK:
9859 /* For __strcat_chk the warning will be emitted only if overflowing
9860 by at least strlen (dest) + 1 bytes. */
9861 case BUILT_IN_STRCAT_CHK:
9862 arg_mask = 6;
9863 is_strlen = 1;
9864 break;
9865 case BUILT_IN_STRNCPY_CHK:
9866 arg_mask = 12;
9867 break;
9868 case BUILT_IN_SNPRINTF_CHK:
9869 case BUILT_IN_VSNPRINTF_CHK:
9870 arg_mask = 10;
9871 break;
9872 default:
9873 gcc_unreachable ();
9876 len = NULL_TREE;
9877 size = NULL_TREE;
9878 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9879 if (arg_mask & 1)
9881 if (len)
9882 size = a;
9883 else
9884 len = a;
9887 if (!len || !size)
9888 return;
9890 len = TREE_VALUE (len);
9891 size = TREE_VALUE (size);
9893 if (! host_integerp (size, 1) || integer_all_onesp (size))
9894 return;
9896 if (is_strlen)
9898 len = c_strlen (len, 1);
9899 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9900 return;
9902 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9903 return;
9905 locus = EXPR_LOCATION (exp);
9906 warning (0, "%Hcall to %D will always overflow destination buffer",
9907 &locus, get_callee_fndecl (exp));
9910 /* Emit warning if a buffer overflow is detected at compile time
9911 in __sprintf_chk/__vsprintf_chk calls. */
9913 static void
9914 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9916 tree arglist = TREE_OPERAND (exp, 1);
9917 tree dest, size, len, fmt, flag;
9918 const char *fmt_str;
9920 /* Verify the required arguments in the original call. */
9921 if (! arglist)
9922 return;
9923 dest = TREE_VALUE (arglist);
9924 arglist = TREE_CHAIN (arglist);
9925 if (! arglist)
9926 return;
9927 flag = TREE_VALUE (arglist);
9928 arglist = TREE_CHAIN (arglist);
9929 if (! arglist)
9930 return;
9931 size = TREE_VALUE (arglist);
9932 arglist = TREE_CHAIN (arglist);
9933 if (! arglist)
9934 return;
9935 fmt = TREE_VALUE (arglist);
9936 arglist = TREE_CHAIN (arglist);
9938 if (! host_integerp (size, 1) || integer_all_onesp (size))
9939 return;
9941 /* Check whether the format is a literal string constant. */
9942 fmt_str = c_getstr (fmt);
9943 if (fmt_str == NULL)
9944 return;
9946 if (!init_target_chars())
9947 return;
9949 /* If the format doesn't contain % args or %%, we know its size. */
9950 if (strchr (fmt_str, target_percent) == 0)
9951 len = build_int_cstu (size_type_node, strlen (fmt_str));
9952 /* If the format is "%s" and first ... argument is a string literal,
9953 we know it too. */
9954 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9956 tree arg;
9958 if (! arglist)
9959 return;
9960 arg = TREE_VALUE (arglist);
9961 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9962 return;
9964 len = c_strlen (arg, 1);
9965 if (!len || ! host_integerp (len, 1))
9966 return;
9968 else
9969 return;
9971 if (! tree_int_cst_lt (len, size))
9973 location_t locus = EXPR_LOCATION (exp);
9974 warning (0, "%Hcall to %D will always overflow destination buffer",
9975 &locus, get_callee_fndecl (exp));
9979 /* Fold a call to __builtin_object_size, if possible. */
9981 tree
9982 fold_builtin_object_size (tree arglist)
9984 tree ptr, ost, ret = 0;
9985 int object_size_type;
9987 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9988 return 0;
9990 ptr = TREE_VALUE (arglist);
9991 ost = TREE_VALUE (TREE_CHAIN (arglist));
9992 STRIP_NOPS (ost);
9994 if (TREE_CODE (ost) != INTEGER_CST
9995 || tree_int_cst_sgn (ost) < 0
9996 || compare_tree_int (ost, 3) > 0)
9997 return 0;
9999 object_size_type = tree_low_cst (ost, 0);
10001 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10002 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10003 and (size_t) 0 for types 2 and 3. */
10004 if (TREE_SIDE_EFFECTS (ptr))
10005 return fold_convert (size_type_node,
10006 object_size_type < 2
10007 ? integer_minus_one_node : integer_zero_node);
10009 if (TREE_CODE (ptr) == ADDR_EXPR)
10010 ret = build_int_cstu (size_type_node,
10011 compute_builtin_object_size (ptr, object_size_type));
10013 else if (TREE_CODE (ptr) == SSA_NAME)
10015 unsigned HOST_WIDE_INT bytes;
10017 /* If object size is not known yet, delay folding until
10018 later. Maybe subsequent passes will help determining
10019 it. */
10020 bytes = compute_builtin_object_size (ptr, object_size_type);
10021 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10022 ? -1 : 0))
10023 ret = build_int_cstu (size_type_node, bytes);
10026 if (ret)
10028 ret = force_fit_type (ret, -1, false, false);
10029 if (TREE_CONSTANT_OVERFLOW (ret))
10030 ret = 0;
10033 return ret;
10036 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10037 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10038 code of the builtin. If MAXLEN is not NULL, it is maximum length
10039 passed as third argument. */
10041 tree
10042 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10043 enum built_in_function fcode)
10045 tree dest, src, len, size, fn;
10047 if (!validate_arglist (arglist,
10048 POINTER_TYPE,
10049 fcode == BUILT_IN_MEMSET_CHK
10050 ? INTEGER_TYPE : POINTER_TYPE,
10051 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10052 return 0;
10054 dest = TREE_VALUE (arglist);
10055 /* Actually val for __memset_chk, but it doesn't matter. */
10056 src = TREE_VALUE (TREE_CHAIN (arglist));
10057 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10058 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10060 /* If SRC and DEST are the same (and not volatile), return DEST
10061 (resp. DEST+LEN for __mempcpy_chk). */
10062 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10064 if (fcode != BUILT_IN_MEMPCPY_CHK)
10065 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10066 else
10068 tree temp = fold_convert (TREE_TYPE (dest), len);
10069 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10070 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10074 if (! host_integerp (size, 1))
10075 return 0;
10077 if (! integer_all_onesp (size))
10079 if (! host_integerp (len, 1))
10081 /* If LEN is not constant, try MAXLEN too.
10082 For MAXLEN only allow optimizing into non-_ocs function
10083 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10084 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10086 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10088 /* (void) __mempcpy_chk () can be optimized into
10089 (void) __memcpy_chk (). */
10090 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10091 if (!fn)
10092 return 0;
10094 return build_function_call_expr (fn, arglist);
10096 return 0;
10099 else
10100 maxlen = len;
10102 if (tree_int_cst_lt (size, maxlen))
10103 return 0;
10106 arglist = build_tree_list (NULL_TREE, len);
10107 arglist = tree_cons (NULL_TREE, src, arglist);
10108 arglist = tree_cons (NULL_TREE, dest, arglist);
10110 fn = NULL_TREE;
10111 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10112 mem{cpy,pcpy,move,set} is available. */
10113 switch (fcode)
10115 case BUILT_IN_MEMCPY_CHK:
10116 fn = built_in_decls[BUILT_IN_MEMCPY];
10117 break;
10118 case BUILT_IN_MEMPCPY_CHK:
10119 fn = built_in_decls[BUILT_IN_MEMPCPY];
10120 break;
10121 case BUILT_IN_MEMMOVE_CHK:
10122 fn = built_in_decls[BUILT_IN_MEMMOVE];
10123 break;
10124 case BUILT_IN_MEMSET_CHK:
10125 fn = built_in_decls[BUILT_IN_MEMSET];
10126 break;
10127 default:
10128 break;
10131 if (!fn)
10132 return 0;
10134 return build_function_call_expr (fn, arglist);
10137 /* Fold a call to the __st[rp]cpy_chk builtin.
10138 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10139 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10140 strings passed as second argument. */
10142 tree
10143 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10144 enum built_in_function fcode)
10146 tree dest, src, size, len, fn;
10148 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10149 VOID_TYPE))
10150 return 0;
10152 dest = TREE_VALUE (arglist);
10153 src = TREE_VALUE (TREE_CHAIN (arglist));
10154 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10156 /* If SRC and DEST are the same (and not volatile), return DEST. */
10157 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10158 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10160 if (! host_integerp (size, 1))
10161 return 0;
10163 if (! integer_all_onesp (size))
10165 len = c_strlen (src, 1);
10166 if (! len || ! host_integerp (len, 1))
10168 /* If LEN is not constant, try MAXLEN too.
10169 For MAXLEN only allow optimizing into non-_ocs function
10170 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10171 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10173 if (fcode == BUILT_IN_STPCPY_CHK)
10175 if (! ignore)
10176 return 0;
10178 /* If return value of __stpcpy_chk is ignored,
10179 optimize into __strcpy_chk. */
10180 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10181 if (!fn)
10182 return 0;
10184 return build_function_call_expr (fn, arglist);
10187 if (! len || TREE_SIDE_EFFECTS (len))
10188 return 0;
10190 /* If c_strlen returned something, but not a constant,
10191 transform __strcpy_chk into __memcpy_chk. */
10192 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10193 if (!fn)
10194 return 0;
10196 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10197 arglist = build_tree_list (NULL_TREE, size);
10198 arglist = tree_cons (NULL_TREE, len, arglist);
10199 arglist = tree_cons (NULL_TREE, src, arglist);
10200 arglist = tree_cons (NULL_TREE, dest, arglist);
10201 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10202 build_function_call_expr (fn, arglist));
10205 else
10206 maxlen = len;
10208 if (! tree_int_cst_lt (maxlen, size))
10209 return 0;
10212 arglist = build_tree_list (NULL_TREE, src);
10213 arglist = tree_cons (NULL_TREE, dest, arglist);
10215 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10216 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10217 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10218 if (!fn)
10219 return 0;
10221 return build_function_call_expr (fn, arglist);
10224 /* Fold a call to the __strncpy_chk builtin.
10225 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10227 tree
10228 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10230 tree dest, src, size, len, fn;
10232 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10233 INTEGER_TYPE, VOID_TYPE))
10234 return 0;
10236 dest = TREE_VALUE (arglist);
10237 src = TREE_VALUE (TREE_CHAIN (arglist));
10238 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10239 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10241 if (! host_integerp (size, 1))
10242 return 0;
10244 if (! integer_all_onesp (size))
10246 if (! host_integerp (len, 1))
10248 /* If LEN is not constant, try MAXLEN too.
10249 For MAXLEN only allow optimizing into non-_ocs function
10250 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10251 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10252 return 0;
10254 else
10255 maxlen = len;
10257 if (tree_int_cst_lt (size, maxlen))
10258 return 0;
10261 arglist = build_tree_list (NULL_TREE, len);
10262 arglist = tree_cons (NULL_TREE, src, arglist);
10263 arglist = tree_cons (NULL_TREE, dest, arglist);
10265 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10266 fn = built_in_decls[BUILT_IN_STRNCPY];
10267 if (!fn)
10268 return 0;
10270 return build_function_call_expr (fn, arglist);
10273 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10275 static tree
10276 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10278 tree dest, src, size, fn;
10279 const char *p;
10281 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10282 VOID_TYPE))
10283 return 0;
10285 dest = TREE_VALUE (arglist);
10286 src = TREE_VALUE (TREE_CHAIN (arglist));
10287 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10289 p = c_getstr (src);
10290 /* If the SRC parameter is "", return DEST. */
10291 if (p && *p == '\0')
10292 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10294 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10295 return 0;
10297 arglist = build_tree_list (NULL_TREE, src);
10298 arglist = tree_cons (NULL_TREE, dest, arglist);
10300 /* If __builtin_strcat_chk is used, assume strcat is available. */
10301 fn = built_in_decls[BUILT_IN_STRCAT];
10302 if (!fn)
10303 return 0;
10305 return build_function_call_expr (fn, arglist);
10308 /* Fold a call to the __strncat_chk builtin EXP. */
10310 static tree
10311 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10313 tree dest, src, size, len, fn;
10314 const char *p;
10316 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10317 INTEGER_TYPE, VOID_TYPE))
10318 return 0;
10320 dest = TREE_VALUE (arglist);
10321 src = TREE_VALUE (TREE_CHAIN (arglist));
10322 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10323 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10325 p = c_getstr (src);
10326 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10327 if (p && *p == '\0')
10328 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10329 else if (integer_zerop (len))
10330 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10332 if (! host_integerp (size, 1))
10333 return 0;
10335 if (! integer_all_onesp (size))
10337 tree src_len = c_strlen (src, 1);
10338 if (src_len
10339 && host_integerp (src_len, 1)
10340 && host_integerp (len, 1)
10341 && ! tree_int_cst_lt (len, src_len))
10343 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10344 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10345 if (!fn)
10346 return 0;
10348 arglist = build_tree_list (NULL_TREE, size);
10349 arglist = tree_cons (NULL_TREE, src, arglist);
10350 arglist = tree_cons (NULL_TREE, dest, arglist);
10351 return build_function_call_expr (fn, arglist);
10353 return 0;
10356 arglist = build_tree_list (NULL_TREE, len);
10357 arglist = tree_cons (NULL_TREE, src, arglist);
10358 arglist = tree_cons (NULL_TREE, dest, arglist);
10360 /* If __builtin_strncat_chk is used, assume strncat is available. */
10361 fn = built_in_decls[BUILT_IN_STRNCAT];
10362 if (!fn)
10363 return 0;
10365 return build_function_call_expr (fn, arglist);
10368 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10369 a normal call should be emitted rather than expanding the function
10370 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10372 static tree
10373 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10375 tree dest, size, len, fn, fmt, flag;
10376 const char *fmt_str;
10378 /* Verify the required arguments in the original call. */
10379 if (! arglist)
10380 return 0;
10381 dest = TREE_VALUE (arglist);
10382 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10383 return 0;
10384 arglist = TREE_CHAIN (arglist);
10385 if (! arglist)
10386 return 0;
10387 flag = TREE_VALUE (arglist);
10388 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10389 return 0;
10390 arglist = TREE_CHAIN (arglist);
10391 if (! arglist)
10392 return 0;
10393 size = TREE_VALUE (arglist);
10394 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10395 return 0;
10396 arglist = TREE_CHAIN (arglist);
10397 if (! arglist)
10398 return 0;
10399 fmt = TREE_VALUE (arglist);
10400 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10401 return 0;
10402 arglist = TREE_CHAIN (arglist);
10404 if (! host_integerp (size, 1))
10405 return 0;
10407 len = NULL_TREE;
10409 if (!init_target_chars())
10410 return 0;
10412 /* Check whether the format is a literal string constant. */
10413 fmt_str = c_getstr (fmt);
10414 if (fmt_str != NULL)
10416 /* If the format doesn't contain % args or %%, we know the size. */
10417 if (strchr (fmt_str, target_percent) == 0)
10419 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10420 len = build_int_cstu (size_type_node, strlen (fmt_str));
10422 /* If the format is "%s" and first ... argument is a string literal,
10423 we know the size too. */
10424 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10426 tree arg;
10428 if (arglist && !TREE_CHAIN (arglist))
10430 arg = TREE_VALUE (arglist);
10431 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10433 len = c_strlen (arg, 1);
10434 if (! len || ! host_integerp (len, 1))
10435 len = NULL_TREE;
10441 if (! integer_all_onesp (size))
10443 if (! len || ! tree_int_cst_lt (len, size))
10444 return 0;
10447 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10448 or if format doesn't contain % chars or is "%s". */
10449 if (! integer_zerop (flag))
10451 if (fmt_str == NULL)
10452 return 0;
10453 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10454 return 0;
10457 arglist = tree_cons (NULL_TREE, fmt, arglist);
10458 arglist = tree_cons (NULL_TREE, dest, arglist);
10460 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10461 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10462 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10463 if (!fn)
10464 return 0;
10466 return build_function_call_expr (fn, arglist);
10469 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10470 a normal call should be emitted rather than expanding the function
10471 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10472 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10473 passed as second argument. */
10475 tree
10476 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10477 enum built_in_function fcode)
10479 tree dest, size, len, fn, fmt, flag;
10480 const char *fmt_str;
10482 /* Verify the required arguments in the original call. */
10483 if (! arglist)
10484 return 0;
10485 dest = TREE_VALUE (arglist);
10486 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10487 return 0;
10488 arglist = TREE_CHAIN (arglist);
10489 if (! arglist)
10490 return 0;
10491 len = TREE_VALUE (arglist);
10492 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10493 return 0;
10494 arglist = TREE_CHAIN (arglist);
10495 if (! arglist)
10496 return 0;
10497 flag = TREE_VALUE (arglist);
10498 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10499 return 0;
10500 arglist = TREE_CHAIN (arglist);
10501 if (! arglist)
10502 return 0;
10503 size = TREE_VALUE (arglist);
10504 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10505 return 0;
10506 arglist = TREE_CHAIN (arglist);
10507 if (! arglist)
10508 return 0;
10509 fmt = TREE_VALUE (arglist);
10510 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10511 return 0;
10512 arglist = TREE_CHAIN (arglist);
10514 if (! host_integerp (size, 1))
10515 return 0;
10517 if (! integer_all_onesp (size))
10519 if (! host_integerp (len, 1))
10521 /* If LEN is not constant, try MAXLEN too.
10522 For MAXLEN only allow optimizing into non-_ocs function
10523 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10524 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10525 return 0;
10527 else
10528 maxlen = len;
10530 if (tree_int_cst_lt (size, maxlen))
10531 return 0;
10534 if (!init_target_chars())
10535 return 0;
10537 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10538 or if format doesn't contain % chars or is "%s". */
10539 if (! integer_zerop (flag))
10541 fmt_str = c_getstr (fmt);
10542 if (fmt_str == NULL)
10543 return 0;
10544 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10545 return 0;
10548 arglist = tree_cons (NULL_TREE, fmt, arglist);
10549 arglist = tree_cons (NULL_TREE, len, arglist);
10550 arglist = tree_cons (NULL_TREE, dest, arglist);
10552 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10553 available. */
10554 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10555 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10556 if (!fn)
10557 return 0;
10559 return build_function_call_expr (fn, arglist);
10562 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10564 Return 0 if no simplification was possible, otherwise return the
10565 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10566 code of the function to be simplified. */
10568 static tree
10569 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10570 enum built_in_function fcode)
10572 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10573 const char *fmt_str = NULL;
10575 /* If the return value is used, don't do the transformation. */
10576 if (! ignore)
10577 return 0;
10579 /* Verify the required arguments in the original call. */
10580 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10582 tree flag;
10584 if (! arglist)
10585 return 0;
10586 flag = TREE_VALUE (arglist);
10587 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10588 || TREE_SIDE_EFFECTS (flag))
10589 return 0;
10590 arglist = TREE_CHAIN (arglist);
10593 if (! arglist)
10594 return 0;
10595 fmt = TREE_VALUE (arglist);
10596 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10597 return 0;
10598 arglist = TREE_CHAIN (arglist);
10600 /* Check whether the format is a literal string constant. */
10601 fmt_str = c_getstr (fmt);
10602 if (fmt_str == NULL)
10603 return NULL_TREE;
10605 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10607 /* If we're using an unlocked function, assume the other
10608 unlocked functions exist explicitly. */
10609 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10610 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10612 else
10614 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10615 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10618 if (!init_target_chars())
10619 return 0;
10621 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10623 const char *str;
10625 if (strcmp (fmt_str, target_percent_s) == 0)
10627 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10628 return 0;
10630 if (! arglist
10631 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10632 || TREE_CHAIN (arglist))
10633 return 0;
10635 str = c_getstr (TREE_VALUE (arglist));
10636 if (str == NULL)
10637 return 0;
10639 else
10641 /* The format specifier doesn't contain any '%' characters. */
10642 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10643 && arglist)
10644 return 0;
10645 str = fmt_str;
10648 /* If the string was "", printf does nothing. */
10649 if (str[0] == '\0')
10650 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10652 /* If the string has length of 1, call putchar. */
10653 if (str[1] == '\0')
10655 /* Given printf("c"), (where c is any one character,)
10656 convert "c"[0] to an int and pass that to the replacement
10657 function. */
10658 arg = build_int_cst (NULL_TREE, str[0]);
10659 arglist = build_tree_list (NULL_TREE, arg);
10660 fn = fn_putchar;
10662 else
10664 /* If the string was "string\n", call puts("string"). */
10665 size_t len = strlen (str);
10666 if ((unsigned char)str[len - 1] == target_newline)
10668 /* Create a NUL-terminated string that's one char shorter
10669 than the original, stripping off the trailing '\n'. */
10670 char *newstr = alloca (len);
10671 memcpy (newstr, str, len - 1);
10672 newstr[len - 1] = 0;
10674 arg = build_string_literal (len, newstr);
10675 arglist = build_tree_list (NULL_TREE, arg);
10676 fn = fn_puts;
10678 else
10679 /* We'd like to arrange to call fputs(string,stdout) here,
10680 but we need stdout and don't have a way to get it yet. */
10681 return 0;
10685 /* The other optimizations can be done only on the non-va_list variants. */
10686 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10687 return 0;
10689 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10690 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10692 if (! arglist
10693 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10694 || TREE_CHAIN (arglist))
10695 return 0;
10696 fn = fn_puts;
10699 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10700 else if (strcmp (fmt_str, target_percent_c) == 0)
10702 if (! arglist
10703 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10704 || TREE_CHAIN (arglist))
10705 return 0;
10706 fn = fn_putchar;
10709 if (!fn)
10710 return 0;
10712 call = build_function_call_expr (fn, arglist);
10713 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10716 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10718 Return 0 if no simplification was possible, otherwise return the
10719 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10720 code of the function to be simplified. */
10722 static tree
10723 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10724 enum built_in_function fcode)
10726 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10727 const char *fmt_str = NULL;
10729 /* If the return value is used, don't do the transformation. */
10730 if (! ignore)
10731 return 0;
10733 /* Verify the required arguments in the original call. */
10734 if (! arglist)
10735 return 0;
10736 fp = TREE_VALUE (arglist);
10737 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10738 return 0;
10739 arglist = TREE_CHAIN (arglist);
10741 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10743 tree flag;
10745 if (! arglist)
10746 return 0;
10747 flag = TREE_VALUE (arglist);
10748 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10749 || TREE_SIDE_EFFECTS (flag))
10750 return 0;
10751 arglist = TREE_CHAIN (arglist);
10754 if (! arglist)
10755 return 0;
10756 fmt = TREE_VALUE (arglist);
10757 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10758 return 0;
10759 arglist = TREE_CHAIN (arglist);
10761 /* Check whether the format is a literal string constant. */
10762 fmt_str = c_getstr (fmt);
10763 if (fmt_str == NULL)
10764 return NULL_TREE;
10766 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10768 /* If we're using an unlocked function, assume the other
10769 unlocked functions exist explicitly. */
10770 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10771 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10773 else
10775 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10776 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10779 if (!init_target_chars())
10780 return 0;
10782 /* If the format doesn't contain % args or %%, use strcpy. */
10783 if (strchr (fmt_str, target_percent) == NULL)
10785 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10786 && arglist)
10787 return 0;
10789 /* If the format specifier was "", fprintf does nothing. */
10790 if (fmt_str[0] == '\0')
10792 /* If FP has side-effects, just wait until gimplification is
10793 done. */
10794 if (TREE_SIDE_EFFECTS (fp))
10795 return 0;
10797 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10800 /* When "string" doesn't contain %, replace all cases of
10801 fprintf (fp, string) with fputs (string, fp). The fputs
10802 builtin will take care of special cases like length == 1. */
10803 arglist = build_tree_list (NULL_TREE, fp);
10804 arglist = tree_cons (NULL_TREE, fmt, arglist);
10805 fn = fn_fputs;
10808 /* The other optimizations can be done only on the non-va_list variants. */
10809 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10810 return 0;
10812 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10813 else if (strcmp (fmt_str, target_percent_s) == 0)
10815 if (! arglist
10816 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10817 || TREE_CHAIN (arglist))
10818 return 0;
10819 arg = TREE_VALUE (arglist);
10820 arglist = build_tree_list (NULL_TREE, fp);
10821 arglist = tree_cons (NULL_TREE, arg, arglist);
10822 fn = fn_fputs;
10825 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10826 else if (strcmp (fmt_str, target_percent_c) == 0)
10828 if (! arglist
10829 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10830 || TREE_CHAIN (arglist))
10831 return 0;
10832 arg = TREE_VALUE (arglist);
10833 arglist = build_tree_list (NULL_TREE, fp);
10834 arglist = tree_cons (NULL_TREE, arg, arglist);
10835 fn = fn_fputc;
10838 if (!fn)
10839 return 0;
10841 call = build_function_call_expr (fn, arglist);
10842 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10845 /* Initialize format string characters in the target charset. */
10847 static bool
10848 init_target_chars (void)
10850 static bool init;
10851 if (!init)
10853 target_newline = lang_hooks.to_target_charset ('\n');
10854 target_percent = lang_hooks.to_target_charset ('%');
10855 target_c = lang_hooks.to_target_charset ('c');
10856 target_s = lang_hooks.to_target_charset ('s');
10857 if (target_newline == 0 || target_percent == 0 || target_c == 0
10858 || target_s == 0)
10859 return false;
10861 target_percent_c[0] = target_percent;
10862 target_percent_c[1] = target_c;
10863 target_percent_c[2] = '\0';
10865 target_percent_s[0] = target_percent;
10866 target_percent_s[1] = target_s;
10867 target_percent_s[2] = '\0';
10869 target_percent_s_newline[0] = target_percent;
10870 target_percent_s_newline[1] = target_s;
10871 target_percent_s_newline[2] = target_newline;
10872 target_percent_s_newline[3] = '\0';
10874 init = true;
10876 return true;