* runtime/fpu.c (_GNU_SOURCE): Don't define here.
[official-gcc.git] / gcc / builtins.c
blob223637453c0d8f660f78892db9d150ced96acdbf
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static 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_int_roundingfn (tree, rtx, rtx);
98 static rtx expand_builtin_args_info (tree);
99 static rtx expand_builtin_next_arg (void);
100 static rtx expand_builtin_va_start (tree);
101 static rtx expand_builtin_va_end (tree);
102 static rtx expand_builtin_va_copy (tree);
103 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
113 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
114 static rtx expand_builtin_bcopy (tree);
115 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
116 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_strlen (tree);
140 static tree fold_builtin_inf (tree, int);
141 static tree fold_builtin_nan (tree, tree, int);
142 static int validate_arglist (tree, ...);
143 static bool integer_valued_real_p (tree);
144 static tree fold_trunc_transparent_mathfn (tree, tree);
145 static bool readonly_data_expr (tree);
146 static rtx expand_builtin_fabs (tree, rtx, rtx);
147 static rtx expand_builtin_signbit (tree, rtx);
148 static tree fold_builtin_cabs (tree, tree);
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);
202 /* Return true if NODE should be considered for inline expansion regardless
203 of the optimization level. This means whenever a function is invoked with
204 its "internal" name, which normally contains the prefix "__builtin". */
206 static bool called_as_built_in (tree node)
208 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
209 if (strncmp (name, "__builtin_", 10) == 0)
210 return true;
211 if (strncmp (name, "__sync_", 7) == 0)
212 return true;
213 return false;
216 /* Return the alignment in bits of EXP, a pointer valued expression.
217 But don't return more than MAX_ALIGN no matter what.
218 The alignment returned is, by default, the alignment of the thing that
219 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
221 Otherwise, look at the expression to see if we can do better, i.e., if the
222 expression is actually pointing at an object whose alignment is tighter. */
224 static int
225 get_pointer_alignment (tree exp, unsigned int max_align)
227 unsigned int align, inner;
229 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
230 return 0;
232 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
233 align = MIN (align, max_align);
235 while (1)
237 switch (TREE_CODE (exp))
239 case NOP_EXPR:
240 case CONVERT_EXPR:
241 case NON_LVALUE_EXPR:
242 exp = TREE_OPERAND (exp, 0);
243 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
244 return align;
246 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
247 align = MIN (inner, max_align);
248 break;
250 case PLUS_EXPR:
251 /* If sum of pointer + int, restrict our maximum alignment to that
252 imposed by the integer. If not, we can't do any better than
253 ALIGN. */
254 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
255 return align;
257 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
258 & (max_align / BITS_PER_UNIT - 1))
259 != 0)
260 max_align >>= 1;
262 exp = TREE_OPERAND (exp, 0);
263 break;
265 case ADDR_EXPR:
266 /* See what we are pointing at and look at its alignment. */
267 exp = TREE_OPERAND (exp, 0);
268 if (TREE_CODE (exp) == FUNCTION_DECL)
269 align = FUNCTION_BOUNDARY;
270 else if (DECL_P (exp))
271 align = DECL_ALIGN (exp);
272 #ifdef CONSTANT_ALIGNMENT
273 else if (CONSTANT_CLASS_P (exp))
274 align = CONSTANT_ALIGNMENT (exp, align);
275 #endif
276 return MIN (align, max_align);
278 default:
279 return align;
284 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
285 way, because it could contain a zero byte in the middle.
286 TREE_STRING_LENGTH is the size of the character array, not the string.
288 ONLY_VALUE should be nonzero if the result is not going to be emitted
289 into the instruction stream and zero if it is going to be expanded.
290 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
291 is returned, otherwise NULL, since
292 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
293 evaluate the side-effects.
295 The value returned is of type `ssizetype'.
297 Unfortunately, string_constant can't access the values of const char
298 arrays with initializers, so neither can we do so here. */
300 tree
301 c_strlen (tree src, int only_value)
303 tree offset_node;
304 HOST_WIDE_INT offset;
305 int max;
306 const char *ptr;
308 STRIP_NOPS (src);
309 if (TREE_CODE (src) == COND_EXPR
310 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
312 tree len1, len2;
314 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
315 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
316 if (tree_int_cst_equal (len1, len2))
317 return len1;
320 if (TREE_CODE (src) == COMPOUND_EXPR
321 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
322 return c_strlen (TREE_OPERAND (src, 1), only_value);
324 src = string_constant (src, &offset_node);
325 if (src == 0)
326 return 0;
328 max = TREE_STRING_LENGTH (src) - 1;
329 ptr = TREE_STRING_POINTER (src);
331 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
333 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
334 compute the offset to the following null if we don't know where to
335 start searching for it. */
336 int i;
338 for (i = 0; i < max; i++)
339 if (ptr[i] == 0)
340 return 0;
342 /* We don't know the starting offset, but we do know that the string
343 has no internal zero bytes. We can assume that the offset falls
344 within the bounds of the string; otherwise, the programmer deserves
345 what he gets. Subtract the offset from the length of the string,
346 and return that. This would perhaps not be valid if we were dealing
347 with named arrays in addition to literal string constants. */
349 return size_diffop (size_int (max), offset_node);
352 /* We have a known offset into the string. Start searching there for
353 a null character if we can represent it as a single HOST_WIDE_INT. */
354 if (offset_node == 0)
355 offset = 0;
356 else if (! host_integerp (offset_node, 0))
357 offset = -1;
358 else
359 offset = tree_low_cst (offset_node, 0);
361 /* If the offset is known to be out of bounds, warn, and call strlen at
362 runtime. */
363 if (offset < 0 || offset > max)
365 warning (0, "offset outside bounds of constant string");
366 return 0;
369 /* Use strlen to search for the first zero byte. Since any strings
370 constructed with build_string will have nulls appended, we win even
371 if we get handed something like (char[4])"abcd".
373 Since OFFSET is our starting index into the string, no further
374 calculation is needed. */
375 return ssize_int (strlen (ptr + offset));
378 /* Return a char pointer for a C string if it is a string constant
379 or sum of string constant and integer constant. */
381 static const char *
382 c_getstr (tree src)
384 tree offset_node;
386 src = string_constant (src, &offset_node);
387 if (src == 0)
388 return 0;
390 if (offset_node == 0)
391 return TREE_STRING_POINTER (src);
392 else if (!host_integerp (offset_node, 1)
393 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
394 return 0;
396 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
399 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
400 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
402 static rtx
403 c_readstr (const char *str, enum machine_mode mode)
405 HOST_WIDE_INT c[2];
406 HOST_WIDE_INT ch;
407 unsigned int i, j;
409 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
411 c[0] = 0;
412 c[1] = 0;
413 ch = 1;
414 for (i = 0; i < GET_MODE_SIZE (mode); i++)
416 j = i;
417 if (WORDS_BIG_ENDIAN)
418 j = GET_MODE_SIZE (mode) - i - 1;
419 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
420 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
421 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
422 j *= BITS_PER_UNIT;
423 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
425 if (ch)
426 ch = (unsigned char) str[i];
427 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
429 return immed_double_const (c[0], c[1], mode);
432 /* Cast a target constant CST to target CHAR and if that value fits into
433 host char type, return zero and put that value into variable pointed to by
434 P. */
436 static int
437 target_char_cast (tree cst, char *p)
439 unsigned HOST_WIDE_INT val, hostval;
441 if (!host_integerp (cst, 1)
442 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
443 return 1;
445 val = tree_low_cst (cst, 1);
446 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
447 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
449 hostval = val;
450 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
451 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
453 if (val != hostval)
454 return 1;
456 *p = hostval;
457 return 0;
460 /* Similar to save_expr, but assumes that arbitrary code is not executed
461 in between the multiple evaluations. In particular, we assume that a
462 non-addressable local variable will not be modified. */
464 static tree
465 builtin_save_expr (tree exp)
467 if (TREE_ADDRESSABLE (exp) == 0
468 && (TREE_CODE (exp) == PARM_DECL
469 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
470 return exp;
472 return save_expr (exp);
475 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
476 times to get the address of either a higher stack frame, or a return
477 address located within it (depending on FNDECL_CODE). */
479 static rtx
480 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
482 int i;
484 #ifdef INITIAL_FRAME_ADDRESS_RTX
485 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
486 #else
487 rtx tem;
489 /* For a zero count, we don't care what frame address we return, so frame
490 pointer elimination is OK, and using the soft frame pointer is OK.
491 For a non-zero count, we require a stable offset from the current frame
492 pointer to the previous one, so we must use the hard frame pointer, and
493 we must disable frame pointer elimination. */
494 if (count == 0)
495 tem = frame_pointer_rtx;
496 else
498 tem = hard_frame_pointer_rtx;
500 /* Tell reload not to eliminate the frame pointer. */
501 current_function_accesses_prior_frames = 1;
503 #endif
505 /* Some machines need special handling before we can access
506 arbitrary frames. For example, on the sparc, we must first flush
507 all register windows to the stack. */
508 #ifdef SETUP_FRAME_ADDRESSES
509 if (count > 0)
510 SETUP_FRAME_ADDRESSES ();
511 #endif
513 /* On the sparc, the return address is not in the frame, it is in a
514 register. There is no way to access it off of the current frame
515 pointer, but it can be accessed off the previous frame pointer by
516 reading the value from the register window save area. */
517 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
518 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
519 count--;
520 #endif
522 /* Scan back COUNT frames to the specified frame. */
523 for (i = 0; i < count; i++)
525 /* Assume the dynamic chain pointer is in the word that the
526 frame address points to, unless otherwise specified. */
527 #ifdef DYNAMIC_CHAIN_ADDRESS
528 tem = DYNAMIC_CHAIN_ADDRESS (tem);
529 #endif
530 tem = memory_address (Pmode, tem);
531 tem = gen_frame_mem (Pmode, tem);
532 tem = copy_to_reg (tem);
535 /* For __builtin_frame_address, return what we've got. */
536 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
537 return tem;
539 /* For __builtin_return_address, Get the return address from that
540 frame. */
541 #ifdef RETURN_ADDR_RTX
542 tem = RETURN_ADDR_RTX (count, tem);
543 #else
544 tem = memory_address (Pmode,
545 plus_constant (tem, GET_MODE_SIZE (Pmode)));
546 tem = gen_frame_mem (Pmode, tem);
547 #endif
548 return tem;
551 /* Alias set used for setjmp buffer. */
552 static HOST_WIDE_INT setjmp_alias_set = -1;
554 /* Construct the leading half of a __builtin_setjmp call. Control will
555 return to RECEIVER_LABEL. This is used directly by sjlj exception
556 handling code. */
558 void
559 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
561 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
562 rtx stack_save;
563 rtx mem;
565 if (setjmp_alias_set == -1)
566 setjmp_alias_set = new_alias_set ();
568 buf_addr = convert_memory_address (Pmode, buf_addr);
570 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
572 /* We store the frame pointer and the address of receiver_label in
573 the buffer and use the rest of it for the stack save area, which
574 is machine-dependent. */
576 mem = gen_rtx_MEM (Pmode, buf_addr);
577 set_mem_alias_set (mem, setjmp_alias_set);
578 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
580 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
581 set_mem_alias_set (mem, setjmp_alias_set);
583 emit_move_insn (validize_mem (mem),
584 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
586 stack_save = gen_rtx_MEM (sa_mode,
587 plus_constant (buf_addr,
588 2 * GET_MODE_SIZE (Pmode)));
589 set_mem_alias_set (stack_save, setjmp_alias_set);
590 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
592 /* If there is further processing to do, do it. */
593 #ifdef HAVE_builtin_setjmp_setup
594 if (HAVE_builtin_setjmp_setup)
595 emit_insn (gen_builtin_setjmp_setup (buf_addr));
596 #endif
598 /* Tell optimize_save_area_alloca that extra work is going to
599 need to go on during alloca. */
600 current_function_calls_setjmp = 1;
602 /* Set this so all the registers get saved in our frame; we need to be
603 able to copy the saved values for any registers from frames we unwind. */
604 current_function_has_nonlocal_label = 1;
607 /* Construct the trailing part of a __builtin_setjmp call.
608 This is used directly by sjlj exception handling code. */
610 void
611 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
613 /* Clobber the FP when we get here, so we have to make sure it's
614 marked as used by this function. */
615 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
617 /* Mark the static chain as clobbered here so life information
618 doesn't get messed up for it. */
619 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
621 /* Now put in the code to restore the frame pointer, and argument
622 pointer, if needed. */
623 #ifdef HAVE_nonlocal_goto
624 if (! HAVE_nonlocal_goto)
625 #endif
626 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
628 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
629 if (fixed_regs[ARG_POINTER_REGNUM])
631 #ifdef ELIMINABLE_REGS
632 size_t i;
633 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
635 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
636 if (elim_regs[i].from == ARG_POINTER_REGNUM
637 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
638 break;
640 if (i == ARRAY_SIZE (elim_regs))
641 #endif
643 /* Now restore our arg pointer from the address at which it
644 was saved in our stack frame. */
645 emit_move_insn (virtual_incoming_args_rtx,
646 copy_to_reg (get_arg_pointer_save_area (cfun)));
649 #endif
651 #ifdef HAVE_builtin_setjmp_receiver
652 if (HAVE_builtin_setjmp_receiver)
653 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
654 else
655 #endif
656 #ifdef HAVE_nonlocal_goto_receiver
657 if (HAVE_nonlocal_goto_receiver)
658 emit_insn (gen_nonlocal_goto_receiver ());
659 else
660 #endif
661 { /* Nothing */ }
663 /* @@@ This is a kludge. Not all machine descriptions define a blockage
664 insn, but we must not allow the code we just generated to be reordered
665 by scheduling. Specifically, the update of the frame pointer must
666 happen immediately, not later. So emit an ASM_INPUT to act as blockage
667 insn. */
668 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
671 /* __builtin_setjmp is passed a pointer to an array of five words (not
672 all will be used on all machines). It operates similarly to the C
673 library function of the same name, but is more efficient. Much of
674 the code below (and for longjmp) is copied from the handling of
675 non-local gotos.
677 NOTE: This is intended for use by GNAT and the exception handling
678 scheme in the compiler and will only work in the method used by
679 them. */
681 static rtx
682 expand_builtin_setjmp (tree arglist, rtx target)
684 rtx buf_addr, next_lab, cont_lab;
686 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
687 return NULL_RTX;
689 if (target == 0 || !REG_P (target)
690 || REGNO (target) < FIRST_PSEUDO_REGISTER)
691 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
693 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
695 next_lab = gen_label_rtx ();
696 cont_lab = gen_label_rtx ();
698 expand_builtin_setjmp_setup (buf_addr, next_lab);
700 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
701 ensure that pending stack adjustments are flushed. */
702 emit_move_insn (target, const0_rtx);
703 emit_jump (cont_lab);
705 emit_label (next_lab);
707 expand_builtin_setjmp_receiver (next_lab);
709 /* Set TARGET to one. */
710 emit_move_insn (target, const1_rtx);
711 emit_label (cont_lab);
713 /* Tell flow about the strange goings on. Putting `next_lab' on
714 `nonlocal_goto_handler_labels' to indicates that function
715 calls may traverse the arc back to this label. */
717 current_function_has_nonlocal_label = 1;
718 nonlocal_goto_handler_labels
719 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
721 return target;
724 /* __builtin_longjmp is passed a pointer to an array of five words (not
725 all will be used on all machines). It operates similarly to the C
726 library function of the same name, but is more efficient. Much of
727 the code below is copied from the handling of non-local gotos.
729 NOTE: This is intended for use by GNAT and the exception handling
730 scheme in the compiler and will only work in the method used by
731 them. */
733 static void
734 expand_builtin_longjmp (rtx buf_addr, rtx value)
736 rtx fp, lab, stack, insn, last;
737 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
739 if (setjmp_alias_set == -1)
740 setjmp_alias_set = new_alias_set ();
742 buf_addr = convert_memory_address (Pmode, buf_addr);
744 buf_addr = force_reg (Pmode, buf_addr);
746 /* We used to store value in static_chain_rtx, but that fails if pointers
747 are smaller than integers. We instead require that the user must pass
748 a second argument of 1, because that is what builtin_setjmp will
749 return. This also makes EH slightly more efficient, since we are no
750 longer copying around a value that we don't care about. */
751 gcc_assert (value == const1_rtx);
753 last = get_last_insn ();
754 #ifdef HAVE_builtin_longjmp
755 if (HAVE_builtin_longjmp)
756 emit_insn (gen_builtin_longjmp (buf_addr));
757 else
758 #endif
760 fp = gen_rtx_MEM (Pmode, buf_addr);
761 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
762 GET_MODE_SIZE (Pmode)));
764 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
765 2 * GET_MODE_SIZE (Pmode)));
766 set_mem_alias_set (fp, setjmp_alias_set);
767 set_mem_alias_set (lab, setjmp_alias_set);
768 set_mem_alias_set (stack, setjmp_alias_set);
770 /* Pick up FP, label, and SP from the block and jump. This code is
771 from expand_goto in stmt.c; see there for detailed comments. */
772 #if HAVE_nonlocal_goto
773 if (HAVE_nonlocal_goto)
774 /* We have to pass a value to the nonlocal_goto pattern that will
775 get copied into the static_chain pointer, but it does not matter
776 what that value is, because builtin_setjmp does not use it. */
777 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
778 else
779 #endif
781 lab = copy_to_reg (lab);
783 emit_insn (gen_rtx_CLOBBER (VOIDmode,
784 gen_rtx_MEM (BLKmode,
785 gen_rtx_SCRATCH (VOIDmode))));
786 emit_insn (gen_rtx_CLOBBER (VOIDmode,
787 gen_rtx_MEM (BLKmode,
788 hard_frame_pointer_rtx)));
790 emit_move_insn (hard_frame_pointer_rtx, fp);
791 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
793 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
794 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
795 emit_indirect_jump (lab);
799 /* Search backwards and mark the jump insn as a non-local goto.
800 Note that this precludes the use of __builtin_longjmp to a
801 __builtin_setjmp target in the same function. However, we've
802 already cautioned the user that these functions are for
803 internal exception handling use only. */
804 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
806 gcc_assert (insn != last);
808 if (JUMP_P (insn))
810 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
811 REG_NOTES (insn));
812 break;
814 else if (CALL_P (insn))
815 break;
819 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
820 and the address of the save area. */
822 static rtx
823 expand_builtin_nonlocal_goto (tree arglist)
825 tree t_label, t_save_area;
826 rtx r_label, r_save_area, r_fp, r_sp, insn;
828 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
829 return NULL_RTX;
831 t_label = TREE_VALUE (arglist);
832 arglist = TREE_CHAIN (arglist);
833 t_save_area = TREE_VALUE (arglist);
835 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
836 r_label = convert_memory_address (Pmode, r_label);
837 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
838 r_save_area = convert_memory_address (Pmode, r_save_area);
839 r_fp = gen_rtx_MEM (Pmode, r_save_area);
840 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
841 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
843 current_function_has_nonlocal_goto = 1;
845 #if HAVE_nonlocal_goto
846 /* ??? We no longer need to pass the static chain value, afaik. */
847 if (HAVE_nonlocal_goto)
848 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
849 else
850 #endif
852 r_label = copy_to_reg (r_label);
854 emit_insn (gen_rtx_CLOBBER (VOIDmode,
855 gen_rtx_MEM (BLKmode,
856 gen_rtx_SCRATCH (VOIDmode))));
858 emit_insn (gen_rtx_CLOBBER (VOIDmode,
859 gen_rtx_MEM (BLKmode,
860 hard_frame_pointer_rtx)));
862 /* Restore frame pointer for containing function.
863 This sets the actual hard register used for the frame pointer
864 to the location of the function's incoming static chain info.
865 The non-local goto handler will then adjust it to contain the
866 proper value and reload the argument pointer, if needed. */
867 emit_move_insn (hard_frame_pointer_rtx, r_fp);
868 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
870 /* USE of hard_frame_pointer_rtx added for consistency;
871 not clear if really needed. */
872 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
873 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
874 emit_indirect_jump (r_label);
877 /* Search backwards to the jump insn and mark it as a
878 non-local goto. */
879 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
881 if (JUMP_P (insn))
883 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
884 const0_rtx, REG_NOTES (insn));
885 break;
887 else if (CALL_P (insn))
888 break;
891 return const0_rtx;
894 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
895 (not all will be used on all machines) that was passed to __builtin_setjmp.
896 It updates the stack pointer in that block to correspond to the current
897 stack pointer. */
899 static void
900 expand_builtin_update_setjmp_buf (rtx buf_addr)
902 enum machine_mode sa_mode = Pmode;
903 rtx stack_save;
906 #ifdef HAVE_save_stack_nonlocal
907 if (HAVE_save_stack_nonlocal)
908 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
909 #endif
910 #ifdef STACK_SAVEAREA_MODE
911 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
912 #endif
914 stack_save
915 = gen_rtx_MEM (sa_mode,
916 memory_address
917 (sa_mode,
918 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
920 #ifdef HAVE_setjmp
921 if (HAVE_setjmp)
922 emit_insn (gen_setjmp ());
923 #endif
925 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
928 /* Expand a call to __builtin_prefetch. For a target that does not support
929 data prefetch, evaluate the memory address argument in case it has side
930 effects. */
932 static void
933 expand_builtin_prefetch (tree arglist)
935 tree arg0, arg1, arg2;
936 rtx op0, op1, op2;
938 if (!validate_arglist (arglist, POINTER_TYPE, 0))
939 return;
941 arg0 = TREE_VALUE (arglist);
942 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
943 zero (read) and argument 2 (locality) defaults to 3 (high degree of
944 locality). */
945 if (TREE_CHAIN (arglist))
947 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
948 if (TREE_CHAIN (TREE_CHAIN (arglist)))
949 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
950 else
951 arg2 = build_int_cst (NULL_TREE, 3);
953 else
955 arg1 = integer_zero_node;
956 arg2 = build_int_cst (NULL_TREE, 3);
959 /* Argument 0 is an address. */
960 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
962 /* Argument 1 (read/write flag) must be a compile-time constant int. */
963 if (TREE_CODE (arg1) != INTEGER_CST)
965 error ("second argument to %<__builtin_prefetch%> must be a constant");
966 arg1 = integer_zero_node;
968 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
969 /* Argument 1 must be either zero or one. */
970 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
972 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
973 " using zero");
974 op1 = const0_rtx;
977 /* Argument 2 (locality) must be a compile-time constant int. */
978 if (TREE_CODE (arg2) != INTEGER_CST)
980 error ("third argument to %<__builtin_prefetch%> must be a constant");
981 arg2 = integer_zero_node;
983 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
984 /* Argument 2 must be 0, 1, 2, or 3. */
985 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
987 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
988 op2 = const0_rtx;
991 #ifdef HAVE_prefetch
992 if (HAVE_prefetch)
994 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
995 (op0,
996 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
997 || (GET_MODE (op0) != Pmode))
999 op0 = convert_memory_address (Pmode, op0);
1000 op0 = force_reg (Pmode, op0);
1002 emit_insn (gen_prefetch (op0, op1, op2));
1004 #endif
1006 /* Don't do anything with direct references to volatile memory, but
1007 generate code to handle other side effects. */
1008 if (!MEM_P (op0) && side_effects_p (op0))
1009 emit_insn (op0);
1012 /* Get a MEM rtx for expression EXP which is the address of an operand
1013 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1014 the maximum length of the block of memory that might be accessed or
1015 NULL if unknown. */
1017 static rtx
1018 get_memory_rtx (tree exp, tree len)
1020 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1021 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1023 /* Get an expression we can use to find the attributes to assign to MEM.
1024 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1025 we can. First remove any nops. */
1026 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1027 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1028 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1029 exp = TREE_OPERAND (exp, 0);
1031 if (TREE_CODE (exp) == ADDR_EXPR)
1032 exp = TREE_OPERAND (exp, 0);
1033 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1034 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1035 else
1036 exp = NULL;
1038 /* Honor attributes derived from exp, except for the alias set
1039 (as builtin stringops may alias with anything) and the size
1040 (as stringops may access multiple array elements). */
1041 if (exp)
1043 set_mem_attributes (mem, exp, 0);
1045 /* Allow the string and memory builtins to overflow from one
1046 field into another, see http://gcc.gnu.org/PR23561.
1047 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1048 memory accessed by the string or memory builtin will fit
1049 within the field. */
1050 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1052 tree mem_expr = MEM_EXPR (mem);
1053 HOST_WIDE_INT offset = -1, length = -1;
1054 tree inner = exp;
1056 while (TREE_CODE (inner) == ARRAY_REF
1057 || TREE_CODE (inner) == NOP_EXPR
1058 || TREE_CODE (inner) == CONVERT_EXPR
1059 || TREE_CODE (inner) == NON_LVALUE_EXPR
1060 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1061 || TREE_CODE (inner) == SAVE_EXPR)
1062 inner = TREE_OPERAND (inner, 0);
1064 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1066 if (MEM_OFFSET (mem)
1067 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1068 offset = INTVAL (MEM_OFFSET (mem));
1070 if (offset >= 0 && len && host_integerp (len, 0))
1071 length = tree_low_cst (len, 0);
1073 while (TREE_CODE (inner) == COMPONENT_REF)
1075 tree field = TREE_OPERAND (inner, 1);
1076 gcc_assert (! DECL_BIT_FIELD (field));
1077 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1078 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1080 if (length >= 0
1081 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1082 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1084 HOST_WIDE_INT size
1085 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1086 /* If we can prove the memory starting at XEXP (mem, 0)
1087 and ending at XEXP (mem, 0) + LENGTH will fit into
1088 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1089 if (offset <= size
1090 && length <= size
1091 && offset + length <= size)
1092 break;
1095 if (offset >= 0
1096 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1097 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1098 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1099 / BITS_PER_UNIT;
1100 else
1102 offset = -1;
1103 length = -1;
1106 mem_expr = TREE_OPERAND (mem_expr, 0);
1107 inner = TREE_OPERAND (inner, 0);
1110 if (mem_expr == NULL)
1111 offset = -1;
1112 if (mem_expr != MEM_EXPR (mem))
1114 set_mem_expr (mem, mem_expr);
1115 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1118 set_mem_alias_set (mem, 0);
1119 set_mem_size (mem, NULL_RTX);
1122 return mem;
1125 /* Built-in functions to perform an untyped call and return. */
1127 /* For each register that may be used for calling a function, this
1128 gives a mode used to copy the register's value. VOIDmode indicates
1129 the register is not used for calling a function. If the machine
1130 has register windows, this gives only the outbound registers.
1131 INCOMING_REGNO gives the corresponding inbound register. */
1132 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1134 /* For each register that may be used for returning values, this gives
1135 a mode used to copy the register's value. VOIDmode indicates the
1136 register is not used for returning values. If the machine has
1137 register windows, this gives only the outbound registers.
1138 INCOMING_REGNO gives the corresponding inbound register. */
1139 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1141 /* For each register that may be used for calling a function, this
1142 gives the offset of that register into the block returned by
1143 __builtin_apply_args. 0 indicates that the register is not
1144 used for calling a function. */
1145 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1147 /* Return the size required for the block returned by __builtin_apply_args,
1148 and initialize apply_args_mode. */
1150 static int
1151 apply_args_size (void)
1153 static int size = -1;
1154 int align;
1155 unsigned int regno;
1156 enum machine_mode mode;
1158 /* The values computed by this function never change. */
1159 if (size < 0)
1161 /* The first value is the incoming arg-pointer. */
1162 size = GET_MODE_SIZE (Pmode);
1164 /* The second value is the structure value address unless this is
1165 passed as an "invisible" first argument. */
1166 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1167 size += GET_MODE_SIZE (Pmode);
1169 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1170 if (FUNCTION_ARG_REGNO_P (regno))
1172 mode = reg_raw_mode[regno];
1174 gcc_assert (mode != VOIDmode);
1176 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1177 if (size % align != 0)
1178 size = CEIL (size, align) * align;
1179 apply_args_reg_offset[regno] = size;
1180 size += GET_MODE_SIZE (mode);
1181 apply_args_mode[regno] = mode;
1183 else
1185 apply_args_mode[regno] = VOIDmode;
1186 apply_args_reg_offset[regno] = 0;
1189 return size;
1192 /* Return the size required for the block returned by __builtin_apply,
1193 and initialize apply_result_mode. */
1195 static int
1196 apply_result_size (void)
1198 static int size = -1;
1199 int align, regno;
1200 enum machine_mode mode;
1202 /* The values computed by this function never change. */
1203 if (size < 0)
1205 size = 0;
1207 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1208 if (FUNCTION_VALUE_REGNO_P (regno))
1210 mode = reg_raw_mode[regno];
1212 gcc_assert (mode != VOIDmode);
1214 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1215 if (size % align != 0)
1216 size = CEIL (size, align) * align;
1217 size += GET_MODE_SIZE (mode);
1218 apply_result_mode[regno] = mode;
1220 else
1221 apply_result_mode[regno] = VOIDmode;
1223 /* Allow targets that use untyped_call and untyped_return to override
1224 the size so that machine-specific information can be stored here. */
1225 #ifdef APPLY_RESULT_SIZE
1226 size = APPLY_RESULT_SIZE;
1227 #endif
1229 return size;
1232 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1233 /* Create a vector describing the result block RESULT. If SAVEP is true,
1234 the result block is used to save the values; otherwise it is used to
1235 restore the values. */
1237 static rtx
1238 result_vector (int savep, rtx result)
1240 int regno, size, align, nelts;
1241 enum machine_mode mode;
1242 rtx reg, mem;
1243 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1245 size = nelts = 0;
1246 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1247 if ((mode = apply_result_mode[regno]) != VOIDmode)
1249 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1250 if (size % align != 0)
1251 size = CEIL (size, align) * align;
1252 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1253 mem = adjust_address (result, mode, size);
1254 savevec[nelts++] = (savep
1255 ? gen_rtx_SET (VOIDmode, mem, reg)
1256 : gen_rtx_SET (VOIDmode, reg, mem));
1257 size += GET_MODE_SIZE (mode);
1259 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1261 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1263 /* Save the state required to perform an untyped call with the same
1264 arguments as were passed to the current function. */
1266 static rtx
1267 expand_builtin_apply_args_1 (void)
1269 rtx registers, tem;
1270 int size, align, regno;
1271 enum machine_mode mode;
1272 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1274 /* Create a block where the arg-pointer, structure value address,
1275 and argument registers can be saved. */
1276 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1278 /* Walk past the arg-pointer and structure value address. */
1279 size = GET_MODE_SIZE (Pmode);
1280 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1281 size += GET_MODE_SIZE (Pmode);
1283 /* Save each register used in calling a function to the block. */
1284 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1285 if ((mode = apply_args_mode[regno]) != VOIDmode)
1287 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1288 if (size % align != 0)
1289 size = CEIL (size, align) * align;
1291 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1293 emit_move_insn (adjust_address (registers, mode, size), tem);
1294 size += GET_MODE_SIZE (mode);
1297 /* Save the arg pointer to the block. */
1298 tem = copy_to_reg (virtual_incoming_args_rtx);
1299 #ifdef STACK_GROWS_DOWNWARD
1300 /* We need the pointer as the caller actually passed them to us, not
1301 as we might have pretended they were passed. Make sure it's a valid
1302 operand, as emit_move_insn isn't expected to handle a PLUS. */
1304 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1305 NULL_RTX);
1306 #endif
1307 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1309 size = GET_MODE_SIZE (Pmode);
1311 /* Save the structure value address unless this is passed as an
1312 "invisible" first argument. */
1313 if (struct_incoming_value)
1315 emit_move_insn (adjust_address (registers, Pmode, size),
1316 copy_to_reg (struct_incoming_value));
1317 size += GET_MODE_SIZE (Pmode);
1320 /* Return the address of the block. */
1321 return copy_addr_to_reg (XEXP (registers, 0));
1324 /* __builtin_apply_args returns block of memory allocated on
1325 the stack into which is stored the arg pointer, structure
1326 value address, static chain, and all the registers that might
1327 possibly be used in performing a function call. The code is
1328 moved to the start of the function so the incoming values are
1329 saved. */
1331 static rtx
1332 expand_builtin_apply_args (void)
1334 /* Don't do __builtin_apply_args more than once in a function.
1335 Save the result of the first call and reuse it. */
1336 if (apply_args_value != 0)
1337 return apply_args_value;
1339 /* When this function is called, it means that registers must be
1340 saved on entry to this function. So we migrate the
1341 call to the first insn of this function. */
1342 rtx temp;
1343 rtx seq;
1345 start_sequence ();
1346 temp = expand_builtin_apply_args_1 ();
1347 seq = get_insns ();
1348 end_sequence ();
1350 apply_args_value = temp;
1352 /* Put the insns after the NOTE that starts the function.
1353 If this is inside a start_sequence, make the outer-level insn
1354 chain current, so the code is placed at the start of the
1355 function. */
1356 push_topmost_sequence ();
1357 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1358 pop_topmost_sequence ();
1359 return temp;
1363 /* Perform an untyped call and save the state required to perform an
1364 untyped return of whatever value was returned by the given function. */
1366 static rtx
1367 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1369 int size, align, regno;
1370 enum machine_mode mode;
1371 rtx incoming_args, result, reg, dest, src, call_insn;
1372 rtx old_stack_level = 0;
1373 rtx call_fusage = 0;
1374 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1376 arguments = convert_memory_address (Pmode, arguments);
1378 /* Create a block where the return registers can be saved. */
1379 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1381 /* Fetch the arg pointer from the ARGUMENTS block. */
1382 incoming_args = gen_reg_rtx (Pmode);
1383 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1384 #ifndef STACK_GROWS_DOWNWARD
1385 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1386 incoming_args, 0, OPTAB_LIB_WIDEN);
1387 #endif
1389 /* Push a new argument block and copy the arguments. Do not allow
1390 the (potential) memcpy call below to interfere with our stack
1391 manipulations. */
1392 do_pending_stack_adjust ();
1393 NO_DEFER_POP;
1395 /* Save the stack with nonlocal if available. */
1396 #ifdef HAVE_save_stack_nonlocal
1397 if (HAVE_save_stack_nonlocal)
1398 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1399 else
1400 #endif
1401 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1403 /* Allocate a block of memory onto the stack and copy the memory
1404 arguments to the outgoing arguments address. */
1405 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1406 dest = virtual_outgoing_args_rtx;
1407 #ifndef STACK_GROWS_DOWNWARD
1408 if (GET_CODE (argsize) == CONST_INT)
1409 dest = plus_constant (dest, -INTVAL (argsize));
1410 else
1411 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1412 #endif
1413 dest = gen_rtx_MEM (BLKmode, dest);
1414 set_mem_align (dest, PARM_BOUNDARY);
1415 src = gen_rtx_MEM (BLKmode, incoming_args);
1416 set_mem_align (src, PARM_BOUNDARY);
1417 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1419 /* Refer to the argument block. */
1420 apply_args_size ();
1421 arguments = gen_rtx_MEM (BLKmode, arguments);
1422 set_mem_align (arguments, PARM_BOUNDARY);
1424 /* Walk past the arg-pointer and structure value address. */
1425 size = GET_MODE_SIZE (Pmode);
1426 if (struct_value)
1427 size += GET_MODE_SIZE (Pmode);
1429 /* Restore each of the registers previously saved. Make USE insns
1430 for each of these registers for use in making the call. */
1431 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1432 if ((mode = apply_args_mode[regno]) != VOIDmode)
1434 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1435 if (size % align != 0)
1436 size = CEIL (size, align) * align;
1437 reg = gen_rtx_REG (mode, regno);
1438 emit_move_insn (reg, adjust_address (arguments, mode, size));
1439 use_reg (&call_fusage, reg);
1440 size += GET_MODE_SIZE (mode);
1443 /* Restore the structure value address unless this is passed as an
1444 "invisible" first argument. */
1445 size = GET_MODE_SIZE (Pmode);
1446 if (struct_value)
1448 rtx value = gen_reg_rtx (Pmode);
1449 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1450 emit_move_insn (struct_value, value);
1451 if (REG_P (struct_value))
1452 use_reg (&call_fusage, struct_value);
1453 size += GET_MODE_SIZE (Pmode);
1456 /* All arguments and registers used for the call are set up by now! */
1457 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1459 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1460 and we don't want to load it into a register as an optimization,
1461 because prepare_call_address already did it if it should be done. */
1462 if (GET_CODE (function) != SYMBOL_REF)
1463 function = memory_address (FUNCTION_MODE, function);
1465 /* Generate the actual call instruction and save the return value. */
1466 #ifdef HAVE_untyped_call
1467 if (HAVE_untyped_call)
1468 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1469 result, result_vector (1, result)));
1470 else
1471 #endif
1472 #ifdef HAVE_call_value
1473 if (HAVE_call_value)
1475 rtx valreg = 0;
1477 /* Locate the unique return register. It is not possible to
1478 express a call that sets more than one return register using
1479 call_value; use untyped_call for that. In fact, untyped_call
1480 only needs to save the return registers in the given block. */
1481 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1482 if ((mode = apply_result_mode[regno]) != VOIDmode)
1484 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1486 valreg = gen_rtx_REG (mode, regno);
1489 emit_call_insn (GEN_CALL_VALUE (valreg,
1490 gen_rtx_MEM (FUNCTION_MODE, function),
1491 const0_rtx, NULL_RTX, const0_rtx));
1493 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1495 else
1496 #endif
1497 gcc_unreachable ();
1499 /* Find the CALL insn we just emitted, and attach the register usage
1500 information. */
1501 call_insn = last_call_insn ();
1502 add_function_usage_to (call_insn, call_fusage);
1504 /* Restore the stack. */
1505 #ifdef HAVE_save_stack_nonlocal
1506 if (HAVE_save_stack_nonlocal)
1507 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1508 else
1509 #endif
1510 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1512 OK_DEFER_POP;
1514 /* Return the address of the result block. */
1515 result = copy_addr_to_reg (XEXP (result, 0));
1516 return convert_memory_address (ptr_mode, result);
1519 /* Perform an untyped return. */
1521 static void
1522 expand_builtin_return (rtx result)
1524 int size, align, regno;
1525 enum machine_mode mode;
1526 rtx reg;
1527 rtx call_fusage = 0;
1529 result = convert_memory_address (Pmode, result);
1531 apply_result_size ();
1532 result = gen_rtx_MEM (BLKmode, result);
1534 #ifdef HAVE_untyped_return
1535 if (HAVE_untyped_return)
1537 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1538 emit_barrier ();
1539 return;
1541 #endif
1543 /* Restore the return value and note that each value is used. */
1544 size = 0;
1545 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1546 if ((mode = apply_result_mode[regno]) != VOIDmode)
1548 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1549 if (size % align != 0)
1550 size = CEIL (size, align) * align;
1551 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1552 emit_move_insn (reg, adjust_address (result, mode, size));
1554 push_to_sequence (call_fusage);
1555 emit_insn (gen_rtx_USE (VOIDmode, reg));
1556 call_fusage = get_insns ();
1557 end_sequence ();
1558 size += GET_MODE_SIZE (mode);
1561 /* Put the USE insns before the return. */
1562 emit_insn (call_fusage);
1564 /* Return whatever values was restored by jumping directly to the end
1565 of the function. */
1566 expand_naked_return ();
1569 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1571 static enum type_class
1572 type_to_class (tree type)
1574 switch (TREE_CODE (type))
1576 case VOID_TYPE: return void_type_class;
1577 case INTEGER_TYPE: return integer_type_class;
1578 case CHAR_TYPE: return char_type_class;
1579 case ENUMERAL_TYPE: return enumeral_type_class;
1580 case BOOLEAN_TYPE: return boolean_type_class;
1581 case POINTER_TYPE: return pointer_type_class;
1582 case REFERENCE_TYPE: return reference_type_class;
1583 case OFFSET_TYPE: return offset_type_class;
1584 case REAL_TYPE: return real_type_class;
1585 case COMPLEX_TYPE: return complex_type_class;
1586 case FUNCTION_TYPE: return function_type_class;
1587 case METHOD_TYPE: return method_type_class;
1588 case RECORD_TYPE: return record_type_class;
1589 case UNION_TYPE:
1590 case QUAL_UNION_TYPE: return union_type_class;
1591 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1592 ? string_type_class : array_type_class);
1593 case LANG_TYPE: return lang_type_class;
1594 default: return no_type_class;
1598 /* Expand a call to __builtin_classify_type with arguments found in
1599 ARGLIST. */
1601 static rtx
1602 expand_builtin_classify_type (tree arglist)
1604 if (arglist != 0)
1605 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1606 return GEN_INT (no_type_class);
1609 /* This helper macro, meant to be used in mathfn_built_in below,
1610 determines which among a set of three builtin math functions is
1611 appropriate for a given type mode. The `F' and `L' cases are
1612 automatically generated from the `double' case. */
1613 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1614 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1615 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1616 fcodel = BUILT_IN_MATHFN##L ; break;
1618 /* Return mathematic function equivalent to FN but operating directly
1619 on TYPE, if available. If we can't do the conversion, return zero. */
1620 tree
1621 mathfn_built_in (tree type, enum built_in_function fn)
1623 enum built_in_function fcode, fcodef, fcodel;
1625 switch (fn)
1627 CASE_MATHFN (BUILT_IN_ACOS)
1628 CASE_MATHFN (BUILT_IN_ACOSH)
1629 CASE_MATHFN (BUILT_IN_ASIN)
1630 CASE_MATHFN (BUILT_IN_ASINH)
1631 CASE_MATHFN (BUILT_IN_ATAN)
1632 CASE_MATHFN (BUILT_IN_ATAN2)
1633 CASE_MATHFN (BUILT_IN_ATANH)
1634 CASE_MATHFN (BUILT_IN_CBRT)
1635 CASE_MATHFN (BUILT_IN_CEIL)
1636 CASE_MATHFN (BUILT_IN_COPYSIGN)
1637 CASE_MATHFN (BUILT_IN_COS)
1638 CASE_MATHFN (BUILT_IN_COSH)
1639 CASE_MATHFN (BUILT_IN_DREM)
1640 CASE_MATHFN (BUILT_IN_ERF)
1641 CASE_MATHFN (BUILT_IN_ERFC)
1642 CASE_MATHFN (BUILT_IN_EXP)
1643 CASE_MATHFN (BUILT_IN_EXP10)
1644 CASE_MATHFN (BUILT_IN_EXP2)
1645 CASE_MATHFN (BUILT_IN_EXPM1)
1646 CASE_MATHFN (BUILT_IN_FABS)
1647 CASE_MATHFN (BUILT_IN_FDIM)
1648 CASE_MATHFN (BUILT_IN_FLOOR)
1649 CASE_MATHFN (BUILT_IN_FMA)
1650 CASE_MATHFN (BUILT_IN_FMAX)
1651 CASE_MATHFN (BUILT_IN_FMIN)
1652 CASE_MATHFN (BUILT_IN_FMOD)
1653 CASE_MATHFN (BUILT_IN_FREXP)
1654 CASE_MATHFN (BUILT_IN_GAMMA)
1655 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1656 CASE_MATHFN (BUILT_IN_HYPOT)
1657 CASE_MATHFN (BUILT_IN_ILOGB)
1658 CASE_MATHFN (BUILT_IN_INF)
1659 CASE_MATHFN (BUILT_IN_J0)
1660 CASE_MATHFN (BUILT_IN_J1)
1661 CASE_MATHFN (BUILT_IN_JN)
1662 CASE_MATHFN (BUILT_IN_LCEIL)
1663 CASE_MATHFN (BUILT_IN_LDEXP)
1664 CASE_MATHFN (BUILT_IN_LFLOOR)
1665 CASE_MATHFN (BUILT_IN_LGAMMA)
1666 CASE_MATHFN (BUILT_IN_LLCEIL)
1667 CASE_MATHFN (BUILT_IN_LLFLOOR)
1668 CASE_MATHFN (BUILT_IN_LLRINT)
1669 CASE_MATHFN (BUILT_IN_LLROUND)
1670 CASE_MATHFN (BUILT_IN_LOG)
1671 CASE_MATHFN (BUILT_IN_LOG10)
1672 CASE_MATHFN (BUILT_IN_LOG1P)
1673 CASE_MATHFN (BUILT_IN_LOG2)
1674 CASE_MATHFN (BUILT_IN_LOGB)
1675 CASE_MATHFN (BUILT_IN_LRINT)
1676 CASE_MATHFN (BUILT_IN_LROUND)
1677 CASE_MATHFN (BUILT_IN_MODF)
1678 CASE_MATHFN (BUILT_IN_NAN)
1679 CASE_MATHFN (BUILT_IN_NANS)
1680 CASE_MATHFN (BUILT_IN_NEARBYINT)
1681 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1682 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1683 CASE_MATHFN (BUILT_IN_POW)
1684 CASE_MATHFN (BUILT_IN_POWI)
1685 CASE_MATHFN (BUILT_IN_POW10)
1686 CASE_MATHFN (BUILT_IN_REMAINDER)
1687 CASE_MATHFN (BUILT_IN_REMQUO)
1688 CASE_MATHFN (BUILT_IN_RINT)
1689 CASE_MATHFN (BUILT_IN_ROUND)
1690 CASE_MATHFN (BUILT_IN_SCALB)
1691 CASE_MATHFN (BUILT_IN_SCALBLN)
1692 CASE_MATHFN (BUILT_IN_SCALBN)
1693 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1694 CASE_MATHFN (BUILT_IN_SIN)
1695 CASE_MATHFN (BUILT_IN_SINCOS)
1696 CASE_MATHFN (BUILT_IN_SINH)
1697 CASE_MATHFN (BUILT_IN_SQRT)
1698 CASE_MATHFN (BUILT_IN_TAN)
1699 CASE_MATHFN (BUILT_IN_TANH)
1700 CASE_MATHFN (BUILT_IN_TGAMMA)
1701 CASE_MATHFN (BUILT_IN_TRUNC)
1702 CASE_MATHFN (BUILT_IN_Y0)
1703 CASE_MATHFN (BUILT_IN_Y1)
1704 CASE_MATHFN (BUILT_IN_YN)
1706 default:
1707 return 0;
1710 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1711 return implicit_built_in_decls[fcode];
1712 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1713 return implicit_built_in_decls[fcodef];
1714 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1715 return implicit_built_in_decls[fcodel];
1716 else
1717 return 0;
1720 /* If errno must be maintained, expand the RTL to check if the result,
1721 TARGET, of a built-in function call, EXP, is NaN, and if so set
1722 errno to EDOM. */
1724 static void
1725 expand_errno_check (tree exp, rtx target)
1727 rtx lab = gen_label_rtx ();
1729 /* Test the result; if it is NaN, set errno=EDOM because
1730 the argument was not in the domain. */
1731 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1732 0, lab);
1734 #ifdef TARGET_EDOM
1735 /* If this built-in doesn't throw an exception, set errno directly. */
1736 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1738 #ifdef GEN_ERRNO_RTX
1739 rtx errno_rtx = GEN_ERRNO_RTX;
1740 #else
1741 rtx errno_rtx
1742 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1743 #endif
1744 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1745 emit_label (lab);
1746 return;
1748 #endif
1750 /* We can't set errno=EDOM directly; let the library call do it.
1751 Pop the arguments right away in case the call gets deleted. */
1752 NO_DEFER_POP;
1753 expand_call (exp, target, 0);
1754 OK_DEFER_POP;
1755 emit_label (lab);
1759 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1760 Return 0 if a normal call should be emitted rather than expanding the
1761 function in-line. EXP is the expression that is a call to the builtin
1762 function; if convenient, the result should be placed in TARGET.
1763 SUBTARGET may be used as the target for computing one of EXP's operands. */
1765 static rtx
1766 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1768 optab builtin_optab;
1769 rtx op0, insns, before_call;
1770 tree fndecl = get_callee_fndecl (exp);
1771 tree arglist = TREE_OPERAND (exp, 1);
1772 enum machine_mode mode;
1773 bool errno_set = false;
1774 tree arg, narg;
1776 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1777 return 0;
1779 arg = TREE_VALUE (arglist);
1781 switch (DECL_FUNCTION_CODE (fndecl))
1783 case BUILT_IN_SQRT:
1784 case BUILT_IN_SQRTF:
1785 case BUILT_IN_SQRTL:
1786 errno_set = ! tree_expr_nonnegative_p (arg);
1787 builtin_optab = sqrt_optab;
1788 break;
1789 case BUILT_IN_EXP:
1790 case BUILT_IN_EXPF:
1791 case BUILT_IN_EXPL:
1792 errno_set = true; builtin_optab = exp_optab; break;
1793 case BUILT_IN_EXP10:
1794 case BUILT_IN_EXP10F:
1795 case BUILT_IN_EXP10L:
1796 case BUILT_IN_POW10:
1797 case BUILT_IN_POW10F:
1798 case BUILT_IN_POW10L:
1799 errno_set = true; builtin_optab = exp10_optab; break;
1800 case BUILT_IN_EXP2:
1801 case BUILT_IN_EXP2F:
1802 case BUILT_IN_EXP2L:
1803 errno_set = true; builtin_optab = exp2_optab; break;
1804 case BUILT_IN_EXPM1:
1805 case BUILT_IN_EXPM1F:
1806 case BUILT_IN_EXPM1L:
1807 errno_set = true; builtin_optab = expm1_optab; break;
1808 case BUILT_IN_LOGB:
1809 case BUILT_IN_LOGBF:
1810 case BUILT_IN_LOGBL:
1811 errno_set = true; builtin_optab = logb_optab; break;
1812 case BUILT_IN_ILOGB:
1813 case BUILT_IN_ILOGBF:
1814 case BUILT_IN_ILOGBL:
1815 errno_set = true; builtin_optab = ilogb_optab; break;
1816 case BUILT_IN_LOG:
1817 case BUILT_IN_LOGF:
1818 case BUILT_IN_LOGL:
1819 errno_set = true; builtin_optab = log_optab; break;
1820 case BUILT_IN_LOG10:
1821 case BUILT_IN_LOG10F:
1822 case BUILT_IN_LOG10L:
1823 errno_set = true; builtin_optab = log10_optab; break;
1824 case BUILT_IN_LOG2:
1825 case BUILT_IN_LOG2F:
1826 case BUILT_IN_LOG2L:
1827 errno_set = true; builtin_optab = log2_optab; break;
1828 case BUILT_IN_LOG1P:
1829 case BUILT_IN_LOG1PF:
1830 case BUILT_IN_LOG1PL:
1831 errno_set = true; builtin_optab = log1p_optab; break;
1832 case BUILT_IN_ASIN:
1833 case BUILT_IN_ASINF:
1834 case BUILT_IN_ASINL:
1835 builtin_optab = asin_optab; break;
1836 case BUILT_IN_ACOS:
1837 case BUILT_IN_ACOSF:
1838 case BUILT_IN_ACOSL:
1839 builtin_optab = acos_optab; break;
1840 case BUILT_IN_TAN:
1841 case BUILT_IN_TANF:
1842 case BUILT_IN_TANL:
1843 builtin_optab = tan_optab; break;
1844 case BUILT_IN_ATAN:
1845 case BUILT_IN_ATANF:
1846 case BUILT_IN_ATANL:
1847 builtin_optab = atan_optab; break;
1848 case BUILT_IN_FLOOR:
1849 case BUILT_IN_FLOORF:
1850 case BUILT_IN_FLOORL:
1851 builtin_optab = floor_optab; break;
1852 case BUILT_IN_CEIL:
1853 case BUILT_IN_CEILF:
1854 case BUILT_IN_CEILL:
1855 builtin_optab = ceil_optab; break;
1856 case BUILT_IN_TRUNC:
1857 case BUILT_IN_TRUNCF:
1858 case BUILT_IN_TRUNCL:
1859 builtin_optab = btrunc_optab; break;
1860 case BUILT_IN_ROUND:
1861 case BUILT_IN_ROUNDF:
1862 case BUILT_IN_ROUNDL:
1863 builtin_optab = round_optab; break;
1864 case BUILT_IN_NEARBYINT:
1865 case BUILT_IN_NEARBYINTF:
1866 case BUILT_IN_NEARBYINTL:
1867 builtin_optab = nearbyint_optab; break;
1868 case BUILT_IN_RINT:
1869 case BUILT_IN_RINTF:
1870 case BUILT_IN_RINTL:
1871 builtin_optab = rint_optab; break;
1872 case BUILT_IN_LRINT:
1873 case BUILT_IN_LRINTF:
1874 case BUILT_IN_LRINTL:
1875 case BUILT_IN_LLRINT:
1876 case BUILT_IN_LLRINTF:
1877 case BUILT_IN_LLRINTL:
1878 builtin_optab = lrint_optab; break;
1879 default:
1880 gcc_unreachable ();
1883 /* Make a suitable register to place result in. */
1884 mode = TYPE_MODE (TREE_TYPE (exp));
1886 if (! flag_errno_math || ! HONOR_NANS (mode))
1887 errno_set = false;
1889 /* Before working hard, check whether the instruction is available. */
1890 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1892 target = gen_reg_rtx (mode);
1894 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1895 need to expand the argument again. This way, we will not perform
1896 side-effects more the once. */
1897 narg = builtin_save_expr (arg);
1898 if (narg != arg)
1900 arg = narg;
1901 arglist = build_tree_list (NULL_TREE, arg);
1902 exp = build_function_call_expr (fndecl, arglist);
1905 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1907 start_sequence ();
1909 /* Compute into TARGET.
1910 Set TARGET to wherever the result comes back. */
1911 target = expand_unop (mode, builtin_optab, op0, target, 0);
1913 if (target != 0)
1915 if (errno_set)
1916 expand_errno_check (exp, target);
1918 /* Output the entire sequence. */
1919 insns = get_insns ();
1920 end_sequence ();
1921 emit_insn (insns);
1922 return target;
1925 /* If we were unable to expand via the builtin, stop the sequence
1926 (without outputting the insns) and call to the library function
1927 with the stabilized argument list. */
1928 end_sequence ();
1931 before_call = get_last_insn ();
1933 target = expand_call (exp, target, target == const0_rtx);
1935 /* If this is a sqrt operation and we don't care about errno, try to
1936 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1937 This allows the semantics of the libcall to be visible to the RTL
1938 optimizers. */
1939 if (builtin_optab == sqrt_optab && !errno_set)
1941 /* Search backwards through the insns emitted by expand_call looking
1942 for the instruction with the REG_RETVAL note. */
1943 rtx last = get_last_insn ();
1944 while (last != before_call)
1946 if (find_reg_note (last, REG_RETVAL, NULL))
1948 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1949 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1950 two elements, i.e. symbol_ref(sqrt) and the operand. */
1951 if (note
1952 && GET_CODE (note) == EXPR_LIST
1953 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1954 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1955 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1957 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1958 /* Check operand is a register with expected mode. */
1959 if (operand
1960 && REG_P (operand)
1961 && GET_MODE (operand) == mode)
1963 /* Replace the REG_EQUAL note with a SQRT rtx. */
1964 rtx equiv = gen_rtx_SQRT (mode, operand);
1965 set_unique_reg_note (last, REG_EQUAL, equiv);
1968 break;
1970 last = PREV_INSN (last);
1974 return target;
1977 /* Expand a call to the builtin binary math functions (pow and atan2).
1978 Return 0 if a normal call should be emitted rather than expanding the
1979 function in-line. EXP is the expression that is a call to the builtin
1980 function; if convenient, the result should be placed in TARGET.
1981 SUBTARGET may be used as the target for computing one of EXP's
1982 operands. */
1984 static rtx
1985 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1987 optab builtin_optab;
1988 rtx op0, op1, insns;
1989 int op1_type = REAL_TYPE;
1990 tree fndecl = get_callee_fndecl (exp);
1991 tree arglist = TREE_OPERAND (exp, 1);
1992 tree arg0, arg1, temp, narg;
1993 enum machine_mode mode;
1994 bool errno_set = true;
1995 bool stable = true;
1997 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1998 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1999 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2000 op1_type = INTEGER_TYPE;
2002 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2003 return 0;
2005 arg0 = TREE_VALUE (arglist);
2006 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2008 switch (DECL_FUNCTION_CODE (fndecl))
2010 case BUILT_IN_POW:
2011 case BUILT_IN_POWF:
2012 case BUILT_IN_POWL:
2013 builtin_optab = pow_optab; break;
2014 case BUILT_IN_ATAN2:
2015 case BUILT_IN_ATAN2F:
2016 case BUILT_IN_ATAN2L:
2017 builtin_optab = atan2_optab; break;
2018 case BUILT_IN_LDEXP:
2019 case BUILT_IN_LDEXPF:
2020 case BUILT_IN_LDEXPL:
2021 builtin_optab = ldexp_optab; break;
2022 case BUILT_IN_FMOD:
2023 case BUILT_IN_FMODF:
2024 case BUILT_IN_FMODL:
2025 builtin_optab = fmod_optab; break;
2026 case BUILT_IN_DREM:
2027 case BUILT_IN_DREMF:
2028 case BUILT_IN_DREML:
2029 builtin_optab = drem_optab; break;
2030 default:
2031 gcc_unreachable ();
2034 /* Make a suitable register to place result in. */
2035 mode = TYPE_MODE (TREE_TYPE (exp));
2037 /* Before working hard, check whether the instruction is available. */
2038 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2039 return 0;
2041 target = gen_reg_rtx (mode);
2043 if (! flag_errno_math || ! HONOR_NANS (mode))
2044 errno_set = false;
2046 /* Always stabilize the argument list. */
2047 narg = builtin_save_expr (arg1);
2048 if (narg != arg1)
2050 arg1 = narg;
2051 temp = build_tree_list (NULL_TREE, narg);
2052 stable = false;
2054 else
2055 temp = TREE_CHAIN (arglist);
2057 narg = builtin_save_expr (arg0);
2058 if (narg != arg0)
2060 arg0 = narg;
2061 arglist = tree_cons (NULL_TREE, narg, temp);
2062 stable = false;
2064 else if (! stable)
2065 arglist = tree_cons (NULL_TREE, arg0, temp);
2067 if (! stable)
2068 exp = build_function_call_expr (fndecl, arglist);
2070 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2071 op1 = expand_expr (arg1, 0, VOIDmode, 0);
2073 start_sequence ();
2075 /* Compute into TARGET.
2076 Set TARGET to wherever the result comes back. */
2077 target = expand_binop (mode, builtin_optab, op0, op1,
2078 target, 0, OPTAB_DIRECT);
2080 /* If we were unable to expand via the builtin, stop the sequence
2081 (without outputting the insns) and call to the library function
2082 with the stabilized argument list. */
2083 if (target == 0)
2085 end_sequence ();
2086 return expand_call (exp, target, target == const0_rtx);
2089 if (errno_set)
2090 expand_errno_check (exp, target);
2092 /* Output the entire sequence. */
2093 insns = get_insns ();
2094 end_sequence ();
2095 emit_insn (insns);
2097 return target;
2100 /* Expand a call to the builtin sin and cos math functions.
2101 Return 0 if a normal call should be emitted rather than expanding the
2102 function in-line. EXP is the expression that is a call to the builtin
2103 function; if convenient, the result should be placed in TARGET.
2104 SUBTARGET may be used as the target for computing one of EXP's
2105 operands. */
2107 static rtx
2108 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2110 optab builtin_optab;
2111 rtx op0, insns;
2112 tree fndecl = get_callee_fndecl (exp);
2113 tree arglist = TREE_OPERAND (exp, 1);
2114 enum machine_mode mode;
2115 bool errno_set = false;
2116 tree arg, narg;
2118 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2119 return 0;
2121 arg = TREE_VALUE (arglist);
2123 switch (DECL_FUNCTION_CODE (fndecl))
2125 case BUILT_IN_SIN:
2126 case BUILT_IN_SINF:
2127 case BUILT_IN_SINL:
2128 case BUILT_IN_COS:
2129 case BUILT_IN_COSF:
2130 case BUILT_IN_COSL:
2131 builtin_optab = sincos_optab; break;
2132 default:
2133 gcc_unreachable ();
2136 /* Make a suitable register to place result in. */
2137 mode = TYPE_MODE (TREE_TYPE (exp));
2139 if (! flag_errno_math || ! HONOR_NANS (mode))
2140 errno_set = false;
2142 /* Check if sincos insn is available, otherwise fallback
2143 to sin or cos insn. */
2144 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2145 switch (DECL_FUNCTION_CODE (fndecl))
2147 case BUILT_IN_SIN:
2148 case BUILT_IN_SINF:
2149 case BUILT_IN_SINL:
2150 builtin_optab = sin_optab; break;
2151 case BUILT_IN_COS:
2152 case BUILT_IN_COSF:
2153 case BUILT_IN_COSL:
2154 builtin_optab = cos_optab; break;
2155 default:
2156 gcc_unreachable ();
2160 /* Before working hard, check whether the instruction is available. */
2161 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2163 target = gen_reg_rtx (mode);
2165 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2166 need to expand the argument again. This way, we will not perform
2167 side-effects more the once. */
2168 narg = save_expr (arg);
2169 if (narg != arg)
2171 arg = narg;
2172 arglist = build_tree_list (NULL_TREE, arg);
2173 exp = build_function_call_expr (fndecl, arglist);
2176 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2178 start_sequence ();
2180 /* Compute into TARGET.
2181 Set TARGET to wherever the result comes back. */
2182 if (builtin_optab == sincos_optab)
2184 int result;
2186 switch (DECL_FUNCTION_CODE (fndecl))
2188 case BUILT_IN_SIN:
2189 case BUILT_IN_SINF:
2190 case BUILT_IN_SINL:
2191 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2192 break;
2193 case BUILT_IN_COS:
2194 case BUILT_IN_COSF:
2195 case BUILT_IN_COSL:
2196 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2197 break;
2198 default:
2199 gcc_unreachable ();
2201 gcc_assert (result);
2203 else
2205 target = expand_unop (mode, builtin_optab, op0, target, 0);
2208 if (target != 0)
2210 if (errno_set)
2211 expand_errno_check (exp, target);
2213 /* Output the entire sequence. */
2214 insns = get_insns ();
2215 end_sequence ();
2216 emit_insn (insns);
2217 return target;
2220 /* If we were unable to expand via the builtin, stop the sequence
2221 (without outputting the insns) and call to the library function
2222 with the stabilized argument list. */
2223 end_sequence ();
2226 target = expand_call (exp, target, target == const0_rtx);
2228 return target;
2231 /* Expand a call to one of the builtin rounding functions (lfloor).
2232 If expanding via optab fails, lower expression to (int)(floor(x)).
2233 EXP is the expression that is a call to the builtin function;
2234 if convenient, the result should be placed in TARGET. SUBTARGET may
2235 be used as the target for computing one of EXP's operands. */
2237 static rtx
2238 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2240 optab builtin_optab;
2241 rtx op0, insns, tmp;
2242 tree fndecl = get_callee_fndecl (exp);
2243 tree arglist = TREE_OPERAND (exp, 1);
2244 enum built_in_function fallback_fn;
2245 tree fallback_fndecl;
2246 enum machine_mode mode;
2247 tree arg, narg;
2249 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2250 gcc_unreachable ();
2252 arg = TREE_VALUE (arglist);
2254 switch (DECL_FUNCTION_CODE (fndecl))
2256 case BUILT_IN_LCEIL:
2257 case BUILT_IN_LCEILF:
2258 case BUILT_IN_LCEILL:
2259 case BUILT_IN_LLCEIL:
2260 case BUILT_IN_LLCEILF:
2261 case BUILT_IN_LLCEILL:
2262 builtin_optab = lceil_optab;
2263 fallback_fn = BUILT_IN_CEIL;
2264 break;
2266 case BUILT_IN_LFLOOR:
2267 case BUILT_IN_LFLOORF:
2268 case BUILT_IN_LFLOORL:
2269 case BUILT_IN_LLFLOOR:
2270 case BUILT_IN_LLFLOORF:
2271 case BUILT_IN_LLFLOORL:
2272 builtin_optab = lfloor_optab;
2273 fallback_fn = BUILT_IN_FLOOR;
2274 break;
2276 default:
2277 gcc_unreachable ();
2280 /* Make a suitable register to place result in. */
2281 mode = TYPE_MODE (TREE_TYPE (exp));
2283 /* Before working hard, check whether the instruction is available. */
2284 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2286 target = gen_reg_rtx (mode);
2288 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2289 need to expand the argument again. This way, we will not perform
2290 side-effects more the once. */
2291 narg = builtin_save_expr (arg);
2292 if (narg != arg)
2294 arg = narg;
2295 arglist = build_tree_list (NULL_TREE, arg);
2296 exp = build_function_call_expr (fndecl, arglist);
2299 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2301 start_sequence ();
2303 /* Compute into TARGET.
2304 Set TARGET to wherever the result comes back. */
2305 target = expand_unop (mode, builtin_optab, op0, target, 0);
2307 if (target != 0)
2309 /* Output the entire sequence. */
2310 insns = get_insns ();
2311 end_sequence ();
2312 emit_insn (insns);
2313 return target;
2316 /* If we were unable to expand via the builtin, stop the sequence
2317 (without outputting the insns). */
2318 end_sequence ();
2321 /* Fall back to floating point rounding optab. */
2322 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2323 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2324 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2325 gcc_assert (fallback_fndecl != NULL_TREE);
2326 exp = build_function_call_expr (fallback_fndecl, arglist);
2328 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2330 /* Truncate the result of floating point optab to integer
2331 via expand_fix (). */
2332 target = gen_reg_rtx (mode);
2333 expand_fix (target, tmp, 0);
2335 return target;
2338 /* To evaluate powi(x,n), the floating point value x raised to the
2339 constant integer exponent n, we use a hybrid algorithm that
2340 combines the "window method" with look-up tables. For an
2341 introduction to exponentiation algorithms and "addition chains",
2342 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2343 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2344 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2345 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2347 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2348 multiplications to inline before calling the system library's pow
2349 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2350 so this default never requires calling pow, powf or powl. */
2352 #ifndef POWI_MAX_MULTS
2353 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2354 #endif
2356 /* The size of the "optimal power tree" lookup table. All
2357 exponents less than this value are simply looked up in the
2358 powi_table below. This threshold is also used to size the
2359 cache of pseudo registers that hold intermediate results. */
2360 #define POWI_TABLE_SIZE 256
2362 /* The size, in bits of the window, used in the "window method"
2363 exponentiation algorithm. This is equivalent to a radix of
2364 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2365 #define POWI_WINDOW_SIZE 3
2367 /* The following table is an efficient representation of an
2368 "optimal power tree". For each value, i, the corresponding
2369 value, j, in the table states than an optimal evaluation
2370 sequence for calculating pow(x,i) can be found by evaluating
2371 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2372 100 integers is given in Knuth's "Seminumerical algorithms". */
2374 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2376 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2377 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2378 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2379 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2380 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2381 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2382 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2383 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2384 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2385 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2386 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2387 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2388 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2389 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2390 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2391 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2392 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2393 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2394 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2395 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2396 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2397 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2398 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2399 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2400 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2401 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2402 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2403 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2404 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2405 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2406 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2407 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2411 /* Return the number of multiplications required to calculate
2412 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2413 subroutine of powi_cost. CACHE is an array indicating
2414 which exponents have already been calculated. */
2416 static int
2417 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2419 /* If we've already calculated this exponent, then this evaluation
2420 doesn't require any additional multiplications. */
2421 if (cache[n])
2422 return 0;
2424 cache[n] = true;
2425 return powi_lookup_cost (n - powi_table[n], cache)
2426 + powi_lookup_cost (powi_table[n], cache) + 1;
2429 /* Return the number of multiplications required to calculate
2430 powi(x,n) for an arbitrary x, given the exponent N. This
2431 function needs to be kept in sync with expand_powi below. */
2433 static int
2434 powi_cost (HOST_WIDE_INT n)
2436 bool cache[POWI_TABLE_SIZE];
2437 unsigned HOST_WIDE_INT digit;
2438 unsigned HOST_WIDE_INT val;
2439 int result;
2441 if (n == 0)
2442 return 0;
2444 /* Ignore the reciprocal when calculating the cost. */
2445 val = (n < 0) ? -n : n;
2447 /* Initialize the exponent cache. */
2448 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2449 cache[1] = true;
2451 result = 0;
2453 while (val >= POWI_TABLE_SIZE)
2455 if (val & 1)
2457 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2458 result += powi_lookup_cost (digit, cache)
2459 + POWI_WINDOW_SIZE + 1;
2460 val >>= POWI_WINDOW_SIZE;
2462 else
2464 val >>= 1;
2465 result++;
2469 return result + powi_lookup_cost (val, cache);
2472 /* Recursive subroutine of expand_powi. This function takes the array,
2473 CACHE, of already calculated exponents and an exponent N and returns
2474 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2476 static rtx
2477 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2479 unsigned HOST_WIDE_INT digit;
2480 rtx target, result;
2481 rtx op0, op1;
2483 if (n < POWI_TABLE_SIZE)
2485 if (cache[n])
2486 return cache[n];
2488 target = gen_reg_rtx (mode);
2489 cache[n] = target;
2491 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2492 op1 = expand_powi_1 (mode, powi_table[n], cache);
2494 else if (n & 1)
2496 target = gen_reg_rtx (mode);
2497 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2498 op0 = expand_powi_1 (mode, n - digit, cache);
2499 op1 = expand_powi_1 (mode, digit, cache);
2501 else
2503 target = gen_reg_rtx (mode);
2504 op0 = expand_powi_1 (mode, n >> 1, cache);
2505 op1 = op0;
2508 result = expand_mult (mode, op0, op1, target, 0);
2509 if (result != target)
2510 emit_move_insn (target, result);
2511 return target;
2514 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2515 floating point operand in mode MODE, and N is the exponent. This
2516 function needs to be kept in sync with powi_cost above. */
2518 static rtx
2519 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2521 unsigned HOST_WIDE_INT val;
2522 rtx cache[POWI_TABLE_SIZE];
2523 rtx result;
2525 if (n == 0)
2526 return CONST1_RTX (mode);
2528 val = (n < 0) ? -n : n;
2530 memset (cache, 0, sizeof (cache));
2531 cache[1] = x;
2533 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2535 /* If the original exponent was negative, reciprocate the result. */
2536 if (n < 0)
2537 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2538 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2540 return result;
2543 /* Expand a call to the pow built-in mathematical function. Return 0 if
2544 a normal call should be emitted rather than expanding the function
2545 in-line. EXP is the expression that is a call to the builtin
2546 function; if convenient, the result should be placed in TARGET. */
2548 static rtx
2549 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2551 tree arglist = TREE_OPERAND (exp, 1);
2552 tree arg0, arg1;
2554 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2555 return 0;
2557 arg0 = TREE_VALUE (arglist);
2558 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2560 if (TREE_CODE (arg1) == REAL_CST
2561 && ! TREE_CONSTANT_OVERFLOW (arg1))
2563 REAL_VALUE_TYPE cint;
2564 REAL_VALUE_TYPE c;
2565 HOST_WIDE_INT n;
2567 c = TREE_REAL_CST (arg1);
2568 n = real_to_integer (&c);
2569 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2570 if (real_identical (&c, &cint))
2572 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2573 Otherwise, check the number of multiplications required.
2574 Note that pow never sets errno for an integer exponent. */
2575 if ((n >= -1 && n <= 2)
2576 || (flag_unsafe_math_optimizations
2577 && ! optimize_size
2578 && powi_cost (n) <= POWI_MAX_MULTS))
2580 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2581 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2582 op = force_reg (mode, op);
2583 return expand_powi (op, mode, n);
2588 if (! flag_unsafe_math_optimizations)
2589 return NULL_RTX;
2590 return expand_builtin_mathfn_2 (exp, target, subtarget);
2593 /* Expand a call to the powi built-in mathematical function. Return 0 if
2594 a normal call should be emitted rather than expanding the function
2595 in-line. EXP is the expression that is a call to the builtin
2596 function; if convenient, the result should be placed in TARGET. */
2598 static rtx
2599 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2601 tree arglist = TREE_OPERAND (exp, 1);
2602 tree arg0, arg1;
2603 rtx op0, op1;
2604 enum machine_mode mode;
2605 enum machine_mode mode2;
2607 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2608 return 0;
2610 arg0 = TREE_VALUE (arglist);
2611 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2612 mode = TYPE_MODE (TREE_TYPE (exp));
2614 /* Handle constant power. */
2616 if (TREE_CODE (arg1) == INTEGER_CST
2617 && ! TREE_CONSTANT_OVERFLOW (arg1))
2619 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2621 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2622 Otherwise, check the number of multiplications required. */
2623 if ((TREE_INT_CST_HIGH (arg1) == 0
2624 || TREE_INT_CST_HIGH (arg1) == -1)
2625 && ((n >= -1 && n <= 2)
2626 || (! optimize_size
2627 && powi_cost (n) <= POWI_MAX_MULTS)))
2629 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2630 op0 = force_reg (mode, op0);
2631 return expand_powi (op0, mode, n);
2635 /* Emit a libcall to libgcc. */
2637 /* Mode of the 2nd argument must match that of an int. */
2638 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2640 if (target == NULL_RTX)
2641 target = gen_reg_rtx (mode);
2643 op0 = expand_expr (arg0, subtarget, mode, 0);
2644 if (GET_MODE (op0) != mode)
2645 op0 = convert_to_mode (mode, op0, 0);
2646 op1 = expand_expr (arg1, 0, mode2, 0);
2647 if (GET_MODE (op1) != mode2)
2648 op1 = convert_to_mode (mode2, op1, 0);
2650 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2651 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2652 op0, mode, op1, mode2);
2654 return target;
2657 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2658 if we failed the caller should emit a normal call, otherwise
2659 try to get the result in TARGET, if convenient. */
2661 static rtx
2662 expand_builtin_strlen (tree arglist, rtx target,
2663 enum machine_mode target_mode)
2665 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2666 return 0;
2667 else
2669 rtx pat;
2670 tree len, src = TREE_VALUE (arglist);
2671 rtx result, src_reg, char_rtx, before_strlen;
2672 enum machine_mode insn_mode = target_mode, char_mode;
2673 enum insn_code icode = CODE_FOR_nothing;
2674 int align;
2676 /* If the length can be computed at compile-time, return it. */
2677 len = c_strlen (src, 0);
2678 if (len)
2679 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2681 /* If the length can be computed at compile-time and is constant
2682 integer, but there are side-effects in src, evaluate
2683 src for side-effects, then return len.
2684 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2685 can be optimized into: i++; x = 3; */
2686 len = c_strlen (src, 1);
2687 if (len && TREE_CODE (len) == INTEGER_CST)
2689 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2690 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2693 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2695 /* If SRC is not a pointer type, don't do this operation inline. */
2696 if (align == 0)
2697 return 0;
2699 /* Bail out if we can't compute strlen in the right mode. */
2700 while (insn_mode != VOIDmode)
2702 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2703 if (icode != CODE_FOR_nothing)
2704 break;
2706 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2708 if (insn_mode == VOIDmode)
2709 return 0;
2711 /* Make a place to write the result of the instruction. */
2712 result = target;
2713 if (! (result != 0
2714 && REG_P (result)
2715 && GET_MODE (result) == insn_mode
2716 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2717 result = gen_reg_rtx (insn_mode);
2719 /* Make a place to hold the source address. We will not expand
2720 the actual source until we are sure that the expansion will
2721 not fail -- there are trees that cannot be expanded twice. */
2722 src_reg = gen_reg_rtx (Pmode);
2724 /* Mark the beginning of the strlen sequence so we can emit the
2725 source operand later. */
2726 before_strlen = get_last_insn ();
2728 char_rtx = const0_rtx;
2729 char_mode = insn_data[(int) icode].operand[2].mode;
2730 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2731 char_mode))
2732 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2734 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2735 char_rtx, GEN_INT (align));
2736 if (! pat)
2737 return 0;
2738 emit_insn (pat);
2740 /* Now that we are assured of success, expand the source. */
2741 start_sequence ();
2742 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2743 if (pat != src_reg)
2744 emit_move_insn (src_reg, pat);
2745 pat = get_insns ();
2746 end_sequence ();
2748 if (before_strlen)
2749 emit_insn_after (pat, before_strlen);
2750 else
2751 emit_insn_before (pat, get_insns ());
2753 /* Return the value in the proper mode for this function. */
2754 if (GET_MODE (result) == target_mode)
2755 target = result;
2756 else if (target != 0)
2757 convert_move (target, result, 0);
2758 else
2759 target = convert_to_mode (target_mode, result, 0);
2761 return target;
2765 /* Expand a call to the strstr builtin. Return 0 if we failed the
2766 caller should emit a normal call, otherwise try to get the result
2767 in TARGET, if convenient (and in mode MODE if that's convenient). */
2769 static rtx
2770 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2772 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2774 tree result = fold_builtin_strstr (arglist, type);
2775 if (result)
2776 return expand_expr (result, target, mode, EXPAND_NORMAL);
2778 return 0;
2781 /* Expand a call to the strchr builtin. Return 0 if we failed the
2782 caller should emit a normal call, otherwise try to get the result
2783 in TARGET, if convenient (and in mode MODE if that's convenient). */
2785 static rtx
2786 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2788 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2790 tree result = fold_builtin_strchr (arglist, type);
2791 if (result)
2792 return expand_expr (result, target, mode, EXPAND_NORMAL);
2794 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2796 return 0;
2799 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2800 caller should emit a normal call, otherwise try to get the result
2801 in TARGET, if convenient (and in mode MODE if that's convenient). */
2803 static rtx
2804 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2806 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2808 tree result = fold_builtin_strrchr (arglist, type);
2809 if (result)
2810 return expand_expr (result, target, mode, EXPAND_NORMAL);
2812 return 0;
2815 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2816 caller should emit a normal call, otherwise try to get the result
2817 in TARGET, if convenient (and in mode MODE if that's convenient). */
2819 static rtx
2820 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2822 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2824 tree result = fold_builtin_strpbrk (arglist, type);
2825 if (result)
2826 return expand_expr (result, target, mode, EXPAND_NORMAL);
2828 return 0;
2831 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2832 bytes from constant string DATA + OFFSET and return it as target
2833 constant. */
2835 static rtx
2836 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2837 enum machine_mode mode)
2839 const char *str = (const char *) data;
2841 gcc_assert (offset >= 0
2842 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2843 <= strlen (str) + 1));
2845 return c_readstr (str + offset, mode);
2848 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2849 Return 0 if we failed, the caller should emit a normal call,
2850 otherwise try to get the result in TARGET, if convenient (and in
2851 mode MODE if that's convenient). */
2852 static rtx
2853 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2855 tree fndecl = get_callee_fndecl (exp);
2856 tree arglist = TREE_OPERAND (exp, 1);
2857 if (!validate_arglist (arglist,
2858 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2859 return 0;
2860 else
2862 tree dest = TREE_VALUE (arglist);
2863 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2864 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2865 const char *src_str;
2866 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2867 unsigned int dest_align
2868 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2869 rtx dest_mem, src_mem, dest_addr, len_rtx;
2870 tree result = fold_builtin_memcpy (fndecl, arglist);
2872 if (result)
2873 return expand_expr (result, target, mode, EXPAND_NORMAL);
2875 /* If DEST is not a pointer type, call the normal function. */
2876 if (dest_align == 0)
2877 return 0;
2879 /* If either SRC is not a pointer type, don't do this
2880 operation in-line. */
2881 if (src_align == 0)
2882 return 0;
2884 dest_mem = get_memory_rtx (dest, len);
2885 set_mem_align (dest_mem, dest_align);
2886 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2887 src_str = c_getstr (src);
2889 /* If SRC is a string constant and block move would be done
2890 by pieces, we can avoid loading the string from memory
2891 and only stored the computed constants. */
2892 if (src_str
2893 && GET_CODE (len_rtx) == CONST_INT
2894 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2895 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2896 (void *) src_str, dest_align))
2898 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2899 builtin_memcpy_read_str,
2900 (void *) src_str, dest_align, 0);
2901 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2902 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2903 return dest_mem;
2906 src_mem = get_memory_rtx (src, len);
2907 set_mem_align (src_mem, src_align);
2909 /* Copy word part most expediently. */
2910 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2911 CALL_EXPR_TAILCALL (exp)
2912 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2914 if (dest_addr == 0)
2916 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2917 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2919 return dest_addr;
2923 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2924 Return 0 if we failed; the caller should emit a normal call,
2925 otherwise try to get the result in TARGET, if convenient (and in
2926 mode MODE if that's convenient). If ENDP is 0 return the
2927 destination pointer, if ENDP is 1 return the end pointer ala
2928 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2929 stpcpy. */
2931 static rtx
2932 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2933 int endp)
2935 if (!validate_arglist (arglist,
2936 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2937 return 0;
2938 /* If return value is ignored, transform mempcpy into memcpy. */
2939 else if (target == const0_rtx)
2941 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2943 if (!fn)
2944 return 0;
2946 return expand_expr (build_function_call_expr (fn, arglist),
2947 target, mode, EXPAND_NORMAL);
2949 else
2951 tree dest = TREE_VALUE (arglist);
2952 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2953 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2954 const char *src_str;
2955 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2956 unsigned int dest_align
2957 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2958 rtx dest_mem, src_mem, len_rtx;
2959 tree result = fold_builtin_mempcpy (arglist, type, endp);
2961 if (result)
2962 return expand_expr (result, target, mode, EXPAND_NORMAL);
2964 /* If either SRC or DEST is not a pointer type, don't do this
2965 operation in-line. */
2966 if (dest_align == 0 || src_align == 0)
2967 return 0;
2969 /* If LEN is not constant, call the normal function. */
2970 if (! host_integerp (len, 1))
2971 return 0;
2973 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2974 src_str = c_getstr (src);
2976 /* If SRC is a string constant and block move would be done
2977 by pieces, we can avoid loading the string from memory
2978 and only stored the computed constants. */
2979 if (src_str
2980 && GET_CODE (len_rtx) == CONST_INT
2981 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2982 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2983 (void *) src_str, dest_align))
2985 dest_mem = get_memory_rtx (dest, len);
2986 set_mem_align (dest_mem, dest_align);
2987 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2988 builtin_memcpy_read_str,
2989 (void *) src_str, dest_align, endp);
2990 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2991 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2992 return dest_mem;
2995 if (GET_CODE (len_rtx) == CONST_INT
2996 && can_move_by_pieces (INTVAL (len_rtx),
2997 MIN (dest_align, src_align)))
2999 dest_mem = get_memory_rtx (dest, len);
3000 set_mem_align (dest_mem, dest_align);
3001 src_mem = get_memory_rtx (src, len);
3002 set_mem_align (src_mem, src_align);
3003 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3004 MIN (dest_align, src_align), endp);
3005 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3006 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3007 return dest_mem;
3010 return 0;
3014 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3015 if we failed; the caller should emit a normal call. */
3017 static rtx
3018 expand_builtin_memmove (tree arglist, tree type, rtx target,
3019 enum machine_mode mode, tree orig_exp)
3021 if (!validate_arglist (arglist,
3022 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3023 return 0;
3024 else
3026 tree dest = TREE_VALUE (arglist);
3027 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3028 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3030 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3031 unsigned int dest_align
3032 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3033 tree result = fold_builtin_memmove (arglist, type);
3035 if (result)
3036 return expand_expr (result, target, mode, EXPAND_NORMAL);
3038 /* If DEST is not a pointer type, call the normal function. */
3039 if (dest_align == 0)
3040 return 0;
3042 /* If either SRC is not a pointer type, don't do this
3043 operation in-line. */
3044 if (src_align == 0)
3045 return 0;
3047 /* If src is categorized for a readonly section we can use
3048 normal memcpy. */
3049 if (readonly_data_expr (src))
3051 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3052 if (!fn)
3053 return 0;
3054 fn = build_function_call_expr (fn, arglist);
3055 if (TREE_CODE (fn) == CALL_EXPR)
3056 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3057 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3060 /* If length is 1 and we can expand memcpy call inline,
3061 it is ok to use memcpy as well. */
3062 if (integer_onep (len))
3064 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3065 /*endp=*/0);
3066 if (ret)
3067 return ret;
3070 /* Otherwise, call the normal function. */
3071 return 0;
3075 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3076 if we failed the caller should emit a normal call. */
3078 static rtx
3079 expand_builtin_bcopy (tree exp)
3081 tree arglist = TREE_OPERAND (exp, 1);
3082 tree type = TREE_TYPE (exp);
3083 tree src, dest, size, newarglist;
3085 if (!validate_arglist (arglist,
3086 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3087 return NULL_RTX;
3089 src = TREE_VALUE (arglist);
3090 dest = TREE_VALUE (TREE_CHAIN (arglist));
3091 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3093 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3094 memmove(ptr y, ptr x, size_t z). This is done this way
3095 so that if it isn't expanded inline, we fallback to
3096 calling bcopy instead of memmove. */
3098 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3099 newarglist = tree_cons (NULL_TREE, src, newarglist);
3100 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3102 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3105 #ifndef HAVE_movstr
3106 # define HAVE_movstr 0
3107 # define CODE_FOR_movstr CODE_FOR_nothing
3108 #endif
3110 /* Expand into a movstr instruction, if one is available. Return 0 if
3111 we failed, the caller should emit a normal call, otherwise try to
3112 get the result in TARGET, if convenient. If ENDP is 0 return the
3113 destination pointer, if ENDP is 1 return the end pointer ala
3114 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3115 stpcpy. */
3117 static rtx
3118 expand_movstr (tree dest, tree src, rtx target, int endp)
3120 rtx end;
3121 rtx dest_mem;
3122 rtx src_mem;
3123 rtx insn;
3124 const struct insn_data * data;
3126 if (!HAVE_movstr)
3127 return 0;
3129 dest_mem = get_memory_rtx (dest, NULL);
3130 src_mem = get_memory_rtx (src, NULL);
3131 if (!endp)
3133 target = force_reg (Pmode, XEXP (dest_mem, 0));
3134 dest_mem = replace_equiv_address (dest_mem, target);
3135 end = gen_reg_rtx (Pmode);
3137 else
3139 if (target == 0 || target == const0_rtx)
3141 end = gen_reg_rtx (Pmode);
3142 if (target == 0)
3143 target = end;
3145 else
3146 end = target;
3149 data = insn_data + CODE_FOR_movstr;
3151 if (data->operand[0].mode != VOIDmode)
3152 end = gen_lowpart (data->operand[0].mode, end);
3154 insn = data->genfun (end, dest_mem, src_mem);
3156 gcc_assert (insn);
3158 emit_insn (insn);
3160 /* movstr is supposed to set end to the address of the NUL
3161 terminator. If the caller requested a mempcpy-like return value,
3162 adjust it. */
3163 if (endp == 1 && target != const0_rtx)
3165 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3166 emit_move_insn (target, force_operand (tem, NULL_RTX));
3169 return target;
3172 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3173 if we failed the caller should emit a normal call, otherwise try to get
3174 the result in TARGET, if convenient (and in mode MODE if that's
3175 convenient). */
3177 static rtx
3178 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3180 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3182 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3183 if (result)
3184 return expand_expr (result, target, mode, EXPAND_NORMAL);
3186 return expand_movstr (TREE_VALUE (arglist),
3187 TREE_VALUE (TREE_CHAIN (arglist)),
3188 target, /*endp=*/0);
3190 return 0;
3193 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3194 Return 0 if we failed the caller should emit a normal call,
3195 otherwise try to get the result in TARGET, if convenient (and in
3196 mode MODE if that's convenient). */
3198 static rtx
3199 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3201 tree arglist = TREE_OPERAND (exp, 1);
3202 /* If return value is ignored, transform stpcpy into strcpy. */
3203 if (target == const0_rtx)
3205 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3206 if (!fn)
3207 return 0;
3209 return expand_expr (build_function_call_expr (fn, arglist),
3210 target, mode, EXPAND_NORMAL);
3213 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3214 return 0;
3215 else
3217 tree dst, src, len, lenp1;
3218 tree narglist;
3219 rtx ret;
3221 /* Ensure we get an actual string whose length can be evaluated at
3222 compile-time, not an expression containing a string. This is
3223 because the latter will potentially produce pessimized code
3224 when used to produce the return value. */
3225 src = TREE_VALUE (TREE_CHAIN (arglist));
3226 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3227 return expand_movstr (TREE_VALUE (arglist),
3228 TREE_VALUE (TREE_CHAIN (arglist)),
3229 target, /*endp=*/2);
3231 dst = TREE_VALUE (arglist);
3232 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3233 narglist = build_tree_list (NULL_TREE, lenp1);
3234 narglist = tree_cons (NULL_TREE, src, narglist);
3235 narglist = tree_cons (NULL_TREE, dst, narglist);
3236 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3237 target, mode, /*endp=*/2);
3239 if (ret)
3240 return ret;
3242 if (TREE_CODE (len) == INTEGER_CST)
3244 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3246 if (GET_CODE (len_rtx) == CONST_INT)
3248 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3249 arglist, target, mode);
3251 if (ret)
3253 if (! target)
3255 if (mode != VOIDmode)
3256 target = gen_reg_rtx (mode);
3257 else
3258 target = gen_reg_rtx (GET_MODE (ret));
3260 if (GET_MODE (target) != GET_MODE (ret))
3261 ret = gen_lowpart (GET_MODE (target), ret);
3263 ret = plus_constant (ret, INTVAL (len_rtx));
3264 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3265 gcc_assert (ret);
3267 return target;
3272 return expand_movstr (TREE_VALUE (arglist),
3273 TREE_VALUE (TREE_CHAIN (arglist)),
3274 target, /*endp=*/2);
3278 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3279 bytes from constant string DATA + OFFSET and return it as target
3280 constant. */
3282 static rtx
3283 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3284 enum machine_mode mode)
3286 const char *str = (const char *) data;
3288 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3289 return const0_rtx;
3291 return c_readstr (str + offset, mode);
3294 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3295 if we failed the caller should emit a normal call. */
3297 static rtx
3298 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3300 tree fndecl = get_callee_fndecl (exp);
3301 tree arglist = TREE_OPERAND (exp, 1);
3302 if (validate_arglist (arglist,
3303 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3305 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3306 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3307 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3309 if (result)
3310 return expand_expr (result, target, mode, EXPAND_NORMAL);
3312 /* We must be passed a constant len and src parameter. */
3313 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3314 return 0;
3316 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3318 /* We're required to pad with trailing zeros if the requested
3319 len is greater than strlen(s2)+1. In that case try to
3320 use store_by_pieces, if it fails, punt. */
3321 if (tree_int_cst_lt (slen, len))
3323 tree dest = TREE_VALUE (arglist);
3324 unsigned int dest_align
3325 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3326 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3327 rtx dest_mem;
3329 if (!p || dest_align == 0 || !host_integerp (len, 1)
3330 || !can_store_by_pieces (tree_low_cst (len, 1),
3331 builtin_strncpy_read_str,
3332 (void *) p, dest_align))
3333 return 0;
3335 dest_mem = get_memory_rtx (dest, len);
3336 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3337 builtin_strncpy_read_str,
3338 (void *) p, dest_align, 0);
3339 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3340 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3341 return dest_mem;
3344 return 0;
3347 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3348 bytes from constant string DATA + OFFSET and return it as target
3349 constant. */
3351 static rtx
3352 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3353 enum machine_mode mode)
3355 const char *c = (const char *) data;
3356 char *p = alloca (GET_MODE_SIZE (mode));
3358 memset (p, *c, GET_MODE_SIZE (mode));
3360 return c_readstr (p, mode);
3363 /* Callback routine for store_by_pieces. Return the RTL of a register
3364 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3365 char value given in the RTL register data. For example, if mode is
3366 4 bytes wide, return the RTL for 0x01010101*data. */
3368 static rtx
3369 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3370 enum machine_mode mode)
3372 rtx target, coeff;
3373 size_t size;
3374 char *p;
3376 size = GET_MODE_SIZE (mode);
3377 if (size == 1)
3378 return (rtx) data;
3380 p = alloca (size);
3381 memset (p, 1, size);
3382 coeff = c_readstr (p, mode);
3384 target = convert_to_mode (mode, (rtx) data, 1);
3385 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3386 return force_reg (mode, target);
3389 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3390 if we failed the caller should emit a normal call, otherwise try to get
3391 the result in TARGET, if convenient (and in mode MODE if that's
3392 convenient). */
3394 static rtx
3395 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3396 tree orig_exp)
3398 if (!validate_arglist (arglist,
3399 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3400 return 0;
3401 else
3403 tree dest = TREE_VALUE (arglist);
3404 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3405 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3406 char c;
3408 unsigned int dest_align
3409 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3410 rtx dest_mem, dest_addr, len_rtx;
3412 /* If DEST is not a pointer type, don't do this
3413 operation in-line. */
3414 if (dest_align == 0)
3415 return 0;
3417 /* If the LEN parameter is zero, return DEST. */
3418 if (integer_zerop (len))
3420 /* Evaluate and ignore VAL in case it has side-effects. */
3421 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3422 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3425 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3426 dest_mem = get_memory_rtx (dest, len);
3428 if (TREE_CODE (val) != INTEGER_CST)
3430 rtx val_rtx;
3432 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3433 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3435 /* Assume that we can memset by pieces if we can store the
3436 * the coefficients by pieces (in the required modes).
3437 * We can't pass builtin_memset_gen_str as that emits RTL. */
3438 c = 1;
3439 if (host_integerp (len, 1)
3440 && !(optimize_size && tree_low_cst (len, 1) > 1)
3441 && can_store_by_pieces (tree_low_cst (len, 1),
3442 builtin_memset_read_str, &c, dest_align))
3444 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3445 val_rtx);
3446 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3447 builtin_memset_gen_str, val_rtx, dest_align, 0);
3449 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3450 dest_align))
3451 return 0;
3453 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3454 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3455 return dest_mem;
3458 if (target_char_cast (val, &c))
3459 return 0;
3461 if (c)
3463 if (host_integerp (len, 1)
3464 && !(optimize_size && tree_low_cst (len, 1) > 1)
3465 && can_store_by_pieces (tree_low_cst (len, 1),
3466 builtin_memset_read_str, &c, dest_align))
3467 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3468 builtin_memset_read_str, &c, dest_align, 0);
3469 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3470 dest_align))
3471 return 0;
3473 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3474 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3475 return dest_mem;
3478 set_mem_align (dest_mem, dest_align);
3479 dest_addr = clear_storage (dest_mem, len_rtx,
3480 CALL_EXPR_TAILCALL (orig_exp)
3481 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3483 if (dest_addr == 0)
3485 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3486 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3489 return dest_addr;
3493 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3494 if we failed the caller should emit a normal call. */
3496 static rtx
3497 expand_builtin_bzero (tree exp)
3499 tree arglist = TREE_OPERAND (exp, 1);
3500 tree dest, size, newarglist;
3502 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3503 return NULL_RTX;
3505 dest = TREE_VALUE (arglist);
3506 size = TREE_VALUE (TREE_CHAIN (arglist));
3508 /* New argument list transforming bzero(ptr x, int y) to
3509 memset(ptr x, int 0, size_t y). This is done this way
3510 so that if it isn't expanded inline, we fallback to
3511 calling bzero instead of memset. */
3513 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3514 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3515 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3517 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3520 /* Expand expression EXP, which is a call to the memcmp built-in function.
3521 ARGLIST is the argument list for this call. Return 0 if we failed and the
3522 caller should emit a normal call, otherwise try to get the result in
3523 TARGET, if convenient (and in mode MODE, if that's convenient). */
3525 static rtx
3526 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3527 enum machine_mode mode)
3529 if (!validate_arglist (arglist,
3530 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3531 return 0;
3532 else
3534 tree result = fold_builtin_memcmp (arglist);
3535 if (result)
3536 return expand_expr (result, target, mode, EXPAND_NORMAL);
3539 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3541 tree arg1 = TREE_VALUE (arglist);
3542 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3543 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3544 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3545 rtx result;
3546 rtx insn;
3548 int arg1_align
3549 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3550 int arg2_align
3551 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3552 enum machine_mode insn_mode;
3554 #ifdef HAVE_cmpmemsi
3555 if (HAVE_cmpmemsi)
3556 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3557 else
3558 #endif
3559 #ifdef HAVE_cmpstrnsi
3560 if (HAVE_cmpstrnsi)
3561 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3562 else
3563 #endif
3564 return 0;
3566 /* If we don't have POINTER_TYPE, call the function. */
3567 if (arg1_align == 0 || arg2_align == 0)
3568 return 0;
3570 /* Make a place to write the result of the instruction. */
3571 result = target;
3572 if (! (result != 0
3573 && REG_P (result) && GET_MODE (result) == insn_mode
3574 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3575 result = gen_reg_rtx (insn_mode);
3577 arg1_rtx = get_memory_rtx (arg1, len);
3578 arg2_rtx = get_memory_rtx (arg2, len);
3579 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3581 /* Set MEM_SIZE as appropriate. */
3582 if (GET_CODE (arg3_rtx) == CONST_INT)
3584 set_mem_size (arg1_rtx, arg3_rtx);
3585 set_mem_size (arg2_rtx, arg3_rtx);
3588 #ifdef HAVE_cmpmemsi
3589 if (HAVE_cmpmemsi)
3590 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3591 GEN_INT (MIN (arg1_align, arg2_align)));
3592 else
3593 #endif
3594 #ifdef HAVE_cmpstrnsi
3595 if (HAVE_cmpstrnsi)
3596 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3597 GEN_INT (MIN (arg1_align, arg2_align)));
3598 else
3599 #endif
3600 gcc_unreachable ();
3602 if (insn)
3603 emit_insn (insn);
3604 else
3605 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3606 TYPE_MODE (integer_type_node), 3,
3607 XEXP (arg1_rtx, 0), Pmode,
3608 XEXP (arg2_rtx, 0), Pmode,
3609 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3610 TYPE_UNSIGNED (sizetype)),
3611 TYPE_MODE (sizetype));
3613 /* Return the value in the proper mode for this function. */
3614 mode = TYPE_MODE (TREE_TYPE (exp));
3615 if (GET_MODE (result) == mode)
3616 return result;
3617 else if (target != 0)
3619 convert_move (target, result, 0);
3620 return target;
3622 else
3623 return convert_to_mode (mode, result, 0);
3625 #endif
3627 return 0;
3630 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3631 if we failed the caller should emit a normal call, otherwise try to get
3632 the result in TARGET, if convenient. */
3634 static rtx
3635 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3637 tree arglist = TREE_OPERAND (exp, 1);
3639 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3640 return 0;
3641 else
3643 tree result = fold_builtin_strcmp (arglist);
3644 if (result)
3645 return expand_expr (result, target, mode, EXPAND_NORMAL);
3648 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3649 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3650 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3652 rtx arg1_rtx, arg2_rtx;
3653 rtx result, insn = NULL_RTX;
3654 tree fndecl, fn;
3656 tree arg1 = TREE_VALUE (arglist);
3657 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3658 int arg1_align
3659 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3660 int arg2_align
3661 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3663 /* If we don't have POINTER_TYPE, call the function. */
3664 if (arg1_align == 0 || arg2_align == 0)
3665 return 0;
3667 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3668 arg1 = builtin_save_expr (arg1);
3669 arg2 = builtin_save_expr (arg2);
3671 arg1_rtx = get_memory_rtx (arg1, NULL);
3672 arg2_rtx = get_memory_rtx (arg2, NULL);
3674 #ifdef HAVE_cmpstrsi
3675 /* Try to call cmpstrsi. */
3676 if (HAVE_cmpstrsi)
3678 enum machine_mode insn_mode
3679 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3681 /* Make a place to write the result of the instruction. */
3682 result = target;
3683 if (! (result != 0
3684 && REG_P (result) && GET_MODE (result) == insn_mode
3685 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3686 result = gen_reg_rtx (insn_mode);
3688 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3689 GEN_INT (MIN (arg1_align, arg2_align)));
3691 #endif
3692 #if HAVE_cmpstrnsi
3693 /* Try to determine at least one length and call cmpstrnsi. */
3694 if (!insn && HAVE_cmpstrnsi)
3696 tree len;
3697 rtx arg3_rtx;
3699 enum machine_mode insn_mode
3700 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3701 tree len1 = c_strlen (arg1, 1);
3702 tree len2 = c_strlen (arg2, 1);
3704 if (len1)
3705 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3706 if (len2)
3707 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3709 /* If we don't have a constant length for the first, use the length
3710 of the second, if we know it. We don't require a constant for
3711 this case; some cost analysis could be done if both are available
3712 but neither is constant. For now, assume they're equally cheap,
3713 unless one has side effects. If both strings have constant lengths,
3714 use the smaller. */
3716 if (!len1)
3717 len = len2;
3718 else if (!len2)
3719 len = len1;
3720 else if (TREE_SIDE_EFFECTS (len1))
3721 len = len2;
3722 else if (TREE_SIDE_EFFECTS (len2))
3723 len = len1;
3724 else if (TREE_CODE (len1) != INTEGER_CST)
3725 len = len2;
3726 else if (TREE_CODE (len2) != INTEGER_CST)
3727 len = len1;
3728 else if (tree_int_cst_lt (len1, len2))
3729 len = len1;
3730 else
3731 len = len2;
3733 /* If both arguments have side effects, we cannot optimize. */
3734 if (!len || TREE_SIDE_EFFECTS (len))
3735 return 0;
3737 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3738 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3740 /* Make a place to write the result of the instruction. */
3741 result = target;
3742 if (! (result != 0
3743 && REG_P (result) && GET_MODE (result) == insn_mode
3744 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3745 result = gen_reg_rtx (insn_mode);
3747 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3748 GEN_INT (MIN (arg1_align, arg2_align)));
3750 #endif
3752 if (insn)
3754 emit_insn (insn);
3756 /* Return the value in the proper mode for this function. */
3757 mode = TYPE_MODE (TREE_TYPE (exp));
3758 if (GET_MODE (result) == mode)
3759 return result;
3760 if (target == 0)
3761 return convert_to_mode (mode, result, 0);
3762 convert_move (target, result, 0);
3763 return target;
3766 /* Expand the library call ourselves using a stabilized argument
3767 list to avoid re-evaluating the function's arguments twice. */
3768 arglist = build_tree_list (NULL_TREE, arg2);
3769 arglist = tree_cons (NULL_TREE, arg1, arglist);
3770 fndecl = get_callee_fndecl (exp);
3771 fn = build_function_call_expr (fndecl, arglist);
3772 if (TREE_CODE (fn) == CALL_EXPR)
3773 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3774 return expand_call (fn, target, target == const0_rtx);
3776 #endif
3777 return 0;
3780 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3781 if we failed the caller should emit a normal call, otherwise try to get
3782 the result in TARGET, if convenient. */
3784 static rtx
3785 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3787 tree arglist = TREE_OPERAND (exp, 1);
3789 if (!validate_arglist (arglist,
3790 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3791 return 0;
3792 else
3794 tree result = fold_builtin_strncmp (arglist);
3795 if (result)
3796 return expand_expr (result, target, mode, EXPAND_NORMAL);
3799 /* If c_strlen can determine an expression for one of the string
3800 lengths, and it doesn't have side effects, then emit cmpstrnsi
3801 using length MIN(strlen(string)+1, arg3). */
3802 #ifdef HAVE_cmpstrnsi
3803 if (HAVE_cmpstrnsi)
3805 tree arg1 = TREE_VALUE (arglist);
3806 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3807 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3808 tree len, len1, len2;
3809 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3810 rtx result, insn;
3811 tree fndecl, fn;
3813 int arg1_align
3814 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3815 int arg2_align
3816 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3817 enum machine_mode insn_mode
3818 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3820 len1 = c_strlen (arg1, 1);
3821 len2 = c_strlen (arg2, 1);
3823 if (len1)
3824 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3825 if (len2)
3826 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3828 /* If we don't have a constant length for the first, use the length
3829 of the second, if we know it. We don't require a constant for
3830 this case; some cost analysis could be done if both are available
3831 but neither is constant. For now, assume they're equally cheap,
3832 unless one has side effects. If both strings have constant lengths,
3833 use the smaller. */
3835 if (!len1)
3836 len = len2;
3837 else if (!len2)
3838 len = len1;
3839 else if (TREE_SIDE_EFFECTS (len1))
3840 len = len2;
3841 else if (TREE_SIDE_EFFECTS (len2))
3842 len = len1;
3843 else if (TREE_CODE (len1) != INTEGER_CST)
3844 len = len2;
3845 else if (TREE_CODE (len2) != INTEGER_CST)
3846 len = len1;
3847 else if (tree_int_cst_lt (len1, len2))
3848 len = len1;
3849 else
3850 len = len2;
3852 /* If both arguments have side effects, we cannot optimize. */
3853 if (!len || TREE_SIDE_EFFECTS (len))
3854 return 0;
3856 /* The actual new length parameter is MIN(len,arg3). */
3857 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3858 fold_convert (TREE_TYPE (len), arg3));
3860 /* If we don't have POINTER_TYPE, call the function. */
3861 if (arg1_align == 0 || arg2_align == 0)
3862 return 0;
3864 /* Make a place to write the result of the instruction. */
3865 result = target;
3866 if (! (result != 0
3867 && REG_P (result) && GET_MODE (result) == insn_mode
3868 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3869 result = gen_reg_rtx (insn_mode);
3871 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3872 arg1 = builtin_save_expr (arg1);
3873 arg2 = builtin_save_expr (arg2);
3874 len = builtin_save_expr (len);
3876 arg1_rtx = get_memory_rtx (arg1, len);
3877 arg2_rtx = get_memory_rtx (arg2, len);
3878 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3879 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3880 GEN_INT (MIN (arg1_align, arg2_align)));
3881 if (insn)
3883 emit_insn (insn);
3885 /* Return the value in the proper mode for this function. */
3886 mode = TYPE_MODE (TREE_TYPE (exp));
3887 if (GET_MODE (result) == mode)
3888 return result;
3889 if (target == 0)
3890 return convert_to_mode (mode, result, 0);
3891 convert_move (target, result, 0);
3892 return target;
3895 /* Expand the library call ourselves using a stabilized argument
3896 list to avoid re-evaluating the function's arguments twice. */
3897 arglist = build_tree_list (NULL_TREE, len);
3898 arglist = tree_cons (NULL_TREE, arg2, arglist);
3899 arglist = tree_cons (NULL_TREE, arg1, arglist);
3900 fndecl = get_callee_fndecl (exp);
3901 fn = build_function_call_expr (fndecl, arglist);
3902 if (TREE_CODE (fn) == CALL_EXPR)
3903 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3904 return expand_call (fn, target, target == const0_rtx);
3906 #endif
3907 return 0;
3910 /* Expand expression EXP, which is a call to the strcat builtin.
3911 Return 0 if we failed the caller should emit a normal call,
3912 otherwise try to get the result in TARGET, if convenient. */
3914 static rtx
3915 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3917 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3918 return 0;
3919 else
3921 tree dst = TREE_VALUE (arglist),
3922 src = TREE_VALUE (TREE_CHAIN (arglist));
3923 const char *p = c_getstr (src);
3925 /* If the string length is zero, return the dst parameter. */
3926 if (p && *p == '\0')
3927 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3929 if (!optimize_size)
3931 /* See if we can store by pieces into (dst + strlen(dst)). */
3932 tree newsrc, newdst,
3933 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3934 rtx insns;
3936 /* Stabilize the argument list. */
3937 newsrc = builtin_save_expr (src);
3938 if (newsrc != src)
3939 arglist = build_tree_list (NULL_TREE, newsrc);
3940 else
3941 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3943 dst = builtin_save_expr (dst);
3945 start_sequence ();
3947 /* Create strlen (dst). */
3948 newdst =
3949 build_function_call_expr (strlen_fn,
3950 build_tree_list (NULL_TREE, dst));
3951 /* Create (dst + (cast) strlen (dst)). */
3952 newdst = fold_convert (TREE_TYPE (dst), newdst);
3953 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3955 newdst = builtin_save_expr (newdst);
3956 arglist = tree_cons (NULL_TREE, newdst, arglist);
3958 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3960 end_sequence (); /* Stop sequence. */
3961 return 0;
3964 /* Output the entire sequence. */
3965 insns = get_insns ();
3966 end_sequence ();
3967 emit_insn (insns);
3969 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3972 return 0;
3976 /* Expand expression EXP, which is a call to the strncat builtin.
3977 Return 0 if we failed the caller should emit a normal call,
3978 otherwise try to get the result in TARGET, if convenient. */
3980 static rtx
3981 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3983 if (validate_arglist (arglist,
3984 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3986 tree result = fold_builtin_strncat (arglist);
3987 if (result)
3988 return expand_expr (result, target, mode, EXPAND_NORMAL);
3990 return 0;
3993 /* Expand expression EXP, which is a call to the strspn builtin.
3994 Return 0 if we failed the caller should emit a normal call,
3995 otherwise try to get the result in TARGET, if convenient. */
3997 static rtx
3998 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4000 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4002 tree result = fold_builtin_strspn (arglist);
4003 if (result)
4004 return expand_expr (result, target, mode, EXPAND_NORMAL);
4006 return 0;
4009 /* Expand expression EXP, which is a call to the strcspn builtin.
4010 Return 0 if we failed the caller should emit a normal call,
4011 otherwise try to get the result in TARGET, if convenient. */
4013 static rtx
4014 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4016 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4018 tree result = fold_builtin_strcspn (arglist);
4019 if (result)
4020 return expand_expr (result, target, mode, EXPAND_NORMAL);
4022 return 0;
4025 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4026 if that's convenient. */
4029 expand_builtin_saveregs (void)
4031 rtx val, seq;
4033 /* Don't do __builtin_saveregs more than once in a function.
4034 Save the result of the first call and reuse it. */
4035 if (saveregs_value != 0)
4036 return saveregs_value;
4038 /* When this function is called, it means that registers must be
4039 saved on entry to this function. So we migrate the call to the
4040 first insn of this function. */
4042 start_sequence ();
4044 /* Do whatever the machine needs done in this case. */
4045 val = targetm.calls.expand_builtin_saveregs ();
4047 seq = get_insns ();
4048 end_sequence ();
4050 saveregs_value = val;
4052 /* Put the insns after the NOTE that starts the function. If this
4053 is inside a start_sequence, make the outer-level insn chain current, so
4054 the code is placed at the start of the function. */
4055 push_topmost_sequence ();
4056 emit_insn_after (seq, entry_of_function ());
4057 pop_topmost_sequence ();
4059 return val;
4062 /* __builtin_args_info (N) returns word N of the arg space info
4063 for the current function. The number and meanings of words
4064 is controlled by the definition of CUMULATIVE_ARGS. */
4066 static rtx
4067 expand_builtin_args_info (tree arglist)
4069 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4070 int *word_ptr = (int *) &current_function_args_info;
4072 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4074 if (arglist != 0)
4076 if (!host_integerp (TREE_VALUE (arglist), 0))
4077 error ("argument of %<__builtin_args_info%> must be constant");
4078 else
4080 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4082 if (wordnum < 0 || wordnum >= nwords)
4083 error ("argument of %<__builtin_args_info%> out of range");
4084 else
4085 return GEN_INT (word_ptr[wordnum]);
4088 else
4089 error ("missing argument in %<__builtin_args_info%>");
4091 return const0_rtx;
4094 /* Expand a call to __builtin_next_arg. */
4096 static rtx
4097 expand_builtin_next_arg (void)
4099 /* Checking arguments is already done in fold_builtin_next_arg
4100 that must be called before this function. */
4101 return expand_binop (Pmode, add_optab,
4102 current_function_internal_arg_pointer,
4103 current_function_arg_offset_rtx,
4104 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4107 /* Make it easier for the backends by protecting the valist argument
4108 from multiple evaluations. */
4110 static tree
4111 stabilize_va_list (tree valist, int needs_lvalue)
4113 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4115 if (TREE_SIDE_EFFECTS (valist))
4116 valist = save_expr (valist);
4118 /* For this case, the backends will be expecting a pointer to
4119 TREE_TYPE (va_list_type_node), but it's possible we've
4120 actually been given an array (an actual va_list_type_node).
4121 So fix it. */
4122 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4124 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4125 valist = build_fold_addr_expr_with_type (valist, p1);
4128 else
4130 tree pt;
4132 if (! needs_lvalue)
4134 if (! TREE_SIDE_EFFECTS (valist))
4135 return valist;
4137 pt = build_pointer_type (va_list_type_node);
4138 valist = fold_build1 (ADDR_EXPR, pt, valist);
4139 TREE_SIDE_EFFECTS (valist) = 1;
4142 if (TREE_SIDE_EFFECTS (valist))
4143 valist = save_expr (valist);
4144 valist = build_fold_indirect_ref (valist);
4147 return valist;
4150 /* The "standard" definition of va_list is void*. */
4152 tree
4153 std_build_builtin_va_list (void)
4155 return ptr_type_node;
4158 /* The "standard" implementation of va_start: just assign `nextarg' to
4159 the variable. */
4161 void
4162 std_expand_builtin_va_start (tree valist, rtx nextarg)
4164 tree t;
4166 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4167 make_tree (ptr_type_node, nextarg));
4168 TREE_SIDE_EFFECTS (t) = 1;
4170 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4173 /* Expand ARGLIST, from a call to __builtin_va_start. */
4175 static rtx
4176 expand_builtin_va_start (tree arglist)
4178 rtx nextarg;
4179 tree chain, valist;
4181 chain = TREE_CHAIN (arglist);
4183 if (!chain)
4185 error ("too few arguments to function %<va_start%>");
4186 return const0_rtx;
4189 if (fold_builtin_next_arg (chain))
4190 return const0_rtx;
4192 nextarg = expand_builtin_next_arg ();
4193 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4195 #ifdef EXPAND_BUILTIN_VA_START
4196 EXPAND_BUILTIN_VA_START (valist, nextarg);
4197 #else
4198 std_expand_builtin_va_start (valist, nextarg);
4199 #endif
4201 return const0_rtx;
4204 /* The "standard" implementation of va_arg: read the value from the
4205 current (padded) address and increment by the (padded) size. */
4207 tree
4208 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4210 tree addr, t, type_size, rounded_size, valist_tmp;
4211 unsigned HOST_WIDE_INT align, boundary;
4212 bool indirect;
4214 #ifdef ARGS_GROW_DOWNWARD
4215 /* All of the alignment and movement below is for args-grow-up machines.
4216 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4217 implement their own specialized gimplify_va_arg_expr routines. */
4218 gcc_unreachable ();
4219 #endif
4221 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4222 if (indirect)
4223 type = build_pointer_type (type);
4225 align = PARM_BOUNDARY / BITS_PER_UNIT;
4226 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4228 /* Hoist the valist value into a temporary for the moment. */
4229 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4231 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4232 requires greater alignment, we must perform dynamic alignment. */
4233 if (boundary > align)
4235 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4236 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4237 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4238 gimplify_and_add (t, pre_p);
4240 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4241 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4242 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4243 gimplify_and_add (t, pre_p);
4245 else
4246 boundary = align;
4248 /* If the actual alignment is less than the alignment of the type,
4249 adjust the type accordingly so that we don't assume strict alignment
4250 when deferencing the pointer. */
4251 boundary *= BITS_PER_UNIT;
4252 if (boundary < TYPE_ALIGN (type))
4254 type = build_variant_type_copy (type);
4255 TYPE_ALIGN (type) = boundary;
4258 /* Compute the rounded size of the type. */
4259 type_size = size_in_bytes (type);
4260 rounded_size = round_up (type_size, align);
4262 /* Reduce rounded_size so it's sharable with the postqueue. */
4263 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4265 /* Get AP. */
4266 addr = valist_tmp;
4267 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4269 /* Small args are padded downward. */
4270 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4271 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4272 size_binop (MINUS_EXPR, rounded_size, type_size));
4273 t = fold_convert (TREE_TYPE (addr), t);
4274 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4277 /* Compute new value for AP. */
4278 t = fold_convert (TREE_TYPE (valist), rounded_size);
4279 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4280 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4281 gimplify_and_add (t, pre_p);
4283 addr = fold_convert (build_pointer_type (type), addr);
4285 if (indirect)
4286 addr = build_va_arg_indirect_ref (addr);
4288 return build_va_arg_indirect_ref (addr);
4291 /* Build an indirect-ref expression over the given TREE, which represents a
4292 piece of a va_arg() expansion. */
4293 tree
4294 build_va_arg_indirect_ref (tree addr)
4296 addr = build_fold_indirect_ref (addr);
4298 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4299 mf_mark (addr);
4301 return addr;
4304 /* Return a dummy expression of type TYPE in order to keep going after an
4305 error. */
4307 static tree
4308 dummy_object (tree type)
4310 tree t = convert (build_pointer_type (type), null_pointer_node);
4311 return build1 (INDIRECT_REF, type, t);
4314 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4315 builtin function, but a very special sort of operator. */
4317 enum gimplify_status
4318 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4320 tree promoted_type, want_va_type, have_va_type;
4321 tree valist = TREE_OPERAND (*expr_p, 0);
4322 tree type = TREE_TYPE (*expr_p);
4323 tree t;
4325 /* Verify that valist is of the proper type. */
4326 want_va_type = va_list_type_node;
4327 have_va_type = TREE_TYPE (valist);
4329 if (have_va_type == error_mark_node)
4330 return GS_ERROR;
4332 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4334 /* If va_list is an array type, the argument may have decayed
4335 to a pointer type, e.g. by being passed to another function.
4336 In that case, unwrap both types so that we can compare the
4337 underlying records. */
4338 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4339 || POINTER_TYPE_P (have_va_type))
4341 want_va_type = TREE_TYPE (want_va_type);
4342 have_va_type = TREE_TYPE (have_va_type);
4346 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4348 error ("first argument to %<va_arg%> not of type %<va_list%>");
4349 return GS_ERROR;
4352 /* Generate a diagnostic for requesting data of a type that cannot
4353 be passed through `...' due to type promotion at the call site. */
4354 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4355 != type)
4357 static bool gave_help;
4359 /* Unfortunately, this is merely undefined, rather than a constraint
4360 violation, so we cannot make this an error. If this call is never
4361 executed, the program is still strictly conforming. */
4362 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4363 type, promoted_type);
4364 if (! gave_help)
4366 gave_help = true;
4367 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4368 promoted_type, type);
4371 /* We can, however, treat "undefined" any way we please.
4372 Call abort to encourage the user to fix the program. */
4373 inform ("if this code is reached, the program will abort");
4374 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4375 NULL);
4376 append_to_statement_list (t, pre_p);
4378 /* This is dead code, but go ahead and finish so that the
4379 mode of the result comes out right. */
4380 *expr_p = dummy_object (type);
4381 return GS_ALL_DONE;
4383 else
4385 /* Make it easier for the backends by protecting the valist argument
4386 from multiple evaluations. */
4387 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4389 /* For this case, the backends will be expecting a pointer to
4390 TREE_TYPE (va_list_type_node), but it's possible we've
4391 actually been given an array (an actual va_list_type_node).
4392 So fix it. */
4393 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4395 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4396 valist = build_fold_addr_expr_with_type (valist, p1);
4398 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4400 else
4401 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4403 if (!targetm.gimplify_va_arg_expr)
4404 /* FIXME:Once most targets are converted we should merely
4405 assert this is non-null. */
4406 return GS_ALL_DONE;
4408 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4409 return GS_OK;
4413 /* Expand ARGLIST, from a call to __builtin_va_end. */
4415 static rtx
4416 expand_builtin_va_end (tree arglist)
4418 tree valist = TREE_VALUE (arglist);
4420 /* Evaluate for side effects, if needed. I hate macros that don't
4421 do that. */
4422 if (TREE_SIDE_EFFECTS (valist))
4423 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4425 return const0_rtx;
4428 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4429 builtin rather than just as an assignment in stdarg.h because of the
4430 nastiness of array-type va_list types. */
4432 static rtx
4433 expand_builtin_va_copy (tree arglist)
4435 tree dst, src, t;
4437 dst = TREE_VALUE (arglist);
4438 src = TREE_VALUE (TREE_CHAIN (arglist));
4440 dst = stabilize_va_list (dst, 1);
4441 src = stabilize_va_list (src, 0);
4443 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4445 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4446 TREE_SIDE_EFFECTS (t) = 1;
4447 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4449 else
4451 rtx dstb, srcb, size;
4453 /* Evaluate to pointers. */
4454 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4455 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4456 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4457 VOIDmode, EXPAND_NORMAL);
4459 dstb = convert_memory_address (Pmode, dstb);
4460 srcb = convert_memory_address (Pmode, srcb);
4462 /* "Dereference" to BLKmode memories. */
4463 dstb = gen_rtx_MEM (BLKmode, dstb);
4464 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4465 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4466 srcb = gen_rtx_MEM (BLKmode, srcb);
4467 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4468 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4470 /* Copy. */
4471 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4474 return const0_rtx;
4477 /* Expand a call to one of the builtin functions __builtin_frame_address or
4478 __builtin_return_address. */
4480 static rtx
4481 expand_builtin_frame_address (tree fndecl, tree arglist)
4483 /* The argument must be a nonnegative integer constant.
4484 It counts the number of frames to scan up the stack.
4485 The value is the return address saved in that frame. */
4486 if (arglist == 0)
4487 /* Warning about missing arg was already issued. */
4488 return const0_rtx;
4489 else if (! host_integerp (TREE_VALUE (arglist), 1))
4491 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4492 error ("invalid argument to %<__builtin_frame_address%>");
4493 else
4494 error ("invalid argument to %<__builtin_return_address%>");
4495 return const0_rtx;
4497 else
4499 rtx tem
4500 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4501 tree_low_cst (TREE_VALUE (arglist), 1));
4503 /* Some ports cannot access arbitrary stack frames. */
4504 if (tem == NULL)
4506 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4507 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4508 else
4509 warning (0, "unsupported argument to %<__builtin_return_address%>");
4510 return const0_rtx;
4513 /* For __builtin_frame_address, return what we've got. */
4514 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4515 return tem;
4517 if (!REG_P (tem)
4518 && ! CONSTANT_P (tem))
4519 tem = copy_to_mode_reg (Pmode, tem);
4520 return tem;
4524 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4525 we failed and the caller should emit a normal call, otherwise try to get
4526 the result in TARGET, if convenient. */
4528 static rtx
4529 expand_builtin_alloca (tree arglist, rtx target)
4531 rtx op0;
4532 rtx result;
4534 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4535 should always expand to function calls. These can be intercepted
4536 in libmudflap. */
4537 if (flag_mudflap)
4538 return 0;
4540 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4541 return 0;
4543 /* Compute the argument. */
4544 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4546 /* Allocate the desired space. */
4547 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4548 result = convert_memory_address (ptr_mode, result);
4550 return result;
4553 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4554 Return 0 if a normal call should be emitted rather than expanding the
4555 function in-line. If convenient, the result should be placed in TARGET.
4556 SUBTARGET may be used as the target for computing one of EXP's operands. */
4558 static rtx
4559 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4560 rtx subtarget, optab op_optab)
4562 rtx op0;
4563 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4564 return 0;
4566 /* Compute the argument. */
4567 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4568 /* Compute op, into TARGET if possible.
4569 Set TARGET to wherever the result comes back. */
4570 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4571 op_optab, op0, target, 1);
4572 gcc_assert (target);
4574 return convert_to_mode (target_mode, target, 0);
4577 /* If the string passed to fputs is a constant and is one character
4578 long, we attempt to transform this call into __builtin_fputc(). */
4580 static rtx
4581 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4583 /* Verify the arguments in the original call. */
4584 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4586 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4587 unlocked, NULL_TREE);
4588 if (result)
4589 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4591 return 0;
4594 /* Expand a call to __builtin_expect. We return our argument and emit a
4595 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4596 a non-jump context. */
4598 static rtx
4599 expand_builtin_expect (tree arglist, rtx target)
4601 tree exp, c;
4602 rtx note, rtx_c;
4604 if (arglist == NULL_TREE
4605 || TREE_CHAIN (arglist) == NULL_TREE)
4606 return const0_rtx;
4607 exp = TREE_VALUE (arglist);
4608 c = TREE_VALUE (TREE_CHAIN (arglist));
4610 if (TREE_CODE (c) != INTEGER_CST)
4612 error ("second argument to %<__builtin_expect%> must be a constant");
4613 c = integer_zero_node;
4616 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4618 /* Don't bother with expected value notes for integral constants. */
4619 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4621 /* We do need to force this into a register so that we can be
4622 moderately sure to be able to correctly interpret the branch
4623 condition later. */
4624 target = force_reg (GET_MODE (target), target);
4626 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4628 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4629 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4632 return target;
4635 /* Like expand_builtin_expect, except do this in a jump context. This is
4636 called from do_jump if the conditional is a __builtin_expect. Return either
4637 a list of insns to emit the jump or NULL if we cannot optimize
4638 __builtin_expect. We need to optimize this at jump time so that machines
4639 like the PowerPC don't turn the test into a SCC operation, and then jump
4640 based on the test being 0/1. */
4643 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4645 tree arglist = TREE_OPERAND (exp, 1);
4646 tree arg0 = TREE_VALUE (arglist);
4647 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4648 rtx ret = NULL_RTX;
4650 /* Only handle __builtin_expect (test, 0) and
4651 __builtin_expect (test, 1). */
4652 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4653 && (integer_zerop (arg1) || integer_onep (arg1)))
4655 rtx insn, drop_through_label, temp;
4657 /* Expand the jump insns. */
4658 start_sequence ();
4659 do_jump (arg0, if_false_label, if_true_label);
4660 ret = get_insns ();
4662 drop_through_label = get_last_insn ();
4663 if (drop_through_label && NOTE_P (drop_through_label))
4664 drop_through_label = prev_nonnote_insn (drop_through_label);
4665 if (drop_through_label && !LABEL_P (drop_through_label))
4666 drop_through_label = NULL_RTX;
4667 end_sequence ();
4669 if (! if_true_label)
4670 if_true_label = drop_through_label;
4671 if (! if_false_label)
4672 if_false_label = drop_through_label;
4674 /* Go through and add the expect's to each of the conditional jumps. */
4675 insn = ret;
4676 while (insn != NULL_RTX)
4678 rtx next = NEXT_INSN (insn);
4680 if (JUMP_P (insn) && any_condjump_p (insn))
4682 rtx ifelse = SET_SRC (pc_set (insn));
4683 rtx then_dest = XEXP (ifelse, 1);
4684 rtx else_dest = XEXP (ifelse, 2);
4685 int taken = -1;
4687 /* First check if we recognize any of the labels. */
4688 if (GET_CODE (then_dest) == LABEL_REF
4689 && XEXP (then_dest, 0) == if_true_label)
4690 taken = 1;
4691 else if (GET_CODE (then_dest) == LABEL_REF
4692 && XEXP (then_dest, 0) == if_false_label)
4693 taken = 0;
4694 else if (GET_CODE (else_dest) == LABEL_REF
4695 && XEXP (else_dest, 0) == if_false_label)
4696 taken = 1;
4697 else if (GET_CODE (else_dest) == LABEL_REF
4698 && XEXP (else_dest, 0) == if_true_label)
4699 taken = 0;
4700 /* Otherwise check where we drop through. */
4701 else if (else_dest == pc_rtx)
4703 if (next && NOTE_P (next))
4704 next = next_nonnote_insn (next);
4706 if (next && JUMP_P (next)
4707 && any_uncondjump_p (next))
4708 temp = XEXP (SET_SRC (pc_set (next)), 0);
4709 else
4710 temp = next;
4712 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4713 else that can't possibly match either target label. */
4714 if (temp == if_false_label)
4715 taken = 1;
4716 else if (temp == if_true_label)
4717 taken = 0;
4719 else if (then_dest == pc_rtx)
4721 if (next && NOTE_P (next))
4722 next = next_nonnote_insn (next);
4724 if (next && JUMP_P (next)
4725 && any_uncondjump_p (next))
4726 temp = XEXP (SET_SRC (pc_set (next)), 0);
4727 else
4728 temp = next;
4730 if (temp == if_false_label)
4731 taken = 0;
4732 else if (temp == if_true_label)
4733 taken = 1;
4736 if (taken != -1)
4738 /* If the test is expected to fail, reverse the
4739 probabilities. */
4740 if (integer_zerop (arg1))
4741 taken = 1 - taken;
4742 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4746 insn = next;
4750 return ret;
4753 void
4754 expand_builtin_trap (void)
4756 #ifdef HAVE_trap
4757 if (HAVE_trap)
4758 emit_insn (gen_trap ());
4759 else
4760 #endif
4761 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4762 emit_barrier ();
4765 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4766 Return 0 if a normal call should be emitted rather than expanding
4767 the function inline. If convenient, the result should be placed
4768 in TARGET. SUBTARGET may be used as the target for computing
4769 the operand. */
4771 static rtx
4772 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4774 enum machine_mode mode;
4775 tree arg;
4776 rtx op0;
4778 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4779 return 0;
4781 arg = TREE_VALUE (arglist);
4782 mode = TYPE_MODE (TREE_TYPE (arg));
4783 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4784 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4787 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4788 Return NULL is a normal call should be emitted rather than expanding the
4789 function inline. If convenient, the result should be placed in TARGET.
4790 SUBTARGET may be used as the target for computing the operand. */
4792 static rtx
4793 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4795 rtx op0, op1;
4796 tree arg;
4798 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4799 return 0;
4801 arg = TREE_VALUE (arglist);
4802 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4804 arg = TREE_VALUE (TREE_CHAIN (arglist));
4805 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4807 return expand_copysign (op0, op1, target);
4810 /* Create a new constant string literal and return a char* pointer to it.
4811 The STRING_CST value is the LEN characters at STR. */
4812 tree
4813 build_string_literal (int len, const char *str)
4815 tree t, elem, index, type;
4817 t = build_string (len, str);
4818 elem = build_type_variant (char_type_node, 1, 0);
4819 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4820 type = build_array_type (elem, index);
4821 TREE_TYPE (t) = type;
4822 TREE_CONSTANT (t) = 1;
4823 TREE_INVARIANT (t) = 1;
4824 TREE_READONLY (t) = 1;
4825 TREE_STATIC (t) = 1;
4827 type = build_pointer_type (type);
4828 t = build1 (ADDR_EXPR, type, t);
4830 type = build_pointer_type (elem);
4831 t = build1 (NOP_EXPR, type, t);
4832 return t;
4835 /* Expand EXP, a call to printf or printf_unlocked.
4836 Return 0 if a normal call should be emitted rather than transforming
4837 the function inline. If convenient, the result should be placed in
4838 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4839 call. */
4840 static rtx
4841 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4842 bool unlocked)
4844 tree arglist = TREE_OPERAND (exp, 1);
4845 tree fn_putchar = unlocked
4846 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4847 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4848 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4849 : implicit_built_in_decls[BUILT_IN_PUTS];
4850 const char *fmt_str;
4851 tree fn, fmt, arg;
4853 /* If the return value is used, don't do the transformation. */
4854 if (target != const0_rtx)
4855 return 0;
4857 /* Verify the required arguments in the original call. */
4858 if (! arglist)
4859 return 0;
4860 fmt = TREE_VALUE (arglist);
4861 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4862 return 0;
4863 arglist = TREE_CHAIN (arglist);
4865 /* Check whether the format is a literal string constant. */
4866 fmt_str = c_getstr (fmt);
4867 if (fmt_str == NULL)
4868 return 0;
4870 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4871 if (strcmp (fmt_str, "%s\n") == 0)
4873 if (! arglist
4874 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4875 || TREE_CHAIN (arglist))
4876 return 0;
4877 fn = fn_puts;
4879 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4880 else if (strcmp (fmt_str, "%c") == 0)
4882 if (! arglist
4883 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4884 || TREE_CHAIN (arglist))
4885 return 0;
4886 fn = fn_putchar;
4888 else
4890 /* We can't handle anything else with % args or %% ... yet. */
4891 if (strchr (fmt_str, '%'))
4892 return 0;
4894 if (arglist)
4895 return 0;
4897 /* If the format specifier was "", printf does nothing. */
4898 if (fmt_str[0] == '\0')
4899 return const0_rtx;
4900 /* If the format specifier has length of 1, call putchar. */
4901 if (fmt_str[1] == '\0')
4903 /* Given printf("c"), (where c is any one character,)
4904 convert "c"[0] to an int and pass that to the replacement
4905 function. */
4906 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4907 arglist = build_tree_list (NULL_TREE, arg);
4908 fn = fn_putchar;
4910 else
4912 /* If the format specifier was "string\n", call puts("string"). */
4913 size_t len = strlen (fmt_str);
4914 if (fmt_str[len - 1] == '\n')
4916 /* Create a NUL-terminated string that's one char shorter
4917 than the original, stripping off the trailing '\n'. */
4918 char *newstr = alloca (len);
4919 memcpy (newstr, fmt_str, len - 1);
4920 newstr[len - 1] = 0;
4922 arg = build_string_literal (len, newstr);
4923 arglist = build_tree_list (NULL_TREE, arg);
4924 fn = fn_puts;
4926 else
4927 /* We'd like to arrange to call fputs(string,stdout) here,
4928 but we need stdout and don't have a way to get it yet. */
4929 return 0;
4933 if (!fn)
4934 return 0;
4935 fn = build_function_call_expr (fn, arglist);
4936 if (TREE_CODE (fn) == CALL_EXPR)
4937 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4938 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4941 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4942 Return 0 if a normal call should be emitted rather than transforming
4943 the function inline. If convenient, the result should be placed in
4944 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4945 call. */
4946 static rtx
4947 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4948 bool unlocked)
4950 tree arglist = TREE_OPERAND (exp, 1);
4951 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4952 : implicit_built_in_decls[BUILT_IN_FPUTC];
4953 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4954 : implicit_built_in_decls[BUILT_IN_FPUTS];
4955 const char *fmt_str;
4956 tree fn, fmt, fp, arg;
4958 /* If the return value is used, don't do the transformation. */
4959 if (target != const0_rtx)
4960 return 0;
4962 /* Verify the required arguments in the original call. */
4963 if (! arglist)
4964 return 0;
4965 fp = TREE_VALUE (arglist);
4966 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4967 return 0;
4968 arglist = TREE_CHAIN (arglist);
4969 if (! arglist)
4970 return 0;
4971 fmt = TREE_VALUE (arglist);
4972 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4973 return 0;
4974 arglist = TREE_CHAIN (arglist);
4976 /* Check whether the format is a literal string constant. */
4977 fmt_str = c_getstr (fmt);
4978 if (fmt_str == NULL)
4979 return 0;
4981 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4982 if (strcmp (fmt_str, "%s") == 0)
4984 if (! arglist
4985 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4986 || TREE_CHAIN (arglist))
4987 return 0;
4988 arg = TREE_VALUE (arglist);
4989 arglist = build_tree_list (NULL_TREE, fp);
4990 arglist = tree_cons (NULL_TREE, arg, arglist);
4991 fn = fn_fputs;
4993 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4994 else if (strcmp (fmt_str, "%c") == 0)
4996 if (! arglist
4997 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4998 || TREE_CHAIN (arglist))
4999 return 0;
5000 arg = TREE_VALUE (arglist);
5001 arglist = build_tree_list (NULL_TREE, fp);
5002 arglist = tree_cons (NULL_TREE, arg, arglist);
5003 fn = fn_fputc;
5005 else
5007 /* We can't handle anything else with % args or %% ... yet. */
5008 if (strchr (fmt_str, '%'))
5009 return 0;
5011 if (arglist)
5012 return 0;
5014 /* If the format specifier was "", fprintf does nothing. */
5015 if (fmt_str[0] == '\0')
5017 /* Evaluate and ignore FILE* argument for side-effects. */
5018 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5019 return const0_rtx;
5022 /* When "string" doesn't contain %, replace all cases of
5023 fprintf(stream,string) with fputs(string,stream). The fputs
5024 builtin will take care of special cases like length == 1. */
5025 arglist = build_tree_list (NULL_TREE, fp);
5026 arglist = tree_cons (NULL_TREE, fmt, arglist);
5027 fn = fn_fputs;
5030 if (!fn)
5031 return 0;
5032 fn = build_function_call_expr (fn, arglist);
5033 if (TREE_CODE (fn) == CALL_EXPR)
5034 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5035 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5038 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5039 a normal call should be emitted rather than expanding the function
5040 inline. If convenient, the result should be placed in TARGET with
5041 mode MODE. */
5043 static rtx
5044 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5046 tree orig_arglist, dest, fmt;
5047 const char *fmt_str;
5049 orig_arglist = arglist;
5051 /* Verify the required arguments in the original call. */
5052 if (! arglist)
5053 return 0;
5054 dest = TREE_VALUE (arglist);
5055 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5056 return 0;
5057 arglist = TREE_CHAIN (arglist);
5058 if (! arglist)
5059 return 0;
5060 fmt = TREE_VALUE (arglist);
5061 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5062 return 0;
5063 arglist = TREE_CHAIN (arglist);
5065 /* Check whether the format is a literal string constant. */
5066 fmt_str = c_getstr (fmt);
5067 if (fmt_str == NULL)
5068 return 0;
5070 /* If the format doesn't contain % args or %%, use strcpy. */
5071 if (strchr (fmt_str, '%') == 0)
5073 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5074 tree exp;
5076 if (arglist || ! fn)
5077 return 0;
5078 expand_expr (build_function_call_expr (fn, orig_arglist),
5079 const0_rtx, VOIDmode, EXPAND_NORMAL);
5080 if (target == const0_rtx)
5081 return const0_rtx;
5082 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5083 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5085 /* If the format is "%s", use strcpy if the result isn't used. */
5086 else if (strcmp (fmt_str, "%s") == 0)
5088 tree fn, arg, len;
5089 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5091 if (! fn)
5092 return 0;
5094 if (! arglist || TREE_CHAIN (arglist))
5095 return 0;
5096 arg = TREE_VALUE (arglist);
5097 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5098 return 0;
5100 if (target != const0_rtx)
5102 len = c_strlen (arg, 1);
5103 if (! len || TREE_CODE (len) != INTEGER_CST)
5104 return 0;
5106 else
5107 len = NULL_TREE;
5109 arglist = build_tree_list (NULL_TREE, arg);
5110 arglist = tree_cons (NULL_TREE, dest, arglist);
5111 expand_expr (build_function_call_expr (fn, arglist),
5112 const0_rtx, VOIDmode, EXPAND_NORMAL);
5114 if (target == const0_rtx)
5115 return const0_rtx;
5116 return expand_expr (len, target, mode, EXPAND_NORMAL);
5119 return 0;
5122 /* Expand a call to either the entry or exit function profiler. */
5124 static rtx
5125 expand_builtin_profile_func (bool exitp)
5127 rtx this, which;
5129 this = DECL_RTL (current_function_decl);
5130 gcc_assert (MEM_P (this));
5131 this = XEXP (this, 0);
5133 if (exitp)
5134 which = profile_function_exit_libfunc;
5135 else
5136 which = profile_function_entry_libfunc;
5138 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5139 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5141 Pmode);
5143 return const0_rtx;
5146 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5148 static rtx
5149 round_trampoline_addr (rtx tramp)
5151 rtx temp, addend, mask;
5153 /* If we don't need too much alignment, we'll have been guaranteed
5154 proper alignment by get_trampoline_type. */
5155 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5156 return tramp;
5158 /* Round address up to desired boundary. */
5159 temp = gen_reg_rtx (Pmode);
5160 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5161 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5163 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5164 temp, 0, OPTAB_LIB_WIDEN);
5165 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5166 temp, 0, OPTAB_LIB_WIDEN);
5168 return tramp;
5171 static rtx
5172 expand_builtin_init_trampoline (tree arglist)
5174 tree t_tramp, t_func, t_chain;
5175 rtx r_tramp, r_func, r_chain;
5176 #ifdef TRAMPOLINE_TEMPLATE
5177 rtx blktramp;
5178 #endif
5180 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5181 POINTER_TYPE, VOID_TYPE))
5182 return NULL_RTX;
5184 t_tramp = TREE_VALUE (arglist);
5185 arglist = TREE_CHAIN (arglist);
5186 t_func = TREE_VALUE (arglist);
5187 arglist = TREE_CHAIN (arglist);
5188 t_chain = TREE_VALUE (arglist);
5190 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5191 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5192 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5194 /* Generate insns to initialize the trampoline. */
5195 r_tramp = round_trampoline_addr (r_tramp);
5196 #ifdef TRAMPOLINE_TEMPLATE
5197 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5198 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5199 emit_block_move (blktramp, assemble_trampoline_template (),
5200 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5201 #endif
5202 trampolines_created = 1;
5203 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5205 return const0_rtx;
5208 static rtx
5209 expand_builtin_adjust_trampoline (tree arglist)
5211 rtx tramp;
5213 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5214 return NULL_RTX;
5216 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5217 tramp = round_trampoline_addr (tramp);
5218 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5219 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5220 #endif
5222 return tramp;
5225 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5226 Return NULL_RTX if a normal call should be emitted rather than expanding
5227 the function in-line. EXP is the expression that is a call to the builtin
5228 function; if convenient, the result should be placed in TARGET. */
5230 static rtx
5231 expand_builtin_signbit (tree exp, rtx target)
5233 const struct real_format *fmt;
5234 enum machine_mode fmode, imode, rmode;
5235 HOST_WIDE_INT hi, lo;
5236 tree arg, arglist;
5237 int word, bitpos;
5238 rtx temp;
5240 arglist = TREE_OPERAND (exp, 1);
5241 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5242 return 0;
5244 arg = TREE_VALUE (arglist);
5245 fmode = TYPE_MODE (TREE_TYPE (arg));
5246 rmode = TYPE_MODE (TREE_TYPE (exp));
5247 fmt = REAL_MODE_FORMAT (fmode);
5249 /* For floating point formats without a sign bit, implement signbit
5250 as "ARG < 0.0". */
5251 bitpos = fmt->signbit_ro;
5252 if (bitpos < 0)
5254 /* But we can't do this if the format supports signed zero. */
5255 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5256 return 0;
5258 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5259 build_real (TREE_TYPE (arg), dconst0));
5260 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5263 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5264 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5266 imode = int_mode_for_mode (fmode);
5267 if (imode == BLKmode)
5268 return 0;
5269 temp = gen_lowpart (imode, temp);
5271 else
5273 imode = word_mode;
5274 /* Handle targets with different FP word orders. */
5275 if (FLOAT_WORDS_BIG_ENDIAN)
5276 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5277 else
5278 word = bitpos / BITS_PER_WORD;
5279 temp = operand_subword_force (temp, word, fmode);
5280 bitpos = bitpos % BITS_PER_WORD;
5283 /* Force the intermediate word_mode (or narrower) result into a
5284 register. This avoids attempting to create paradoxical SUBREGs
5285 of floating point modes below. */
5286 temp = force_reg (imode, temp);
5288 /* If the bitpos is within the "result mode" lowpart, the operation
5289 can be implement with a single bitwise AND. Otherwise, we need
5290 a right shift and an AND. */
5292 if (bitpos < GET_MODE_BITSIZE (rmode))
5294 if (bitpos < HOST_BITS_PER_WIDE_INT)
5296 hi = 0;
5297 lo = (HOST_WIDE_INT) 1 << bitpos;
5299 else
5301 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5302 lo = 0;
5305 if (imode != rmode)
5306 temp = gen_lowpart (rmode, temp);
5307 temp = expand_binop (rmode, and_optab, temp,
5308 immed_double_const (lo, hi, rmode),
5309 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5311 else
5313 /* Perform a logical right shift to place the signbit in the least
5314 significant bit, then truncate the result to the desired mode
5315 and mask just this bit. */
5316 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5317 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5318 temp = gen_lowpart (rmode, temp);
5319 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5320 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5323 return temp;
5326 /* Expand fork or exec calls. TARGET is the desired target of the
5327 call. ARGLIST is the list of arguments of the call. FN is the
5328 identificator of the actual function. IGNORE is nonzero if the
5329 value is to be ignored. */
5331 static rtx
5332 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5334 tree id, decl;
5335 tree call;
5337 /* If we are not profiling, just call the function. */
5338 if (!profile_arc_flag)
5339 return NULL_RTX;
5341 /* Otherwise call the wrapper. This should be equivalent for the rest of
5342 compiler, so the code does not diverge, and the wrapper may run the
5343 code necessary for keeping the profiling sane. */
5345 switch (DECL_FUNCTION_CODE (fn))
5347 case BUILT_IN_FORK:
5348 id = get_identifier ("__gcov_fork");
5349 break;
5351 case BUILT_IN_EXECL:
5352 id = get_identifier ("__gcov_execl");
5353 break;
5355 case BUILT_IN_EXECV:
5356 id = get_identifier ("__gcov_execv");
5357 break;
5359 case BUILT_IN_EXECLP:
5360 id = get_identifier ("__gcov_execlp");
5361 break;
5363 case BUILT_IN_EXECLE:
5364 id = get_identifier ("__gcov_execle");
5365 break;
5367 case BUILT_IN_EXECVP:
5368 id = get_identifier ("__gcov_execvp");
5369 break;
5371 case BUILT_IN_EXECVE:
5372 id = get_identifier ("__gcov_execve");
5373 break;
5375 default:
5376 gcc_unreachable ();
5379 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5380 DECL_EXTERNAL (decl) = 1;
5381 TREE_PUBLIC (decl) = 1;
5382 DECL_ARTIFICIAL (decl) = 1;
5383 TREE_NOTHROW (decl) = 1;
5384 call = build_function_call_expr (decl, arglist);
5386 return expand_call (call, target, ignore);
5390 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5391 the pointer in these functions is void*, the tree optimizers may remove
5392 casts. The mode computed in expand_builtin isn't reliable either, due
5393 to __sync_bool_compare_and_swap.
5395 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5396 group of builtins. This gives us log2 of the mode size. */
5398 static inline enum machine_mode
5399 get_builtin_sync_mode (int fcode_diff)
5401 /* The size is not negotiable, so ask not to get BLKmode in return
5402 if the target indicates that a smaller size would be better. */
5403 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5406 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5407 ARGLIST is the operands list to the function. CODE is the rtx code
5408 that corresponds to the arithmetic or logical operation from the name;
5409 an exception here is that NOT actually means NAND. TARGET is an optional
5410 place for us to store the results; AFTER is true if this is the
5411 fetch_and_xxx form. IGNORE is true if we don't actually care about
5412 the result of the operation at all. */
5414 static rtx
5415 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5416 enum rtx_code code, bool after,
5417 rtx target, bool ignore)
5419 rtx addr, val, mem;
5421 /* Expand the operands. */
5422 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5424 arglist = TREE_CHAIN (arglist);
5425 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5427 /* Note that we explicitly do not want any alias information for this
5428 memory, so that we kill all other live memories. Otherwise we don't
5429 satisfy the full barrier semantics of the intrinsic. */
5430 mem = validize_mem (gen_rtx_MEM (mode, addr));
5431 MEM_VOLATILE_P (mem) = 1;
5433 if (ignore)
5434 return expand_sync_operation (mem, val, code);
5435 else
5436 return expand_sync_fetch_operation (mem, val, code, after, target);
5439 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5440 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5441 true if this is the boolean form. TARGET is a place for us to store the
5442 results; this is NOT optional if IS_BOOL is true. */
5444 static rtx
5445 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5446 bool is_bool, rtx target)
5448 rtx addr, old_val, new_val, mem;
5450 /* Expand the operands. */
5451 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5453 arglist = TREE_CHAIN (arglist);
5454 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5456 arglist = TREE_CHAIN (arglist);
5457 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5459 /* Note that we explicitly do not want any alias information for this
5460 memory, so that we kill all other live memories. Otherwise we don't
5461 satisfy the full barrier semantics of the intrinsic. */
5462 mem = validize_mem (gen_rtx_MEM (mode, addr));
5463 MEM_VOLATILE_P (mem) = 1;
5465 if (is_bool)
5466 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5467 else
5468 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5471 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5472 general form is actually an atomic exchange, and some targets only
5473 support a reduced form with the second argument being a constant 1.
5474 ARGLIST is the operands list to the function; TARGET is an optional
5475 place for us to store the results. */
5477 static rtx
5478 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5479 rtx target)
5481 rtx addr, val, mem;
5483 /* Expand the operands. */
5484 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5486 arglist = TREE_CHAIN (arglist);
5487 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5489 /* Note that we explicitly do not want any alias information for this
5490 memory, so that we kill all other live memories. Otherwise we don't
5491 satisfy the barrier semantics of the intrinsic. */
5492 mem = validize_mem (gen_rtx_MEM (mode, addr));
5493 MEM_VOLATILE_P (mem) = 1;
5495 return expand_sync_lock_test_and_set (mem, val, target);
5498 /* Expand the __sync_synchronize intrinsic. */
5500 static void
5501 expand_builtin_synchronize (void)
5503 tree x;
5505 #ifdef HAVE_memory_barrier
5506 if (HAVE_memory_barrier)
5508 emit_insn (gen_memory_barrier ());
5509 return;
5511 #endif
5513 /* If no explicit memory barrier instruction is available, create an
5514 empty asm stmt with a memory clobber. */
5515 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5516 tree_cons (NULL, build_string (6, "memory"), NULL));
5517 ASM_VOLATILE_P (x) = 1;
5518 expand_asm_expr (x);
5521 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5522 to the function. */
5524 static void
5525 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5527 enum insn_code icode;
5528 rtx addr, mem, insn;
5529 rtx val = const0_rtx;
5531 /* Expand the operands. */
5532 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5534 /* Note that we explicitly do not want any alias information for this
5535 memory, so that we kill all other live memories. Otherwise we don't
5536 satisfy the barrier semantics of the intrinsic. */
5537 mem = validize_mem (gen_rtx_MEM (mode, addr));
5538 MEM_VOLATILE_P (mem) = 1;
5540 /* If there is an explicit operation in the md file, use it. */
5541 icode = sync_lock_release[mode];
5542 if (icode != CODE_FOR_nothing)
5544 if (!insn_data[icode].operand[1].predicate (val, mode))
5545 val = force_reg (mode, val);
5547 insn = GEN_FCN (icode) (mem, val);
5548 if (insn)
5550 emit_insn (insn);
5551 return;
5555 /* Otherwise we can implement this operation by emitting a barrier
5556 followed by a store of zero. */
5557 expand_builtin_synchronize ();
5558 emit_move_insn (mem, val);
5561 /* Expand an expression EXP that calls a built-in function,
5562 with result going to TARGET if that's convenient
5563 (and in mode MODE if that's convenient).
5564 SUBTARGET may be used as the target for computing one of EXP's operands.
5565 IGNORE is nonzero if the value is to be ignored. */
5568 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5569 int ignore)
5571 tree fndecl = get_callee_fndecl (exp);
5572 tree arglist = TREE_OPERAND (exp, 1);
5573 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5574 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5576 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5577 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5579 /* When not optimizing, generate calls to library functions for a certain
5580 set of builtins. */
5581 if (!optimize
5582 && !called_as_built_in (fndecl)
5583 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5584 && fcode != BUILT_IN_ALLOCA)
5585 return expand_call (exp, target, ignore);
5587 /* The built-in function expanders test for target == const0_rtx
5588 to determine whether the function's result will be ignored. */
5589 if (ignore)
5590 target = const0_rtx;
5592 /* If the result of a pure or const built-in function is ignored, and
5593 none of its arguments are volatile, we can avoid expanding the
5594 built-in call and just evaluate the arguments for side-effects. */
5595 if (target == const0_rtx
5596 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5598 bool volatilep = false;
5599 tree arg;
5601 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5602 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5604 volatilep = true;
5605 break;
5608 if (! volatilep)
5610 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5611 expand_expr (TREE_VALUE (arg), const0_rtx,
5612 VOIDmode, EXPAND_NORMAL);
5613 return const0_rtx;
5617 switch (fcode)
5619 case BUILT_IN_FABS:
5620 case BUILT_IN_FABSF:
5621 case BUILT_IN_FABSL:
5622 target = expand_builtin_fabs (arglist, target, subtarget);
5623 if (target)
5624 return target;
5625 break;
5627 case BUILT_IN_COPYSIGN:
5628 case BUILT_IN_COPYSIGNF:
5629 case BUILT_IN_COPYSIGNL:
5630 target = expand_builtin_copysign (arglist, target, subtarget);
5631 if (target)
5632 return target;
5633 break;
5635 /* Just do a normal library call if we were unable to fold
5636 the values. */
5637 case BUILT_IN_CABS:
5638 case BUILT_IN_CABSF:
5639 case BUILT_IN_CABSL:
5640 break;
5642 case BUILT_IN_EXP:
5643 case BUILT_IN_EXPF:
5644 case BUILT_IN_EXPL:
5645 case BUILT_IN_EXP10:
5646 case BUILT_IN_EXP10F:
5647 case BUILT_IN_EXP10L:
5648 case BUILT_IN_POW10:
5649 case BUILT_IN_POW10F:
5650 case BUILT_IN_POW10L:
5651 case BUILT_IN_EXP2:
5652 case BUILT_IN_EXP2F:
5653 case BUILT_IN_EXP2L:
5654 case BUILT_IN_EXPM1:
5655 case BUILT_IN_EXPM1F:
5656 case BUILT_IN_EXPM1L:
5657 case BUILT_IN_LOGB:
5658 case BUILT_IN_LOGBF:
5659 case BUILT_IN_LOGBL:
5660 case BUILT_IN_ILOGB:
5661 case BUILT_IN_ILOGBF:
5662 case BUILT_IN_ILOGBL:
5663 case BUILT_IN_LOG:
5664 case BUILT_IN_LOGF:
5665 case BUILT_IN_LOGL:
5666 case BUILT_IN_LOG10:
5667 case BUILT_IN_LOG10F:
5668 case BUILT_IN_LOG10L:
5669 case BUILT_IN_LOG2:
5670 case BUILT_IN_LOG2F:
5671 case BUILT_IN_LOG2L:
5672 case BUILT_IN_LOG1P:
5673 case BUILT_IN_LOG1PF:
5674 case BUILT_IN_LOG1PL:
5675 case BUILT_IN_TAN:
5676 case BUILT_IN_TANF:
5677 case BUILT_IN_TANL:
5678 case BUILT_IN_ASIN:
5679 case BUILT_IN_ASINF:
5680 case BUILT_IN_ASINL:
5681 case BUILT_IN_ACOS:
5682 case BUILT_IN_ACOSF:
5683 case BUILT_IN_ACOSL:
5684 case BUILT_IN_ATAN:
5685 case BUILT_IN_ATANF:
5686 case BUILT_IN_ATANL:
5687 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5688 because of possible accuracy problems. */
5689 if (! flag_unsafe_math_optimizations)
5690 break;
5691 case BUILT_IN_SQRT:
5692 case BUILT_IN_SQRTF:
5693 case BUILT_IN_SQRTL:
5694 case BUILT_IN_FLOOR:
5695 case BUILT_IN_FLOORF:
5696 case BUILT_IN_FLOORL:
5697 case BUILT_IN_CEIL:
5698 case BUILT_IN_CEILF:
5699 case BUILT_IN_CEILL:
5700 case BUILT_IN_TRUNC:
5701 case BUILT_IN_TRUNCF:
5702 case BUILT_IN_TRUNCL:
5703 case BUILT_IN_ROUND:
5704 case BUILT_IN_ROUNDF:
5705 case BUILT_IN_ROUNDL:
5706 case BUILT_IN_NEARBYINT:
5707 case BUILT_IN_NEARBYINTF:
5708 case BUILT_IN_NEARBYINTL:
5709 case BUILT_IN_RINT:
5710 case BUILT_IN_RINTF:
5711 case BUILT_IN_RINTL:
5712 case BUILT_IN_LRINT:
5713 case BUILT_IN_LRINTF:
5714 case BUILT_IN_LRINTL:
5715 case BUILT_IN_LLRINT:
5716 case BUILT_IN_LLRINTF:
5717 case BUILT_IN_LLRINTL:
5718 target = expand_builtin_mathfn (exp, target, subtarget);
5719 if (target)
5720 return target;
5721 break;
5723 case BUILT_IN_LCEIL:
5724 case BUILT_IN_LCEILF:
5725 case BUILT_IN_LCEILL:
5726 case BUILT_IN_LLCEIL:
5727 case BUILT_IN_LLCEILF:
5728 case BUILT_IN_LLCEILL:
5729 case BUILT_IN_LFLOOR:
5730 case BUILT_IN_LFLOORF:
5731 case BUILT_IN_LFLOORL:
5732 case BUILT_IN_LLFLOOR:
5733 case BUILT_IN_LLFLOORF:
5734 case BUILT_IN_LLFLOORL:
5735 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5736 if (target)
5737 return target;
5738 break;
5740 case BUILT_IN_POW:
5741 case BUILT_IN_POWF:
5742 case BUILT_IN_POWL:
5743 target = expand_builtin_pow (exp, target, subtarget);
5744 if (target)
5745 return target;
5746 break;
5748 case BUILT_IN_POWI:
5749 case BUILT_IN_POWIF:
5750 case BUILT_IN_POWIL:
5751 target = expand_builtin_powi (exp, target, subtarget);
5752 if (target)
5753 return target;
5754 break;
5756 case BUILT_IN_ATAN2:
5757 case BUILT_IN_ATAN2F:
5758 case BUILT_IN_ATAN2L:
5759 case BUILT_IN_LDEXP:
5760 case BUILT_IN_LDEXPF:
5761 case BUILT_IN_LDEXPL:
5762 case BUILT_IN_FMOD:
5763 case BUILT_IN_FMODF:
5764 case BUILT_IN_FMODL:
5765 case BUILT_IN_DREM:
5766 case BUILT_IN_DREMF:
5767 case BUILT_IN_DREML:
5768 if (! flag_unsafe_math_optimizations)
5769 break;
5770 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5771 if (target)
5772 return target;
5773 break;
5775 case BUILT_IN_SIN:
5776 case BUILT_IN_SINF:
5777 case BUILT_IN_SINL:
5778 case BUILT_IN_COS:
5779 case BUILT_IN_COSF:
5780 case BUILT_IN_COSL:
5781 if (! flag_unsafe_math_optimizations)
5782 break;
5783 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5784 if (target)
5785 return target;
5786 break;
5788 case BUILT_IN_APPLY_ARGS:
5789 return expand_builtin_apply_args ();
5791 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5792 FUNCTION with a copy of the parameters described by
5793 ARGUMENTS, and ARGSIZE. It returns a block of memory
5794 allocated on the stack into which is stored all the registers
5795 that might possibly be used for returning the result of a
5796 function. ARGUMENTS is the value returned by
5797 __builtin_apply_args. ARGSIZE is the number of bytes of
5798 arguments that must be copied. ??? How should this value be
5799 computed? We'll also need a safe worst case value for varargs
5800 functions. */
5801 case BUILT_IN_APPLY:
5802 if (!validate_arglist (arglist, POINTER_TYPE,
5803 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5804 && !validate_arglist (arglist, REFERENCE_TYPE,
5805 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5806 return const0_rtx;
5807 else
5809 int i;
5810 tree t;
5811 rtx ops[3];
5813 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5814 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5816 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5819 /* __builtin_return (RESULT) causes the function to return the
5820 value described by RESULT. RESULT is address of the block of
5821 memory returned by __builtin_apply. */
5822 case BUILT_IN_RETURN:
5823 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5824 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5825 NULL_RTX, VOIDmode, 0));
5826 return const0_rtx;
5828 case BUILT_IN_SAVEREGS:
5829 return expand_builtin_saveregs ();
5831 case BUILT_IN_ARGS_INFO:
5832 return expand_builtin_args_info (arglist);
5834 /* Return the address of the first anonymous stack arg. */
5835 case BUILT_IN_NEXT_ARG:
5836 if (fold_builtin_next_arg (arglist))
5837 return const0_rtx;
5838 return expand_builtin_next_arg ();
5840 case BUILT_IN_CLASSIFY_TYPE:
5841 return expand_builtin_classify_type (arglist);
5843 case BUILT_IN_CONSTANT_P:
5844 return const0_rtx;
5846 case BUILT_IN_FRAME_ADDRESS:
5847 case BUILT_IN_RETURN_ADDRESS:
5848 return expand_builtin_frame_address (fndecl, arglist);
5850 /* Returns the address of the area where the structure is returned.
5851 0 otherwise. */
5852 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5853 if (arglist != 0
5854 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5855 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5856 return const0_rtx;
5857 else
5858 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5860 case BUILT_IN_ALLOCA:
5861 target = expand_builtin_alloca (arglist, target);
5862 if (target)
5863 return target;
5864 break;
5866 case BUILT_IN_STACK_SAVE:
5867 return expand_stack_save ();
5869 case BUILT_IN_STACK_RESTORE:
5870 expand_stack_restore (TREE_VALUE (arglist));
5871 return const0_rtx;
5873 case BUILT_IN_FFS:
5874 case BUILT_IN_FFSL:
5875 case BUILT_IN_FFSLL:
5876 case BUILT_IN_FFSIMAX:
5877 target = expand_builtin_unop (target_mode, arglist, target,
5878 subtarget, ffs_optab);
5879 if (target)
5880 return target;
5881 break;
5883 case BUILT_IN_CLZ:
5884 case BUILT_IN_CLZL:
5885 case BUILT_IN_CLZLL:
5886 case BUILT_IN_CLZIMAX:
5887 target = expand_builtin_unop (target_mode, arglist, target,
5888 subtarget, clz_optab);
5889 if (target)
5890 return target;
5891 break;
5893 case BUILT_IN_CTZ:
5894 case BUILT_IN_CTZL:
5895 case BUILT_IN_CTZLL:
5896 case BUILT_IN_CTZIMAX:
5897 target = expand_builtin_unop (target_mode, arglist, target,
5898 subtarget, ctz_optab);
5899 if (target)
5900 return target;
5901 break;
5903 case BUILT_IN_POPCOUNT:
5904 case BUILT_IN_POPCOUNTL:
5905 case BUILT_IN_POPCOUNTLL:
5906 case BUILT_IN_POPCOUNTIMAX:
5907 target = expand_builtin_unop (target_mode, arglist, target,
5908 subtarget, popcount_optab);
5909 if (target)
5910 return target;
5911 break;
5913 case BUILT_IN_PARITY:
5914 case BUILT_IN_PARITYL:
5915 case BUILT_IN_PARITYLL:
5916 case BUILT_IN_PARITYIMAX:
5917 target = expand_builtin_unop (target_mode, arglist, target,
5918 subtarget, parity_optab);
5919 if (target)
5920 return target;
5921 break;
5923 case BUILT_IN_STRLEN:
5924 target = expand_builtin_strlen (arglist, target, target_mode);
5925 if (target)
5926 return target;
5927 break;
5929 case BUILT_IN_STRCPY:
5930 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5931 if (target)
5932 return target;
5933 break;
5935 case BUILT_IN_STRNCPY:
5936 target = expand_builtin_strncpy (exp, target, mode);
5937 if (target)
5938 return target;
5939 break;
5941 case BUILT_IN_STPCPY:
5942 target = expand_builtin_stpcpy (exp, target, mode);
5943 if (target)
5944 return target;
5945 break;
5947 case BUILT_IN_STRCAT:
5948 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5949 if (target)
5950 return target;
5951 break;
5953 case BUILT_IN_STRNCAT:
5954 target = expand_builtin_strncat (arglist, target, mode);
5955 if (target)
5956 return target;
5957 break;
5959 case BUILT_IN_STRSPN:
5960 target = expand_builtin_strspn (arglist, target, mode);
5961 if (target)
5962 return target;
5963 break;
5965 case BUILT_IN_STRCSPN:
5966 target = expand_builtin_strcspn (arglist, target, mode);
5967 if (target)
5968 return target;
5969 break;
5971 case BUILT_IN_STRSTR:
5972 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5973 if (target)
5974 return target;
5975 break;
5977 case BUILT_IN_STRPBRK:
5978 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5979 if (target)
5980 return target;
5981 break;
5983 case BUILT_IN_INDEX:
5984 case BUILT_IN_STRCHR:
5985 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5986 if (target)
5987 return target;
5988 break;
5990 case BUILT_IN_RINDEX:
5991 case BUILT_IN_STRRCHR:
5992 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5993 if (target)
5994 return target;
5995 break;
5997 case BUILT_IN_MEMCPY:
5998 target = expand_builtin_memcpy (exp, target, mode);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_MEMPCPY:
6004 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6005 if (target)
6006 return target;
6007 break;
6009 case BUILT_IN_MEMMOVE:
6010 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6011 mode, exp);
6012 if (target)
6013 return target;
6014 break;
6016 case BUILT_IN_BCOPY:
6017 target = expand_builtin_bcopy (exp);
6018 if (target)
6019 return target;
6020 break;
6022 case BUILT_IN_MEMSET:
6023 target = expand_builtin_memset (arglist, target, mode, exp);
6024 if (target)
6025 return target;
6026 break;
6028 case BUILT_IN_BZERO:
6029 target = expand_builtin_bzero (exp);
6030 if (target)
6031 return target;
6032 break;
6034 case BUILT_IN_STRCMP:
6035 target = expand_builtin_strcmp (exp, target, mode);
6036 if (target)
6037 return target;
6038 break;
6040 case BUILT_IN_STRNCMP:
6041 target = expand_builtin_strncmp (exp, target, mode);
6042 if (target)
6043 return target;
6044 break;
6046 case BUILT_IN_BCMP:
6047 case BUILT_IN_MEMCMP:
6048 target = expand_builtin_memcmp (exp, arglist, target, mode);
6049 if (target)
6050 return target;
6051 break;
6053 case BUILT_IN_SETJMP:
6054 target = expand_builtin_setjmp (arglist, target);
6055 if (target)
6056 return target;
6057 break;
6059 /* __builtin_longjmp is passed a pointer to an array of five words.
6060 It's similar to the C library longjmp function but works with
6061 __builtin_setjmp above. */
6062 case BUILT_IN_LONGJMP:
6063 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6064 break;
6065 else
6067 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6068 VOIDmode, 0);
6069 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6070 NULL_RTX, VOIDmode, 0);
6072 if (value != const1_rtx)
6074 error ("%<__builtin_longjmp%> second argument must be 1");
6075 return const0_rtx;
6078 expand_builtin_longjmp (buf_addr, value);
6079 return const0_rtx;
6082 case BUILT_IN_NONLOCAL_GOTO:
6083 target = expand_builtin_nonlocal_goto (arglist);
6084 if (target)
6085 return target;
6086 break;
6088 /* This updates the setjmp buffer that is its argument with the value
6089 of the current stack pointer. */
6090 case BUILT_IN_UPDATE_SETJMP_BUF:
6091 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6093 rtx buf_addr
6094 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6096 expand_builtin_update_setjmp_buf (buf_addr);
6097 return const0_rtx;
6099 break;
6101 case BUILT_IN_TRAP:
6102 expand_builtin_trap ();
6103 return const0_rtx;
6105 case BUILT_IN_PRINTF:
6106 target = expand_builtin_printf (exp, target, mode, false);
6107 if (target)
6108 return target;
6109 break;
6111 case BUILT_IN_PRINTF_UNLOCKED:
6112 target = expand_builtin_printf (exp, target, mode, true);
6113 if (target)
6114 return target;
6115 break;
6117 case BUILT_IN_FPUTS:
6118 target = expand_builtin_fputs (arglist, target, false);
6119 if (target)
6120 return target;
6121 break;
6122 case BUILT_IN_FPUTS_UNLOCKED:
6123 target = expand_builtin_fputs (arglist, target, true);
6124 if (target)
6125 return target;
6126 break;
6128 case BUILT_IN_FPRINTF:
6129 target = expand_builtin_fprintf (exp, target, mode, false);
6130 if (target)
6131 return target;
6132 break;
6134 case BUILT_IN_FPRINTF_UNLOCKED:
6135 target = expand_builtin_fprintf (exp, target, mode, true);
6136 if (target)
6137 return target;
6138 break;
6140 case BUILT_IN_SPRINTF:
6141 target = expand_builtin_sprintf (arglist, target, mode);
6142 if (target)
6143 return target;
6144 break;
6146 case BUILT_IN_SIGNBIT:
6147 case BUILT_IN_SIGNBITF:
6148 case BUILT_IN_SIGNBITL:
6149 target = expand_builtin_signbit (exp, target);
6150 if (target)
6151 return target;
6152 break;
6154 /* Various hooks for the DWARF 2 __throw routine. */
6155 case BUILT_IN_UNWIND_INIT:
6156 expand_builtin_unwind_init ();
6157 return const0_rtx;
6158 case BUILT_IN_DWARF_CFA:
6159 return virtual_cfa_rtx;
6160 #ifdef DWARF2_UNWIND_INFO
6161 case BUILT_IN_DWARF_SP_COLUMN:
6162 return expand_builtin_dwarf_sp_column ();
6163 case BUILT_IN_INIT_DWARF_REG_SIZES:
6164 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6165 return const0_rtx;
6166 #endif
6167 case BUILT_IN_FROB_RETURN_ADDR:
6168 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6169 case BUILT_IN_EXTRACT_RETURN_ADDR:
6170 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6171 case BUILT_IN_EH_RETURN:
6172 expand_builtin_eh_return (TREE_VALUE (arglist),
6173 TREE_VALUE (TREE_CHAIN (arglist)));
6174 return const0_rtx;
6175 #ifdef EH_RETURN_DATA_REGNO
6176 case BUILT_IN_EH_RETURN_DATA_REGNO:
6177 return expand_builtin_eh_return_data_regno (arglist);
6178 #endif
6179 case BUILT_IN_EXTEND_POINTER:
6180 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6182 case BUILT_IN_VA_START:
6183 case BUILT_IN_STDARG_START:
6184 return expand_builtin_va_start (arglist);
6185 case BUILT_IN_VA_END:
6186 return expand_builtin_va_end (arglist);
6187 case BUILT_IN_VA_COPY:
6188 return expand_builtin_va_copy (arglist);
6189 case BUILT_IN_EXPECT:
6190 return expand_builtin_expect (arglist, target);
6191 case BUILT_IN_PREFETCH:
6192 expand_builtin_prefetch (arglist);
6193 return const0_rtx;
6195 case BUILT_IN_PROFILE_FUNC_ENTER:
6196 return expand_builtin_profile_func (false);
6197 case BUILT_IN_PROFILE_FUNC_EXIT:
6198 return expand_builtin_profile_func (true);
6200 case BUILT_IN_INIT_TRAMPOLINE:
6201 return expand_builtin_init_trampoline (arglist);
6202 case BUILT_IN_ADJUST_TRAMPOLINE:
6203 return expand_builtin_adjust_trampoline (arglist);
6205 case BUILT_IN_FORK:
6206 case BUILT_IN_EXECL:
6207 case BUILT_IN_EXECV:
6208 case BUILT_IN_EXECLP:
6209 case BUILT_IN_EXECLE:
6210 case BUILT_IN_EXECVP:
6211 case BUILT_IN_EXECVE:
6212 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6213 if (target)
6214 return target;
6215 break;
6217 case BUILT_IN_FETCH_AND_ADD_1:
6218 case BUILT_IN_FETCH_AND_ADD_2:
6219 case BUILT_IN_FETCH_AND_ADD_4:
6220 case BUILT_IN_FETCH_AND_ADD_8:
6221 case BUILT_IN_FETCH_AND_ADD_16:
6222 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6223 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6224 false, target, ignore);
6225 if (target)
6226 return target;
6227 break;
6229 case BUILT_IN_FETCH_AND_SUB_1:
6230 case BUILT_IN_FETCH_AND_SUB_2:
6231 case BUILT_IN_FETCH_AND_SUB_4:
6232 case BUILT_IN_FETCH_AND_SUB_8:
6233 case BUILT_IN_FETCH_AND_SUB_16:
6234 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6235 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6236 false, target, ignore);
6237 if (target)
6238 return target;
6239 break;
6241 case BUILT_IN_FETCH_AND_OR_1:
6242 case BUILT_IN_FETCH_AND_OR_2:
6243 case BUILT_IN_FETCH_AND_OR_4:
6244 case BUILT_IN_FETCH_AND_OR_8:
6245 case BUILT_IN_FETCH_AND_OR_16:
6246 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6247 target = expand_builtin_sync_operation (mode, arglist, IOR,
6248 false, target, ignore);
6249 if (target)
6250 return target;
6251 break;
6253 case BUILT_IN_FETCH_AND_AND_1:
6254 case BUILT_IN_FETCH_AND_AND_2:
6255 case BUILT_IN_FETCH_AND_AND_4:
6256 case BUILT_IN_FETCH_AND_AND_8:
6257 case BUILT_IN_FETCH_AND_AND_16:
6258 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6259 target = expand_builtin_sync_operation (mode, arglist, AND,
6260 false, target, ignore);
6261 if (target)
6262 return target;
6263 break;
6265 case BUILT_IN_FETCH_AND_XOR_1:
6266 case BUILT_IN_FETCH_AND_XOR_2:
6267 case BUILT_IN_FETCH_AND_XOR_4:
6268 case BUILT_IN_FETCH_AND_XOR_8:
6269 case BUILT_IN_FETCH_AND_XOR_16:
6270 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6271 target = expand_builtin_sync_operation (mode, arglist, XOR,
6272 false, target, ignore);
6273 if (target)
6274 return target;
6275 break;
6277 case BUILT_IN_FETCH_AND_NAND_1:
6278 case BUILT_IN_FETCH_AND_NAND_2:
6279 case BUILT_IN_FETCH_AND_NAND_4:
6280 case BUILT_IN_FETCH_AND_NAND_8:
6281 case BUILT_IN_FETCH_AND_NAND_16:
6282 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6283 target = expand_builtin_sync_operation (mode, arglist, NOT,
6284 false, target, ignore);
6285 if (target)
6286 return target;
6287 break;
6289 case BUILT_IN_ADD_AND_FETCH_1:
6290 case BUILT_IN_ADD_AND_FETCH_2:
6291 case BUILT_IN_ADD_AND_FETCH_4:
6292 case BUILT_IN_ADD_AND_FETCH_8:
6293 case BUILT_IN_ADD_AND_FETCH_16:
6294 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6295 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6296 true, target, ignore);
6297 if (target)
6298 return target;
6299 break;
6301 case BUILT_IN_SUB_AND_FETCH_1:
6302 case BUILT_IN_SUB_AND_FETCH_2:
6303 case BUILT_IN_SUB_AND_FETCH_4:
6304 case BUILT_IN_SUB_AND_FETCH_8:
6305 case BUILT_IN_SUB_AND_FETCH_16:
6306 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6307 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6308 true, target, ignore);
6309 if (target)
6310 return target;
6311 break;
6313 case BUILT_IN_OR_AND_FETCH_1:
6314 case BUILT_IN_OR_AND_FETCH_2:
6315 case BUILT_IN_OR_AND_FETCH_4:
6316 case BUILT_IN_OR_AND_FETCH_8:
6317 case BUILT_IN_OR_AND_FETCH_16:
6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6319 target = expand_builtin_sync_operation (mode, arglist, IOR,
6320 true, target, ignore);
6321 if (target)
6322 return target;
6323 break;
6325 case BUILT_IN_AND_AND_FETCH_1:
6326 case BUILT_IN_AND_AND_FETCH_2:
6327 case BUILT_IN_AND_AND_FETCH_4:
6328 case BUILT_IN_AND_AND_FETCH_8:
6329 case BUILT_IN_AND_AND_FETCH_16:
6330 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6331 target = expand_builtin_sync_operation (mode, arglist, AND,
6332 true, target, ignore);
6333 if (target)
6334 return target;
6335 break;
6337 case BUILT_IN_XOR_AND_FETCH_1:
6338 case BUILT_IN_XOR_AND_FETCH_2:
6339 case BUILT_IN_XOR_AND_FETCH_4:
6340 case BUILT_IN_XOR_AND_FETCH_8:
6341 case BUILT_IN_XOR_AND_FETCH_16:
6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6343 target = expand_builtin_sync_operation (mode, arglist, XOR,
6344 true, target, ignore);
6345 if (target)
6346 return target;
6347 break;
6349 case BUILT_IN_NAND_AND_FETCH_1:
6350 case BUILT_IN_NAND_AND_FETCH_2:
6351 case BUILT_IN_NAND_AND_FETCH_4:
6352 case BUILT_IN_NAND_AND_FETCH_8:
6353 case BUILT_IN_NAND_AND_FETCH_16:
6354 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6355 target = expand_builtin_sync_operation (mode, arglist, NOT,
6356 true, target, ignore);
6357 if (target)
6358 return target;
6359 break;
6361 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6362 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6363 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6364 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6365 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6366 if (mode == VOIDmode)
6367 mode = TYPE_MODE (boolean_type_node);
6368 if (!target || !register_operand (target, mode))
6369 target = gen_reg_rtx (mode);
6371 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6372 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6373 if (target)
6374 return target;
6375 break;
6377 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6378 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6379 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6380 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6381 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6382 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6383 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6384 if (target)
6385 return target;
6386 break;
6388 case BUILT_IN_LOCK_TEST_AND_SET_1:
6389 case BUILT_IN_LOCK_TEST_AND_SET_2:
6390 case BUILT_IN_LOCK_TEST_AND_SET_4:
6391 case BUILT_IN_LOCK_TEST_AND_SET_8:
6392 case BUILT_IN_LOCK_TEST_AND_SET_16:
6393 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6394 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6395 if (target)
6396 return target;
6397 break;
6399 case BUILT_IN_LOCK_RELEASE_1:
6400 case BUILT_IN_LOCK_RELEASE_2:
6401 case BUILT_IN_LOCK_RELEASE_4:
6402 case BUILT_IN_LOCK_RELEASE_8:
6403 case BUILT_IN_LOCK_RELEASE_16:
6404 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6405 expand_builtin_lock_release (mode, arglist);
6406 return const0_rtx;
6408 case BUILT_IN_SYNCHRONIZE:
6409 expand_builtin_synchronize ();
6410 return const0_rtx;
6412 case BUILT_IN_OBJECT_SIZE:
6413 return expand_builtin_object_size (exp);
6415 case BUILT_IN_MEMCPY_CHK:
6416 case BUILT_IN_MEMPCPY_CHK:
6417 case BUILT_IN_MEMMOVE_CHK:
6418 case BUILT_IN_MEMSET_CHK:
6419 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6420 if (target)
6421 return target;
6422 break;
6424 case BUILT_IN_STRCPY_CHK:
6425 case BUILT_IN_STPCPY_CHK:
6426 case BUILT_IN_STRNCPY_CHK:
6427 case BUILT_IN_STRCAT_CHK:
6428 case BUILT_IN_SNPRINTF_CHK:
6429 case BUILT_IN_VSNPRINTF_CHK:
6430 maybe_emit_chk_warning (exp, fcode);
6431 break;
6433 case BUILT_IN_SPRINTF_CHK:
6434 case BUILT_IN_VSPRINTF_CHK:
6435 maybe_emit_sprintf_chk_warning (exp, fcode);
6436 break;
6438 default: /* just do library call, if unknown builtin */
6439 break;
6442 /* The switch statement above can drop through to cause the function
6443 to be called normally. */
6444 return expand_call (exp, target, ignore);
6447 /* Determine whether a tree node represents a call to a built-in
6448 function. If the tree T is a call to a built-in function with
6449 the right number of arguments of the appropriate types, return
6450 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6451 Otherwise the return value is END_BUILTINS. */
6453 enum built_in_function
6454 builtin_mathfn_code (tree t)
6456 tree fndecl, arglist, parmlist;
6457 tree argtype, parmtype;
6459 if (TREE_CODE (t) != CALL_EXPR
6460 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6461 return END_BUILTINS;
6463 fndecl = get_callee_fndecl (t);
6464 if (fndecl == NULL_TREE
6465 || TREE_CODE (fndecl) != FUNCTION_DECL
6466 || ! DECL_BUILT_IN (fndecl)
6467 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6468 return END_BUILTINS;
6470 arglist = TREE_OPERAND (t, 1);
6471 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6472 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6474 /* If a function doesn't take a variable number of arguments,
6475 the last element in the list will have type `void'. */
6476 parmtype = TREE_VALUE (parmlist);
6477 if (VOID_TYPE_P (parmtype))
6479 if (arglist)
6480 return END_BUILTINS;
6481 return DECL_FUNCTION_CODE (fndecl);
6484 if (! arglist)
6485 return END_BUILTINS;
6487 argtype = TREE_TYPE (TREE_VALUE (arglist));
6489 if (SCALAR_FLOAT_TYPE_P (parmtype))
6491 if (! SCALAR_FLOAT_TYPE_P (argtype))
6492 return END_BUILTINS;
6494 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6496 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6497 return END_BUILTINS;
6499 else if (POINTER_TYPE_P (parmtype))
6501 if (! POINTER_TYPE_P (argtype))
6502 return END_BUILTINS;
6504 else if (INTEGRAL_TYPE_P (parmtype))
6506 if (! INTEGRAL_TYPE_P (argtype))
6507 return END_BUILTINS;
6509 else
6510 return END_BUILTINS;
6512 arglist = TREE_CHAIN (arglist);
6515 /* Variable-length argument list. */
6516 return DECL_FUNCTION_CODE (fndecl);
6519 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6520 constant. ARGLIST is the argument list of the call. */
6522 static tree
6523 fold_builtin_constant_p (tree arglist)
6525 if (arglist == 0)
6526 return 0;
6528 arglist = TREE_VALUE (arglist);
6530 /* We return 1 for a numeric type that's known to be a constant
6531 value at compile-time or for an aggregate type that's a
6532 literal constant. */
6533 STRIP_NOPS (arglist);
6535 /* If we know this is a constant, emit the constant of one. */
6536 if (CONSTANT_CLASS_P (arglist)
6537 || (TREE_CODE (arglist) == CONSTRUCTOR
6538 && TREE_CONSTANT (arglist)))
6539 return integer_one_node;
6540 if (TREE_CODE (arglist) == ADDR_EXPR)
6542 tree op = TREE_OPERAND (arglist, 0);
6543 if (TREE_CODE (op) == STRING_CST
6544 || (TREE_CODE (op) == ARRAY_REF
6545 && integer_zerop (TREE_OPERAND (op, 1))
6546 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6547 return integer_one_node;
6550 /* If this expression has side effects, show we don't know it to be a
6551 constant. Likewise if it's a pointer or aggregate type since in
6552 those case we only want literals, since those are only optimized
6553 when generating RTL, not later.
6554 And finally, if we are compiling an initializer, not code, we
6555 need to return a definite result now; there's not going to be any
6556 more optimization done. */
6557 if (TREE_SIDE_EFFECTS (arglist)
6558 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6559 || POINTER_TYPE_P (TREE_TYPE (arglist))
6560 || cfun == 0)
6561 return integer_zero_node;
6563 return 0;
6566 /* Fold a call to __builtin_expect, if we expect that a comparison against
6567 the argument will fold to a constant. In practice, this means a true
6568 constant or the address of a non-weak symbol. ARGLIST is the argument
6569 list of the call. */
6571 static tree
6572 fold_builtin_expect (tree arglist)
6574 tree arg, inner;
6576 if (arglist == 0)
6577 return 0;
6579 arg = TREE_VALUE (arglist);
6581 /* If the argument isn't invariant, then there's nothing we can do. */
6582 if (!TREE_INVARIANT (arg))
6583 return 0;
6585 /* If we're looking at an address of a weak decl, then do not fold. */
6586 inner = arg;
6587 STRIP_NOPS (inner);
6588 if (TREE_CODE (inner) == ADDR_EXPR)
6592 inner = TREE_OPERAND (inner, 0);
6594 while (TREE_CODE (inner) == COMPONENT_REF
6595 || TREE_CODE (inner) == ARRAY_REF);
6596 if (DECL_P (inner) && DECL_WEAK (inner))
6597 return 0;
6600 /* Otherwise, ARG already has the proper type for the return value. */
6601 return arg;
6604 /* Fold a call to __builtin_classify_type. */
6606 static tree
6607 fold_builtin_classify_type (tree arglist)
6609 if (arglist == 0)
6610 return build_int_cst (NULL_TREE, no_type_class);
6612 return build_int_cst (NULL_TREE,
6613 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6616 /* Fold a call to __builtin_strlen. */
6618 static tree
6619 fold_builtin_strlen (tree arglist)
6621 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6622 return NULL_TREE;
6623 else
6625 tree len = c_strlen (TREE_VALUE (arglist), 0);
6627 if (len)
6629 /* Convert from the internal "sizetype" type to "size_t". */
6630 if (size_type_node)
6631 len = fold_convert (size_type_node, len);
6632 return len;
6635 return NULL_TREE;
6639 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6641 static tree
6642 fold_builtin_inf (tree type, int warn)
6644 REAL_VALUE_TYPE real;
6646 /* __builtin_inff is intended to be usable to define INFINITY on all
6647 targets. If an infinity is not available, INFINITY expands "to a
6648 positive constant of type float that overflows at translation
6649 time", footnote "In this case, using INFINITY will violate the
6650 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6651 Thus we pedwarn to ensure this constraint violation is
6652 diagnosed. */
6653 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6654 pedwarn ("target format does not support infinity");
6656 real_inf (&real);
6657 return build_real (type, real);
6660 /* Fold a call to __builtin_nan or __builtin_nans. */
6662 static tree
6663 fold_builtin_nan (tree arglist, tree type, int quiet)
6665 REAL_VALUE_TYPE real;
6666 const char *str;
6668 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6669 return 0;
6670 str = c_getstr (TREE_VALUE (arglist));
6671 if (!str)
6672 return 0;
6674 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6675 return 0;
6677 return build_real (type, real);
6680 /* Return true if the floating point expression T has an integer value.
6681 We also allow +Inf, -Inf and NaN to be considered integer values. */
6683 static bool
6684 integer_valued_real_p (tree t)
6686 switch (TREE_CODE (t))
6688 case FLOAT_EXPR:
6689 return true;
6691 case ABS_EXPR:
6692 case SAVE_EXPR:
6693 case NON_LVALUE_EXPR:
6694 return integer_valued_real_p (TREE_OPERAND (t, 0));
6696 case COMPOUND_EXPR:
6697 case MODIFY_EXPR:
6698 case BIND_EXPR:
6699 return integer_valued_real_p (TREE_OPERAND (t, 1));
6701 case PLUS_EXPR:
6702 case MINUS_EXPR:
6703 case MULT_EXPR:
6704 case MIN_EXPR:
6705 case MAX_EXPR:
6706 return integer_valued_real_p (TREE_OPERAND (t, 0))
6707 && integer_valued_real_p (TREE_OPERAND (t, 1));
6709 case COND_EXPR:
6710 return integer_valued_real_p (TREE_OPERAND (t, 1))
6711 && integer_valued_real_p (TREE_OPERAND (t, 2));
6713 case REAL_CST:
6714 if (! TREE_CONSTANT_OVERFLOW (t))
6716 REAL_VALUE_TYPE c, cint;
6718 c = TREE_REAL_CST (t);
6719 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6720 return real_identical (&c, &cint);
6723 case NOP_EXPR:
6725 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6726 if (TREE_CODE (type) == INTEGER_TYPE)
6727 return true;
6728 if (TREE_CODE (type) == REAL_TYPE)
6729 return integer_valued_real_p (TREE_OPERAND (t, 0));
6730 break;
6733 case CALL_EXPR:
6734 switch (builtin_mathfn_code (t))
6736 case BUILT_IN_CEIL:
6737 case BUILT_IN_CEILF:
6738 case BUILT_IN_CEILL:
6739 case BUILT_IN_FLOOR:
6740 case BUILT_IN_FLOORF:
6741 case BUILT_IN_FLOORL:
6742 case BUILT_IN_NEARBYINT:
6743 case BUILT_IN_NEARBYINTF:
6744 case BUILT_IN_NEARBYINTL:
6745 case BUILT_IN_RINT:
6746 case BUILT_IN_RINTF:
6747 case BUILT_IN_RINTL:
6748 case BUILT_IN_ROUND:
6749 case BUILT_IN_ROUNDF:
6750 case BUILT_IN_ROUNDL:
6751 case BUILT_IN_TRUNC:
6752 case BUILT_IN_TRUNCF:
6753 case BUILT_IN_TRUNCL:
6754 return true;
6756 default:
6757 break;
6759 break;
6761 default:
6762 break;
6764 return false;
6767 /* EXP is assumed to be builtin call where truncation can be propagated
6768 across (for instance floor((double)f) == (double)floorf (f).
6769 Do the transformation. */
6771 static tree
6772 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6774 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6775 tree arg;
6777 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6778 return 0;
6780 arg = TREE_VALUE (arglist);
6781 /* Integer rounding functions are idempotent. */
6782 if (fcode == builtin_mathfn_code (arg))
6783 return arg;
6785 /* If argument is already integer valued, and we don't need to worry
6786 about setting errno, there's no need to perform rounding. */
6787 if (! flag_errno_math && integer_valued_real_p (arg))
6788 return arg;
6790 if (optimize)
6792 tree arg0 = strip_float_extensions (arg);
6793 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6794 tree newtype = TREE_TYPE (arg0);
6795 tree decl;
6797 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6798 && (decl = mathfn_built_in (newtype, fcode)))
6800 arglist =
6801 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6802 return fold_convert (ftype,
6803 build_function_call_expr (decl, arglist));
6806 return 0;
6809 /* EXP is assumed to be builtin call which can narrow the FP type of
6810 the argument, for instance lround((double)f) -> lroundf (f). */
6812 static tree
6813 fold_fixed_mathfn (tree fndecl, tree arglist)
6815 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6816 tree arg;
6818 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6819 return 0;
6821 arg = TREE_VALUE (arglist);
6823 /* If argument is already integer valued, and we don't need to worry
6824 about setting errno, there's no need to perform rounding. */
6825 if (! flag_errno_math && integer_valued_real_p (arg))
6826 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6828 if (optimize)
6830 tree ftype = TREE_TYPE (arg);
6831 tree arg0 = strip_float_extensions (arg);
6832 tree newtype = TREE_TYPE (arg0);
6833 tree decl;
6835 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6836 && (decl = mathfn_built_in (newtype, fcode)))
6838 arglist =
6839 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6840 return build_function_call_expr (decl, arglist);
6843 return 0;
6846 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6847 is the argument list and TYPE is the return type. Return
6848 NULL_TREE if no if no simplification can be made. */
6850 static tree
6851 fold_builtin_cabs (tree arglist, tree type)
6853 tree arg;
6855 if (!arglist || TREE_CHAIN (arglist))
6856 return NULL_TREE;
6858 arg = TREE_VALUE (arglist);
6859 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6860 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6861 return NULL_TREE;
6863 /* Evaluate cabs of a constant at compile-time. */
6864 if (flag_unsafe_math_optimizations
6865 && TREE_CODE (arg) == COMPLEX_CST
6866 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6867 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6868 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6869 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6871 REAL_VALUE_TYPE r, i;
6873 r = TREE_REAL_CST (TREE_REALPART (arg));
6874 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6876 real_arithmetic (&r, MULT_EXPR, &r, &r);
6877 real_arithmetic (&i, MULT_EXPR, &i, &i);
6878 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6879 if (real_sqrt (&r, TYPE_MODE (type), &r)
6880 || ! flag_trapping_math)
6881 return build_real (type, r);
6884 /* If either part is zero, cabs is fabs of the other. */
6885 if (TREE_CODE (arg) == COMPLEX_EXPR
6886 && real_zerop (TREE_OPERAND (arg, 0)))
6887 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6888 if (TREE_CODE (arg) == COMPLEX_EXPR
6889 && real_zerop (TREE_OPERAND (arg, 1)))
6890 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6892 /* Don't do this when optimizing for size. */
6893 if (flag_unsafe_math_optimizations
6894 && optimize && !optimize_size)
6896 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6898 if (sqrtfn != NULL_TREE)
6900 tree rpart, ipart, result, arglist;
6902 arg = builtin_save_expr (arg);
6904 rpart = fold_build1 (REALPART_EXPR, type, arg);
6905 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6907 rpart = builtin_save_expr (rpart);
6908 ipart = builtin_save_expr (ipart);
6910 result = fold_build2 (PLUS_EXPR, type,
6911 fold_build2 (MULT_EXPR, type,
6912 rpart, rpart),
6913 fold_build2 (MULT_EXPR, type,
6914 ipart, ipart));
6916 arglist = build_tree_list (NULL_TREE, result);
6917 return build_function_call_expr (sqrtfn, arglist);
6921 return NULL_TREE;
6924 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6925 NULL_TREE if no simplification can be made. */
6927 static tree
6928 fold_builtin_sqrt (tree arglist, tree type)
6931 enum built_in_function fcode;
6932 tree arg = TREE_VALUE (arglist);
6934 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6935 return NULL_TREE;
6937 /* Optimize sqrt of constant value. */
6938 if (TREE_CODE (arg) == REAL_CST
6939 && ! TREE_CONSTANT_OVERFLOW (arg))
6941 REAL_VALUE_TYPE r, x;
6943 x = TREE_REAL_CST (arg);
6944 if (real_sqrt (&r, TYPE_MODE (type), &x)
6945 || (!flag_trapping_math && !flag_errno_math))
6946 return build_real (type, r);
6949 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6950 fcode = builtin_mathfn_code (arg);
6951 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6953 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6954 arg = fold_build2 (MULT_EXPR, type,
6955 TREE_VALUE (TREE_OPERAND (arg, 1)),
6956 build_real (type, dconsthalf));
6957 arglist = build_tree_list (NULL_TREE, arg);
6958 return build_function_call_expr (expfn, arglist);
6961 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6962 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6964 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6966 if (powfn)
6968 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6969 tree tree_root;
6970 /* The inner root was either sqrt or cbrt. */
6971 REAL_VALUE_TYPE dconstroot =
6972 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6974 /* Adjust for the outer root. */
6975 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6976 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6977 tree_root = build_real (type, dconstroot);
6978 arglist = tree_cons (NULL_TREE, arg0,
6979 build_tree_list (NULL_TREE, tree_root));
6980 return build_function_call_expr (powfn, arglist);
6984 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6985 if (flag_unsafe_math_optimizations
6986 && (fcode == BUILT_IN_POW
6987 || fcode == BUILT_IN_POWF
6988 || fcode == BUILT_IN_POWL))
6990 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6991 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6992 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6993 tree narg1;
6994 if (!tree_expr_nonnegative_p (arg0))
6995 arg0 = build1 (ABS_EXPR, type, arg0);
6996 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6997 build_real (type, dconsthalf));
6998 arglist = tree_cons (NULL_TREE, arg0,
6999 build_tree_list (NULL_TREE, narg1));
7000 return build_function_call_expr (powfn, arglist);
7003 return NULL_TREE;
7006 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7007 NULL_TREE if no simplification can be made. */
7008 static tree
7009 fold_builtin_cbrt (tree arglist, tree type)
7011 tree arg = TREE_VALUE (arglist);
7012 const enum built_in_function fcode = builtin_mathfn_code (arg);
7014 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7015 return NULL_TREE;
7017 /* Optimize cbrt of constant value. */
7018 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7019 return arg;
7021 if (flag_unsafe_math_optimizations)
7023 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7024 if (BUILTIN_EXPONENT_P (fcode))
7026 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7027 const REAL_VALUE_TYPE third_trunc =
7028 real_value_truncate (TYPE_MODE (type), dconstthird);
7029 arg = fold_build2 (MULT_EXPR, type,
7030 TREE_VALUE (TREE_OPERAND (arg, 1)),
7031 build_real (type, third_trunc));
7032 arglist = build_tree_list (NULL_TREE, arg);
7033 return build_function_call_expr (expfn, arglist);
7036 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7037 if (BUILTIN_SQRT_P (fcode))
7039 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7041 if (powfn)
7043 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7044 tree tree_root;
7045 REAL_VALUE_TYPE dconstroot = dconstthird;
7047 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7048 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7049 tree_root = build_real (type, dconstroot);
7050 arglist = tree_cons (NULL_TREE, arg0,
7051 build_tree_list (NULL_TREE, tree_root));
7052 return build_function_call_expr (powfn, arglist);
7056 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7057 if (BUILTIN_CBRT_P (fcode))
7059 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7060 if (tree_expr_nonnegative_p (arg0))
7062 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7064 if (powfn)
7066 tree tree_root;
7067 REAL_VALUE_TYPE dconstroot;
7069 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7070 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7071 tree_root = build_real (type, dconstroot);
7072 arglist = tree_cons (NULL_TREE, arg0,
7073 build_tree_list (NULL_TREE, tree_root));
7074 return build_function_call_expr (powfn, arglist);
7079 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7080 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7081 || fcode == BUILT_IN_POWL)
7083 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7084 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7085 if (tree_expr_nonnegative_p (arg00))
7087 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7088 const REAL_VALUE_TYPE dconstroot
7089 = real_value_truncate (TYPE_MODE (type), dconstthird);
7090 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7091 build_real (type, dconstroot));
7092 arglist = tree_cons (NULL_TREE, arg00,
7093 build_tree_list (NULL_TREE, narg01));
7094 return build_function_call_expr (powfn, arglist);
7098 return NULL_TREE;
7101 /* Fold function call to builtin sin, sinf, or sinl. Return
7102 NULL_TREE if no simplification can be made. */
7103 static tree
7104 fold_builtin_sin (tree arglist)
7106 tree arg = TREE_VALUE (arglist);
7108 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7109 return NULL_TREE;
7111 /* Optimize sin (0.0) = 0.0. */
7112 if (real_zerop (arg))
7113 return arg;
7115 return NULL_TREE;
7118 /* Fold function call to builtin cos, cosf, or cosl. Return
7119 NULL_TREE if no simplification can be made. */
7120 static tree
7121 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7123 tree arg = TREE_VALUE (arglist);
7125 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7126 return NULL_TREE;
7128 /* Optimize cos (0.0) = 1.0. */
7129 if (real_zerop (arg))
7130 return build_real (type, dconst1);
7132 /* Optimize cos(-x) into cos (x). */
7133 if (TREE_CODE (arg) == NEGATE_EXPR)
7135 tree args = build_tree_list (NULL_TREE,
7136 TREE_OPERAND (arg, 0));
7137 return build_function_call_expr (fndecl, args);
7140 return NULL_TREE;
7143 /* Fold function call to builtin tan, tanf, or tanl. Return
7144 NULL_TREE if no simplification can be made. */
7145 static tree
7146 fold_builtin_tan (tree arglist)
7148 enum built_in_function fcode;
7149 tree arg = TREE_VALUE (arglist);
7151 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7152 return NULL_TREE;
7154 /* Optimize tan(0.0) = 0.0. */
7155 if (real_zerop (arg))
7156 return arg;
7158 /* Optimize tan(atan(x)) = x. */
7159 fcode = builtin_mathfn_code (arg);
7160 if (flag_unsafe_math_optimizations
7161 && (fcode == BUILT_IN_ATAN
7162 || fcode == BUILT_IN_ATANF
7163 || fcode == BUILT_IN_ATANL))
7164 return TREE_VALUE (TREE_OPERAND (arg, 1));
7166 return NULL_TREE;
7169 /* Fold function call to builtin atan, atanf, or atanl. Return
7170 NULL_TREE if no simplification can be made. */
7172 static tree
7173 fold_builtin_atan (tree arglist, tree type)
7176 tree arg = TREE_VALUE (arglist);
7178 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7179 return NULL_TREE;
7181 /* Optimize atan(0.0) = 0.0. */
7182 if (real_zerop (arg))
7183 return arg;
7185 /* Optimize atan(1.0) = pi/4. */
7186 if (real_onep (arg))
7188 REAL_VALUE_TYPE cst;
7190 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7191 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7192 return build_real (type, cst);
7195 return NULL_TREE;
7198 /* Fold function call to builtin trunc, truncf or truncl. Return
7199 NULL_TREE if no simplification can be made. */
7201 static tree
7202 fold_builtin_trunc (tree fndecl, tree arglist)
7204 tree arg;
7206 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7207 return 0;
7209 /* Optimize trunc of constant value. */
7210 arg = TREE_VALUE (arglist);
7211 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7213 REAL_VALUE_TYPE r, x;
7214 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7216 x = TREE_REAL_CST (arg);
7217 real_trunc (&r, TYPE_MODE (type), &x);
7218 return build_real (type, r);
7221 return fold_trunc_transparent_mathfn (fndecl, arglist);
7224 /* Fold function call to builtin floor, floorf or floorl. Return
7225 NULL_TREE if no simplification can be made. */
7227 static tree
7228 fold_builtin_floor (tree fndecl, tree arglist)
7230 tree arg;
7232 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7233 return 0;
7235 /* Optimize floor of constant value. */
7236 arg = TREE_VALUE (arglist);
7237 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7239 REAL_VALUE_TYPE x;
7241 x = TREE_REAL_CST (arg);
7242 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7244 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7245 REAL_VALUE_TYPE r;
7247 real_floor (&r, TYPE_MODE (type), &x);
7248 return build_real (type, r);
7252 return fold_trunc_transparent_mathfn (fndecl, arglist);
7255 /* Fold function call to builtin ceil, ceilf or ceill. Return
7256 NULL_TREE if no simplification can be made. */
7258 static tree
7259 fold_builtin_ceil (tree fndecl, tree arglist)
7261 tree arg;
7263 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7264 return 0;
7266 /* Optimize ceil of constant value. */
7267 arg = TREE_VALUE (arglist);
7268 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7270 REAL_VALUE_TYPE x;
7272 x = TREE_REAL_CST (arg);
7273 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7275 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7276 REAL_VALUE_TYPE r;
7278 real_ceil (&r, TYPE_MODE (type), &x);
7279 return build_real (type, r);
7283 return fold_trunc_transparent_mathfn (fndecl, arglist);
7286 /* Fold function call to builtin round, roundf or roundl. Return
7287 NULL_TREE if no simplification can be made. */
7289 static tree
7290 fold_builtin_round (tree fndecl, tree arglist)
7292 tree arg;
7294 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7295 return 0;
7297 /* Optimize round of constant value. */
7298 arg = TREE_VALUE (arglist);
7299 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7301 REAL_VALUE_TYPE x;
7303 x = TREE_REAL_CST (arg);
7304 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7306 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7307 REAL_VALUE_TYPE r;
7309 real_round (&r, TYPE_MODE (type), &x);
7310 return build_real (type, r);
7314 return fold_trunc_transparent_mathfn (fndecl, arglist);
7317 /* Fold function call to builtin lround, lroundf or lroundl (or the
7318 corresponding long long versions) and other rounding functions.
7319 Return NULL_TREE if no simplification can be made. */
7321 static tree
7322 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7324 tree arg;
7326 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7327 return 0;
7329 /* Optimize lround of constant value. */
7330 arg = TREE_VALUE (arglist);
7331 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7333 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7335 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7337 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7338 tree ftype = TREE_TYPE (arg), result;
7339 HOST_WIDE_INT hi, lo;
7340 REAL_VALUE_TYPE r;
7342 switch (DECL_FUNCTION_CODE (fndecl))
7344 case BUILT_IN_LFLOOR:
7345 case BUILT_IN_LFLOORF:
7346 case BUILT_IN_LFLOORL:
7347 case BUILT_IN_LLFLOOR:
7348 case BUILT_IN_LLFLOORF:
7349 case BUILT_IN_LLFLOORL:
7350 real_floor (&r, TYPE_MODE (ftype), &x);
7351 break;
7353 case BUILT_IN_LCEIL:
7354 case BUILT_IN_LCEILF:
7355 case BUILT_IN_LCEILL:
7356 case BUILT_IN_LLCEIL:
7357 case BUILT_IN_LLCEILF:
7358 case BUILT_IN_LLCEILL:
7359 real_ceil (&r, TYPE_MODE (ftype), &x);
7360 break;
7362 case BUILT_IN_LROUND:
7363 case BUILT_IN_LROUNDF:
7364 case BUILT_IN_LROUNDL:
7365 case BUILT_IN_LLROUND:
7366 case BUILT_IN_LLROUNDF:
7367 case BUILT_IN_LLROUNDL:
7368 real_round (&r, TYPE_MODE (ftype), &x);
7369 break;
7371 default:
7372 gcc_unreachable ();
7375 REAL_VALUE_TO_INT (&lo, &hi, r);
7376 result = build_int_cst_wide (NULL_TREE, lo, hi);
7377 if (int_fits_type_p (result, itype))
7378 return fold_convert (itype, result);
7382 return fold_fixed_mathfn (fndecl, arglist);
7385 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7386 and their long and long long variants (i.e. ffsl and ffsll).
7387 Return NULL_TREE if no simplification can be made. */
7389 static tree
7390 fold_builtin_bitop (tree fndecl, tree arglist)
7392 tree arg;
7394 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7395 return NULL_TREE;
7397 /* Optimize for constant argument. */
7398 arg = TREE_VALUE (arglist);
7399 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7401 HOST_WIDE_INT hi, width, result;
7402 unsigned HOST_WIDE_INT lo;
7403 tree type;
7405 type = TREE_TYPE (arg);
7406 width = TYPE_PRECISION (type);
7407 lo = TREE_INT_CST_LOW (arg);
7409 /* Clear all the bits that are beyond the type's precision. */
7410 if (width > HOST_BITS_PER_WIDE_INT)
7412 hi = TREE_INT_CST_HIGH (arg);
7413 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7414 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7416 else
7418 hi = 0;
7419 if (width < HOST_BITS_PER_WIDE_INT)
7420 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7423 switch (DECL_FUNCTION_CODE (fndecl))
7425 case BUILT_IN_FFS:
7426 case BUILT_IN_FFSL:
7427 case BUILT_IN_FFSLL:
7428 if (lo != 0)
7429 result = exact_log2 (lo & -lo) + 1;
7430 else if (hi != 0)
7431 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7432 else
7433 result = 0;
7434 break;
7436 case BUILT_IN_CLZ:
7437 case BUILT_IN_CLZL:
7438 case BUILT_IN_CLZLL:
7439 if (hi != 0)
7440 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7441 else if (lo != 0)
7442 result = width - floor_log2 (lo) - 1;
7443 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7444 result = width;
7445 break;
7447 case BUILT_IN_CTZ:
7448 case BUILT_IN_CTZL:
7449 case BUILT_IN_CTZLL:
7450 if (lo != 0)
7451 result = exact_log2 (lo & -lo);
7452 else if (hi != 0)
7453 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7454 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7455 result = width;
7456 break;
7458 case BUILT_IN_POPCOUNT:
7459 case BUILT_IN_POPCOUNTL:
7460 case BUILT_IN_POPCOUNTLL:
7461 result = 0;
7462 while (lo)
7463 result++, lo &= lo - 1;
7464 while (hi)
7465 result++, hi &= hi - 1;
7466 break;
7468 case BUILT_IN_PARITY:
7469 case BUILT_IN_PARITYL:
7470 case BUILT_IN_PARITYLL:
7471 result = 0;
7472 while (lo)
7473 result++, lo &= lo - 1;
7474 while (hi)
7475 result++, hi &= hi - 1;
7476 result &= 1;
7477 break;
7479 default:
7480 gcc_unreachable ();
7483 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7486 return NULL_TREE;
7489 /* Return true if EXPR is the real constant contained in VALUE. */
7491 static bool
7492 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7494 STRIP_NOPS (expr);
7496 return ((TREE_CODE (expr) == REAL_CST
7497 && ! TREE_CONSTANT_OVERFLOW (expr)
7498 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7499 || (TREE_CODE (expr) == COMPLEX_CST
7500 && real_dconstp (TREE_REALPART (expr), value)
7501 && real_zerop (TREE_IMAGPART (expr))));
7504 /* A subroutine of fold_builtin to fold the various logarithmic
7505 functions. EXP is the CALL_EXPR of a call to a builtin logN
7506 function. VALUE is the base of the logN function. */
7508 static tree
7509 fold_builtin_logarithm (tree fndecl, tree arglist,
7510 const REAL_VALUE_TYPE *value)
7512 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7514 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7515 tree arg = TREE_VALUE (arglist);
7516 const enum built_in_function fcode = builtin_mathfn_code (arg);
7518 /* Optimize logN(1.0) = 0.0. */
7519 if (real_onep (arg))
7520 return build_real (type, dconst0);
7522 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7523 exactly, then only do this if flag_unsafe_math_optimizations. */
7524 if (exact_real_truncate (TYPE_MODE (type), value)
7525 || flag_unsafe_math_optimizations)
7527 const REAL_VALUE_TYPE value_truncate =
7528 real_value_truncate (TYPE_MODE (type), *value);
7529 if (real_dconstp (arg, &value_truncate))
7530 return build_real (type, dconst1);
7533 /* Special case, optimize logN(expN(x)) = x. */
7534 if (flag_unsafe_math_optimizations
7535 && ((value == &dconste
7536 && (fcode == BUILT_IN_EXP
7537 || fcode == BUILT_IN_EXPF
7538 || fcode == BUILT_IN_EXPL))
7539 || (value == &dconst2
7540 && (fcode == BUILT_IN_EXP2
7541 || fcode == BUILT_IN_EXP2F
7542 || fcode == BUILT_IN_EXP2L))
7543 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7544 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7546 /* Optimize logN(func()) for various exponential functions. We
7547 want to determine the value "x" and the power "exponent" in
7548 order to transform logN(x**exponent) into exponent*logN(x). */
7549 if (flag_unsafe_math_optimizations)
7551 tree exponent = 0, x = 0;
7553 switch (fcode)
7555 case BUILT_IN_EXP:
7556 case BUILT_IN_EXPF:
7557 case BUILT_IN_EXPL:
7558 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7559 x = build_real (type,
7560 real_value_truncate (TYPE_MODE (type), dconste));
7561 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7562 break;
7563 case BUILT_IN_EXP2:
7564 case BUILT_IN_EXP2F:
7565 case BUILT_IN_EXP2L:
7566 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7567 x = build_real (type, dconst2);
7568 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7569 break;
7570 case BUILT_IN_EXP10:
7571 case BUILT_IN_EXP10F:
7572 case BUILT_IN_EXP10L:
7573 case BUILT_IN_POW10:
7574 case BUILT_IN_POW10F:
7575 case BUILT_IN_POW10L:
7576 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7577 x = build_real (type, dconst10);
7578 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7579 break;
7580 case BUILT_IN_SQRT:
7581 case BUILT_IN_SQRTF:
7582 case BUILT_IN_SQRTL:
7583 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7584 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7585 exponent = build_real (type, dconsthalf);
7586 break;
7587 case BUILT_IN_CBRT:
7588 case BUILT_IN_CBRTF:
7589 case BUILT_IN_CBRTL:
7590 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7591 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7592 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7593 dconstthird));
7594 break;
7595 case BUILT_IN_POW:
7596 case BUILT_IN_POWF:
7597 case BUILT_IN_POWL:
7598 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7599 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7600 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7601 break;
7602 default:
7603 break;
7606 /* Now perform the optimization. */
7607 if (x && exponent)
7609 tree logfn;
7610 arglist = build_tree_list (NULL_TREE, x);
7611 logfn = build_function_call_expr (fndecl, arglist);
7612 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7617 return 0;
7620 /* Fold a builtin function call to pow, powf, or powl. Return
7621 NULL_TREE if no simplification can be made. */
7622 static tree
7623 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7625 tree arg0 = TREE_VALUE (arglist);
7626 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7628 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7629 return NULL_TREE;
7631 /* Optimize pow(1.0,y) = 1.0. */
7632 if (real_onep (arg0))
7633 return omit_one_operand (type, build_real (type, dconst1), arg1);
7635 if (TREE_CODE (arg1) == REAL_CST
7636 && ! TREE_CONSTANT_OVERFLOW (arg1))
7638 REAL_VALUE_TYPE cint;
7639 REAL_VALUE_TYPE c;
7640 HOST_WIDE_INT n;
7642 c = TREE_REAL_CST (arg1);
7644 /* Optimize pow(x,0.0) = 1.0. */
7645 if (REAL_VALUES_EQUAL (c, dconst0))
7646 return omit_one_operand (type, build_real (type, dconst1),
7647 arg0);
7649 /* Optimize pow(x,1.0) = x. */
7650 if (REAL_VALUES_EQUAL (c, dconst1))
7651 return arg0;
7653 /* Optimize pow(x,-1.0) = 1.0/x. */
7654 if (REAL_VALUES_EQUAL (c, dconstm1))
7655 return fold_build2 (RDIV_EXPR, type,
7656 build_real (type, dconst1), arg0);
7658 /* Optimize pow(x,0.5) = sqrt(x). */
7659 if (flag_unsafe_math_optimizations
7660 && REAL_VALUES_EQUAL (c, dconsthalf))
7662 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7664 if (sqrtfn != NULL_TREE)
7666 tree arglist = build_tree_list (NULL_TREE, arg0);
7667 return build_function_call_expr (sqrtfn, arglist);
7671 /* Check for an integer exponent. */
7672 n = real_to_integer (&c);
7673 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7674 if (real_identical (&c, &cint))
7676 /* Attempt to evaluate pow at compile-time. */
7677 if (TREE_CODE (arg0) == REAL_CST
7678 && ! TREE_CONSTANT_OVERFLOW (arg0))
7680 REAL_VALUE_TYPE x;
7681 bool inexact;
7683 x = TREE_REAL_CST (arg0);
7684 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7685 if (flag_unsafe_math_optimizations || !inexact)
7686 return build_real (type, x);
7689 /* Strip sign ops from even integer powers. */
7690 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7692 tree narg0 = fold_strip_sign_ops (arg0);
7693 if (narg0)
7695 arglist = build_tree_list (NULL_TREE, arg1);
7696 arglist = tree_cons (NULL_TREE, narg0, arglist);
7697 return build_function_call_expr (fndecl, arglist);
7703 if (flag_unsafe_math_optimizations)
7705 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7707 /* Optimize pow(expN(x),y) = expN(x*y). */
7708 if (BUILTIN_EXPONENT_P (fcode))
7710 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7711 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7712 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7713 arglist = build_tree_list (NULL_TREE, arg);
7714 return build_function_call_expr (expfn, arglist);
7717 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7718 if (BUILTIN_SQRT_P (fcode))
7720 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7721 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7722 build_real (type, dconsthalf));
7724 arglist = tree_cons (NULL_TREE, narg0,
7725 build_tree_list (NULL_TREE, narg1));
7726 return build_function_call_expr (fndecl, arglist);
7729 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7730 if (BUILTIN_CBRT_P (fcode))
7732 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7733 if (tree_expr_nonnegative_p (arg))
7735 const REAL_VALUE_TYPE dconstroot
7736 = real_value_truncate (TYPE_MODE (type), dconstthird);
7737 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7738 build_real (type, dconstroot));
7739 arglist = tree_cons (NULL_TREE, arg,
7740 build_tree_list (NULL_TREE, narg1));
7741 return build_function_call_expr (fndecl, arglist);
7745 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7746 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7747 || fcode == BUILT_IN_POWL)
7749 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7750 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7751 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7752 arglist = tree_cons (NULL_TREE, arg00,
7753 build_tree_list (NULL_TREE, narg1));
7754 return build_function_call_expr (fndecl, arglist);
7758 return NULL_TREE;
7761 /* Fold a builtin function call to powi, powif, or powil. Return
7762 NULL_TREE if no simplification can be made. */
7763 static tree
7764 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7766 tree arg0 = TREE_VALUE (arglist);
7767 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7769 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7770 return NULL_TREE;
7772 /* Optimize pow(1.0,y) = 1.0. */
7773 if (real_onep (arg0))
7774 return omit_one_operand (type, build_real (type, dconst1), arg1);
7776 if (host_integerp (arg1, 0))
7778 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7780 /* Evaluate powi at compile-time. */
7781 if (TREE_CODE (arg0) == REAL_CST
7782 && ! TREE_CONSTANT_OVERFLOW (arg0))
7784 REAL_VALUE_TYPE x;
7785 x = TREE_REAL_CST (arg0);
7786 real_powi (&x, TYPE_MODE (type), &x, c);
7787 return build_real (type, x);
7790 /* Optimize pow(x,0) = 1.0. */
7791 if (c == 0)
7792 return omit_one_operand (type, build_real (type, dconst1),
7793 arg0);
7795 /* Optimize pow(x,1) = x. */
7796 if (c == 1)
7797 return arg0;
7799 /* Optimize pow(x,-1) = 1.0/x. */
7800 if (c == -1)
7801 return fold_build2 (RDIV_EXPR, type,
7802 build_real (type, dconst1), arg0);
7805 return NULL_TREE;
7808 /* A subroutine of fold_builtin to fold the various exponent
7809 functions. EXP is the CALL_EXPR of a call to a builtin function.
7810 VALUE is the value which will be raised to a power. */
7812 static tree
7813 fold_builtin_exponent (tree fndecl, tree arglist,
7814 const REAL_VALUE_TYPE *value)
7816 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7818 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7819 tree arg = TREE_VALUE (arglist);
7821 /* Optimize exp*(0.0) = 1.0. */
7822 if (real_zerop (arg))
7823 return build_real (type, dconst1);
7825 /* Optimize expN(1.0) = N. */
7826 if (real_onep (arg))
7828 REAL_VALUE_TYPE cst;
7830 real_convert (&cst, TYPE_MODE (type), value);
7831 return build_real (type, cst);
7834 /* Attempt to evaluate expN(integer) at compile-time. */
7835 if (flag_unsafe_math_optimizations
7836 && TREE_CODE (arg) == REAL_CST
7837 && ! TREE_CONSTANT_OVERFLOW (arg))
7839 REAL_VALUE_TYPE cint;
7840 REAL_VALUE_TYPE c;
7841 HOST_WIDE_INT n;
7843 c = TREE_REAL_CST (arg);
7844 n = real_to_integer (&c);
7845 real_from_integer (&cint, VOIDmode, n,
7846 n < 0 ? -1 : 0, 0);
7847 if (real_identical (&c, &cint))
7849 REAL_VALUE_TYPE x;
7851 real_powi (&x, TYPE_MODE (type), value, n);
7852 return build_real (type, x);
7856 /* Optimize expN(logN(x)) = x. */
7857 if (flag_unsafe_math_optimizations)
7859 const enum built_in_function fcode = builtin_mathfn_code (arg);
7861 if ((value == &dconste
7862 && (fcode == BUILT_IN_LOG
7863 || fcode == BUILT_IN_LOGF
7864 || fcode == BUILT_IN_LOGL))
7865 || (value == &dconst2
7866 && (fcode == BUILT_IN_LOG2
7867 || fcode == BUILT_IN_LOG2F
7868 || fcode == BUILT_IN_LOG2L))
7869 || (value == &dconst10
7870 && (fcode == BUILT_IN_LOG10
7871 || fcode == BUILT_IN_LOG10F
7872 || fcode == BUILT_IN_LOG10L)))
7873 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7877 return 0;
7880 /* Fold function call to builtin memcpy. Return
7881 NULL_TREE if no simplification can be made. */
7883 static tree
7884 fold_builtin_memcpy (tree fndecl, tree arglist)
7886 tree dest, src, len;
7888 if (!validate_arglist (arglist,
7889 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7890 return 0;
7892 dest = TREE_VALUE (arglist);
7893 src = TREE_VALUE (TREE_CHAIN (arglist));
7894 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7896 /* If the LEN parameter is zero, return DEST. */
7897 if (integer_zerop (len))
7898 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7900 /* If SRC and DEST are the same (and not volatile), return DEST. */
7901 if (operand_equal_p (src, dest, 0))
7902 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7904 return 0;
7907 /* Fold function call to builtin mempcpy. Return
7908 NULL_TREE if no simplification can be made. */
7910 static tree
7911 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7913 if (validate_arglist (arglist,
7914 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7916 tree dest = TREE_VALUE (arglist);
7917 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7918 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7920 /* If the LEN parameter is zero, return DEST. */
7921 if (integer_zerop (len))
7922 return omit_one_operand (type, dest, src);
7924 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7925 if (operand_equal_p (src, dest, 0))
7927 if (endp == 0)
7928 return omit_one_operand (type, dest, len);
7930 if (endp == 2)
7931 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7932 ssize_int (1));
7934 len = fold_convert (TREE_TYPE (dest), len);
7935 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7936 return fold_convert (type, len);
7939 return 0;
7942 /* Fold function call to builtin memmove. Return
7943 NULL_TREE if no simplification can be made. */
7945 static tree
7946 fold_builtin_memmove (tree arglist, tree type)
7948 tree dest, src, len;
7950 if (!validate_arglist (arglist,
7951 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7952 return 0;
7954 dest = TREE_VALUE (arglist);
7955 src = TREE_VALUE (TREE_CHAIN (arglist));
7956 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7958 /* If the LEN parameter is zero, return DEST. */
7959 if (integer_zerop (len))
7960 return omit_one_operand (type, dest, src);
7962 /* If SRC and DEST are the same (and not volatile), return DEST. */
7963 if (operand_equal_p (src, dest, 0))
7964 return omit_one_operand (type, dest, len);
7966 return 0;
7969 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7970 the length of the string to be copied. Return NULL_TREE if no
7971 simplification can be made. */
7973 tree
7974 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7976 tree dest, src, fn;
7978 if (!validate_arglist (arglist,
7979 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7980 return 0;
7982 dest = TREE_VALUE (arglist);
7983 src = TREE_VALUE (TREE_CHAIN (arglist));
7985 /* If SRC and DEST are the same (and not volatile), return DEST. */
7986 if (operand_equal_p (src, dest, 0))
7987 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7989 if (optimize_size)
7990 return 0;
7992 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7993 if (!fn)
7994 return 0;
7996 if (!len)
7998 len = c_strlen (src, 1);
7999 if (! len || TREE_SIDE_EFFECTS (len))
8000 return 0;
8003 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8004 arglist = build_tree_list (NULL_TREE, len);
8005 arglist = tree_cons (NULL_TREE, src, arglist);
8006 arglist = tree_cons (NULL_TREE, dest, arglist);
8007 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8008 build_function_call_expr (fn, arglist));
8011 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8012 the length of the source string. Return NULL_TREE if no simplification
8013 can be made. */
8015 tree
8016 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8018 tree dest, src, len, fn;
8020 if (!validate_arglist (arglist,
8021 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8022 return 0;
8024 dest = TREE_VALUE (arglist);
8025 src = TREE_VALUE (TREE_CHAIN (arglist));
8026 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8028 /* If the LEN parameter is zero, return DEST. */
8029 if (integer_zerop (len))
8030 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8032 /* We can't compare slen with len as constants below if len is not a
8033 constant. */
8034 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8035 return 0;
8037 if (!slen)
8038 slen = c_strlen (src, 1);
8040 /* Now, we must be passed a constant src ptr parameter. */
8041 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8042 return 0;
8044 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8046 /* We do not support simplification of this case, though we do
8047 support it when expanding trees into RTL. */
8048 /* FIXME: generate a call to __builtin_memset. */
8049 if (tree_int_cst_lt (slen, len))
8050 return 0;
8052 /* OK transform into builtin memcpy. */
8053 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8054 if (!fn)
8055 return 0;
8056 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8057 build_function_call_expr (fn, arglist));
8060 /* Fold function call to builtin memcmp. Return
8061 NULL_TREE if no simplification can be made. */
8063 static tree
8064 fold_builtin_memcmp (tree arglist)
8066 tree arg1, arg2, len;
8067 const char *p1, *p2;
8069 if (!validate_arglist (arglist,
8070 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8071 return 0;
8073 arg1 = TREE_VALUE (arglist);
8074 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8075 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8077 /* If the LEN parameter is zero, return zero. */
8078 if (integer_zerop (len))
8079 return omit_two_operands (integer_type_node, integer_zero_node,
8080 arg1, arg2);
8082 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8083 if (operand_equal_p (arg1, arg2, 0))
8084 return omit_one_operand (integer_type_node, integer_zero_node, len);
8086 p1 = c_getstr (arg1);
8087 p2 = c_getstr (arg2);
8089 /* If all arguments are constant, and the value of len is not greater
8090 than the lengths of arg1 and arg2, evaluate at compile-time. */
8091 if (host_integerp (len, 1) && p1 && p2
8092 && compare_tree_int (len, strlen (p1) + 1) <= 0
8093 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8095 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8097 if (r > 0)
8098 return integer_one_node;
8099 else if (r < 0)
8100 return integer_minus_one_node;
8101 else
8102 return integer_zero_node;
8105 /* If len parameter is one, return an expression corresponding to
8106 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8107 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8109 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8110 tree cst_uchar_ptr_node
8111 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8113 tree ind1 = fold_convert (integer_type_node,
8114 build1 (INDIRECT_REF, cst_uchar_node,
8115 fold_convert (cst_uchar_ptr_node,
8116 arg1)));
8117 tree ind2 = fold_convert (integer_type_node,
8118 build1 (INDIRECT_REF, cst_uchar_node,
8119 fold_convert (cst_uchar_ptr_node,
8120 arg2)));
8121 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8124 return 0;
8127 /* Fold function call to builtin strcmp. Return
8128 NULL_TREE if no simplification can be made. */
8130 static tree
8131 fold_builtin_strcmp (tree arglist)
8133 tree arg1, arg2;
8134 const char *p1, *p2;
8136 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8137 return 0;
8139 arg1 = TREE_VALUE (arglist);
8140 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8142 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8143 if (operand_equal_p (arg1, arg2, 0))
8144 return integer_zero_node;
8146 p1 = c_getstr (arg1);
8147 p2 = c_getstr (arg2);
8149 if (p1 && p2)
8151 const int i = strcmp (p1, p2);
8152 if (i < 0)
8153 return integer_minus_one_node;
8154 else if (i > 0)
8155 return integer_one_node;
8156 else
8157 return integer_zero_node;
8160 /* If the second arg is "", return *(const unsigned char*)arg1. */
8161 if (p2 && *p2 == '\0')
8163 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8164 tree cst_uchar_ptr_node
8165 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8167 return fold_convert (integer_type_node,
8168 build1 (INDIRECT_REF, cst_uchar_node,
8169 fold_convert (cst_uchar_ptr_node,
8170 arg1)));
8173 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8174 if (p1 && *p1 == '\0')
8176 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8177 tree cst_uchar_ptr_node
8178 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8180 tree temp = fold_convert (integer_type_node,
8181 build1 (INDIRECT_REF, cst_uchar_node,
8182 fold_convert (cst_uchar_ptr_node,
8183 arg2)));
8184 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8187 return 0;
8190 /* Fold function call to builtin strncmp. Return
8191 NULL_TREE if no simplification can be made. */
8193 static tree
8194 fold_builtin_strncmp (tree arglist)
8196 tree arg1, arg2, len;
8197 const char *p1, *p2;
8199 if (!validate_arglist (arglist,
8200 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8201 return 0;
8203 arg1 = TREE_VALUE (arglist);
8204 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8205 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8207 /* If the LEN parameter is zero, return zero. */
8208 if (integer_zerop (len))
8209 return omit_two_operands (integer_type_node, integer_zero_node,
8210 arg1, arg2);
8212 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8213 if (operand_equal_p (arg1, arg2, 0))
8214 return omit_one_operand (integer_type_node, integer_zero_node, len);
8216 p1 = c_getstr (arg1);
8217 p2 = c_getstr (arg2);
8219 if (host_integerp (len, 1) && p1 && p2)
8221 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8222 if (i > 0)
8223 return integer_one_node;
8224 else if (i < 0)
8225 return integer_minus_one_node;
8226 else
8227 return integer_zero_node;
8230 /* If the second arg is "", and the length is greater than zero,
8231 return *(const unsigned char*)arg1. */
8232 if (p2 && *p2 == '\0'
8233 && TREE_CODE (len) == INTEGER_CST
8234 && tree_int_cst_sgn (len) == 1)
8236 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8237 tree cst_uchar_ptr_node
8238 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8240 return fold_convert (integer_type_node,
8241 build1 (INDIRECT_REF, cst_uchar_node,
8242 fold_convert (cst_uchar_ptr_node,
8243 arg1)));
8246 /* If the first arg is "", and the length is greater than zero,
8247 return -*(const unsigned char*)arg2. */
8248 if (p1 && *p1 == '\0'
8249 && TREE_CODE (len) == INTEGER_CST
8250 && tree_int_cst_sgn (len) == 1)
8252 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8253 tree cst_uchar_ptr_node
8254 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8256 tree temp = fold_convert (integer_type_node,
8257 build1 (INDIRECT_REF, cst_uchar_node,
8258 fold_convert (cst_uchar_ptr_node,
8259 arg2)));
8260 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8263 /* If len parameter is one, return an expression corresponding to
8264 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8265 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8267 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8268 tree cst_uchar_ptr_node
8269 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8271 tree ind1 = fold_convert (integer_type_node,
8272 build1 (INDIRECT_REF, cst_uchar_node,
8273 fold_convert (cst_uchar_ptr_node,
8274 arg1)));
8275 tree ind2 = fold_convert (integer_type_node,
8276 build1 (INDIRECT_REF, cst_uchar_node,
8277 fold_convert (cst_uchar_ptr_node,
8278 arg2)));
8279 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8282 return 0;
8285 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8286 NULL_TREE if no simplification can be made. */
8288 static tree
8289 fold_builtin_signbit (tree fndecl, tree arglist)
8291 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8292 tree arg, temp;
8294 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8295 return NULL_TREE;
8297 arg = TREE_VALUE (arglist);
8299 /* If ARG is a compile-time constant, determine the result. */
8300 if (TREE_CODE (arg) == REAL_CST
8301 && !TREE_CONSTANT_OVERFLOW (arg))
8303 REAL_VALUE_TYPE c;
8305 c = TREE_REAL_CST (arg);
8306 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8307 return fold_convert (type, temp);
8310 /* If ARG is non-negative, the result is always zero. */
8311 if (tree_expr_nonnegative_p (arg))
8312 return omit_one_operand (type, integer_zero_node, arg);
8314 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8315 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8316 return fold_build2 (LT_EXPR, type, arg,
8317 build_real (TREE_TYPE (arg), dconst0));
8319 return NULL_TREE;
8322 /* Fold function call to builtin copysign, copysignf or copysignl.
8323 Return NULL_TREE if no simplification can be made. */
8325 static tree
8326 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8328 tree arg1, arg2, tem;
8330 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8331 return NULL_TREE;
8333 arg1 = TREE_VALUE (arglist);
8334 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8336 /* copysign(X,X) is X. */
8337 if (operand_equal_p (arg1, arg2, 0))
8338 return fold_convert (type, arg1);
8340 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8341 if (TREE_CODE (arg1) == REAL_CST
8342 && TREE_CODE (arg2) == REAL_CST
8343 && !TREE_CONSTANT_OVERFLOW (arg1)
8344 && !TREE_CONSTANT_OVERFLOW (arg2))
8346 REAL_VALUE_TYPE c1, c2;
8348 c1 = TREE_REAL_CST (arg1);
8349 c2 = TREE_REAL_CST (arg2);
8350 real_copysign (&c1, &c2);
8351 return build_real (type, c1);
8352 c1.sign = c2.sign;
8355 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8356 Remember to evaluate Y for side-effects. */
8357 if (tree_expr_nonnegative_p (arg2))
8358 return omit_one_operand (type,
8359 fold_build1 (ABS_EXPR, type, arg1),
8360 arg2);
8362 /* Strip sign changing operations for the first argument. */
8363 tem = fold_strip_sign_ops (arg1);
8364 if (tem)
8366 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8367 return build_function_call_expr (fndecl, arglist);
8370 return NULL_TREE;
8373 /* Fold a call to builtin isascii. */
8375 static tree
8376 fold_builtin_isascii (tree arglist)
8378 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8379 return 0;
8380 else
8382 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8383 tree arg = TREE_VALUE (arglist);
8385 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8386 build_int_cst (NULL_TREE,
8387 ~ (unsigned HOST_WIDE_INT) 0x7f));
8388 arg = fold_build2 (EQ_EXPR, integer_type_node,
8389 arg, integer_zero_node);
8391 if (in_gimple_form && !TREE_CONSTANT (arg))
8392 return NULL_TREE;
8393 else
8394 return arg;
8398 /* Fold a call to builtin toascii. */
8400 static tree
8401 fold_builtin_toascii (tree arglist)
8403 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8404 return 0;
8405 else
8407 /* Transform toascii(c) -> (c & 0x7f). */
8408 tree arg = TREE_VALUE (arglist);
8410 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8411 build_int_cst (NULL_TREE, 0x7f));
8415 /* Fold a call to builtin isdigit. */
8417 static tree
8418 fold_builtin_isdigit (tree arglist)
8420 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8421 return 0;
8422 else
8424 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8425 /* According to the C standard, isdigit is unaffected by locale.
8426 However, it definitely is affected by the target character set. */
8427 tree arg;
8428 unsigned HOST_WIDE_INT target_digit0
8429 = lang_hooks.to_target_charset ('0');
8431 if (target_digit0 == 0)
8432 return NULL_TREE;
8434 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8435 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8436 build_int_cst (unsigned_type_node, target_digit0));
8437 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8438 build_int_cst (unsigned_type_node, 9));
8439 if (in_gimple_form && !TREE_CONSTANT (arg))
8440 return NULL_TREE;
8441 else
8442 return arg;
8446 /* Fold a call to fabs, fabsf or fabsl. */
8448 static tree
8449 fold_builtin_fabs (tree arglist, tree type)
8451 tree arg;
8453 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8454 return 0;
8456 arg = TREE_VALUE (arglist);
8457 arg = fold_convert (type, arg);
8458 if (TREE_CODE (arg) == REAL_CST)
8459 return fold_abs_const (arg, type);
8460 return fold_build1 (ABS_EXPR, type, arg);
8463 /* Fold a call to abs, labs, llabs or imaxabs. */
8465 static tree
8466 fold_builtin_abs (tree arglist, tree type)
8468 tree arg;
8470 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8471 return 0;
8473 arg = TREE_VALUE (arglist);
8474 arg = fold_convert (type, arg);
8475 if (TREE_CODE (arg) == INTEGER_CST)
8476 return fold_abs_const (arg, type);
8477 return fold_build1 (ABS_EXPR, type, arg);
8480 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8481 EXP is the CALL_EXPR for the call. */
8483 static tree
8484 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8486 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8487 tree arg;
8488 REAL_VALUE_TYPE r;
8490 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8492 /* Check that we have exactly one argument. */
8493 if (arglist == 0)
8495 error ("too few arguments to function %qs",
8496 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8497 return error_mark_node;
8499 else if (TREE_CHAIN (arglist) != 0)
8501 error ("too many arguments to function %qs",
8502 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8503 return error_mark_node;
8505 else
8507 error ("non-floating-point argument to function %qs",
8508 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8509 return error_mark_node;
8513 arg = TREE_VALUE (arglist);
8514 switch (builtin_index)
8516 case BUILT_IN_ISINF:
8517 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8518 return omit_one_operand (type, integer_zero_node, arg);
8520 if (TREE_CODE (arg) == REAL_CST)
8522 r = TREE_REAL_CST (arg);
8523 if (real_isinf (&r))
8524 return real_compare (GT_EXPR, &r, &dconst0)
8525 ? integer_one_node : integer_minus_one_node;
8526 else
8527 return integer_zero_node;
8530 return NULL_TREE;
8532 case BUILT_IN_FINITE:
8533 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8534 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8535 return omit_one_operand (type, integer_zero_node, arg);
8537 if (TREE_CODE (arg) == REAL_CST)
8539 r = TREE_REAL_CST (arg);
8540 return real_isinf (&r) || real_isnan (&r)
8541 ? integer_zero_node : integer_one_node;
8544 return NULL_TREE;
8546 case BUILT_IN_ISNAN:
8547 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8548 return omit_one_operand (type, integer_zero_node, arg);
8550 if (TREE_CODE (arg) == REAL_CST)
8552 r = TREE_REAL_CST (arg);
8553 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8556 arg = builtin_save_expr (arg);
8557 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8559 default:
8560 gcc_unreachable ();
8564 /* Fold a call to an unordered comparison function such as
8565 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8566 being called and ARGLIST is the argument list for the call.
8567 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8568 the opposite of the desired result. UNORDERED_CODE is used
8569 for modes that can hold NaNs and ORDERED_CODE is used for
8570 the rest. */
8572 static tree
8573 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8574 enum tree_code unordered_code,
8575 enum tree_code ordered_code)
8577 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8578 enum tree_code code;
8579 tree arg0, arg1;
8580 tree type0, type1;
8581 enum tree_code code0, code1;
8582 tree cmp_type = NULL_TREE;
8584 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8586 /* Check that we have exactly two arguments. */
8587 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8589 error ("too few arguments to function %qs",
8590 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8591 return error_mark_node;
8593 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8595 error ("too many arguments to function %qs",
8596 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8597 return error_mark_node;
8601 arg0 = TREE_VALUE (arglist);
8602 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8604 type0 = TREE_TYPE (arg0);
8605 type1 = TREE_TYPE (arg1);
8607 code0 = TREE_CODE (type0);
8608 code1 = TREE_CODE (type1);
8610 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8611 /* Choose the wider of two real types. */
8612 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8613 ? type0 : type1;
8614 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8615 cmp_type = type0;
8616 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8617 cmp_type = type1;
8618 else
8620 error ("non-floating-point argument to function %qs",
8621 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8622 return error_mark_node;
8625 arg0 = fold_convert (cmp_type, arg0);
8626 arg1 = fold_convert (cmp_type, arg1);
8628 if (unordered_code == UNORDERED_EXPR)
8630 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8631 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8632 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8635 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8636 : ordered_code;
8637 return fold_build1 (TRUTH_NOT_EXPR, type,
8638 fold_build2 (code, type, arg0, arg1));
8641 /* Used by constant folding to simplify calls to builtin functions. EXP is
8642 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8643 result of the function call is ignored. This function returns NULL_TREE
8644 if no simplification was possible. */
8646 static tree
8647 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8649 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8650 enum built_in_function fcode;
8652 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8653 return targetm.fold_builtin (fndecl, arglist, ignore);
8655 fcode = DECL_FUNCTION_CODE (fndecl);
8656 switch (fcode)
8658 case BUILT_IN_FPUTS:
8659 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8661 case BUILT_IN_FPUTS_UNLOCKED:
8662 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8664 case BUILT_IN_STRSTR:
8665 return fold_builtin_strstr (arglist, type);
8667 case BUILT_IN_STRCAT:
8668 return fold_builtin_strcat (arglist);
8670 case BUILT_IN_STRNCAT:
8671 return fold_builtin_strncat (arglist);
8673 case BUILT_IN_STRSPN:
8674 return fold_builtin_strspn (arglist);
8676 case BUILT_IN_STRCSPN:
8677 return fold_builtin_strcspn (arglist);
8679 case BUILT_IN_STRCHR:
8680 case BUILT_IN_INDEX:
8681 return fold_builtin_strchr (arglist, type);
8683 case BUILT_IN_STRRCHR:
8684 case BUILT_IN_RINDEX:
8685 return fold_builtin_strrchr (arglist, type);
8687 case BUILT_IN_STRCPY:
8688 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8690 case BUILT_IN_STRNCPY:
8691 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8693 case BUILT_IN_STRCMP:
8694 return fold_builtin_strcmp (arglist);
8696 case BUILT_IN_STRNCMP:
8697 return fold_builtin_strncmp (arglist);
8699 case BUILT_IN_STRPBRK:
8700 return fold_builtin_strpbrk (arglist, type);
8702 case BUILT_IN_BCMP:
8703 case BUILT_IN_MEMCMP:
8704 return fold_builtin_memcmp (arglist);
8706 case BUILT_IN_SPRINTF:
8707 return fold_builtin_sprintf (arglist, ignore);
8709 case BUILT_IN_CONSTANT_P:
8711 tree val;
8713 val = fold_builtin_constant_p (arglist);
8714 /* Gimplification will pull the CALL_EXPR for the builtin out of
8715 an if condition. When not optimizing, we'll not CSE it back.
8716 To avoid link error types of regressions, return false now. */
8717 if (!val && !optimize)
8718 val = integer_zero_node;
8720 return val;
8723 case BUILT_IN_EXPECT:
8724 return fold_builtin_expect (arglist);
8726 case BUILT_IN_CLASSIFY_TYPE:
8727 return fold_builtin_classify_type (arglist);
8729 case BUILT_IN_STRLEN:
8730 return fold_builtin_strlen (arglist);
8732 case BUILT_IN_FABS:
8733 case BUILT_IN_FABSF:
8734 case BUILT_IN_FABSL:
8735 return fold_builtin_fabs (arglist, type);
8737 case BUILT_IN_ABS:
8738 case BUILT_IN_LABS:
8739 case BUILT_IN_LLABS:
8740 case BUILT_IN_IMAXABS:
8741 return fold_builtin_abs (arglist, type);
8743 case BUILT_IN_CONJ:
8744 case BUILT_IN_CONJF:
8745 case BUILT_IN_CONJL:
8746 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8747 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8748 break;
8750 case BUILT_IN_CREAL:
8751 case BUILT_IN_CREALF:
8752 case BUILT_IN_CREALL:
8753 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8754 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8755 TREE_VALUE (arglist)));
8756 break;
8758 case BUILT_IN_CIMAG:
8759 case BUILT_IN_CIMAGF:
8760 case BUILT_IN_CIMAGL:
8761 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8762 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8763 TREE_VALUE (arglist)));
8764 break;
8766 case BUILT_IN_CABS:
8767 case BUILT_IN_CABSF:
8768 case BUILT_IN_CABSL:
8769 return fold_builtin_cabs (arglist, type);
8771 case BUILT_IN_SQRT:
8772 case BUILT_IN_SQRTF:
8773 case BUILT_IN_SQRTL:
8774 return fold_builtin_sqrt (arglist, type);
8776 case BUILT_IN_CBRT:
8777 case BUILT_IN_CBRTF:
8778 case BUILT_IN_CBRTL:
8779 return fold_builtin_cbrt (arglist, type);
8781 case BUILT_IN_SIN:
8782 case BUILT_IN_SINF:
8783 case BUILT_IN_SINL:
8784 return fold_builtin_sin (arglist);
8786 case BUILT_IN_COS:
8787 case BUILT_IN_COSF:
8788 case BUILT_IN_COSL:
8789 return fold_builtin_cos (arglist, type, fndecl);
8791 case BUILT_IN_EXP:
8792 case BUILT_IN_EXPF:
8793 case BUILT_IN_EXPL:
8794 return fold_builtin_exponent (fndecl, arglist, &dconste);
8796 case BUILT_IN_EXP2:
8797 case BUILT_IN_EXP2F:
8798 case BUILT_IN_EXP2L:
8799 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8801 case BUILT_IN_EXP10:
8802 case BUILT_IN_EXP10F:
8803 case BUILT_IN_EXP10L:
8804 case BUILT_IN_POW10:
8805 case BUILT_IN_POW10F:
8806 case BUILT_IN_POW10L:
8807 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8809 case BUILT_IN_LOG:
8810 case BUILT_IN_LOGF:
8811 case BUILT_IN_LOGL:
8812 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8814 case BUILT_IN_LOG2:
8815 case BUILT_IN_LOG2F:
8816 case BUILT_IN_LOG2L:
8817 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8819 case BUILT_IN_LOG10:
8820 case BUILT_IN_LOG10F:
8821 case BUILT_IN_LOG10L:
8822 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8824 case BUILT_IN_TAN:
8825 case BUILT_IN_TANF:
8826 case BUILT_IN_TANL:
8827 return fold_builtin_tan (arglist);
8829 case BUILT_IN_ATAN:
8830 case BUILT_IN_ATANF:
8831 case BUILT_IN_ATANL:
8832 return fold_builtin_atan (arglist, type);
8834 case BUILT_IN_POW:
8835 case BUILT_IN_POWF:
8836 case BUILT_IN_POWL:
8837 return fold_builtin_pow (fndecl, arglist, type);
8839 case BUILT_IN_POWI:
8840 case BUILT_IN_POWIF:
8841 case BUILT_IN_POWIL:
8842 return fold_builtin_powi (fndecl, arglist, type);
8844 case BUILT_IN_INF:
8845 case BUILT_IN_INFF:
8846 case BUILT_IN_INFL:
8847 return fold_builtin_inf (type, true);
8849 case BUILT_IN_HUGE_VAL:
8850 case BUILT_IN_HUGE_VALF:
8851 case BUILT_IN_HUGE_VALL:
8852 return fold_builtin_inf (type, false);
8854 case BUILT_IN_NAN:
8855 case BUILT_IN_NANF:
8856 case BUILT_IN_NANL:
8857 return fold_builtin_nan (arglist, type, true);
8859 case BUILT_IN_NANS:
8860 case BUILT_IN_NANSF:
8861 case BUILT_IN_NANSL:
8862 return fold_builtin_nan (arglist, type, false);
8864 case BUILT_IN_FLOOR:
8865 case BUILT_IN_FLOORF:
8866 case BUILT_IN_FLOORL:
8867 return fold_builtin_floor (fndecl, arglist);
8869 case BUILT_IN_CEIL:
8870 case BUILT_IN_CEILF:
8871 case BUILT_IN_CEILL:
8872 return fold_builtin_ceil (fndecl, arglist);
8874 case BUILT_IN_TRUNC:
8875 case BUILT_IN_TRUNCF:
8876 case BUILT_IN_TRUNCL:
8877 return fold_builtin_trunc (fndecl, arglist);
8879 case BUILT_IN_ROUND:
8880 case BUILT_IN_ROUNDF:
8881 case BUILT_IN_ROUNDL:
8882 return fold_builtin_round (fndecl, arglist);
8884 case BUILT_IN_NEARBYINT:
8885 case BUILT_IN_NEARBYINTF:
8886 case BUILT_IN_NEARBYINTL:
8887 case BUILT_IN_RINT:
8888 case BUILT_IN_RINTF:
8889 case BUILT_IN_RINTL:
8890 return fold_trunc_transparent_mathfn (fndecl, arglist);
8892 case BUILT_IN_LCEIL:
8893 case BUILT_IN_LCEILF:
8894 case BUILT_IN_LCEILL:
8895 case BUILT_IN_LLCEIL:
8896 case BUILT_IN_LLCEILF:
8897 case BUILT_IN_LLCEILL:
8898 case BUILT_IN_LFLOOR:
8899 case BUILT_IN_LFLOORF:
8900 case BUILT_IN_LFLOORL:
8901 case BUILT_IN_LLFLOOR:
8902 case BUILT_IN_LLFLOORF:
8903 case BUILT_IN_LLFLOORL:
8904 case BUILT_IN_LROUND:
8905 case BUILT_IN_LROUNDF:
8906 case BUILT_IN_LROUNDL:
8907 case BUILT_IN_LLROUND:
8908 case BUILT_IN_LLROUNDF:
8909 case BUILT_IN_LLROUNDL:
8910 return fold_builtin_int_roundingfn (fndecl, arglist);
8912 case BUILT_IN_LRINT:
8913 case BUILT_IN_LRINTF:
8914 case BUILT_IN_LRINTL:
8915 case BUILT_IN_LLRINT:
8916 case BUILT_IN_LLRINTF:
8917 case BUILT_IN_LLRINTL:
8918 return fold_fixed_mathfn (fndecl, arglist);
8920 case BUILT_IN_FFS:
8921 case BUILT_IN_FFSL:
8922 case BUILT_IN_FFSLL:
8923 case BUILT_IN_CLZ:
8924 case BUILT_IN_CLZL:
8925 case BUILT_IN_CLZLL:
8926 case BUILT_IN_CTZ:
8927 case BUILT_IN_CTZL:
8928 case BUILT_IN_CTZLL:
8929 case BUILT_IN_POPCOUNT:
8930 case BUILT_IN_POPCOUNTL:
8931 case BUILT_IN_POPCOUNTLL:
8932 case BUILT_IN_PARITY:
8933 case BUILT_IN_PARITYL:
8934 case BUILT_IN_PARITYLL:
8935 return fold_builtin_bitop (fndecl, arglist);
8937 case BUILT_IN_MEMCPY:
8938 return fold_builtin_memcpy (fndecl, arglist);
8940 case BUILT_IN_MEMPCPY:
8941 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8943 case BUILT_IN_MEMMOVE:
8944 return fold_builtin_memmove (arglist, type);
8946 case BUILT_IN_SIGNBIT:
8947 case BUILT_IN_SIGNBITF:
8948 case BUILT_IN_SIGNBITL:
8949 return fold_builtin_signbit (fndecl, arglist);
8951 case BUILT_IN_ISASCII:
8952 return fold_builtin_isascii (arglist);
8954 case BUILT_IN_TOASCII:
8955 return fold_builtin_toascii (arglist);
8957 case BUILT_IN_ISDIGIT:
8958 return fold_builtin_isdigit (arglist);
8960 case BUILT_IN_COPYSIGN:
8961 case BUILT_IN_COPYSIGNF:
8962 case BUILT_IN_COPYSIGNL:
8963 return fold_builtin_copysign (fndecl, arglist, type);
8965 case BUILT_IN_FINITE:
8966 case BUILT_IN_FINITEF:
8967 case BUILT_IN_FINITEL:
8968 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8970 case BUILT_IN_ISINF:
8971 case BUILT_IN_ISINFF:
8972 case BUILT_IN_ISINFL:
8973 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8975 case BUILT_IN_ISNAN:
8976 case BUILT_IN_ISNANF:
8977 case BUILT_IN_ISNANL:
8978 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8980 case BUILT_IN_ISGREATER:
8981 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8982 case BUILT_IN_ISGREATEREQUAL:
8983 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8984 case BUILT_IN_ISLESS:
8985 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8986 case BUILT_IN_ISLESSEQUAL:
8987 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8988 case BUILT_IN_ISLESSGREATER:
8989 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8990 case BUILT_IN_ISUNORDERED:
8991 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8992 NOP_EXPR);
8994 /* We do the folding for va_start in the expander. */
8995 case BUILT_IN_VA_START:
8996 break;
8998 case BUILT_IN_OBJECT_SIZE:
8999 return fold_builtin_object_size (arglist);
9000 case BUILT_IN_MEMCPY_CHK:
9001 case BUILT_IN_MEMPCPY_CHK:
9002 case BUILT_IN_MEMMOVE_CHK:
9003 case BUILT_IN_MEMSET_CHK:
9004 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9005 DECL_FUNCTION_CODE (fndecl));
9006 case BUILT_IN_STRCPY_CHK:
9007 case BUILT_IN_STPCPY_CHK:
9008 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9009 DECL_FUNCTION_CODE (fndecl));
9010 case BUILT_IN_STRNCPY_CHK:
9011 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9012 case BUILT_IN_STRCAT_CHK:
9013 return fold_builtin_strcat_chk (fndecl, arglist);
9014 case BUILT_IN_STRNCAT_CHK:
9015 return fold_builtin_strncat_chk (fndecl, arglist);
9016 case BUILT_IN_SPRINTF_CHK:
9017 case BUILT_IN_VSPRINTF_CHK:
9018 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9019 case BUILT_IN_SNPRINTF_CHK:
9020 case BUILT_IN_VSNPRINTF_CHK:
9021 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9022 DECL_FUNCTION_CODE (fndecl));
9024 case BUILT_IN_PRINTF:
9025 case BUILT_IN_PRINTF_UNLOCKED:
9026 case BUILT_IN_VPRINTF:
9027 case BUILT_IN_PRINTF_CHK:
9028 case BUILT_IN_VPRINTF_CHK:
9029 return fold_builtin_printf (fndecl, arglist, ignore,
9030 DECL_FUNCTION_CODE (fndecl));
9032 case BUILT_IN_FPRINTF:
9033 case BUILT_IN_FPRINTF_UNLOCKED:
9034 case BUILT_IN_VFPRINTF:
9035 case BUILT_IN_FPRINTF_CHK:
9036 case BUILT_IN_VFPRINTF_CHK:
9037 return fold_builtin_fprintf (fndecl, arglist, ignore,
9038 DECL_FUNCTION_CODE (fndecl));
9040 default:
9041 break;
9044 return 0;
9047 /* A wrapper function for builtin folding that prevents warnings for
9048 "statement without effect" and the like, caused by removing the
9049 call node earlier than the warning is generated. */
9051 tree
9052 fold_builtin (tree fndecl, tree arglist, bool ignore)
9054 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9055 if (exp)
9057 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9058 TREE_NO_WARNING (exp) = 1;
9061 return exp;
9064 /* Conveniently construct a function call expression. */
9066 tree
9067 build_function_call_expr (tree fn, tree arglist)
9069 tree call_expr;
9071 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9072 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9073 call_expr, arglist, NULL_TREE);
9076 /* This function validates the types of a function call argument list
9077 represented as a tree chain of parameters against a specified list
9078 of tree_codes. If the last specifier is a 0, that represents an
9079 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9081 static int
9082 validate_arglist (tree arglist, ...)
9084 enum tree_code code;
9085 int res = 0;
9086 va_list ap;
9088 va_start (ap, arglist);
9092 code = va_arg (ap, enum tree_code);
9093 switch (code)
9095 case 0:
9096 /* This signifies an ellipses, any further arguments are all ok. */
9097 res = 1;
9098 goto end;
9099 case VOID_TYPE:
9100 /* This signifies an endlink, if no arguments remain, return
9101 true, otherwise return false. */
9102 res = arglist == 0;
9103 goto end;
9104 default:
9105 /* If no parameters remain or the parameter's code does not
9106 match the specified code, return false. Otherwise continue
9107 checking any remaining arguments. */
9108 if (arglist == 0)
9109 goto end;
9110 if (code == POINTER_TYPE)
9112 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9113 goto end;
9115 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9116 goto end;
9117 break;
9119 arglist = TREE_CHAIN (arglist);
9121 while (1);
9123 /* We need gotos here since we can only have one VA_CLOSE in a
9124 function. */
9125 end: ;
9126 va_end (ap);
9128 return res;
9131 /* Default target-specific builtin expander that does nothing. */
9134 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9135 rtx target ATTRIBUTE_UNUSED,
9136 rtx subtarget ATTRIBUTE_UNUSED,
9137 enum machine_mode mode ATTRIBUTE_UNUSED,
9138 int ignore ATTRIBUTE_UNUSED)
9140 return NULL_RTX;
9143 /* Returns true is EXP represents data that would potentially reside
9144 in a readonly section. */
9146 static bool
9147 readonly_data_expr (tree exp)
9149 STRIP_NOPS (exp);
9151 if (TREE_CODE (exp) != ADDR_EXPR)
9152 return false;
9154 exp = get_base_address (TREE_OPERAND (exp, 0));
9155 if (!exp)
9156 return false;
9158 /* Make sure we call decl_readonly_section only for trees it
9159 can handle (since it returns true for everything it doesn't
9160 understand). */
9161 if (TREE_CODE (exp) == STRING_CST
9162 || TREE_CODE (exp) == CONSTRUCTOR
9163 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9164 return decl_readonly_section (exp, 0);
9165 else
9166 return false;
9169 /* Simplify a call to the strstr builtin.
9171 Return 0 if no simplification was possible, otherwise return the
9172 simplified form of the call as a tree.
9174 The simplified form may be a constant or other expression which
9175 computes the same value, but in a more efficient manner (including
9176 calls to other builtin functions).
9178 The call may contain arguments which need to be evaluated, but
9179 which are not useful to determine the result of the call. In
9180 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9181 COMPOUND_EXPR will be an argument which must be evaluated.
9182 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9183 COMPOUND_EXPR in the chain will contain the tree for the simplified
9184 form of the builtin function call. */
9186 static tree
9187 fold_builtin_strstr (tree arglist, tree type)
9189 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9190 return 0;
9191 else
9193 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9194 tree fn;
9195 const char *p1, *p2;
9197 p2 = c_getstr (s2);
9198 if (p2 == NULL)
9199 return 0;
9201 p1 = c_getstr (s1);
9202 if (p1 != NULL)
9204 const char *r = strstr (p1, p2);
9205 tree tem;
9207 if (r == NULL)
9208 return build_int_cst (TREE_TYPE (s1), 0);
9210 /* Return an offset into the constant string argument. */
9211 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9212 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9213 return fold_convert (type, tem);
9216 if (p2[0] == '\0')
9217 return s1;
9219 if (p2[1] != '\0')
9220 return 0;
9222 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9223 if (!fn)
9224 return 0;
9226 /* New argument list transforming strstr(s1, s2) to
9227 strchr(s1, s2[0]). */
9228 arglist = build_tree_list (NULL_TREE,
9229 build_int_cst (NULL_TREE, p2[0]));
9230 arglist = tree_cons (NULL_TREE, s1, arglist);
9231 return build_function_call_expr (fn, arglist);
9235 /* Simplify a call to the strchr builtin.
9237 Return 0 if no simplification was possible, otherwise return the
9238 simplified form of the call as a tree.
9240 The simplified form may be a constant or other expression which
9241 computes the same value, but in a more efficient manner (including
9242 calls to other builtin functions).
9244 The call may contain arguments which need to be evaluated, but
9245 which are not useful to determine the result of the call. In
9246 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9247 COMPOUND_EXPR will be an argument which must be evaluated.
9248 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9249 COMPOUND_EXPR in the chain will contain the tree for the simplified
9250 form of the builtin function call. */
9252 static tree
9253 fold_builtin_strchr (tree arglist, tree type)
9255 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9256 return 0;
9257 else
9259 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9260 const char *p1;
9262 if (TREE_CODE (s2) != INTEGER_CST)
9263 return 0;
9265 p1 = c_getstr (s1);
9266 if (p1 != NULL)
9268 char c;
9269 const char *r;
9270 tree tem;
9272 if (target_char_cast (s2, &c))
9273 return 0;
9275 r = strchr (p1, c);
9277 if (r == NULL)
9278 return build_int_cst (TREE_TYPE (s1), 0);
9280 /* Return an offset into the constant string argument. */
9281 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9282 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9283 return fold_convert (type, tem);
9285 return 0;
9289 /* Simplify a call to the strrchr builtin.
9291 Return 0 if no simplification was possible, otherwise return the
9292 simplified form of the call as a tree.
9294 The simplified form may be a constant or other expression which
9295 computes the same value, but in a more efficient manner (including
9296 calls to other builtin functions).
9298 The call may contain arguments which need to be evaluated, but
9299 which are not useful to determine the result of the call. In
9300 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9301 COMPOUND_EXPR will be an argument which must be evaluated.
9302 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9303 COMPOUND_EXPR in the chain will contain the tree for the simplified
9304 form of the builtin function call. */
9306 static tree
9307 fold_builtin_strrchr (tree arglist, tree type)
9309 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9310 return 0;
9311 else
9313 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9314 tree fn;
9315 const char *p1;
9317 if (TREE_CODE (s2) != INTEGER_CST)
9318 return 0;
9320 p1 = c_getstr (s1);
9321 if (p1 != NULL)
9323 char c;
9324 const char *r;
9325 tree tem;
9327 if (target_char_cast (s2, &c))
9328 return 0;
9330 r = strrchr (p1, c);
9332 if (r == NULL)
9333 return build_int_cst (TREE_TYPE (s1), 0);
9335 /* Return an offset into the constant string argument. */
9336 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9337 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9338 return fold_convert (type, tem);
9341 if (! integer_zerop (s2))
9342 return 0;
9344 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9345 if (!fn)
9346 return 0;
9348 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9349 return build_function_call_expr (fn, arglist);
9353 /* Simplify a call to the strpbrk builtin.
9355 Return 0 if no simplification was possible, otherwise return the
9356 simplified form of the call as a tree.
9358 The simplified form may be a constant or other expression which
9359 computes the same value, but in a more efficient manner (including
9360 calls to other builtin functions).
9362 The call may contain arguments which need to be evaluated, but
9363 which are not useful to determine the result of the call. In
9364 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9365 COMPOUND_EXPR will be an argument which must be evaluated.
9366 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9367 COMPOUND_EXPR in the chain will contain the tree for the simplified
9368 form of the builtin function call. */
9370 static tree
9371 fold_builtin_strpbrk (tree arglist, tree type)
9373 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9374 return 0;
9375 else
9377 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9378 tree fn;
9379 const char *p1, *p2;
9381 p2 = c_getstr (s2);
9382 if (p2 == NULL)
9383 return 0;
9385 p1 = c_getstr (s1);
9386 if (p1 != NULL)
9388 const char *r = strpbrk (p1, p2);
9389 tree tem;
9391 if (r == NULL)
9392 return build_int_cst (TREE_TYPE (s1), 0);
9394 /* Return an offset into the constant string argument. */
9395 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9396 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9397 return fold_convert (type, tem);
9400 if (p2[0] == '\0')
9401 /* strpbrk(x, "") == NULL.
9402 Evaluate and ignore s1 in case it had side-effects. */
9403 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9405 if (p2[1] != '\0')
9406 return 0; /* Really call strpbrk. */
9408 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9409 if (!fn)
9410 return 0;
9412 /* New argument list transforming strpbrk(s1, s2) to
9413 strchr(s1, s2[0]). */
9414 arglist = build_tree_list (NULL_TREE,
9415 build_int_cst (NULL_TREE, p2[0]));
9416 arglist = tree_cons (NULL_TREE, s1, arglist);
9417 return build_function_call_expr (fn, arglist);
9421 /* Simplify a call to the strcat builtin.
9423 Return 0 if no simplification was possible, otherwise return the
9424 simplified form of the call as a tree.
9426 The simplified form may be a constant or other expression which
9427 computes the same value, but in a more efficient manner (including
9428 calls to other builtin functions).
9430 The call may contain arguments which need to be evaluated, but
9431 which are not useful to determine the result of the call. In
9432 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9433 COMPOUND_EXPR will be an argument which must be evaluated.
9434 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9435 COMPOUND_EXPR in the chain will contain the tree for the simplified
9436 form of the builtin function call. */
9438 static tree
9439 fold_builtin_strcat (tree arglist)
9441 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9442 return 0;
9443 else
9445 tree dst = TREE_VALUE (arglist),
9446 src = TREE_VALUE (TREE_CHAIN (arglist));
9447 const char *p = c_getstr (src);
9449 /* If the string length is zero, return the dst parameter. */
9450 if (p && *p == '\0')
9451 return dst;
9453 return 0;
9457 /* Simplify a call to the strncat builtin.
9459 Return 0 if no simplification was possible, otherwise return the
9460 simplified form of the call as a tree.
9462 The simplified form may be a constant or other expression which
9463 computes the same value, but in a more efficient manner (including
9464 calls to other builtin functions).
9466 The call may contain arguments which need to be evaluated, but
9467 which are not useful to determine the result of the call. In
9468 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9469 COMPOUND_EXPR will be an argument which must be evaluated.
9470 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9471 COMPOUND_EXPR in the chain will contain the tree for the simplified
9472 form of the builtin function call. */
9474 static tree
9475 fold_builtin_strncat (tree arglist)
9477 if (!validate_arglist (arglist,
9478 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9479 return 0;
9480 else
9482 tree dst = TREE_VALUE (arglist);
9483 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9484 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9485 const char *p = c_getstr (src);
9487 /* If the requested length is zero, or the src parameter string
9488 length is zero, return the dst parameter. */
9489 if (integer_zerop (len) || (p && *p == '\0'))
9490 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9492 /* If the requested len is greater than or equal to the string
9493 length, call strcat. */
9494 if (TREE_CODE (len) == INTEGER_CST && p
9495 && compare_tree_int (len, strlen (p)) >= 0)
9497 tree newarglist
9498 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9499 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9501 /* If the replacement _DECL isn't initialized, don't do the
9502 transformation. */
9503 if (!fn)
9504 return 0;
9506 return build_function_call_expr (fn, newarglist);
9508 return 0;
9512 /* Simplify a call to the strspn builtin.
9514 Return 0 if no simplification was possible, otherwise return the
9515 simplified form of the call as a tree.
9517 The simplified form may be a constant or other expression which
9518 computes the same value, but in a more efficient manner (including
9519 calls to other builtin functions).
9521 The call may contain arguments which need to be evaluated, but
9522 which are not useful to determine the result of the call. In
9523 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9524 COMPOUND_EXPR will be an argument which must be evaluated.
9525 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9526 COMPOUND_EXPR in the chain will contain the tree for the simplified
9527 form of the builtin function call. */
9529 static tree
9530 fold_builtin_strspn (tree arglist)
9532 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9533 return 0;
9534 else
9536 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9537 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9539 /* If both arguments are constants, evaluate at compile-time. */
9540 if (p1 && p2)
9542 const size_t r = strspn (p1, p2);
9543 return size_int (r);
9546 /* If either argument is "", return 0. */
9547 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9548 /* Evaluate and ignore both arguments in case either one has
9549 side-effects. */
9550 return omit_two_operands (integer_type_node, integer_zero_node,
9551 s1, s2);
9552 return 0;
9556 /* Simplify a call to the strcspn builtin.
9558 Return 0 if no simplification was possible, otherwise return the
9559 simplified form of the call as a tree.
9561 The simplified form may be a constant or other expression which
9562 computes the same value, but in a more efficient manner (including
9563 calls to other builtin functions).
9565 The call may contain arguments which need to be evaluated, but
9566 which are not useful to determine the result of the call. In
9567 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9568 COMPOUND_EXPR will be an argument which must be evaluated.
9569 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9570 COMPOUND_EXPR in the chain will contain the tree for the simplified
9571 form of the builtin function call. */
9573 static tree
9574 fold_builtin_strcspn (tree arglist)
9576 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9577 return 0;
9578 else
9580 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9581 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9583 /* If both arguments are constants, evaluate at compile-time. */
9584 if (p1 && p2)
9586 const size_t r = strcspn (p1, p2);
9587 return size_int (r);
9590 /* If the first argument is "", return 0. */
9591 if (p1 && *p1 == '\0')
9593 /* Evaluate and ignore argument s2 in case it has
9594 side-effects. */
9595 return omit_one_operand (integer_type_node,
9596 integer_zero_node, s2);
9599 /* If the second argument is "", return __builtin_strlen(s1). */
9600 if (p2 && *p2 == '\0')
9602 tree newarglist = build_tree_list (NULL_TREE, s1),
9603 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9605 /* If the replacement _DECL isn't initialized, don't do the
9606 transformation. */
9607 if (!fn)
9608 return 0;
9610 return build_function_call_expr (fn, newarglist);
9612 return 0;
9616 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9617 by the builtin will be ignored. UNLOCKED is true is true if this
9618 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9619 the known length of the string. Return NULL_TREE if no simplification
9620 was possible. */
9622 tree
9623 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9625 tree fn;
9626 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9627 : implicit_built_in_decls[BUILT_IN_FPUTC];
9628 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9629 : implicit_built_in_decls[BUILT_IN_FWRITE];
9631 /* If the return value is used, or the replacement _DECL isn't
9632 initialized, don't do the transformation. */
9633 if (!ignore || !fn_fputc || !fn_fwrite)
9634 return 0;
9636 /* Verify the arguments in the original call. */
9637 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9638 return 0;
9640 if (! len)
9641 len = c_strlen (TREE_VALUE (arglist), 0);
9643 /* Get the length of the string passed to fputs. If the length
9644 can't be determined, punt. */
9645 if (!len
9646 || TREE_CODE (len) != INTEGER_CST)
9647 return 0;
9649 switch (compare_tree_int (len, 1))
9651 case -1: /* length is 0, delete the call entirely . */
9652 return omit_one_operand (integer_type_node, integer_zero_node,
9653 TREE_VALUE (TREE_CHAIN (arglist)));
9655 case 0: /* length is 1, call fputc. */
9657 const char *p = c_getstr (TREE_VALUE (arglist));
9659 if (p != NULL)
9661 /* New argument list transforming fputs(string, stream) to
9662 fputc(string[0], stream). */
9663 arglist = build_tree_list (NULL_TREE,
9664 TREE_VALUE (TREE_CHAIN (arglist)));
9665 arglist = tree_cons (NULL_TREE,
9666 build_int_cst (NULL_TREE, p[0]),
9667 arglist);
9668 fn = fn_fputc;
9669 break;
9672 /* FALLTHROUGH */
9673 case 1: /* length is greater than 1, call fwrite. */
9675 tree string_arg;
9677 /* If optimizing for size keep fputs. */
9678 if (optimize_size)
9679 return 0;
9680 string_arg = TREE_VALUE (arglist);
9681 /* New argument list transforming fputs(string, stream) to
9682 fwrite(string, 1, len, stream). */
9683 arglist = build_tree_list (NULL_TREE,
9684 TREE_VALUE (TREE_CHAIN (arglist)));
9685 arglist = tree_cons (NULL_TREE, len, arglist);
9686 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9687 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9688 fn = fn_fwrite;
9689 break;
9691 default:
9692 gcc_unreachable ();
9695 /* These optimizations are only performed when the result is ignored,
9696 hence there's no need to cast the result to integer_type_node. */
9697 return build_function_call_expr (fn, arglist);
9700 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9701 produced. False otherwise. This is done so that we don't output the error
9702 or warning twice or three times. */
9703 bool
9704 fold_builtin_next_arg (tree arglist)
9706 tree fntype = TREE_TYPE (current_function_decl);
9708 if (TYPE_ARG_TYPES (fntype) == 0
9709 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9710 == void_type_node))
9712 error ("%<va_start%> used in function with fixed args");
9713 return true;
9715 else if (!arglist)
9717 /* Evidently an out of date version of <stdarg.h>; can't validate
9718 va_start's second argument, but can still work as intended. */
9719 warning (0, "%<__builtin_next_arg%> called without an argument");
9720 return true;
9722 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9723 when we checked the arguments and if needed issued a warning. */
9724 else if (!TREE_CHAIN (arglist)
9725 || !integer_zerop (TREE_VALUE (arglist))
9726 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9727 || TREE_CHAIN (TREE_CHAIN (arglist)))
9729 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9730 tree arg = TREE_VALUE (arglist);
9732 if (TREE_CHAIN (arglist))
9734 error ("%<va_start%> used with too many arguments");
9735 return true;
9738 /* Strip off all nops for the sake of the comparison. This
9739 is not quite the same as STRIP_NOPS. It does more.
9740 We must also strip off INDIRECT_EXPR for C++ reference
9741 parameters. */
9742 while (TREE_CODE (arg) == NOP_EXPR
9743 || TREE_CODE (arg) == CONVERT_EXPR
9744 || TREE_CODE (arg) == NON_LVALUE_EXPR
9745 || TREE_CODE (arg) == INDIRECT_REF)
9746 arg = TREE_OPERAND (arg, 0);
9747 if (arg != last_parm)
9749 /* FIXME: Sometimes with the tree optimizers we can get the
9750 not the last argument even though the user used the last
9751 argument. We just warn and set the arg to be the last
9752 argument so that we will get wrong-code because of
9753 it. */
9754 warning (0, "second parameter of %<va_start%> not last named argument");
9756 /* We want to verify the second parameter just once before the tree
9757 optimizers are run and then avoid keeping it in the tree,
9758 as otherwise we could warn even for correct code like:
9759 void foo (int i, ...)
9760 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9761 TREE_VALUE (arglist) = integer_zero_node;
9762 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9764 return false;
9768 /* Simplify a call to the sprintf builtin.
9770 Return 0 if no simplification was possible, otherwise return the
9771 simplified form of the call as a tree. If IGNORED is true, it means that
9772 the caller does not use the returned value of the function. */
9774 static tree
9775 fold_builtin_sprintf (tree arglist, int ignored)
9777 tree call, retval, dest, fmt;
9778 const char *fmt_str = NULL;
9780 /* Verify the required arguments in the original call. We deal with two
9781 types of sprintf() calls: 'sprintf (str, fmt)' and
9782 'sprintf (dest, "%s", orig)'. */
9783 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9784 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9785 VOID_TYPE))
9786 return NULL_TREE;
9788 /* Get the destination string and the format specifier. */
9789 dest = TREE_VALUE (arglist);
9790 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9792 /* Check whether the format is a literal string constant. */
9793 fmt_str = c_getstr (fmt);
9794 if (fmt_str == NULL)
9795 return NULL_TREE;
9797 call = NULL_TREE;
9798 retval = NULL_TREE;
9800 /* If the format doesn't contain % args or %%, use strcpy. */
9801 if (strchr (fmt_str, '%') == NULL)
9803 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9805 if (!fn)
9806 return NULL_TREE;
9808 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9809 'format' is known to contain no % formats. */
9810 arglist = build_tree_list (NULL_TREE, fmt);
9811 arglist = tree_cons (NULL_TREE, dest, arglist);
9812 call = build_function_call_expr (fn, arglist);
9813 if (!ignored)
9814 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9817 /* If the format is "%s", use strcpy if the result isn't used. */
9818 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9820 tree fn, orig;
9821 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9823 if (!fn)
9824 return NULL_TREE;
9826 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9827 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9828 arglist = build_tree_list (NULL_TREE, orig);
9829 arglist = tree_cons (NULL_TREE, dest, arglist);
9830 if (!ignored)
9832 retval = c_strlen (orig, 1);
9833 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9834 return NULL_TREE;
9836 call = build_function_call_expr (fn, arglist);
9839 if (call && retval)
9841 retval = convert
9842 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9843 retval);
9844 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9846 else
9847 return call;
9850 /* Expand a call to __builtin_object_size. */
9853 expand_builtin_object_size (tree exp)
9855 tree ost;
9856 int object_size_type;
9857 tree fndecl = get_callee_fndecl (exp);
9858 tree arglist = TREE_OPERAND (exp, 1);
9859 location_t locus = EXPR_LOCATION (exp);
9861 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9863 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9864 &locus, fndecl);
9865 expand_builtin_trap ();
9866 return const0_rtx;
9869 ost = TREE_VALUE (TREE_CHAIN (arglist));
9870 STRIP_NOPS (ost);
9872 if (TREE_CODE (ost) != INTEGER_CST
9873 || tree_int_cst_sgn (ost) < 0
9874 || compare_tree_int (ost, 3) > 0)
9876 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9877 &locus, fndecl);
9878 expand_builtin_trap ();
9879 return const0_rtx;
9882 object_size_type = tree_low_cst (ost, 0);
9884 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9887 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9888 FCODE is the BUILT_IN_* to use.
9889 Return 0 if we failed; the caller should emit a normal call,
9890 otherwise try to get the result in TARGET, if convenient (and in
9891 mode MODE if that's convenient). */
9893 static rtx
9894 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9895 enum built_in_function fcode)
9897 tree arglist = TREE_OPERAND (exp, 1);
9898 tree dest, src, len, size;
9900 if (!validate_arglist (arglist,
9901 POINTER_TYPE,
9902 fcode == BUILT_IN_MEMSET_CHK
9903 ? INTEGER_TYPE : POINTER_TYPE,
9904 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9905 return 0;
9907 dest = TREE_VALUE (arglist);
9908 src = TREE_VALUE (TREE_CHAIN (arglist));
9909 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9910 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9912 if (! host_integerp (size, 1))
9913 return 0;
9915 if (host_integerp (len, 1) || integer_all_onesp (size))
9917 tree fn;
9919 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9921 location_t locus = EXPR_LOCATION (exp);
9922 warning (0, "%Hcall to %D will always overflow destination buffer",
9923 &locus, get_callee_fndecl (exp));
9924 return 0;
9927 arglist = build_tree_list (NULL_TREE, len);
9928 arglist = tree_cons (NULL_TREE, src, arglist);
9929 arglist = tree_cons (NULL_TREE, dest, arglist);
9931 fn = NULL_TREE;
9932 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9933 mem{cpy,pcpy,move,set} is available. */
9934 switch (fcode)
9936 case BUILT_IN_MEMCPY_CHK:
9937 fn = built_in_decls[BUILT_IN_MEMCPY];
9938 break;
9939 case BUILT_IN_MEMPCPY_CHK:
9940 fn = built_in_decls[BUILT_IN_MEMPCPY];
9941 break;
9942 case BUILT_IN_MEMMOVE_CHK:
9943 fn = built_in_decls[BUILT_IN_MEMMOVE];
9944 break;
9945 case BUILT_IN_MEMSET_CHK:
9946 fn = built_in_decls[BUILT_IN_MEMSET];
9947 break;
9948 default:
9949 break;
9952 if (! fn)
9953 return 0;
9955 fn = build_function_call_expr (fn, arglist);
9956 if (TREE_CODE (fn) == CALL_EXPR)
9957 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9958 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9960 else if (fcode == BUILT_IN_MEMSET_CHK)
9961 return 0;
9962 else
9964 unsigned int dest_align
9965 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9967 /* If DEST is not a pointer type, call the normal function. */
9968 if (dest_align == 0)
9969 return 0;
9971 /* If SRC and DEST are the same (and not volatile), do nothing. */
9972 if (operand_equal_p (src, dest, 0))
9974 tree expr;
9976 if (fcode != BUILT_IN_MEMPCPY_CHK)
9978 /* Evaluate and ignore LEN in case it has side-effects. */
9979 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9980 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9983 len = fold_convert (TREE_TYPE (dest), len);
9984 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9985 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9988 /* __memmove_chk special case. */
9989 if (fcode == BUILT_IN_MEMMOVE_CHK)
9991 unsigned int src_align
9992 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9994 if (src_align == 0)
9995 return 0;
9997 /* If src is categorized for a readonly section we can use
9998 normal __memcpy_chk. */
9999 if (readonly_data_expr (src))
10001 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10002 if (!fn)
10003 return 0;
10004 fn = build_function_call_expr (fn, arglist);
10005 if (TREE_CODE (fn) == CALL_EXPR)
10006 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10007 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10010 return 0;
10014 /* Emit warning if a buffer overflow is detected at compile time. */
10016 static void
10017 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10019 int arg_mask, is_strlen = 0;
10020 tree arglist = TREE_OPERAND (exp, 1), a;
10021 tree len, size;
10022 location_t locus;
10024 switch (fcode)
10026 case BUILT_IN_STRCPY_CHK:
10027 case BUILT_IN_STPCPY_CHK:
10028 /* For __strcat_chk the warning will be emitted only if overflowing
10029 by at least strlen (dest) + 1 bytes. */
10030 case BUILT_IN_STRCAT_CHK:
10031 arg_mask = 6;
10032 is_strlen = 1;
10033 break;
10034 case BUILT_IN_STRNCPY_CHK:
10035 arg_mask = 12;
10036 break;
10037 case BUILT_IN_SNPRINTF_CHK:
10038 case BUILT_IN_VSNPRINTF_CHK:
10039 arg_mask = 10;
10040 break;
10041 default:
10042 gcc_unreachable ();
10045 len = NULL_TREE;
10046 size = NULL_TREE;
10047 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10048 if (arg_mask & 1)
10050 if (len)
10051 size = a;
10052 else
10053 len = a;
10056 if (!len || !size)
10057 return;
10059 len = TREE_VALUE (len);
10060 size = TREE_VALUE (size);
10062 if (! host_integerp (size, 1) || integer_all_onesp (size))
10063 return;
10065 if (is_strlen)
10067 len = c_strlen (len, 1);
10068 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10069 return;
10071 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10072 return;
10074 locus = EXPR_LOCATION (exp);
10075 warning (0, "%Hcall to %D will always overflow destination buffer",
10076 &locus, get_callee_fndecl (exp));
10079 /* Emit warning if a buffer overflow is detected at compile time
10080 in __sprintf_chk/__vsprintf_chk calls. */
10082 static void
10083 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10085 tree arglist = TREE_OPERAND (exp, 1);
10086 tree dest, size, len, fmt, flag;
10087 const char *fmt_str;
10089 /* Verify the required arguments in the original call. */
10090 if (! arglist)
10091 return;
10092 dest = TREE_VALUE (arglist);
10093 arglist = TREE_CHAIN (arglist);
10094 if (! arglist)
10095 return;
10096 flag = TREE_VALUE (arglist);
10097 arglist = TREE_CHAIN (arglist);
10098 if (! arglist)
10099 return;
10100 size = TREE_VALUE (arglist);
10101 arglist = TREE_CHAIN (arglist);
10102 if (! arglist)
10103 return;
10104 fmt = TREE_VALUE (arglist);
10105 arglist = TREE_CHAIN (arglist);
10107 if (! host_integerp (size, 1) || integer_all_onesp (size))
10108 return;
10110 /* Check whether the format is a literal string constant. */
10111 fmt_str = c_getstr (fmt);
10112 if (fmt_str == NULL)
10113 return;
10115 /* If the format doesn't contain % args or %%, we know its size. */
10116 if (strchr (fmt_str, '%') == 0)
10117 len = build_int_cstu (size_type_node, strlen (fmt_str));
10118 /* If the format is "%s" and first ... argument is a string literal,
10119 we know it too. */
10120 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10122 tree arg;
10124 if (! arglist)
10125 return;
10126 arg = TREE_VALUE (arglist);
10127 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10128 return;
10130 len = c_strlen (arg, 1);
10131 if (!len || ! host_integerp (len, 1))
10132 return;
10134 else
10135 return;
10137 if (! tree_int_cst_lt (len, size))
10139 location_t locus = EXPR_LOCATION (exp);
10140 warning (0, "%Hcall to %D will always overflow destination buffer",
10141 &locus, get_callee_fndecl (exp));
10145 /* Fold a call to __builtin_object_size, if possible. */
10147 tree
10148 fold_builtin_object_size (tree arglist)
10150 tree ptr, ost, ret = 0;
10151 int object_size_type;
10153 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10154 return 0;
10156 ptr = TREE_VALUE (arglist);
10157 ost = TREE_VALUE (TREE_CHAIN (arglist));
10158 STRIP_NOPS (ost);
10160 if (TREE_CODE (ost) != INTEGER_CST
10161 || tree_int_cst_sgn (ost) < 0
10162 || compare_tree_int (ost, 3) > 0)
10163 return 0;
10165 object_size_type = tree_low_cst (ost, 0);
10167 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10168 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10169 and (size_t) 0 for types 2 and 3. */
10170 if (TREE_SIDE_EFFECTS (ptr))
10171 return fold_convert (size_type_node,
10172 object_size_type < 2
10173 ? integer_minus_one_node : integer_zero_node);
10175 if (TREE_CODE (ptr) == ADDR_EXPR)
10176 ret = build_int_cstu (size_type_node,
10177 compute_builtin_object_size (ptr, object_size_type));
10179 else if (TREE_CODE (ptr) == SSA_NAME)
10181 unsigned HOST_WIDE_INT bytes;
10183 /* If object size is not known yet, delay folding until
10184 later. Maybe subsequent passes will help determining
10185 it. */
10186 bytes = compute_builtin_object_size (ptr, object_size_type);
10187 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10188 ? -1 : 0))
10189 ret = build_int_cstu (size_type_node, bytes);
10192 if (ret)
10194 ret = force_fit_type (ret, -1, false, false);
10195 if (TREE_CONSTANT_OVERFLOW (ret))
10196 ret = 0;
10199 return ret;
10202 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10203 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10204 code of the builtin. If MAXLEN is not NULL, it is maximum length
10205 passed as third argument. */
10207 tree
10208 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10209 enum built_in_function fcode)
10211 tree dest, src, len, size, fn;
10213 if (!validate_arglist (arglist,
10214 POINTER_TYPE,
10215 fcode == BUILT_IN_MEMSET_CHK
10216 ? INTEGER_TYPE : POINTER_TYPE,
10217 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10218 return 0;
10220 dest = TREE_VALUE (arglist);
10221 /* Actually val for __memset_chk, but it doesn't matter. */
10222 src = TREE_VALUE (TREE_CHAIN (arglist));
10223 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10224 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10226 /* If SRC and DEST are the same (and not volatile), return DEST
10227 (resp. DEST+LEN for __mempcpy_chk). */
10228 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10230 if (fcode != BUILT_IN_MEMPCPY_CHK)
10231 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10232 else
10234 tree temp = fold_convert (TREE_TYPE (dest), len);
10235 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10236 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10240 if (! host_integerp (size, 1))
10241 return 0;
10243 if (! integer_all_onesp (size))
10245 if (! host_integerp (len, 1))
10247 /* If LEN is not constant, try MAXLEN too.
10248 For MAXLEN only allow optimizing into non-_ocs function
10249 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10250 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10252 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10254 /* (void) __mempcpy_chk () can be optimized into
10255 (void) __memcpy_chk (). */
10256 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10257 if (!fn)
10258 return 0;
10260 return build_function_call_expr (fn, arglist);
10262 return 0;
10265 else
10266 maxlen = len;
10268 if (tree_int_cst_lt (size, maxlen))
10269 return 0;
10272 arglist = build_tree_list (NULL_TREE, len);
10273 arglist = tree_cons (NULL_TREE, src, arglist);
10274 arglist = tree_cons (NULL_TREE, dest, arglist);
10276 fn = NULL_TREE;
10277 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10278 mem{cpy,pcpy,move,set} is available. */
10279 switch (fcode)
10281 case BUILT_IN_MEMCPY_CHK:
10282 fn = built_in_decls[BUILT_IN_MEMCPY];
10283 break;
10284 case BUILT_IN_MEMPCPY_CHK:
10285 fn = built_in_decls[BUILT_IN_MEMPCPY];
10286 break;
10287 case BUILT_IN_MEMMOVE_CHK:
10288 fn = built_in_decls[BUILT_IN_MEMMOVE];
10289 break;
10290 case BUILT_IN_MEMSET_CHK:
10291 fn = built_in_decls[BUILT_IN_MEMSET];
10292 break;
10293 default:
10294 break;
10297 if (!fn)
10298 return 0;
10300 return build_function_call_expr (fn, arglist);
10303 /* Fold a call to the __st[rp]cpy_chk builtin.
10304 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10305 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10306 strings passed as second argument. */
10308 tree
10309 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10310 enum built_in_function fcode)
10312 tree dest, src, size, len, fn;
10314 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10315 VOID_TYPE))
10316 return 0;
10318 dest = TREE_VALUE (arglist);
10319 src = TREE_VALUE (TREE_CHAIN (arglist));
10320 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10322 /* If SRC and DEST are the same (and not volatile), return DEST. */
10323 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10324 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10326 if (! host_integerp (size, 1))
10327 return 0;
10329 if (! integer_all_onesp (size))
10331 len = c_strlen (src, 1);
10332 if (! len || ! host_integerp (len, 1))
10334 /* If LEN is not constant, try MAXLEN too.
10335 For MAXLEN only allow optimizing into non-_ocs function
10336 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10337 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10339 if (fcode == BUILT_IN_STPCPY_CHK)
10341 if (! ignore)
10342 return 0;
10344 /* If return value of __stpcpy_chk is ignored,
10345 optimize into __strcpy_chk. */
10346 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10347 if (!fn)
10348 return 0;
10350 return build_function_call_expr (fn, arglist);
10353 if (! len || TREE_SIDE_EFFECTS (len))
10354 return 0;
10356 /* If c_strlen returned something, but not a constant,
10357 transform __strcpy_chk into __memcpy_chk. */
10358 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10359 if (!fn)
10360 return 0;
10362 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10363 arglist = build_tree_list (NULL_TREE, size);
10364 arglist = tree_cons (NULL_TREE, len, arglist);
10365 arglist = tree_cons (NULL_TREE, src, arglist);
10366 arglist = tree_cons (NULL_TREE, dest, arglist);
10367 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10368 build_function_call_expr (fn, arglist));
10371 else
10372 maxlen = len;
10374 if (! tree_int_cst_lt (maxlen, size))
10375 return 0;
10378 arglist = build_tree_list (NULL_TREE, src);
10379 arglist = tree_cons (NULL_TREE, dest, arglist);
10381 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10382 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10383 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10384 if (!fn)
10385 return 0;
10387 return build_function_call_expr (fn, arglist);
10390 /* Fold a call to the __strncpy_chk builtin.
10391 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10393 tree
10394 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10396 tree dest, src, size, len, fn;
10398 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10399 INTEGER_TYPE, VOID_TYPE))
10400 return 0;
10402 dest = TREE_VALUE (arglist);
10403 src = TREE_VALUE (TREE_CHAIN (arglist));
10404 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10405 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10407 if (! host_integerp (size, 1))
10408 return 0;
10410 if (! integer_all_onesp (size))
10412 if (! host_integerp (len, 1))
10414 /* If LEN is not constant, try MAXLEN too.
10415 For MAXLEN only allow optimizing into non-_ocs function
10416 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10417 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10418 return 0;
10420 else
10421 maxlen = len;
10423 if (tree_int_cst_lt (size, maxlen))
10424 return 0;
10427 arglist = build_tree_list (NULL_TREE, len);
10428 arglist = tree_cons (NULL_TREE, src, arglist);
10429 arglist = tree_cons (NULL_TREE, dest, arglist);
10431 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10432 fn = built_in_decls[BUILT_IN_STRNCPY];
10433 if (!fn)
10434 return 0;
10436 return build_function_call_expr (fn, arglist);
10439 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10441 static tree
10442 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10444 tree dest, src, size, fn;
10445 const char *p;
10447 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10448 VOID_TYPE))
10449 return 0;
10451 dest = TREE_VALUE (arglist);
10452 src = TREE_VALUE (TREE_CHAIN (arglist));
10453 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10455 p = c_getstr (src);
10456 /* If the SRC parameter is "", return DEST. */
10457 if (p && *p == '\0')
10458 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10460 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10461 return 0;
10463 arglist = build_tree_list (NULL_TREE, src);
10464 arglist = tree_cons (NULL_TREE, dest, arglist);
10466 /* If __builtin_strcat_chk is used, assume strcat is available. */
10467 fn = built_in_decls[BUILT_IN_STRCAT];
10468 if (!fn)
10469 return 0;
10471 return build_function_call_expr (fn, arglist);
10474 /* Fold a call to the __strncat_chk builtin EXP. */
10476 static tree
10477 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10479 tree dest, src, size, len, fn;
10480 const char *p;
10482 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10483 INTEGER_TYPE, VOID_TYPE))
10484 return 0;
10486 dest = TREE_VALUE (arglist);
10487 src = TREE_VALUE (TREE_CHAIN (arglist));
10488 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10489 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10491 p = c_getstr (src);
10492 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10493 if (p && *p == '\0')
10494 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10495 else if (integer_zerop (len))
10496 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10498 if (! host_integerp (size, 1))
10499 return 0;
10501 if (! integer_all_onesp (size))
10503 tree src_len = c_strlen (src, 1);
10504 if (src_len
10505 && host_integerp (src_len, 1)
10506 && host_integerp (len, 1)
10507 && ! tree_int_cst_lt (len, src_len))
10509 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10510 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10511 if (!fn)
10512 return 0;
10514 arglist = build_tree_list (NULL_TREE, size);
10515 arglist = tree_cons (NULL_TREE, src, arglist);
10516 arglist = tree_cons (NULL_TREE, dest, arglist);
10517 return build_function_call_expr (fn, arglist);
10519 return 0;
10522 arglist = build_tree_list (NULL_TREE, len);
10523 arglist = tree_cons (NULL_TREE, src, arglist);
10524 arglist = tree_cons (NULL_TREE, dest, arglist);
10526 /* If __builtin_strncat_chk is used, assume strncat is available. */
10527 fn = built_in_decls[BUILT_IN_STRNCAT];
10528 if (!fn)
10529 return 0;
10531 return build_function_call_expr (fn, arglist);
10534 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10535 a normal call should be emitted rather than expanding the function
10536 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10538 static tree
10539 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10541 tree dest, size, len, fn, fmt, flag;
10542 const char *fmt_str;
10544 /* Verify the required arguments in the original call. */
10545 if (! arglist)
10546 return 0;
10547 dest = TREE_VALUE (arglist);
10548 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10549 return 0;
10550 arglist = TREE_CHAIN (arglist);
10551 if (! arglist)
10552 return 0;
10553 flag = TREE_VALUE (arglist);
10554 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10555 return 0;
10556 arglist = TREE_CHAIN (arglist);
10557 if (! arglist)
10558 return 0;
10559 size = TREE_VALUE (arglist);
10560 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10561 return 0;
10562 arglist = TREE_CHAIN (arglist);
10563 if (! arglist)
10564 return 0;
10565 fmt = TREE_VALUE (arglist);
10566 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10567 return 0;
10568 arglist = TREE_CHAIN (arglist);
10570 if (! host_integerp (size, 1))
10571 return 0;
10573 len = NULL_TREE;
10575 /* Check whether the format is a literal string constant. */
10576 fmt_str = c_getstr (fmt);
10577 if (fmt_str != NULL)
10579 /* If the format doesn't contain % args or %%, we know the size. */
10580 if (strchr (fmt_str, '%') == 0)
10582 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10583 len = build_int_cstu (size_type_node, strlen (fmt_str));
10585 /* If the format is "%s" and first ... argument is a string literal,
10586 we know the size too. */
10587 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10589 tree arg;
10591 if (arglist && !TREE_CHAIN (arglist))
10593 arg = TREE_VALUE (arglist);
10594 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10596 len = c_strlen (arg, 1);
10597 if (! len || ! host_integerp (len, 1))
10598 len = NULL_TREE;
10604 if (! integer_all_onesp (size))
10606 if (! len || ! tree_int_cst_lt (len, size))
10607 return 0;
10610 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10611 or if format doesn't contain % chars or is "%s". */
10612 if (! integer_zerop (flag))
10614 if (fmt_str == NULL)
10615 return 0;
10616 if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10617 return 0;
10620 arglist = tree_cons (NULL_TREE, fmt, arglist);
10621 arglist = tree_cons (NULL_TREE, dest, arglist);
10623 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10624 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10625 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10626 if (!fn)
10627 return 0;
10629 return build_function_call_expr (fn, arglist);
10632 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10633 a normal call should be emitted rather than expanding the function
10634 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10635 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10636 passed as second argument. */
10638 tree
10639 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10640 enum built_in_function fcode)
10642 tree dest, size, len, fn, fmt, flag;
10643 const char *fmt_str;
10645 /* Verify the required arguments in the original call. */
10646 if (! arglist)
10647 return 0;
10648 dest = TREE_VALUE (arglist);
10649 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10650 return 0;
10651 arglist = TREE_CHAIN (arglist);
10652 if (! arglist)
10653 return 0;
10654 len = TREE_VALUE (arglist);
10655 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10656 return 0;
10657 arglist = TREE_CHAIN (arglist);
10658 if (! arglist)
10659 return 0;
10660 flag = TREE_VALUE (arglist);
10661 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10662 return 0;
10663 arglist = TREE_CHAIN (arglist);
10664 if (! arglist)
10665 return 0;
10666 size = TREE_VALUE (arglist);
10667 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10668 return 0;
10669 arglist = TREE_CHAIN (arglist);
10670 if (! arglist)
10671 return 0;
10672 fmt = TREE_VALUE (arglist);
10673 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10674 return 0;
10675 arglist = TREE_CHAIN (arglist);
10677 if (! host_integerp (size, 1))
10678 return 0;
10680 if (! integer_all_onesp (size))
10682 if (! host_integerp (len, 1))
10684 /* If LEN is not constant, try MAXLEN too.
10685 For MAXLEN only allow optimizing into non-_ocs function
10686 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10687 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10688 return 0;
10690 else
10691 maxlen = len;
10693 if (tree_int_cst_lt (size, maxlen))
10694 return 0;
10697 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10698 or if format doesn't contain % chars or is "%s". */
10699 if (! integer_zerop (flag))
10701 fmt_str = c_getstr (fmt);
10702 if (fmt_str == NULL)
10703 return 0;
10704 if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10705 return 0;
10708 arglist = tree_cons (NULL_TREE, fmt, arglist);
10709 arglist = tree_cons (NULL_TREE, len, arglist);
10710 arglist = tree_cons (NULL_TREE, dest, arglist);
10712 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10713 available. */
10714 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10715 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10716 if (!fn)
10717 return 0;
10719 return build_function_call_expr (fn, arglist);
10722 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10724 Return 0 if no simplification was possible, otherwise return the
10725 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10726 code of the function to be simplified. */
10728 static tree
10729 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10730 enum built_in_function fcode)
10732 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10733 const char *fmt_str = NULL;
10735 /* If the return value is used, don't do the transformation. */
10736 if (! ignore)
10737 return 0;
10739 /* Verify the required arguments in the original call. */
10740 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10742 tree flag;
10744 if (! arglist)
10745 return 0;
10746 flag = TREE_VALUE (arglist);
10747 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10748 || TREE_SIDE_EFFECTS (flag))
10749 return 0;
10750 arglist = TREE_CHAIN (arglist);
10753 if (! arglist)
10754 return 0;
10755 fmt = TREE_VALUE (arglist);
10756 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10757 return 0;
10758 arglist = TREE_CHAIN (arglist);
10760 /* Check whether the format is a literal string constant. */
10761 fmt_str = c_getstr (fmt);
10762 if (fmt_str == NULL)
10763 return NULL_TREE;
10765 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10767 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10768 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10770 else
10772 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10773 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10776 if (strcmp (fmt_str, "%s") == 0 || strchr (fmt_str, '%') == NULL)
10778 const char *str;
10780 if (strcmp (fmt_str, "%s") == 0)
10782 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10783 return 0;
10785 if (! arglist
10786 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10787 || TREE_CHAIN (arglist))
10788 return 0;
10790 str = c_getstr (TREE_VALUE (arglist));
10791 if (str == NULL)
10792 return 0;
10794 else
10796 /* The format specifier doesn't contain any '%' characters. */
10797 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10798 && arglist)
10799 return 0;
10800 str = fmt_str;
10803 /* If the string was "", printf does nothing. */
10804 if (str[0] == '\0')
10805 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10807 /* If the string has length of 1, call putchar. */
10808 if (str[1] == '\0')
10810 /* Given printf("c"), (where c is any one character,)
10811 convert "c"[0] to an int and pass that to the replacement
10812 function. */
10813 arg = build_int_cst (NULL_TREE, str[0]);
10814 arglist = build_tree_list (NULL_TREE, arg);
10815 fn = fn_putchar;
10817 else
10819 /* If the string was "string\n", call puts("string"). */
10820 size_t len = strlen (str);
10821 if (str[len - 1] == '\n')
10823 /* Create a NUL-terminated string that's one char shorter
10824 than the original, stripping off the trailing '\n'. */
10825 char *newstr = alloca (len);
10826 memcpy (newstr, str, len - 1);
10827 newstr[len - 1] = 0;
10829 arg = build_string_literal (len, newstr);
10830 arglist = build_tree_list (NULL_TREE, arg);
10831 fn = fn_puts;
10833 else
10834 /* We'd like to arrange to call fputs(string,stdout) here,
10835 but we need stdout and don't have a way to get it yet. */
10836 return 0;
10840 /* The other optimizations can be done only on the non-va_list variants. */
10841 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10842 return 0;
10844 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10845 else if (strcmp (fmt_str, "%s\n") == 0)
10847 if (! arglist
10848 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10849 || TREE_CHAIN (arglist))
10850 return 0;
10851 fn = fn_puts;
10854 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10855 else if (strcmp (fmt_str, "%c") == 0)
10857 if (! arglist
10858 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10859 || TREE_CHAIN (arglist))
10860 return 0;
10861 fn = fn_putchar;
10864 if (!fn)
10865 return 0;
10867 call = build_function_call_expr (fn, arglist);
10868 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10871 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10873 Return 0 if no simplification was possible, otherwise return the
10874 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10875 code of the function to be simplified. */
10877 static tree
10878 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10879 enum built_in_function fcode)
10881 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10882 const char *fmt_str = NULL;
10884 /* If the return value is used, don't do the transformation. */
10885 if (! ignore)
10886 return 0;
10888 /* Verify the required arguments in the original call. */
10889 if (! arglist)
10890 return 0;
10891 fp = TREE_VALUE (arglist);
10892 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10893 return 0;
10894 arglist = TREE_CHAIN (arglist);
10896 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10898 tree flag;
10900 if (! arglist)
10901 return 0;
10902 flag = TREE_VALUE (arglist);
10903 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10904 || TREE_SIDE_EFFECTS (flag))
10905 return 0;
10906 arglist = TREE_CHAIN (arglist);
10909 if (! arglist)
10910 return 0;
10911 fmt = TREE_VALUE (arglist);
10912 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10913 return 0;
10914 arglist = TREE_CHAIN (arglist);
10916 /* Check whether the format is a literal string constant. */
10917 fmt_str = c_getstr (fmt);
10918 if (fmt_str == NULL)
10919 return NULL_TREE;
10921 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10923 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10924 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10926 else
10928 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10929 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10932 /* If the format doesn't contain % args or %%, use strcpy. */
10933 if (strchr (fmt_str, '%') == NULL)
10935 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10936 && arglist)
10937 return 0;
10939 /* If the format specifier was "", fprintf does nothing. */
10940 if (fmt_str[0] == '\0')
10942 /* If FP has side-effects, just wait until gimplification is
10943 done. */
10944 if (TREE_SIDE_EFFECTS (fp))
10945 return 0;
10947 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10950 /* When "string" doesn't contain %, replace all cases of
10951 fprintf (fp, string) with fputs (string, fp). The fputs
10952 builtin will take care of special cases like length == 1. */
10953 arglist = build_tree_list (NULL_TREE, fp);
10954 arglist = tree_cons (NULL_TREE, fmt, arglist);
10955 fn = fn_fputs;
10958 /* The other optimizations can be done only on the non-va_list variants. */
10959 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10960 return 0;
10962 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10963 else if (strcmp (fmt_str, "%s") == 0)
10965 if (! arglist
10966 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10967 || TREE_CHAIN (arglist))
10968 return 0;
10969 arg = TREE_VALUE (arglist);
10970 arglist = build_tree_list (NULL_TREE, fp);
10971 arglist = tree_cons (NULL_TREE, arg, arglist);
10972 fn = fn_fputs;
10975 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10976 else if (strcmp (fmt_str, "%c") == 0)
10978 if (! arglist
10979 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10980 || TREE_CHAIN (arglist))
10981 return 0;
10982 arg = TREE_VALUE (arglist);
10983 arglist = build_tree_list (NULL_TREE, fp);
10984 arglist = tree_cons (NULL_TREE, arg, arglist);
10985 fn = fn_fputc;
10988 if (!fn)
10989 return 0;
10991 call = build_function_call_expr (fn, arglist);
10992 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);