builtins.c (do_mpfr_arg3): New.
[official-gcc.git] / gcc / builtins.c
blob9d27243bd22e6f82870e85f927468db9c08dd45e
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static void expand_builtin_update_setjmp_buf (rtx);
85 static void expand_builtin_prefetch (tree);
86 static rtx expand_builtin_apply_args (void);
87 static rtx expand_builtin_apply_args_1 (void);
88 static rtx expand_builtin_apply (rtx, rtx, rtx);
89 static void expand_builtin_return (rtx);
90 static enum type_class type_to_class (tree);
91 static rtx expand_builtin_classify_type (tree);
92 static void expand_errno_check (tree, rtx);
93 static rtx expand_builtin_mathfn (tree, rtx, rtx);
94 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
96 static rtx expand_builtin_sincos (tree);
97 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_cos (tree, tree, tree);
154 static tree fold_builtin_tan (tree, tree);
155 static tree fold_builtin_trunc (tree, tree);
156 static tree fold_builtin_floor (tree, tree);
157 static tree fold_builtin_ceil (tree, tree);
158 static tree fold_builtin_round (tree, tree);
159 static tree fold_builtin_int_roundingfn (tree, tree);
160 static tree fold_builtin_bitop (tree, tree);
161 static tree fold_builtin_memory_op (tree, tree, bool, int);
162 static tree fold_builtin_strchr (tree, tree);
163 static tree fold_builtin_memcmp (tree);
164 static tree fold_builtin_strcmp (tree);
165 static tree fold_builtin_strncmp (tree);
166 static tree fold_builtin_signbit (tree, tree);
167 static tree fold_builtin_copysign (tree, tree, tree);
168 static tree fold_builtin_isascii (tree);
169 static tree fold_builtin_toascii (tree);
170 static tree fold_builtin_isdigit (tree);
171 static tree fold_builtin_fabs (tree, tree);
172 static tree fold_builtin_abs (tree, tree);
173 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
174 enum tree_code);
175 static tree fold_builtin_1 (tree, tree, bool);
177 static tree fold_builtin_strpbrk (tree, tree);
178 static tree fold_builtin_strstr (tree, tree);
179 static tree fold_builtin_strrchr (tree, tree);
180 static tree fold_builtin_strcat (tree);
181 static tree fold_builtin_strncat (tree);
182 static tree fold_builtin_strspn (tree);
183 static tree fold_builtin_strcspn (tree);
184 static tree fold_builtin_sprintf (tree, int);
186 static rtx expand_builtin_object_size (tree);
187 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
188 enum built_in_function);
189 static void maybe_emit_chk_warning (tree, enum built_in_function);
190 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
191 static tree fold_builtin_object_size (tree);
192 static tree fold_builtin_strcat_chk (tree, tree);
193 static tree fold_builtin_strncat_chk (tree, tree);
194 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
195 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
196 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
197 static bool init_target_chars (void);
199 static unsigned HOST_WIDE_INT target_newline;
200 static unsigned HOST_WIDE_INT target_percent;
201 static unsigned HOST_WIDE_INT target_c;
202 static unsigned HOST_WIDE_INT target_s;
203 static char target_percent_c[3];
204 static char target_percent_s[3];
205 static char target_percent_s_newline[4];
206 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
207 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
208 static tree do_mpfr_arg2 (tree, tree, tree,
209 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
210 static tree do_mpfr_arg3 (tree, tree, tree, tree,
211 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
212 static tree do_mpfr_sincos (tree, tree, tree);
214 /* Return true if NODE should be considered for inline expansion regardless
215 of the optimization level. This means whenever a function is invoked with
216 its "internal" name, which normally contains the prefix "__builtin". */
218 static bool called_as_built_in (tree node)
220 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
221 if (strncmp (name, "__builtin_", 10) == 0)
222 return true;
223 if (strncmp (name, "__sync_", 7) == 0)
224 return true;
225 return false;
228 /* Return the alignment in bits of EXP, a pointer valued expression.
229 But don't return more than MAX_ALIGN no matter what.
230 The alignment returned is, by default, the alignment of the thing that
231 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
233 Otherwise, look at the expression to see if we can do better, i.e., if the
234 expression is actually pointing at an object whose alignment is tighter. */
236 static int
237 get_pointer_alignment (tree exp, unsigned int max_align)
239 unsigned int align, inner;
241 /* We rely on TER to compute accurate alignment information. */
242 if (!(optimize && flag_tree_ter))
243 return 0;
245 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
246 return 0;
248 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
249 align = MIN (align, max_align);
251 while (1)
253 switch (TREE_CODE (exp))
255 case NOP_EXPR:
256 case CONVERT_EXPR:
257 case NON_LVALUE_EXPR:
258 exp = TREE_OPERAND (exp, 0);
259 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
260 return align;
262 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
263 align = MIN (inner, max_align);
264 break;
266 case PLUS_EXPR:
267 /* If sum of pointer + int, restrict our maximum alignment to that
268 imposed by the integer. If not, we can't do any better than
269 ALIGN. */
270 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
271 return align;
273 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
274 & (max_align / BITS_PER_UNIT - 1))
275 != 0)
276 max_align >>= 1;
278 exp = TREE_OPERAND (exp, 0);
279 break;
281 case ADDR_EXPR:
282 /* See what we are pointing at and look at its alignment. */
283 exp = TREE_OPERAND (exp, 0);
284 inner = max_align;
285 if (handled_component_p (exp))
287 HOST_WIDE_INT bitsize, bitpos;
288 tree offset;
289 enum machine_mode mode;
290 int unsignedp, volatilep;
292 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
293 &mode, &unsignedp, &volatilep, true);
294 if (bitpos)
295 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
296 if (offset && TREE_CODE (offset) == PLUS_EXPR
297 && host_integerp (TREE_OPERAND (offset, 1), 1))
299 /* Any overflow in calculating offset_bits won't change
300 the alignment. */
301 unsigned offset_bits
302 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
303 * BITS_PER_UNIT);
305 if (offset_bits)
306 inner = MIN (inner, (offset_bits & -offset_bits));
307 offset = TREE_OPERAND (offset, 0);
309 if (offset && TREE_CODE (offset) == MULT_EXPR
310 && host_integerp (TREE_OPERAND (offset, 1), 1))
312 /* Any overflow in calculating offset_factor won't change
313 the alignment. */
314 unsigned offset_factor
315 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
316 * BITS_PER_UNIT);
318 if (offset_factor)
319 inner = MIN (inner, (offset_factor & -offset_factor));
321 else if (offset)
322 inner = MIN (inner, BITS_PER_UNIT);
324 if (TREE_CODE (exp) == FUNCTION_DECL)
325 align = FUNCTION_BOUNDARY;
326 else if (DECL_P (exp))
327 align = MIN (inner, DECL_ALIGN (exp));
328 #ifdef CONSTANT_ALIGNMENT
329 else if (CONSTANT_CLASS_P (exp))
330 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
331 #endif
332 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
333 || TREE_CODE (exp) == INDIRECT_REF)
334 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
335 else
336 align = MIN (align, inner);
337 return MIN (align, max_align);
339 default:
340 return align;
345 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
346 way, because it could contain a zero byte in the middle.
347 TREE_STRING_LENGTH is the size of the character array, not the string.
349 ONLY_VALUE should be nonzero if the result is not going to be emitted
350 into the instruction stream and zero if it is going to be expanded.
351 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
352 is returned, otherwise NULL, since
353 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
354 evaluate the side-effects.
356 The value returned is of type `ssizetype'.
358 Unfortunately, string_constant can't access the values of const char
359 arrays with initializers, so neither can we do so here. */
361 tree
362 c_strlen (tree src, int only_value)
364 tree offset_node;
365 HOST_WIDE_INT offset;
366 int max;
367 const char *ptr;
369 STRIP_NOPS (src);
370 if (TREE_CODE (src) == COND_EXPR
371 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
373 tree len1, len2;
375 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
376 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
377 if (tree_int_cst_equal (len1, len2))
378 return len1;
381 if (TREE_CODE (src) == COMPOUND_EXPR
382 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
383 return c_strlen (TREE_OPERAND (src, 1), only_value);
385 src = string_constant (src, &offset_node);
386 if (src == 0)
387 return 0;
389 max = TREE_STRING_LENGTH (src) - 1;
390 ptr = TREE_STRING_POINTER (src);
392 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
394 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
395 compute the offset to the following null if we don't know where to
396 start searching for it. */
397 int i;
399 for (i = 0; i < max; i++)
400 if (ptr[i] == 0)
401 return 0;
403 /* We don't know the starting offset, but we do know that the string
404 has no internal zero bytes. We can assume that the offset falls
405 within the bounds of the string; otherwise, the programmer deserves
406 what he gets. Subtract the offset from the length of the string,
407 and return that. This would perhaps not be valid if we were dealing
408 with named arrays in addition to literal string constants. */
410 return size_diffop (size_int (max), offset_node);
413 /* We have a known offset into the string. Start searching there for
414 a null character if we can represent it as a single HOST_WIDE_INT. */
415 if (offset_node == 0)
416 offset = 0;
417 else if (! host_integerp (offset_node, 0))
418 offset = -1;
419 else
420 offset = tree_low_cst (offset_node, 0);
422 /* If the offset is known to be out of bounds, warn, and call strlen at
423 runtime. */
424 if (offset < 0 || offset > max)
426 warning (0, "offset outside bounds of constant string");
427 return 0;
430 /* Use strlen to search for the first zero byte. Since any strings
431 constructed with build_string will have nulls appended, we win even
432 if we get handed something like (char[4])"abcd".
434 Since OFFSET is our starting index into the string, no further
435 calculation is needed. */
436 return ssize_int (strlen (ptr + offset));
439 /* Return a char pointer for a C string if it is a string constant
440 or sum of string constant and integer constant. */
442 static const char *
443 c_getstr (tree src)
445 tree offset_node;
447 src = string_constant (src, &offset_node);
448 if (src == 0)
449 return 0;
451 if (offset_node == 0)
452 return TREE_STRING_POINTER (src);
453 else if (!host_integerp (offset_node, 1)
454 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
455 return 0;
457 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
460 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
461 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
463 static rtx
464 c_readstr (const char *str, enum machine_mode mode)
466 HOST_WIDE_INT c[2];
467 HOST_WIDE_INT ch;
468 unsigned int i, j;
470 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
472 c[0] = 0;
473 c[1] = 0;
474 ch = 1;
475 for (i = 0; i < GET_MODE_SIZE (mode); i++)
477 j = i;
478 if (WORDS_BIG_ENDIAN)
479 j = GET_MODE_SIZE (mode) - i - 1;
480 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
481 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
482 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
483 j *= BITS_PER_UNIT;
484 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
486 if (ch)
487 ch = (unsigned char) str[i];
488 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
490 return immed_double_const (c[0], c[1], mode);
493 /* Cast a target constant CST to target CHAR and if that value fits into
494 host char type, return zero and put that value into variable pointed to by
495 P. */
497 static int
498 target_char_cast (tree cst, char *p)
500 unsigned HOST_WIDE_INT val, hostval;
502 if (!host_integerp (cst, 1)
503 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
504 return 1;
506 val = tree_low_cst (cst, 1);
507 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
508 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
510 hostval = val;
511 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
512 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
514 if (val != hostval)
515 return 1;
517 *p = hostval;
518 return 0;
521 /* Similar to save_expr, but assumes that arbitrary code is not executed
522 in between the multiple evaluations. In particular, we assume that a
523 non-addressable local variable will not be modified. */
525 static tree
526 builtin_save_expr (tree exp)
528 if (TREE_ADDRESSABLE (exp) == 0
529 && (TREE_CODE (exp) == PARM_DECL
530 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
531 return exp;
533 return save_expr (exp);
536 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
537 times to get the address of either a higher stack frame, or a return
538 address located within it (depending on FNDECL_CODE). */
540 static rtx
541 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
543 int i;
545 #ifdef INITIAL_FRAME_ADDRESS_RTX
546 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
547 #else
548 rtx tem;
550 /* For a zero count with __builtin_return_address, we don't care what
551 frame address we return, because target-specific definitions will
552 override us. Therefore frame pointer elimination is OK, and using
553 the soft frame pointer is OK.
555 For a non-zero count, or a zero count with __builtin_frame_address,
556 we require a stable offset from the current frame pointer to the
557 previous one, so we must use the hard frame pointer, and
558 we must disable frame pointer elimination. */
559 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
560 tem = frame_pointer_rtx;
561 else
563 tem = hard_frame_pointer_rtx;
565 /* Tell reload not to eliminate the frame pointer. */
566 current_function_accesses_prior_frames = 1;
568 #endif
570 /* Some machines need special handling before we can access
571 arbitrary frames. For example, on the SPARC, we must first flush
572 all register windows to the stack. */
573 #ifdef SETUP_FRAME_ADDRESSES
574 if (count > 0)
575 SETUP_FRAME_ADDRESSES ();
576 #endif
578 /* On the SPARC, the return address is not in the frame, it is in a
579 register. There is no way to access it off of the current frame
580 pointer, but it can be accessed off the previous frame pointer by
581 reading the value from the register window save area. */
582 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
583 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
584 count--;
585 #endif
587 /* Scan back COUNT frames to the specified frame. */
588 for (i = 0; i < count; i++)
590 /* Assume the dynamic chain pointer is in the word that the
591 frame address points to, unless otherwise specified. */
592 #ifdef DYNAMIC_CHAIN_ADDRESS
593 tem = DYNAMIC_CHAIN_ADDRESS (tem);
594 #endif
595 tem = memory_address (Pmode, tem);
596 tem = gen_frame_mem (Pmode, tem);
597 tem = copy_to_reg (tem);
600 /* For __builtin_frame_address, return what we've got. But, on
601 the SPARC for example, we may have to add a bias. */
602 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
603 #ifdef FRAME_ADDR_RTX
604 return FRAME_ADDR_RTX (tem);
605 #else
606 return tem;
607 #endif
609 /* For __builtin_return_address, get the return address from that frame. */
610 #ifdef RETURN_ADDR_RTX
611 tem = RETURN_ADDR_RTX (count, tem);
612 #else
613 tem = memory_address (Pmode,
614 plus_constant (tem, GET_MODE_SIZE (Pmode)));
615 tem = gen_frame_mem (Pmode, tem);
616 #endif
617 return tem;
620 /* Alias set used for setjmp buffer. */
621 static HOST_WIDE_INT setjmp_alias_set = -1;
623 /* Construct the leading half of a __builtin_setjmp call. Control will
624 return to RECEIVER_LABEL. This is also called directly by the SJLJ
625 exception handling code. */
627 void
628 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
630 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
631 rtx stack_save;
632 rtx mem;
634 if (setjmp_alias_set == -1)
635 setjmp_alias_set = new_alias_set ();
637 buf_addr = convert_memory_address (Pmode, buf_addr);
639 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
641 /* We store the frame pointer and the address of receiver_label in
642 the buffer and use the rest of it for the stack save area, which
643 is machine-dependent. */
645 mem = gen_rtx_MEM (Pmode, buf_addr);
646 set_mem_alias_set (mem, setjmp_alias_set);
647 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
649 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
650 set_mem_alias_set (mem, setjmp_alias_set);
652 emit_move_insn (validize_mem (mem),
653 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
655 stack_save = gen_rtx_MEM (sa_mode,
656 plus_constant (buf_addr,
657 2 * GET_MODE_SIZE (Pmode)));
658 set_mem_alias_set (stack_save, setjmp_alias_set);
659 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
661 /* If there is further processing to do, do it. */
662 #ifdef HAVE_builtin_setjmp_setup
663 if (HAVE_builtin_setjmp_setup)
664 emit_insn (gen_builtin_setjmp_setup (buf_addr));
665 #endif
667 /* Tell optimize_save_area_alloca that extra work is going to
668 need to go on during alloca. */
669 current_function_calls_setjmp = 1;
671 /* Set this so all the registers get saved in our frame; we need to be
672 able to copy the saved values for any registers from frames we unwind. */
673 current_function_has_nonlocal_label = 1;
676 /* Construct the trailing part of a __builtin_setjmp call. This is
677 also called directly by the SJLJ exception handling code. */
679 void
680 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
682 /* Clobber the FP when we get here, so we have to make sure it's
683 marked as used by this function. */
684 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
686 /* Mark the static chain as clobbered here so life information
687 doesn't get messed up for it. */
688 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
690 /* Now put in the code to restore the frame pointer, and argument
691 pointer, if needed. */
692 #ifdef HAVE_nonlocal_goto
693 if (! HAVE_nonlocal_goto)
694 #endif
696 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
697 /* This might change the hard frame pointer in ways that aren't
698 apparent to early optimization passes, so force a clobber. */
699 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
702 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
703 if (fixed_regs[ARG_POINTER_REGNUM])
705 #ifdef ELIMINABLE_REGS
706 size_t i;
707 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
709 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
710 if (elim_regs[i].from == ARG_POINTER_REGNUM
711 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
712 break;
714 if (i == ARRAY_SIZE (elim_regs))
715 #endif
717 /* Now restore our arg pointer from the address at which it
718 was saved in our stack frame. */
719 emit_move_insn (virtual_incoming_args_rtx,
720 copy_to_reg (get_arg_pointer_save_area (cfun)));
723 #endif
725 #ifdef HAVE_builtin_setjmp_receiver
726 if (HAVE_builtin_setjmp_receiver)
727 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
728 else
729 #endif
730 #ifdef HAVE_nonlocal_goto_receiver
731 if (HAVE_nonlocal_goto_receiver)
732 emit_insn (gen_nonlocal_goto_receiver ());
733 else
734 #endif
735 { /* Nothing */ }
737 /* @@@ This is a kludge. Not all machine descriptions define a blockage
738 insn, but we must not allow the code we just generated to be reordered
739 by scheduling. Specifically, the update of the frame pointer must
740 happen immediately, not later. So emit an ASM_INPUT to act as blockage
741 insn. */
742 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
745 /* __builtin_longjmp is passed a pointer to an array of five words (not
746 all will be used on all machines). It operates similarly to the C
747 library function of the same name, but is more efficient. Much of
748 the code below is copied from the handling of non-local gotos. */
750 static void
751 expand_builtin_longjmp (rtx buf_addr, rtx value)
753 rtx fp, lab, stack, insn, last;
754 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
756 if (setjmp_alias_set == -1)
757 setjmp_alias_set = new_alias_set ();
759 buf_addr = convert_memory_address (Pmode, buf_addr);
761 buf_addr = force_reg (Pmode, buf_addr);
763 /* We used to store value in static_chain_rtx, but that fails if pointers
764 are smaller than integers. We instead require that the user must pass
765 a second argument of 1, because that is what builtin_setjmp will
766 return. This also makes EH slightly more efficient, since we are no
767 longer copying around a value that we don't care about. */
768 gcc_assert (value == const1_rtx);
770 last = get_last_insn ();
771 #ifdef HAVE_builtin_longjmp
772 if (HAVE_builtin_longjmp)
773 emit_insn (gen_builtin_longjmp (buf_addr));
774 else
775 #endif
777 fp = gen_rtx_MEM (Pmode, buf_addr);
778 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
779 GET_MODE_SIZE (Pmode)));
781 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
782 2 * GET_MODE_SIZE (Pmode)));
783 set_mem_alias_set (fp, setjmp_alias_set);
784 set_mem_alias_set (lab, setjmp_alias_set);
785 set_mem_alias_set (stack, setjmp_alias_set);
787 /* Pick up FP, label, and SP from the block and jump. This code is
788 from expand_goto in stmt.c; see there for detailed comments. */
789 #ifdef HAVE_nonlocal_goto
790 if (HAVE_nonlocal_goto)
791 /* We have to pass a value to the nonlocal_goto pattern that will
792 get copied into the static_chain pointer, but it does not matter
793 what that value is, because builtin_setjmp does not use it. */
794 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
795 else
796 #endif
798 lab = copy_to_reg (lab);
800 emit_insn (gen_rtx_CLOBBER (VOIDmode,
801 gen_rtx_MEM (BLKmode,
802 gen_rtx_SCRATCH (VOIDmode))));
803 emit_insn (gen_rtx_CLOBBER (VOIDmode,
804 gen_rtx_MEM (BLKmode,
805 hard_frame_pointer_rtx)));
807 emit_move_insn (hard_frame_pointer_rtx, fp);
808 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
810 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
811 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
812 emit_indirect_jump (lab);
816 /* Search backwards and mark the jump insn as a non-local goto.
817 Note that this precludes the use of __builtin_longjmp to a
818 __builtin_setjmp target in the same function. However, we've
819 already cautioned the user that these functions are for
820 internal exception handling use only. */
821 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
823 gcc_assert (insn != last);
825 if (JUMP_P (insn))
827 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
828 REG_NOTES (insn));
829 break;
831 else if (CALL_P (insn))
832 break;
836 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
837 and the address of the save area. */
839 static rtx
840 expand_builtin_nonlocal_goto (tree arglist)
842 tree t_label, t_save_area;
843 rtx r_label, r_save_area, r_fp, r_sp, insn;
845 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
846 return NULL_RTX;
848 t_label = TREE_VALUE (arglist);
849 arglist = TREE_CHAIN (arglist);
850 t_save_area = TREE_VALUE (arglist);
852 r_label = expand_normal (t_label);
853 r_label = convert_memory_address (Pmode, r_label);
854 r_save_area = expand_normal (t_save_area);
855 r_save_area = convert_memory_address (Pmode, r_save_area);
856 r_fp = gen_rtx_MEM (Pmode, r_save_area);
857 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
858 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
860 current_function_has_nonlocal_goto = 1;
862 #ifdef HAVE_nonlocal_goto
863 /* ??? We no longer need to pass the static chain value, afaik. */
864 if (HAVE_nonlocal_goto)
865 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
866 else
867 #endif
869 r_label = copy_to_reg (r_label);
871 emit_insn (gen_rtx_CLOBBER (VOIDmode,
872 gen_rtx_MEM (BLKmode,
873 gen_rtx_SCRATCH (VOIDmode))));
875 emit_insn (gen_rtx_CLOBBER (VOIDmode,
876 gen_rtx_MEM (BLKmode,
877 hard_frame_pointer_rtx)));
879 /* Restore frame pointer for containing function.
880 This sets the actual hard register used for the frame pointer
881 to the location of the function's incoming static chain info.
882 The non-local goto handler will then adjust it to contain the
883 proper value and reload the argument pointer, if needed. */
884 emit_move_insn (hard_frame_pointer_rtx, r_fp);
885 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
887 /* USE of hard_frame_pointer_rtx added for consistency;
888 not clear if really needed. */
889 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
890 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
891 emit_indirect_jump (r_label);
894 /* Search backwards to the jump insn and mark it as a
895 non-local goto. */
896 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
898 if (JUMP_P (insn))
900 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
901 const0_rtx, REG_NOTES (insn));
902 break;
904 else if (CALL_P (insn))
905 break;
908 return const0_rtx;
911 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
912 (not all will be used on all machines) that was passed to __builtin_setjmp.
913 It updates the stack pointer in that block to correspond to the current
914 stack pointer. */
916 static void
917 expand_builtin_update_setjmp_buf (rtx buf_addr)
919 enum machine_mode sa_mode = Pmode;
920 rtx stack_save;
923 #ifdef HAVE_save_stack_nonlocal
924 if (HAVE_save_stack_nonlocal)
925 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
926 #endif
927 #ifdef STACK_SAVEAREA_MODE
928 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
929 #endif
931 stack_save
932 = gen_rtx_MEM (sa_mode,
933 memory_address
934 (sa_mode,
935 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
937 #ifdef HAVE_setjmp
938 if (HAVE_setjmp)
939 emit_insn (gen_setjmp ());
940 #endif
942 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
945 /* Expand a call to __builtin_prefetch. For a target that does not support
946 data prefetch, evaluate the memory address argument in case it has side
947 effects. */
949 static void
950 expand_builtin_prefetch (tree arglist)
952 tree arg0, arg1, arg2;
953 rtx op0, op1, op2;
955 if (!validate_arglist (arglist, POINTER_TYPE, 0))
956 return;
958 arg0 = TREE_VALUE (arglist);
959 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
960 zero (read) and argument 2 (locality) defaults to 3 (high degree of
961 locality). */
962 if (TREE_CHAIN (arglist))
964 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
965 if (TREE_CHAIN (TREE_CHAIN (arglist)))
966 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
967 else
968 arg2 = build_int_cst (NULL_TREE, 3);
970 else
972 arg1 = integer_zero_node;
973 arg2 = build_int_cst (NULL_TREE, 3);
976 /* Argument 0 is an address. */
977 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
979 /* Argument 1 (read/write flag) must be a compile-time constant int. */
980 if (TREE_CODE (arg1) != INTEGER_CST)
982 error ("second argument to %<__builtin_prefetch%> must be a constant");
983 arg1 = integer_zero_node;
985 op1 = expand_normal (arg1);
986 /* Argument 1 must be either zero or one. */
987 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
989 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
990 " using zero");
991 op1 = const0_rtx;
994 /* Argument 2 (locality) must be a compile-time constant int. */
995 if (TREE_CODE (arg2) != INTEGER_CST)
997 error ("third argument to %<__builtin_prefetch%> must be a constant");
998 arg2 = integer_zero_node;
1000 op2 = expand_normal (arg2);
1001 /* Argument 2 must be 0, 1, 2, or 3. */
1002 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1004 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1005 op2 = const0_rtx;
1008 #ifdef HAVE_prefetch
1009 if (HAVE_prefetch)
1011 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1012 (op0,
1013 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1014 || (GET_MODE (op0) != Pmode))
1016 op0 = convert_memory_address (Pmode, op0);
1017 op0 = force_reg (Pmode, op0);
1019 emit_insn (gen_prefetch (op0, op1, op2));
1021 #endif
1023 /* Don't do anything with direct references to volatile memory, but
1024 generate code to handle other side effects. */
1025 if (!MEM_P (op0) && side_effects_p (op0))
1026 emit_insn (op0);
1029 /* Get a MEM rtx for expression EXP which is the address of an operand
1030 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1031 the maximum length of the block of memory that might be accessed or
1032 NULL if unknown. */
1034 static rtx
1035 get_memory_rtx (tree exp, tree len)
1037 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1038 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1040 /* Get an expression we can use to find the attributes to assign to MEM.
1041 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1042 we can. First remove any nops. */
1043 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1044 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1045 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1046 exp = TREE_OPERAND (exp, 0);
1048 if (TREE_CODE (exp) == ADDR_EXPR)
1049 exp = TREE_OPERAND (exp, 0);
1050 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1051 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1052 else
1053 exp = NULL;
1055 /* Honor attributes derived from exp, except for the alias set
1056 (as builtin stringops may alias with anything) and the size
1057 (as stringops may access multiple array elements). */
1058 if (exp)
1060 set_mem_attributes (mem, exp, 0);
1062 /* Allow the string and memory builtins to overflow from one
1063 field into another, see http://gcc.gnu.org/PR23561.
1064 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1065 memory accessed by the string or memory builtin will fit
1066 within the field. */
1067 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1069 tree mem_expr = MEM_EXPR (mem);
1070 HOST_WIDE_INT offset = -1, length = -1;
1071 tree inner = exp;
1073 while (TREE_CODE (inner) == ARRAY_REF
1074 || TREE_CODE (inner) == NOP_EXPR
1075 || TREE_CODE (inner) == CONVERT_EXPR
1076 || TREE_CODE (inner) == NON_LVALUE_EXPR
1077 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1078 || TREE_CODE (inner) == SAVE_EXPR)
1079 inner = TREE_OPERAND (inner, 0);
1081 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1083 if (MEM_OFFSET (mem)
1084 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1085 offset = INTVAL (MEM_OFFSET (mem));
1087 if (offset >= 0 && len && host_integerp (len, 0))
1088 length = tree_low_cst (len, 0);
1090 while (TREE_CODE (inner) == COMPONENT_REF)
1092 tree field = TREE_OPERAND (inner, 1);
1093 gcc_assert (! DECL_BIT_FIELD (field));
1094 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1095 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1097 if (length >= 0
1098 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1099 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1101 HOST_WIDE_INT size
1102 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1103 /* If we can prove the memory starting at XEXP (mem, 0)
1104 and ending at XEXP (mem, 0) + LENGTH will fit into
1105 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1106 if (offset <= size
1107 && length <= size
1108 && offset + length <= size)
1109 break;
1112 if (offset >= 0
1113 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1114 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1115 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1116 / BITS_PER_UNIT;
1117 else
1119 offset = -1;
1120 length = -1;
1123 mem_expr = TREE_OPERAND (mem_expr, 0);
1124 inner = TREE_OPERAND (inner, 0);
1127 if (mem_expr == NULL)
1128 offset = -1;
1129 if (mem_expr != MEM_EXPR (mem))
1131 set_mem_expr (mem, mem_expr);
1132 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1135 set_mem_alias_set (mem, 0);
1136 set_mem_size (mem, NULL_RTX);
1139 return mem;
1142 /* Built-in functions to perform an untyped call and return. */
1144 /* For each register that may be used for calling a function, this
1145 gives a mode used to copy the register's value. VOIDmode indicates
1146 the register is not used for calling a function. If the machine
1147 has register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1151 /* For each register that may be used for returning values, this gives
1152 a mode used to copy the register's value. VOIDmode indicates the
1153 register is not used for returning values. If the machine has
1154 register windows, this gives only the outbound registers.
1155 INCOMING_REGNO gives the corresponding inbound register. */
1156 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1158 /* For each register that may be used for calling a function, this
1159 gives the offset of that register into the block returned by
1160 __builtin_apply_args. 0 indicates that the register is not
1161 used for calling a function. */
1162 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1164 /* Return the size required for the block returned by __builtin_apply_args,
1165 and initialize apply_args_mode. */
1167 static int
1168 apply_args_size (void)
1170 static int size = -1;
1171 int align;
1172 unsigned int regno;
1173 enum machine_mode mode;
1175 /* The values computed by this function never change. */
1176 if (size < 0)
1178 /* The first value is the incoming arg-pointer. */
1179 size = GET_MODE_SIZE (Pmode);
1181 /* The second value is the structure value address unless this is
1182 passed as an "invisible" first argument. */
1183 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1184 size += GET_MODE_SIZE (Pmode);
1186 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1187 if (FUNCTION_ARG_REGNO_P (regno))
1189 mode = reg_raw_mode[regno];
1191 gcc_assert (mode != VOIDmode);
1193 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1194 if (size % align != 0)
1195 size = CEIL (size, align) * align;
1196 apply_args_reg_offset[regno] = size;
1197 size += GET_MODE_SIZE (mode);
1198 apply_args_mode[regno] = mode;
1200 else
1202 apply_args_mode[regno] = VOIDmode;
1203 apply_args_reg_offset[regno] = 0;
1206 return size;
1209 /* Return the size required for the block returned by __builtin_apply,
1210 and initialize apply_result_mode. */
1212 static int
1213 apply_result_size (void)
1215 static int size = -1;
1216 int align, regno;
1217 enum machine_mode mode;
1219 /* The values computed by this function never change. */
1220 if (size < 0)
1222 size = 0;
1224 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1225 if (FUNCTION_VALUE_REGNO_P (regno))
1227 mode = reg_raw_mode[regno];
1229 gcc_assert (mode != VOIDmode);
1231 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1232 if (size % align != 0)
1233 size = CEIL (size, align) * align;
1234 size += GET_MODE_SIZE (mode);
1235 apply_result_mode[regno] = mode;
1237 else
1238 apply_result_mode[regno] = VOIDmode;
1240 /* Allow targets that use untyped_call and untyped_return to override
1241 the size so that machine-specific information can be stored here. */
1242 #ifdef APPLY_RESULT_SIZE
1243 size = APPLY_RESULT_SIZE;
1244 #endif
1246 return size;
1249 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1250 /* Create a vector describing the result block RESULT. If SAVEP is true,
1251 the result block is used to save the values; otherwise it is used to
1252 restore the values. */
1254 static rtx
1255 result_vector (int savep, rtx result)
1257 int regno, size, align, nelts;
1258 enum machine_mode mode;
1259 rtx reg, mem;
1260 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1262 size = nelts = 0;
1263 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1264 if ((mode = apply_result_mode[regno]) != VOIDmode)
1266 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1267 if (size % align != 0)
1268 size = CEIL (size, align) * align;
1269 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1270 mem = adjust_address (result, mode, size);
1271 savevec[nelts++] = (savep
1272 ? gen_rtx_SET (VOIDmode, mem, reg)
1273 : gen_rtx_SET (VOIDmode, reg, mem));
1274 size += GET_MODE_SIZE (mode);
1276 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1278 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1280 /* Save the state required to perform an untyped call with the same
1281 arguments as were passed to the current function. */
1283 static rtx
1284 expand_builtin_apply_args_1 (void)
1286 rtx registers, tem;
1287 int size, align, regno;
1288 enum machine_mode mode;
1289 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1291 /* Create a block where the arg-pointer, structure value address,
1292 and argument registers can be saved. */
1293 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1295 /* Walk past the arg-pointer and structure value address. */
1296 size = GET_MODE_SIZE (Pmode);
1297 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1298 size += GET_MODE_SIZE (Pmode);
1300 /* Save each register used in calling a function to the block. */
1301 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1302 if ((mode = apply_args_mode[regno]) != VOIDmode)
1304 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1305 if (size % align != 0)
1306 size = CEIL (size, align) * align;
1308 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1310 emit_move_insn (adjust_address (registers, mode, size), tem);
1311 size += GET_MODE_SIZE (mode);
1314 /* Save the arg pointer to the block. */
1315 tem = copy_to_reg (virtual_incoming_args_rtx);
1316 #ifdef STACK_GROWS_DOWNWARD
1317 /* We need the pointer as the caller actually passed them to us, not
1318 as we might have pretended they were passed. Make sure it's a valid
1319 operand, as emit_move_insn isn't expected to handle a PLUS. */
1321 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1322 NULL_RTX);
1323 #endif
1324 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1326 size = GET_MODE_SIZE (Pmode);
1328 /* Save the structure value address unless this is passed as an
1329 "invisible" first argument. */
1330 if (struct_incoming_value)
1332 emit_move_insn (adjust_address (registers, Pmode, size),
1333 copy_to_reg (struct_incoming_value));
1334 size += GET_MODE_SIZE (Pmode);
1337 /* Return the address of the block. */
1338 return copy_addr_to_reg (XEXP (registers, 0));
1341 /* __builtin_apply_args returns block of memory allocated on
1342 the stack into which is stored the arg pointer, structure
1343 value address, static chain, and all the registers that might
1344 possibly be used in performing a function call. The code is
1345 moved to the start of the function so the incoming values are
1346 saved. */
1348 static rtx
1349 expand_builtin_apply_args (void)
1351 /* Don't do __builtin_apply_args more than once in a function.
1352 Save the result of the first call and reuse it. */
1353 if (apply_args_value != 0)
1354 return apply_args_value;
1356 /* When this function is called, it means that registers must be
1357 saved on entry to this function. So we migrate the
1358 call to the first insn of this function. */
1359 rtx temp;
1360 rtx seq;
1362 start_sequence ();
1363 temp = expand_builtin_apply_args_1 ();
1364 seq = get_insns ();
1365 end_sequence ();
1367 apply_args_value = temp;
1369 /* Put the insns after the NOTE that starts the function.
1370 If this is inside a start_sequence, make the outer-level insn
1371 chain current, so the code is placed at the start of the
1372 function. */
1373 push_topmost_sequence ();
1374 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1375 pop_topmost_sequence ();
1376 return temp;
1380 /* Perform an untyped call and save the state required to perform an
1381 untyped return of whatever value was returned by the given function. */
1383 static rtx
1384 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1386 int size, align, regno;
1387 enum machine_mode mode;
1388 rtx incoming_args, result, reg, dest, src, call_insn;
1389 rtx old_stack_level = 0;
1390 rtx call_fusage = 0;
1391 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1393 arguments = convert_memory_address (Pmode, arguments);
1395 /* Create a block where the return registers can be saved. */
1396 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1398 /* Fetch the arg pointer from the ARGUMENTS block. */
1399 incoming_args = gen_reg_rtx (Pmode);
1400 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1401 #ifndef STACK_GROWS_DOWNWARD
1402 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1403 incoming_args, 0, OPTAB_LIB_WIDEN);
1404 #endif
1406 /* Push a new argument block and copy the arguments. Do not allow
1407 the (potential) memcpy call below to interfere with our stack
1408 manipulations. */
1409 do_pending_stack_adjust ();
1410 NO_DEFER_POP;
1412 /* Save the stack with nonlocal if available. */
1413 #ifdef HAVE_save_stack_nonlocal
1414 if (HAVE_save_stack_nonlocal)
1415 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1416 else
1417 #endif
1418 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1420 /* Allocate a block of memory onto the stack and copy the memory
1421 arguments to the outgoing arguments address. */
1422 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1423 dest = virtual_outgoing_args_rtx;
1424 #ifndef STACK_GROWS_DOWNWARD
1425 if (GET_CODE (argsize) == CONST_INT)
1426 dest = plus_constant (dest, -INTVAL (argsize));
1427 else
1428 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1429 #endif
1430 dest = gen_rtx_MEM (BLKmode, dest);
1431 set_mem_align (dest, PARM_BOUNDARY);
1432 src = gen_rtx_MEM (BLKmode, incoming_args);
1433 set_mem_align (src, PARM_BOUNDARY);
1434 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1436 /* Refer to the argument block. */
1437 apply_args_size ();
1438 arguments = gen_rtx_MEM (BLKmode, arguments);
1439 set_mem_align (arguments, PARM_BOUNDARY);
1441 /* Walk past the arg-pointer and structure value address. */
1442 size = GET_MODE_SIZE (Pmode);
1443 if (struct_value)
1444 size += GET_MODE_SIZE (Pmode);
1446 /* Restore each of the registers previously saved. Make USE insns
1447 for each of these registers for use in making the call. */
1448 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1449 if ((mode = apply_args_mode[regno]) != VOIDmode)
1451 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1452 if (size % align != 0)
1453 size = CEIL (size, align) * align;
1454 reg = gen_rtx_REG (mode, regno);
1455 emit_move_insn (reg, adjust_address (arguments, mode, size));
1456 use_reg (&call_fusage, reg);
1457 size += GET_MODE_SIZE (mode);
1460 /* Restore the structure value address unless this is passed as an
1461 "invisible" first argument. */
1462 size = GET_MODE_SIZE (Pmode);
1463 if (struct_value)
1465 rtx value = gen_reg_rtx (Pmode);
1466 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1467 emit_move_insn (struct_value, value);
1468 if (REG_P (struct_value))
1469 use_reg (&call_fusage, struct_value);
1470 size += GET_MODE_SIZE (Pmode);
1473 /* All arguments and registers used for the call are set up by now! */
1474 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1476 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1477 and we don't want to load it into a register as an optimization,
1478 because prepare_call_address already did it if it should be done. */
1479 if (GET_CODE (function) != SYMBOL_REF)
1480 function = memory_address (FUNCTION_MODE, function);
1482 /* Generate the actual call instruction and save the return value. */
1483 #ifdef HAVE_untyped_call
1484 if (HAVE_untyped_call)
1485 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1486 result, result_vector (1, result)));
1487 else
1488 #endif
1489 #ifdef HAVE_call_value
1490 if (HAVE_call_value)
1492 rtx valreg = 0;
1494 /* Locate the unique return register. It is not possible to
1495 express a call that sets more than one return register using
1496 call_value; use untyped_call for that. In fact, untyped_call
1497 only needs to save the return registers in the given block. */
1498 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1499 if ((mode = apply_result_mode[regno]) != VOIDmode)
1501 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1503 valreg = gen_rtx_REG (mode, regno);
1506 emit_call_insn (GEN_CALL_VALUE (valreg,
1507 gen_rtx_MEM (FUNCTION_MODE, function),
1508 const0_rtx, NULL_RTX, const0_rtx));
1510 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1512 else
1513 #endif
1514 gcc_unreachable ();
1516 /* Find the CALL insn we just emitted, and attach the register usage
1517 information. */
1518 call_insn = last_call_insn ();
1519 add_function_usage_to (call_insn, call_fusage);
1521 /* Restore the stack. */
1522 #ifdef HAVE_save_stack_nonlocal
1523 if (HAVE_save_stack_nonlocal)
1524 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1525 else
1526 #endif
1527 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1529 OK_DEFER_POP;
1531 /* Return the address of the result block. */
1532 result = copy_addr_to_reg (XEXP (result, 0));
1533 return convert_memory_address (ptr_mode, result);
1536 /* Perform an untyped return. */
1538 static void
1539 expand_builtin_return (rtx result)
1541 int size, align, regno;
1542 enum machine_mode mode;
1543 rtx reg;
1544 rtx call_fusage = 0;
1546 result = convert_memory_address (Pmode, result);
1548 apply_result_size ();
1549 result = gen_rtx_MEM (BLKmode, result);
1551 #ifdef HAVE_untyped_return
1552 if (HAVE_untyped_return)
1554 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1555 emit_barrier ();
1556 return;
1558 #endif
1560 /* Restore the return value and note that each value is used. */
1561 size = 0;
1562 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1563 if ((mode = apply_result_mode[regno]) != VOIDmode)
1565 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1566 if (size % align != 0)
1567 size = CEIL (size, align) * align;
1568 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1569 emit_move_insn (reg, adjust_address (result, mode, size));
1571 push_to_sequence (call_fusage);
1572 emit_insn (gen_rtx_USE (VOIDmode, reg));
1573 call_fusage = get_insns ();
1574 end_sequence ();
1575 size += GET_MODE_SIZE (mode);
1578 /* Put the USE insns before the return. */
1579 emit_insn (call_fusage);
1581 /* Return whatever values was restored by jumping directly to the end
1582 of the function. */
1583 expand_naked_return ();
1586 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1588 static enum type_class
1589 type_to_class (tree type)
1591 switch (TREE_CODE (type))
1593 case VOID_TYPE: return void_type_class;
1594 case INTEGER_TYPE: return integer_type_class;
1595 case ENUMERAL_TYPE: return enumeral_type_class;
1596 case BOOLEAN_TYPE: return boolean_type_class;
1597 case POINTER_TYPE: return pointer_type_class;
1598 case REFERENCE_TYPE: return reference_type_class;
1599 case OFFSET_TYPE: return offset_type_class;
1600 case REAL_TYPE: return real_type_class;
1601 case COMPLEX_TYPE: return complex_type_class;
1602 case FUNCTION_TYPE: return function_type_class;
1603 case METHOD_TYPE: return method_type_class;
1604 case RECORD_TYPE: return record_type_class;
1605 case UNION_TYPE:
1606 case QUAL_UNION_TYPE: return union_type_class;
1607 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1608 ? string_type_class : array_type_class);
1609 case LANG_TYPE: return lang_type_class;
1610 default: return no_type_class;
1614 /* Expand a call to __builtin_classify_type with arguments found in
1615 ARGLIST. */
1617 static rtx
1618 expand_builtin_classify_type (tree arglist)
1620 if (arglist != 0)
1621 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1622 return GEN_INT (no_type_class);
1625 /* This helper macro, meant to be used in mathfn_built_in below,
1626 determines which among a set of three builtin math functions is
1627 appropriate for a given type mode. The `F' and `L' cases are
1628 automatically generated from the `double' case. */
1629 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1630 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1631 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1632 fcodel = BUILT_IN_MATHFN##L ; break;
1634 /* Return mathematic function equivalent to FN but operating directly
1635 on TYPE, if available. If we can't do the conversion, return zero. */
1636 tree
1637 mathfn_built_in (tree type, enum built_in_function fn)
1639 enum built_in_function fcode, fcodef, fcodel;
1641 switch (fn)
1643 CASE_MATHFN (BUILT_IN_ACOS)
1644 CASE_MATHFN (BUILT_IN_ACOSH)
1645 CASE_MATHFN (BUILT_IN_ASIN)
1646 CASE_MATHFN (BUILT_IN_ASINH)
1647 CASE_MATHFN (BUILT_IN_ATAN)
1648 CASE_MATHFN (BUILT_IN_ATAN2)
1649 CASE_MATHFN (BUILT_IN_ATANH)
1650 CASE_MATHFN (BUILT_IN_CBRT)
1651 CASE_MATHFN (BUILT_IN_CEIL)
1652 CASE_MATHFN (BUILT_IN_COPYSIGN)
1653 CASE_MATHFN (BUILT_IN_COS)
1654 CASE_MATHFN (BUILT_IN_COSH)
1655 CASE_MATHFN (BUILT_IN_DREM)
1656 CASE_MATHFN (BUILT_IN_ERF)
1657 CASE_MATHFN (BUILT_IN_ERFC)
1658 CASE_MATHFN (BUILT_IN_EXP)
1659 CASE_MATHFN (BUILT_IN_EXP10)
1660 CASE_MATHFN (BUILT_IN_EXP2)
1661 CASE_MATHFN (BUILT_IN_EXPM1)
1662 CASE_MATHFN (BUILT_IN_FABS)
1663 CASE_MATHFN (BUILT_IN_FDIM)
1664 CASE_MATHFN (BUILT_IN_FLOOR)
1665 CASE_MATHFN (BUILT_IN_FMA)
1666 CASE_MATHFN (BUILT_IN_FMAX)
1667 CASE_MATHFN (BUILT_IN_FMIN)
1668 CASE_MATHFN (BUILT_IN_FMOD)
1669 CASE_MATHFN (BUILT_IN_FREXP)
1670 CASE_MATHFN (BUILT_IN_GAMMA)
1671 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1672 CASE_MATHFN (BUILT_IN_HYPOT)
1673 CASE_MATHFN (BUILT_IN_ILOGB)
1674 CASE_MATHFN (BUILT_IN_INF)
1675 CASE_MATHFN (BUILT_IN_J0)
1676 CASE_MATHFN (BUILT_IN_J1)
1677 CASE_MATHFN (BUILT_IN_JN)
1678 CASE_MATHFN (BUILT_IN_LCEIL)
1679 CASE_MATHFN (BUILT_IN_LDEXP)
1680 CASE_MATHFN (BUILT_IN_LFLOOR)
1681 CASE_MATHFN (BUILT_IN_LGAMMA)
1682 CASE_MATHFN (BUILT_IN_LLCEIL)
1683 CASE_MATHFN (BUILT_IN_LLFLOOR)
1684 CASE_MATHFN (BUILT_IN_LLRINT)
1685 CASE_MATHFN (BUILT_IN_LLROUND)
1686 CASE_MATHFN (BUILT_IN_LOG)
1687 CASE_MATHFN (BUILT_IN_LOG10)
1688 CASE_MATHFN (BUILT_IN_LOG1P)
1689 CASE_MATHFN (BUILT_IN_LOG2)
1690 CASE_MATHFN (BUILT_IN_LOGB)
1691 CASE_MATHFN (BUILT_IN_LRINT)
1692 CASE_MATHFN (BUILT_IN_LROUND)
1693 CASE_MATHFN (BUILT_IN_MODF)
1694 CASE_MATHFN (BUILT_IN_NAN)
1695 CASE_MATHFN (BUILT_IN_NANS)
1696 CASE_MATHFN (BUILT_IN_NEARBYINT)
1697 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1698 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1699 CASE_MATHFN (BUILT_IN_POW)
1700 CASE_MATHFN (BUILT_IN_POWI)
1701 CASE_MATHFN (BUILT_IN_POW10)
1702 CASE_MATHFN (BUILT_IN_REMAINDER)
1703 CASE_MATHFN (BUILT_IN_REMQUO)
1704 CASE_MATHFN (BUILT_IN_RINT)
1705 CASE_MATHFN (BUILT_IN_ROUND)
1706 CASE_MATHFN (BUILT_IN_SCALB)
1707 CASE_MATHFN (BUILT_IN_SCALBLN)
1708 CASE_MATHFN (BUILT_IN_SCALBN)
1709 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1710 CASE_MATHFN (BUILT_IN_SIN)
1711 CASE_MATHFN (BUILT_IN_SINCOS)
1712 CASE_MATHFN (BUILT_IN_SINH)
1713 CASE_MATHFN (BUILT_IN_SQRT)
1714 CASE_MATHFN (BUILT_IN_TAN)
1715 CASE_MATHFN (BUILT_IN_TANH)
1716 CASE_MATHFN (BUILT_IN_TGAMMA)
1717 CASE_MATHFN (BUILT_IN_TRUNC)
1718 CASE_MATHFN (BUILT_IN_Y0)
1719 CASE_MATHFN (BUILT_IN_Y1)
1720 CASE_MATHFN (BUILT_IN_YN)
1722 default:
1723 return 0;
1726 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1727 return implicit_built_in_decls[fcode];
1728 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1729 return implicit_built_in_decls[fcodef];
1730 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1731 return implicit_built_in_decls[fcodel];
1732 else
1733 return 0;
1736 /* If errno must be maintained, expand the RTL to check if the result,
1737 TARGET, of a built-in function call, EXP, is NaN, and if so set
1738 errno to EDOM. */
1740 static void
1741 expand_errno_check (tree exp, rtx target)
1743 rtx lab = gen_label_rtx ();
1745 /* Test the result; if it is NaN, set errno=EDOM because
1746 the argument was not in the domain. */
1747 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1748 0, lab);
1750 #ifdef TARGET_EDOM
1751 /* If this built-in doesn't throw an exception, set errno directly. */
1752 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1754 #ifdef GEN_ERRNO_RTX
1755 rtx errno_rtx = GEN_ERRNO_RTX;
1756 #else
1757 rtx errno_rtx
1758 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1759 #endif
1760 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1761 emit_label (lab);
1762 return;
1764 #endif
1766 /* We can't set errno=EDOM directly; let the library call do it.
1767 Pop the arguments right away in case the call gets deleted. */
1768 NO_DEFER_POP;
1769 expand_call (exp, target, 0);
1770 OK_DEFER_POP;
1771 emit_label (lab);
1775 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1776 Return 0 if a normal call should be emitted rather than expanding the
1777 function in-line. EXP is the expression that is a call to the builtin
1778 function; if convenient, the result should be placed in TARGET.
1779 SUBTARGET may be used as the target for computing one of EXP's operands. */
1781 static rtx
1782 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1784 optab builtin_optab;
1785 rtx op0, insns, before_call;
1786 tree fndecl = get_callee_fndecl (exp);
1787 tree arglist = TREE_OPERAND (exp, 1);
1788 enum machine_mode mode;
1789 bool errno_set = false;
1790 tree arg, narg;
1792 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1793 return 0;
1795 arg = TREE_VALUE (arglist);
1797 switch (DECL_FUNCTION_CODE (fndecl))
1799 CASE_FLT_FN (BUILT_IN_SQRT):
1800 errno_set = ! tree_expr_nonnegative_p (arg);
1801 builtin_optab = sqrt_optab;
1802 break;
1803 CASE_FLT_FN (BUILT_IN_EXP):
1804 errno_set = true; builtin_optab = exp_optab; break;
1805 CASE_FLT_FN (BUILT_IN_EXP10):
1806 CASE_FLT_FN (BUILT_IN_POW10):
1807 errno_set = true; builtin_optab = exp10_optab; break;
1808 CASE_FLT_FN (BUILT_IN_EXP2):
1809 errno_set = true; builtin_optab = exp2_optab; break;
1810 CASE_FLT_FN (BUILT_IN_EXPM1):
1811 errno_set = true; builtin_optab = expm1_optab; break;
1812 CASE_FLT_FN (BUILT_IN_LOGB):
1813 errno_set = true; builtin_optab = logb_optab; break;
1814 CASE_FLT_FN (BUILT_IN_ILOGB):
1815 errno_set = true; builtin_optab = ilogb_optab; break;
1816 CASE_FLT_FN (BUILT_IN_LOG):
1817 errno_set = true; builtin_optab = log_optab; break;
1818 CASE_FLT_FN (BUILT_IN_LOG10):
1819 errno_set = true; builtin_optab = log10_optab; break;
1820 CASE_FLT_FN (BUILT_IN_LOG2):
1821 errno_set = true; builtin_optab = log2_optab; break;
1822 CASE_FLT_FN (BUILT_IN_LOG1P):
1823 errno_set = true; builtin_optab = log1p_optab; break;
1824 CASE_FLT_FN (BUILT_IN_ASIN):
1825 builtin_optab = asin_optab; break;
1826 CASE_FLT_FN (BUILT_IN_ACOS):
1827 builtin_optab = acos_optab; break;
1828 CASE_FLT_FN (BUILT_IN_TAN):
1829 builtin_optab = tan_optab; break;
1830 CASE_FLT_FN (BUILT_IN_ATAN):
1831 builtin_optab = atan_optab; break;
1832 CASE_FLT_FN (BUILT_IN_FLOOR):
1833 builtin_optab = floor_optab; break;
1834 CASE_FLT_FN (BUILT_IN_CEIL):
1835 builtin_optab = ceil_optab; break;
1836 CASE_FLT_FN (BUILT_IN_TRUNC):
1837 builtin_optab = btrunc_optab; break;
1838 CASE_FLT_FN (BUILT_IN_ROUND):
1839 builtin_optab = round_optab; break;
1840 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1841 builtin_optab = nearbyint_optab;
1842 if (flag_trapping_math)
1843 break;
1844 /* Else fallthrough and expand as rint. */
1845 CASE_FLT_FN (BUILT_IN_RINT):
1846 builtin_optab = rint_optab; break;
1847 default:
1848 gcc_unreachable ();
1851 /* Make a suitable register to place result in. */
1852 mode = TYPE_MODE (TREE_TYPE (exp));
1854 if (! flag_errno_math || ! HONOR_NANS (mode))
1855 errno_set = false;
1857 /* Before working hard, check whether the instruction is available. */
1858 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1860 target = gen_reg_rtx (mode);
1862 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1863 need to expand the argument again. This way, we will not perform
1864 side-effects more the once. */
1865 narg = builtin_save_expr (arg);
1866 if (narg != arg)
1868 arg = narg;
1869 arglist = build_tree_list (NULL_TREE, arg);
1870 exp = build_function_call_expr (fndecl, arglist);
1873 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1875 start_sequence ();
1877 /* Compute into TARGET.
1878 Set TARGET to wherever the result comes back. */
1879 target = expand_unop (mode, builtin_optab, op0, target, 0);
1881 if (target != 0)
1883 if (errno_set)
1884 expand_errno_check (exp, target);
1886 /* Output the entire sequence. */
1887 insns = get_insns ();
1888 end_sequence ();
1889 emit_insn (insns);
1890 return target;
1893 /* If we were unable to expand via the builtin, stop the sequence
1894 (without outputting the insns) and call to the library function
1895 with the stabilized argument list. */
1896 end_sequence ();
1899 before_call = get_last_insn ();
1901 target = expand_call (exp, target, target == const0_rtx);
1903 /* If this is a sqrt operation and we don't care about errno, try to
1904 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1905 This allows the semantics of the libcall to be visible to the RTL
1906 optimizers. */
1907 if (builtin_optab == sqrt_optab && !errno_set)
1909 /* Search backwards through the insns emitted by expand_call looking
1910 for the instruction with the REG_RETVAL note. */
1911 rtx last = get_last_insn ();
1912 while (last != before_call)
1914 if (find_reg_note (last, REG_RETVAL, NULL))
1916 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1917 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1918 two elements, i.e. symbol_ref(sqrt) and the operand. */
1919 if (note
1920 && GET_CODE (note) == EXPR_LIST
1921 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1922 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1923 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1925 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1926 /* Check operand is a register with expected mode. */
1927 if (operand
1928 && REG_P (operand)
1929 && GET_MODE (operand) == mode)
1931 /* Replace the REG_EQUAL note with a SQRT rtx. */
1932 rtx equiv = gen_rtx_SQRT (mode, operand);
1933 set_unique_reg_note (last, REG_EQUAL, equiv);
1936 break;
1938 last = PREV_INSN (last);
1942 return target;
1945 /* Expand a call to the builtin binary math functions (pow and atan2).
1946 Return 0 if a normal call should be emitted rather than expanding the
1947 function in-line. EXP is the expression that is a call to the builtin
1948 function; if convenient, the result should be placed in TARGET.
1949 SUBTARGET may be used as the target for computing one of EXP's
1950 operands. */
1952 static rtx
1953 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1955 optab builtin_optab;
1956 rtx op0, op1, insns;
1957 int op1_type = REAL_TYPE;
1958 tree fndecl = get_callee_fndecl (exp);
1959 tree arglist = TREE_OPERAND (exp, 1);
1960 tree arg0, arg1, temp, narg;
1961 enum machine_mode mode;
1962 bool errno_set = true;
1963 bool stable = true;
1965 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1966 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1967 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1968 op1_type = INTEGER_TYPE;
1970 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1971 return 0;
1973 arg0 = TREE_VALUE (arglist);
1974 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1976 switch (DECL_FUNCTION_CODE (fndecl))
1978 CASE_FLT_FN (BUILT_IN_POW):
1979 builtin_optab = pow_optab; break;
1980 CASE_FLT_FN (BUILT_IN_ATAN2):
1981 builtin_optab = atan2_optab; break;
1982 CASE_FLT_FN (BUILT_IN_LDEXP):
1983 builtin_optab = ldexp_optab; break;
1984 CASE_FLT_FN (BUILT_IN_FMOD):
1985 builtin_optab = fmod_optab; break;
1986 CASE_FLT_FN (BUILT_IN_REMAINDER):
1987 CASE_FLT_FN (BUILT_IN_DREM):
1988 builtin_optab = remainder_optab; break;
1989 default:
1990 gcc_unreachable ();
1993 /* Make a suitable register to place result in. */
1994 mode = TYPE_MODE (TREE_TYPE (exp));
1996 /* Before working hard, check whether the instruction is available. */
1997 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1998 return 0;
2000 target = gen_reg_rtx (mode);
2002 if (! flag_errno_math || ! HONOR_NANS (mode))
2003 errno_set = false;
2005 /* Always stabilize the argument list. */
2006 narg = builtin_save_expr (arg1);
2007 if (narg != arg1)
2009 arg1 = narg;
2010 temp = build_tree_list (NULL_TREE, narg);
2011 stable = false;
2013 else
2014 temp = TREE_CHAIN (arglist);
2016 narg = builtin_save_expr (arg0);
2017 if (narg != arg0)
2019 arg0 = narg;
2020 arglist = tree_cons (NULL_TREE, narg, temp);
2021 stable = false;
2023 else if (! stable)
2024 arglist = tree_cons (NULL_TREE, arg0, temp);
2026 if (! stable)
2027 exp = build_function_call_expr (fndecl, arglist);
2029 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2030 op1 = expand_normal (arg1);
2032 start_sequence ();
2034 /* Compute into TARGET.
2035 Set TARGET to wherever the result comes back. */
2036 target = expand_binop (mode, builtin_optab, op0, op1,
2037 target, 0, OPTAB_DIRECT);
2039 /* If we were unable to expand via the builtin, stop the sequence
2040 (without outputting the insns) and call to the library function
2041 with the stabilized argument list. */
2042 if (target == 0)
2044 end_sequence ();
2045 return expand_call (exp, target, target == const0_rtx);
2048 if (errno_set)
2049 expand_errno_check (exp, target);
2051 /* Output the entire sequence. */
2052 insns = get_insns ();
2053 end_sequence ();
2054 emit_insn (insns);
2056 return target;
2059 /* Expand a call to the builtin sin and cos math functions.
2060 Return 0 if a normal call should be emitted rather than expanding the
2061 function in-line. EXP is the expression that is a call to the builtin
2062 function; if convenient, the result should be placed in TARGET.
2063 SUBTARGET may be used as the target for computing one of EXP's
2064 operands. */
2066 static rtx
2067 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2069 optab builtin_optab;
2070 rtx op0, insns;
2071 tree fndecl = get_callee_fndecl (exp);
2072 tree arglist = TREE_OPERAND (exp, 1);
2073 enum machine_mode mode;
2074 tree arg, narg;
2076 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2077 return 0;
2079 arg = TREE_VALUE (arglist);
2081 switch (DECL_FUNCTION_CODE (fndecl))
2083 CASE_FLT_FN (BUILT_IN_SIN):
2084 CASE_FLT_FN (BUILT_IN_COS):
2085 builtin_optab = sincos_optab; break;
2086 default:
2087 gcc_unreachable ();
2090 /* Make a suitable register to place result in. */
2091 mode = TYPE_MODE (TREE_TYPE (exp));
2093 /* Check if sincos insn is available, otherwise fallback
2094 to sin or cos insn. */
2095 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2096 switch (DECL_FUNCTION_CODE (fndecl))
2098 CASE_FLT_FN (BUILT_IN_SIN):
2099 builtin_optab = sin_optab; break;
2100 CASE_FLT_FN (BUILT_IN_COS):
2101 builtin_optab = cos_optab; break;
2102 default:
2103 gcc_unreachable ();
2106 /* Before working hard, check whether the instruction is available. */
2107 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2109 target = gen_reg_rtx (mode);
2111 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2112 need to expand the argument again. This way, we will not perform
2113 side-effects more the once. */
2114 narg = save_expr (arg);
2115 if (narg != arg)
2117 arg = narg;
2118 arglist = build_tree_list (NULL_TREE, arg);
2119 exp = build_function_call_expr (fndecl, arglist);
2122 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2124 start_sequence ();
2126 /* Compute into TARGET.
2127 Set TARGET to wherever the result comes back. */
2128 if (builtin_optab == sincos_optab)
2130 int result;
2132 switch (DECL_FUNCTION_CODE (fndecl))
2134 CASE_FLT_FN (BUILT_IN_SIN):
2135 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2136 break;
2137 CASE_FLT_FN (BUILT_IN_COS):
2138 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2139 break;
2140 default:
2141 gcc_unreachable ();
2143 gcc_assert (result);
2145 else
2147 target = expand_unop (mode, builtin_optab, op0, target, 0);
2150 if (target != 0)
2152 /* Output the entire sequence. */
2153 insns = get_insns ();
2154 end_sequence ();
2155 emit_insn (insns);
2156 return target;
2159 /* If we were unable to expand via the builtin, stop the sequence
2160 (without outputting the insns) and call to the library function
2161 with the stabilized argument list. */
2162 end_sequence ();
2165 target = expand_call (exp, target, target == const0_rtx);
2167 return target;
2170 /* Expand a call to the builtin sincos math function.
2171 Return 0 if a normal call should be emitted rather than expanding the
2172 function in-line. EXP is the expression that is a call to the builtin
2173 function. */
2175 static rtx
2176 expand_builtin_sincos (tree exp)
2178 rtx op0, op1, op2, target1, target2;
2179 tree arglist = TREE_OPERAND (exp, 1);
2180 enum machine_mode mode;
2181 tree arg, sinp, cosp;
2182 int result;
2184 if (!validate_arglist (arglist, REAL_TYPE,
2185 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2186 return 0;
2188 arg = TREE_VALUE (arglist);
2189 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2190 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2192 /* Make a suitable register to place result in. */
2193 mode = TYPE_MODE (TREE_TYPE (arg));
2195 /* Check if sincos insn is available, otherwise emit the call. */
2196 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2197 return NULL_RTX;
2199 target1 = gen_reg_rtx (mode);
2200 target2 = gen_reg_rtx (mode);
2202 op0 = expand_normal (arg);
2203 op1 = expand_normal (build_fold_indirect_ref (sinp));
2204 op2 = expand_normal (build_fold_indirect_ref (cosp));
2206 /* Compute into target1 and target2.
2207 Set TARGET to wherever the result comes back. */
2208 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2209 gcc_assert (result);
2211 /* Move target1 and target2 to the memory locations indicated
2212 by op1 and op2. */
2213 emit_move_insn (op1, target1);
2214 emit_move_insn (op2, target2);
2216 return const0_rtx;
2219 /* Expand a call to one of the builtin rounding functions gcc defines
2220 as an extension (lfloor and lceil). As these are gcc extensions we
2221 do not need to worry about setting errno to EDOM.
2222 If expanding via optab fails, lower expression to (int)(floor(x)).
2223 EXP is the expression that is a call to the builtin function;
2224 if convenient, the result should be placed in TARGET. SUBTARGET may
2225 be used as the target for computing one of EXP's operands. */
2227 static rtx
2228 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2230 convert_optab builtin_optab;
2231 rtx op0, insns, tmp;
2232 tree fndecl = get_callee_fndecl (exp);
2233 tree arglist = TREE_OPERAND (exp, 1);
2234 enum built_in_function fallback_fn;
2235 tree fallback_fndecl;
2236 enum machine_mode mode;
2237 tree arg, narg;
2239 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2240 gcc_unreachable ();
2242 arg = TREE_VALUE (arglist);
2244 switch (DECL_FUNCTION_CODE (fndecl))
2246 CASE_FLT_FN (BUILT_IN_LCEIL):
2247 CASE_FLT_FN (BUILT_IN_LLCEIL):
2248 builtin_optab = lceil_optab;
2249 fallback_fn = BUILT_IN_CEIL;
2250 break;
2252 CASE_FLT_FN (BUILT_IN_LFLOOR):
2253 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2254 builtin_optab = lfloor_optab;
2255 fallback_fn = BUILT_IN_FLOOR;
2256 break;
2258 default:
2259 gcc_unreachable ();
2262 /* Make a suitable register to place result in. */
2263 mode = TYPE_MODE (TREE_TYPE (exp));
2265 target = gen_reg_rtx (mode);
2267 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2268 need to expand the argument again. This way, we will not perform
2269 side-effects more the once. */
2270 narg = builtin_save_expr (arg);
2271 if (narg != arg)
2273 arg = narg;
2274 arglist = build_tree_list (NULL_TREE, arg);
2275 exp = build_function_call_expr (fndecl, arglist);
2278 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2280 start_sequence ();
2282 /* Compute into TARGET. */
2283 if (expand_sfix_optab (target, op0, builtin_optab))
2285 /* Output the entire sequence. */
2286 insns = get_insns ();
2287 end_sequence ();
2288 emit_insn (insns);
2289 return target;
2292 /* If we were unable to expand via the builtin, stop the sequence
2293 (without outputting the insns). */
2294 end_sequence ();
2296 /* Fall back to floating point rounding optab. */
2297 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2298 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2299 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2300 gcc_assert (fallback_fndecl != NULL_TREE);
2301 exp = build_function_call_expr (fallback_fndecl, arglist);
2303 tmp = expand_normal (exp);
2305 /* Truncate the result of floating point optab to integer
2306 via expand_fix (). */
2307 target = gen_reg_rtx (mode);
2308 expand_fix (target, tmp, 0);
2310 return target;
2313 /* Expand a call to one of the builtin math functions doing integer
2314 conversion (lrint).
2315 Return 0 if a normal call should be emitted rather than expanding the
2316 function in-line. EXP is the expression that is a call to the builtin
2317 function; if convenient, the result should be placed in TARGET.
2318 SUBTARGET may be used as the target for computing one of EXP's operands. */
2320 static rtx
2321 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2323 convert_optab builtin_optab;
2324 rtx op0, insns;
2325 tree fndecl = get_callee_fndecl (exp);
2326 tree arglist = TREE_OPERAND (exp, 1);
2327 enum machine_mode mode;
2328 tree arg, narg;
2330 /* There's no easy way to detect the case we need to set EDOM. */
2331 if (flag_errno_math)
2332 return NULL_RTX;
2334 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2335 return NULL_RTX;
2337 arg = TREE_VALUE (arglist);
2339 switch (DECL_FUNCTION_CODE (fndecl))
2341 CASE_FLT_FN (BUILT_IN_LRINT):
2342 CASE_FLT_FN (BUILT_IN_LLRINT):
2343 builtin_optab = lrint_optab; break;
2344 CASE_FLT_FN (BUILT_IN_LROUND):
2345 CASE_FLT_FN (BUILT_IN_LLROUND):
2346 builtin_optab = lround_optab; break;
2347 default:
2348 gcc_unreachable ();
2351 /* Make a suitable register to place result in. */
2352 mode = TYPE_MODE (TREE_TYPE (exp));
2354 target = gen_reg_rtx (mode);
2356 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2357 need to expand the argument again. This way, we will not perform
2358 side-effects more the once. */
2359 narg = builtin_save_expr (arg);
2360 if (narg != arg)
2362 arg = narg;
2363 arglist = build_tree_list (NULL_TREE, arg);
2364 exp = build_function_call_expr (fndecl, arglist);
2367 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2369 start_sequence ();
2371 if (expand_sfix_optab (target, op0, builtin_optab))
2373 /* Output the entire sequence. */
2374 insns = get_insns ();
2375 end_sequence ();
2376 emit_insn (insns);
2377 return target;
2380 /* If we were unable to expand via the builtin, stop the sequence
2381 (without outputting the insns) and call to the library function
2382 with the stabilized argument list. */
2383 end_sequence ();
2385 target = expand_call (exp, target, target == const0_rtx);
2387 return target;
2390 /* To evaluate powi(x,n), the floating point value x raised to the
2391 constant integer exponent n, we use a hybrid algorithm that
2392 combines the "window method" with look-up tables. For an
2393 introduction to exponentiation algorithms and "addition chains",
2394 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2395 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2396 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2397 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2399 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2400 multiplications to inline before calling the system library's pow
2401 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2402 so this default never requires calling pow, powf or powl. */
2404 #ifndef POWI_MAX_MULTS
2405 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2406 #endif
2408 /* The size of the "optimal power tree" lookup table. All
2409 exponents less than this value are simply looked up in the
2410 powi_table below. This threshold is also used to size the
2411 cache of pseudo registers that hold intermediate results. */
2412 #define POWI_TABLE_SIZE 256
2414 /* The size, in bits of the window, used in the "window method"
2415 exponentiation algorithm. This is equivalent to a radix of
2416 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2417 #define POWI_WINDOW_SIZE 3
2419 /* The following table is an efficient representation of an
2420 "optimal power tree". For each value, i, the corresponding
2421 value, j, in the table states than an optimal evaluation
2422 sequence for calculating pow(x,i) can be found by evaluating
2423 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2424 100 integers is given in Knuth's "Seminumerical algorithms". */
2426 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2428 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2429 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2430 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2431 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2432 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2433 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2434 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2435 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2436 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2437 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2438 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2439 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2440 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2441 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2442 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2443 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2444 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2445 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2446 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2447 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2448 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2449 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2450 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2451 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2452 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2453 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2454 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2455 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2456 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2457 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2458 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2459 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2463 /* Return the number of multiplications required to calculate
2464 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2465 subroutine of powi_cost. CACHE is an array indicating
2466 which exponents have already been calculated. */
2468 static int
2469 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2471 /* If we've already calculated this exponent, then this evaluation
2472 doesn't require any additional multiplications. */
2473 if (cache[n])
2474 return 0;
2476 cache[n] = true;
2477 return powi_lookup_cost (n - powi_table[n], cache)
2478 + powi_lookup_cost (powi_table[n], cache) + 1;
2481 /* Return the number of multiplications required to calculate
2482 powi(x,n) for an arbitrary x, given the exponent N. This
2483 function needs to be kept in sync with expand_powi below. */
2485 static int
2486 powi_cost (HOST_WIDE_INT n)
2488 bool cache[POWI_TABLE_SIZE];
2489 unsigned HOST_WIDE_INT digit;
2490 unsigned HOST_WIDE_INT val;
2491 int result;
2493 if (n == 0)
2494 return 0;
2496 /* Ignore the reciprocal when calculating the cost. */
2497 val = (n < 0) ? -n : n;
2499 /* Initialize the exponent cache. */
2500 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2501 cache[1] = true;
2503 result = 0;
2505 while (val >= POWI_TABLE_SIZE)
2507 if (val & 1)
2509 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2510 result += powi_lookup_cost (digit, cache)
2511 + POWI_WINDOW_SIZE + 1;
2512 val >>= POWI_WINDOW_SIZE;
2514 else
2516 val >>= 1;
2517 result++;
2521 return result + powi_lookup_cost (val, cache);
2524 /* Recursive subroutine of expand_powi. This function takes the array,
2525 CACHE, of already calculated exponents and an exponent N and returns
2526 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2528 static rtx
2529 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2531 unsigned HOST_WIDE_INT digit;
2532 rtx target, result;
2533 rtx op0, op1;
2535 if (n < POWI_TABLE_SIZE)
2537 if (cache[n])
2538 return cache[n];
2540 target = gen_reg_rtx (mode);
2541 cache[n] = target;
2543 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2544 op1 = expand_powi_1 (mode, powi_table[n], cache);
2546 else if (n & 1)
2548 target = gen_reg_rtx (mode);
2549 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2550 op0 = expand_powi_1 (mode, n - digit, cache);
2551 op1 = expand_powi_1 (mode, digit, cache);
2553 else
2555 target = gen_reg_rtx (mode);
2556 op0 = expand_powi_1 (mode, n >> 1, cache);
2557 op1 = op0;
2560 result = expand_mult (mode, op0, op1, target, 0);
2561 if (result != target)
2562 emit_move_insn (target, result);
2563 return target;
2566 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2567 floating point operand in mode MODE, and N is the exponent. This
2568 function needs to be kept in sync with powi_cost above. */
2570 static rtx
2571 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2573 unsigned HOST_WIDE_INT val;
2574 rtx cache[POWI_TABLE_SIZE];
2575 rtx result;
2577 if (n == 0)
2578 return CONST1_RTX (mode);
2580 val = (n < 0) ? -n : n;
2582 memset (cache, 0, sizeof (cache));
2583 cache[1] = x;
2585 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2587 /* If the original exponent was negative, reciprocate the result. */
2588 if (n < 0)
2589 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2590 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2592 return result;
2595 /* Expand a call to the pow built-in mathematical function. Return 0 if
2596 a normal call should be emitted rather than expanding the function
2597 in-line. EXP is the expression that is a call to the builtin
2598 function; if convenient, the result should be placed in TARGET. */
2600 static rtx
2601 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2603 tree arglist = TREE_OPERAND (exp, 1);
2604 tree arg0, arg1;
2606 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2607 return 0;
2609 arg0 = TREE_VALUE (arglist);
2610 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2612 if (TREE_CODE (arg1) == REAL_CST
2613 && ! TREE_CONSTANT_OVERFLOW (arg1))
2615 REAL_VALUE_TYPE cint;
2616 REAL_VALUE_TYPE c;
2617 HOST_WIDE_INT n;
2619 c = TREE_REAL_CST (arg1);
2620 n = real_to_integer (&c);
2621 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2622 if (real_identical (&c, &cint))
2624 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2625 Otherwise, check the number of multiplications required.
2626 Note that pow never sets errno for an integer exponent. */
2627 if ((n >= -1 && n <= 2)
2628 || (flag_unsafe_math_optimizations
2629 && ! optimize_size
2630 && powi_cost (n) <= POWI_MAX_MULTS))
2632 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2633 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2634 op = force_reg (mode, op);
2635 return expand_powi (op, mode, n);
2640 if (! flag_unsafe_math_optimizations)
2641 return NULL_RTX;
2642 return expand_builtin_mathfn_2 (exp, target, subtarget);
2645 /* Expand a call to the powi built-in mathematical function. Return 0 if
2646 a normal call should be emitted rather than expanding the function
2647 in-line. EXP is the expression that is a call to the builtin
2648 function; if convenient, the result should be placed in TARGET. */
2650 static rtx
2651 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2653 tree arglist = TREE_OPERAND (exp, 1);
2654 tree arg0, arg1;
2655 rtx op0, op1;
2656 enum machine_mode mode;
2657 enum machine_mode mode2;
2659 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2660 return 0;
2662 arg0 = TREE_VALUE (arglist);
2663 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2664 mode = TYPE_MODE (TREE_TYPE (exp));
2666 /* Handle constant power. */
2668 if (TREE_CODE (arg1) == INTEGER_CST
2669 && ! TREE_CONSTANT_OVERFLOW (arg1))
2671 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2673 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2674 Otherwise, check the number of multiplications required. */
2675 if ((TREE_INT_CST_HIGH (arg1) == 0
2676 || TREE_INT_CST_HIGH (arg1) == -1)
2677 && ((n >= -1 && n <= 2)
2678 || (! optimize_size
2679 && powi_cost (n) <= POWI_MAX_MULTS)))
2681 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2682 op0 = force_reg (mode, op0);
2683 return expand_powi (op0, mode, n);
2687 /* Emit a libcall to libgcc. */
2689 /* Mode of the 2nd argument must match that of an int. */
2690 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2692 if (target == NULL_RTX)
2693 target = gen_reg_rtx (mode);
2695 op0 = expand_expr (arg0, subtarget, mode, 0);
2696 if (GET_MODE (op0) != mode)
2697 op0 = convert_to_mode (mode, op0, 0);
2698 op1 = expand_expr (arg1, 0, mode2, 0);
2699 if (GET_MODE (op1) != mode2)
2700 op1 = convert_to_mode (mode2, op1, 0);
2702 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2703 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2704 op0, mode, op1, mode2);
2706 return target;
2709 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2710 if we failed the caller should emit a normal call, otherwise
2711 try to get the result in TARGET, if convenient. */
2713 static rtx
2714 expand_builtin_strlen (tree arglist, rtx target,
2715 enum machine_mode target_mode)
2717 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2718 return 0;
2719 else
2721 rtx pat;
2722 tree len, src = TREE_VALUE (arglist);
2723 rtx result, src_reg, char_rtx, before_strlen;
2724 enum machine_mode insn_mode = target_mode, char_mode;
2725 enum insn_code icode = CODE_FOR_nothing;
2726 int align;
2728 /* If the length can be computed at compile-time, return it. */
2729 len = c_strlen (src, 0);
2730 if (len)
2731 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2733 /* If the length can be computed at compile-time and is constant
2734 integer, but there are side-effects in src, evaluate
2735 src for side-effects, then return len.
2736 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2737 can be optimized into: i++; x = 3; */
2738 len = c_strlen (src, 1);
2739 if (len && TREE_CODE (len) == INTEGER_CST)
2741 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2742 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2745 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2747 /* If SRC is not a pointer type, don't do this operation inline. */
2748 if (align == 0)
2749 return 0;
2751 /* Bail out if we can't compute strlen in the right mode. */
2752 while (insn_mode != VOIDmode)
2754 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2755 if (icode != CODE_FOR_nothing)
2756 break;
2758 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2760 if (insn_mode == VOIDmode)
2761 return 0;
2763 /* Make a place to write the result of the instruction. */
2764 result = target;
2765 if (! (result != 0
2766 && REG_P (result)
2767 && GET_MODE (result) == insn_mode
2768 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2769 result = gen_reg_rtx (insn_mode);
2771 /* Make a place to hold the source address. We will not expand
2772 the actual source until we are sure that the expansion will
2773 not fail -- there are trees that cannot be expanded twice. */
2774 src_reg = gen_reg_rtx (Pmode);
2776 /* Mark the beginning of the strlen sequence so we can emit the
2777 source operand later. */
2778 before_strlen = get_last_insn ();
2780 char_rtx = const0_rtx;
2781 char_mode = insn_data[(int) icode].operand[2].mode;
2782 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2783 char_mode))
2784 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2786 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2787 char_rtx, GEN_INT (align));
2788 if (! pat)
2789 return 0;
2790 emit_insn (pat);
2792 /* Now that we are assured of success, expand the source. */
2793 start_sequence ();
2794 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2795 if (pat != src_reg)
2796 emit_move_insn (src_reg, pat);
2797 pat = get_insns ();
2798 end_sequence ();
2800 if (before_strlen)
2801 emit_insn_after (pat, before_strlen);
2802 else
2803 emit_insn_before (pat, get_insns ());
2805 /* Return the value in the proper mode for this function. */
2806 if (GET_MODE (result) == target_mode)
2807 target = result;
2808 else if (target != 0)
2809 convert_move (target, result, 0);
2810 else
2811 target = convert_to_mode (target_mode, result, 0);
2813 return target;
2817 /* Expand a call to the strstr builtin. Return 0 if we failed the
2818 caller should emit a normal call, otherwise try to get the result
2819 in TARGET, if convenient (and in mode MODE if that's convenient). */
2821 static rtx
2822 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2824 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2826 tree result = fold_builtin_strstr (arglist, type);
2827 if (result)
2828 return expand_expr (result, target, mode, EXPAND_NORMAL);
2830 return 0;
2833 /* Expand a call to the strchr builtin. Return 0 if we failed the
2834 caller should emit a normal call, otherwise try to get the result
2835 in TARGET, if convenient (and in mode MODE if that's convenient). */
2837 static rtx
2838 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2840 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2842 tree result = fold_builtin_strchr (arglist, type);
2843 if (result)
2844 return expand_expr (result, target, mode, EXPAND_NORMAL);
2846 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2848 return 0;
2851 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2852 caller should emit a normal call, otherwise try to get the result
2853 in TARGET, if convenient (and in mode MODE if that's convenient). */
2855 static rtx
2856 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2858 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2860 tree result = fold_builtin_strrchr (arglist, type);
2861 if (result)
2862 return expand_expr (result, target, mode, EXPAND_NORMAL);
2864 return 0;
2867 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2868 caller should emit a normal call, otherwise try to get the result
2869 in TARGET, if convenient (and in mode MODE if that's convenient). */
2871 static rtx
2872 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2874 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2876 tree result = fold_builtin_strpbrk (arglist, type);
2877 if (result)
2878 return expand_expr (result, target, mode, EXPAND_NORMAL);
2880 return 0;
2883 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2884 bytes from constant string DATA + OFFSET and return it as target
2885 constant. */
2887 static rtx
2888 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2889 enum machine_mode mode)
2891 const char *str = (const char *) data;
2893 gcc_assert (offset >= 0
2894 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2895 <= strlen (str) + 1));
2897 return c_readstr (str + offset, mode);
2900 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2901 Return 0 if we failed, the caller should emit a normal call,
2902 otherwise try to get the result in TARGET, if convenient (and in
2903 mode MODE if that's convenient). */
2904 static rtx
2905 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2907 tree fndecl = get_callee_fndecl (exp);
2908 tree arglist = TREE_OPERAND (exp, 1);
2909 if (!validate_arglist (arglist,
2910 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2911 return 0;
2912 else
2914 tree dest = TREE_VALUE (arglist);
2915 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2916 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2917 const char *src_str;
2918 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2919 unsigned int dest_align
2920 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2921 rtx dest_mem, src_mem, dest_addr, len_rtx;
2922 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2923 false, /*endp=*/0);
2925 if (result)
2927 while (TREE_CODE (result) == COMPOUND_EXPR)
2929 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2930 EXPAND_NORMAL);
2931 result = TREE_OPERAND (result, 1);
2933 return expand_expr (result, target, mode, EXPAND_NORMAL);
2936 /* If DEST is not a pointer type, call the normal function. */
2937 if (dest_align == 0)
2938 return 0;
2940 /* If either SRC is not a pointer type, don't do this
2941 operation in-line. */
2942 if (src_align == 0)
2943 return 0;
2945 dest_mem = get_memory_rtx (dest, len);
2946 set_mem_align (dest_mem, dest_align);
2947 len_rtx = expand_normal (len);
2948 src_str = c_getstr (src);
2950 /* If SRC is a string constant and block move would be done
2951 by pieces, we can avoid loading the string from memory
2952 and only stored the computed constants. */
2953 if (src_str
2954 && GET_CODE (len_rtx) == CONST_INT
2955 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2956 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2957 (void *) src_str, dest_align))
2959 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2960 builtin_memcpy_read_str,
2961 (void *) src_str, dest_align, 0);
2962 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2963 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2964 return dest_mem;
2967 src_mem = get_memory_rtx (src, len);
2968 set_mem_align (src_mem, src_align);
2970 /* Copy word part most expediently. */
2971 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2972 CALL_EXPR_TAILCALL (exp)
2973 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2975 if (dest_addr == 0)
2977 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2978 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2980 return dest_addr;
2984 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2985 Return 0 if we failed; the caller should emit a normal call,
2986 otherwise try to get the result in TARGET, if convenient (and in
2987 mode MODE if that's convenient). If ENDP is 0 return the
2988 destination pointer, if ENDP is 1 return the end pointer ala
2989 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2990 stpcpy. */
2992 static rtx
2993 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2994 int endp)
2996 if (!validate_arglist (arglist,
2997 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2998 return 0;
2999 /* If return value is ignored, transform mempcpy into memcpy. */
3000 else if (target == const0_rtx)
3002 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3004 if (!fn)
3005 return 0;
3007 return expand_expr (build_function_call_expr (fn, arglist),
3008 target, mode, EXPAND_NORMAL);
3010 else
3012 tree dest = TREE_VALUE (arglist);
3013 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3014 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3015 const char *src_str;
3016 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3017 unsigned int dest_align
3018 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3019 rtx dest_mem, src_mem, len_rtx;
3020 tree result = fold_builtin_memory_op (arglist, type, false, endp);
3022 if (result)
3024 while (TREE_CODE (result) == COMPOUND_EXPR)
3026 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3027 EXPAND_NORMAL);
3028 result = TREE_OPERAND (result, 1);
3030 return expand_expr (result, target, mode, EXPAND_NORMAL);
3033 /* If either SRC or DEST is not a pointer type, don't do this
3034 operation in-line. */
3035 if (dest_align == 0 || src_align == 0)
3036 return 0;
3038 /* If LEN is not constant, call the normal function. */
3039 if (! host_integerp (len, 1))
3040 return 0;
3042 len_rtx = expand_normal (len);
3043 src_str = c_getstr (src);
3045 /* If SRC is a string constant and block move would be done
3046 by pieces, we can avoid loading the string from memory
3047 and only stored the computed constants. */
3048 if (src_str
3049 && GET_CODE (len_rtx) == CONST_INT
3050 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3051 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3052 (void *) src_str, dest_align))
3054 dest_mem = get_memory_rtx (dest, len);
3055 set_mem_align (dest_mem, dest_align);
3056 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3057 builtin_memcpy_read_str,
3058 (void *) src_str, dest_align, endp);
3059 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3060 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3061 return dest_mem;
3064 if (GET_CODE (len_rtx) == CONST_INT
3065 && can_move_by_pieces (INTVAL (len_rtx),
3066 MIN (dest_align, src_align)))
3068 dest_mem = get_memory_rtx (dest, len);
3069 set_mem_align (dest_mem, dest_align);
3070 src_mem = get_memory_rtx (src, len);
3071 set_mem_align (src_mem, src_align);
3072 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3073 MIN (dest_align, src_align), endp);
3074 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3075 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3076 return dest_mem;
3079 return 0;
3083 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3084 if we failed; the caller should emit a normal call. */
3086 static rtx
3087 expand_builtin_memmove (tree arglist, tree type, rtx target,
3088 enum machine_mode mode)
3090 if (!validate_arglist (arglist,
3091 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3092 return 0;
3093 else
3095 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3097 if (result)
3099 while (TREE_CODE (result) == COMPOUND_EXPR)
3101 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3102 EXPAND_NORMAL);
3103 result = TREE_OPERAND (result, 1);
3105 return expand_expr (result, target, mode, EXPAND_NORMAL);
3108 /* Otherwise, call the normal function. */
3109 return 0;
3113 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3114 if we failed the caller should emit a normal call. */
3116 static rtx
3117 expand_builtin_bcopy (tree exp)
3119 tree arglist = TREE_OPERAND (exp, 1);
3120 tree type = TREE_TYPE (exp);
3121 tree src, dest, size, newarglist;
3123 if (!validate_arglist (arglist,
3124 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3125 return NULL_RTX;
3127 src = TREE_VALUE (arglist);
3128 dest = TREE_VALUE (TREE_CHAIN (arglist));
3129 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3131 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3132 memmove(ptr y, ptr x, size_t z). This is done this way
3133 so that if it isn't expanded inline, we fallback to
3134 calling bcopy instead of memmove. */
3136 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3137 newarglist = tree_cons (NULL_TREE, src, newarglist);
3138 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3140 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
3143 #ifndef HAVE_movstr
3144 # define HAVE_movstr 0
3145 # define CODE_FOR_movstr CODE_FOR_nothing
3146 #endif
3148 /* Expand into a movstr instruction, if one is available. Return 0 if
3149 we failed, the caller should emit a normal call, otherwise try to
3150 get the result in TARGET, if convenient. If ENDP is 0 return the
3151 destination pointer, if ENDP is 1 return the end pointer ala
3152 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3153 stpcpy. */
3155 static rtx
3156 expand_movstr (tree dest, tree src, rtx target, int endp)
3158 rtx end;
3159 rtx dest_mem;
3160 rtx src_mem;
3161 rtx insn;
3162 const struct insn_data * data;
3164 if (!HAVE_movstr)
3165 return 0;
3167 dest_mem = get_memory_rtx (dest, NULL);
3168 src_mem = get_memory_rtx (src, NULL);
3169 if (!endp)
3171 target = force_reg (Pmode, XEXP (dest_mem, 0));
3172 dest_mem = replace_equiv_address (dest_mem, target);
3173 end = gen_reg_rtx (Pmode);
3175 else
3177 if (target == 0 || target == const0_rtx)
3179 end = gen_reg_rtx (Pmode);
3180 if (target == 0)
3181 target = end;
3183 else
3184 end = target;
3187 data = insn_data + CODE_FOR_movstr;
3189 if (data->operand[0].mode != VOIDmode)
3190 end = gen_lowpart (data->operand[0].mode, end);
3192 insn = data->genfun (end, dest_mem, src_mem);
3194 gcc_assert (insn);
3196 emit_insn (insn);
3198 /* movstr is supposed to set end to the address of the NUL
3199 terminator. If the caller requested a mempcpy-like return value,
3200 adjust it. */
3201 if (endp == 1 && target != const0_rtx)
3203 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3204 emit_move_insn (target, force_operand (tem, NULL_RTX));
3207 return target;
3210 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3211 if we failed the caller should emit a normal call, otherwise try to get
3212 the result in TARGET, if convenient (and in mode MODE if that's
3213 convenient). */
3215 static rtx
3216 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3218 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3220 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3221 if (result)
3223 while (TREE_CODE (result) == COMPOUND_EXPR)
3225 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3226 EXPAND_NORMAL);
3227 result = TREE_OPERAND (result, 1);
3229 return expand_expr (result, target, mode, EXPAND_NORMAL);
3232 return expand_movstr (TREE_VALUE (arglist),
3233 TREE_VALUE (TREE_CHAIN (arglist)),
3234 target, /*endp=*/0);
3236 return 0;
3239 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3240 Return 0 if we failed the caller should emit a normal call,
3241 otherwise try to get the result in TARGET, if convenient (and in
3242 mode MODE if that's convenient). */
3244 static rtx
3245 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3247 tree arglist = TREE_OPERAND (exp, 1);
3248 /* If return value is ignored, transform stpcpy into strcpy. */
3249 if (target == const0_rtx)
3251 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3252 if (!fn)
3253 return 0;
3255 return expand_expr (build_function_call_expr (fn, arglist),
3256 target, mode, EXPAND_NORMAL);
3259 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3260 return 0;
3261 else
3263 tree dst, src, len, lenp1;
3264 tree narglist;
3265 rtx ret;
3267 /* Ensure we get an actual string whose length can be evaluated at
3268 compile-time, not an expression containing a string. This is
3269 because the latter will potentially produce pessimized code
3270 when used to produce the return value. */
3271 src = TREE_VALUE (TREE_CHAIN (arglist));
3272 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3273 return expand_movstr (TREE_VALUE (arglist),
3274 TREE_VALUE (TREE_CHAIN (arglist)),
3275 target, /*endp=*/2);
3277 dst = TREE_VALUE (arglist);
3278 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3279 narglist = build_tree_list (NULL_TREE, lenp1);
3280 narglist = tree_cons (NULL_TREE, src, narglist);
3281 narglist = tree_cons (NULL_TREE, dst, narglist);
3282 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3283 target, mode, /*endp=*/2);
3285 if (ret)
3286 return ret;
3288 if (TREE_CODE (len) == INTEGER_CST)
3290 rtx len_rtx = expand_normal (len);
3292 if (GET_CODE (len_rtx) == CONST_INT)
3294 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3295 arglist, target, mode);
3297 if (ret)
3299 if (! target)
3301 if (mode != VOIDmode)
3302 target = gen_reg_rtx (mode);
3303 else
3304 target = gen_reg_rtx (GET_MODE (ret));
3306 if (GET_MODE (target) != GET_MODE (ret))
3307 ret = gen_lowpart (GET_MODE (target), ret);
3309 ret = plus_constant (ret, INTVAL (len_rtx));
3310 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3311 gcc_assert (ret);
3313 return target;
3318 return expand_movstr (TREE_VALUE (arglist),
3319 TREE_VALUE (TREE_CHAIN (arglist)),
3320 target, /*endp=*/2);
3324 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3325 bytes from constant string DATA + OFFSET and return it as target
3326 constant. */
3328 static rtx
3329 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3330 enum machine_mode mode)
3332 const char *str = (const char *) data;
3334 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3335 return const0_rtx;
3337 return c_readstr (str + offset, mode);
3340 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3341 if we failed the caller should emit a normal call. */
3343 static rtx
3344 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3346 tree fndecl = get_callee_fndecl (exp);
3347 tree arglist = TREE_OPERAND (exp, 1);
3348 if (validate_arglist (arglist,
3349 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3351 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3352 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3353 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3355 if (result)
3357 while (TREE_CODE (result) == COMPOUND_EXPR)
3359 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3360 EXPAND_NORMAL);
3361 result = TREE_OPERAND (result, 1);
3363 return expand_expr (result, target, mode, EXPAND_NORMAL);
3366 /* We must be passed a constant len and src parameter. */
3367 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3368 return 0;
3370 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3372 /* We're required to pad with trailing zeros if the requested
3373 len is greater than strlen(s2)+1. In that case try to
3374 use store_by_pieces, if it fails, punt. */
3375 if (tree_int_cst_lt (slen, len))
3377 tree dest = TREE_VALUE (arglist);
3378 unsigned int dest_align
3379 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3380 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3381 rtx dest_mem;
3383 if (!p || dest_align == 0 || !host_integerp (len, 1)
3384 || !can_store_by_pieces (tree_low_cst (len, 1),
3385 builtin_strncpy_read_str,
3386 (void *) p, dest_align))
3387 return 0;
3389 dest_mem = get_memory_rtx (dest, len);
3390 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3391 builtin_strncpy_read_str,
3392 (void *) p, dest_align, 0);
3393 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3394 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3395 return dest_mem;
3398 return 0;
3401 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3402 bytes from constant string DATA + OFFSET and return it as target
3403 constant. */
3405 static rtx
3406 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3407 enum machine_mode mode)
3409 const char *c = (const char *) data;
3410 char *p = alloca (GET_MODE_SIZE (mode));
3412 memset (p, *c, GET_MODE_SIZE (mode));
3414 return c_readstr (p, mode);
3417 /* Callback routine for store_by_pieces. Return the RTL of a register
3418 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3419 char value given in the RTL register data. For example, if mode is
3420 4 bytes wide, return the RTL for 0x01010101*data. */
3422 static rtx
3423 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3424 enum machine_mode mode)
3426 rtx target, coeff;
3427 size_t size;
3428 char *p;
3430 size = GET_MODE_SIZE (mode);
3431 if (size == 1)
3432 return (rtx) data;
3434 p = alloca (size);
3435 memset (p, 1, size);
3436 coeff = c_readstr (p, mode);
3438 target = convert_to_mode (mode, (rtx) data, 1);
3439 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3440 return force_reg (mode, target);
3443 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3444 if we failed the caller should emit a normal call, otherwise try to get
3445 the result in TARGET, if convenient (and in mode MODE if that's
3446 convenient). */
3448 static rtx
3449 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3450 tree orig_exp)
3452 if (!validate_arglist (arglist,
3453 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3454 return 0;
3455 else
3457 tree dest = TREE_VALUE (arglist);
3458 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3459 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3460 tree fndecl, fn;
3461 enum built_in_function fcode;
3462 char c;
3463 unsigned int dest_align;
3464 rtx dest_mem, dest_addr, len_rtx;
3466 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3468 /* If DEST is not a pointer type, don't do this
3469 operation in-line. */
3470 if (dest_align == 0)
3471 return 0;
3473 /* If the LEN parameter is zero, return DEST. */
3474 if (integer_zerop (len))
3476 /* Evaluate and ignore VAL in case it has side-effects. */
3477 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3478 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3481 /* Stabilize the arguments in case we fail. */
3482 dest = builtin_save_expr (dest);
3483 val = builtin_save_expr (val);
3484 len = builtin_save_expr (len);
3486 len_rtx = expand_normal (len);
3487 dest_mem = get_memory_rtx (dest, len);
3489 if (TREE_CODE (val) != INTEGER_CST)
3491 rtx val_rtx;
3493 val_rtx = expand_normal (val);
3494 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3495 val_rtx, 0);
3497 /* Assume that we can memset by pieces if we can store the
3498 * the coefficients by pieces (in the required modes).
3499 * We can't pass builtin_memset_gen_str as that emits RTL. */
3500 c = 1;
3501 if (host_integerp (len, 1)
3502 && !(optimize_size && tree_low_cst (len, 1) > 1)
3503 && can_store_by_pieces (tree_low_cst (len, 1),
3504 builtin_memset_read_str, &c, dest_align))
3506 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3507 val_rtx);
3508 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3509 builtin_memset_gen_str, val_rtx, dest_align, 0);
3511 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3512 dest_align))
3513 goto do_libcall;
3515 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3516 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3517 return dest_mem;
3520 if (target_char_cast (val, &c))
3521 goto do_libcall;
3523 if (c)
3525 if (host_integerp (len, 1)
3526 && !(optimize_size && tree_low_cst (len, 1) > 1)
3527 && can_store_by_pieces (tree_low_cst (len, 1),
3528 builtin_memset_read_str, &c, dest_align))
3529 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3530 builtin_memset_read_str, &c, dest_align, 0);
3531 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3532 dest_align))
3533 goto do_libcall;
3535 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3536 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3537 return dest_mem;
3540 set_mem_align (dest_mem, dest_align);
3541 dest_addr = clear_storage (dest_mem, len_rtx,
3542 CALL_EXPR_TAILCALL (orig_exp)
3543 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3545 if (dest_addr == 0)
3547 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3548 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3551 return dest_addr;
3553 do_libcall:
3554 fndecl = get_callee_fndecl (orig_exp);
3555 fcode = DECL_FUNCTION_CODE (fndecl);
3556 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3557 arglist = build_tree_list (NULL_TREE, len);
3558 if (fcode == BUILT_IN_MEMSET)
3559 arglist = tree_cons (NULL_TREE, val, arglist);
3560 arglist = tree_cons (NULL_TREE, dest, arglist);
3561 fn = build_function_call_expr (fndecl, arglist);
3562 if (TREE_CODE (fn) == CALL_EXPR)
3563 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3564 return expand_call (fn, target, target == const0_rtx);
3568 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3569 if we failed the caller should emit a normal call. */
3571 static rtx
3572 expand_builtin_bzero (tree exp)
3574 tree arglist = TREE_OPERAND (exp, 1);
3575 tree dest, size, newarglist;
3577 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3578 return NULL_RTX;
3580 dest = TREE_VALUE (arglist);
3581 size = TREE_VALUE (TREE_CHAIN (arglist));
3583 /* New argument list transforming bzero(ptr x, int y) to
3584 memset(ptr x, int 0, size_t y). This is done this way
3585 so that if it isn't expanded inline, we fallback to
3586 calling bzero instead of memset. */
3588 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3589 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3590 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3592 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3595 /* Expand expression EXP, which is a call to the memcmp built-in function.
3596 ARGLIST is the argument list for this call. Return 0 if we failed and the
3597 caller should emit a normal call, otherwise try to get the result in
3598 TARGET, if convenient (and in mode MODE, if that's convenient). */
3600 static rtx
3601 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3602 enum machine_mode mode)
3604 if (!validate_arglist (arglist,
3605 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3606 return 0;
3607 else
3609 tree result = fold_builtin_memcmp (arglist);
3610 if (result)
3611 return expand_expr (result, target, mode, EXPAND_NORMAL);
3614 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3616 tree arg1 = TREE_VALUE (arglist);
3617 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3618 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3619 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3620 rtx result;
3621 rtx insn;
3623 int arg1_align
3624 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3625 int arg2_align
3626 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3627 enum machine_mode insn_mode;
3629 #ifdef HAVE_cmpmemsi
3630 if (HAVE_cmpmemsi)
3631 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3632 else
3633 #endif
3634 #ifdef HAVE_cmpstrnsi
3635 if (HAVE_cmpstrnsi)
3636 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3637 else
3638 #endif
3639 return 0;
3641 /* If we don't have POINTER_TYPE, call the function. */
3642 if (arg1_align == 0 || arg2_align == 0)
3643 return 0;
3645 /* Make a place to write the result of the instruction. */
3646 result = target;
3647 if (! (result != 0
3648 && REG_P (result) && GET_MODE (result) == insn_mode
3649 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3650 result = gen_reg_rtx (insn_mode);
3652 arg1_rtx = get_memory_rtx (arg1, len);
3653 arg2_rtx = get_memory_rtx (arg2, len);
3654 arg3_rtx = expand_normal (len);
3656 /* Set MEM_SIZE as appropriate. */
3657 if (GET_CODE (arg3_rtx) == CONST_INT)
3659 set_mem_size (arg1_rtx, arg3_rtx);
3660 set_mem_size (arg2_rtx, arg3_rtx);
3663 #ifdef HAVE_cmpmemsi
3664 if (HAVE_cmpmemsi)
3665 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3666 GEN_INT (MIN (arg1_align, arg2_align)));
3667 else
3668 #endif
3669 #ifdef HAVE_cmpstrnsi
3670 if (HAVE_cmpstrnsi)
3671 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3672 GEN_INT (MIN (arg1_align, arg2_align)));
3673 else
3674 #endif
3675 gcc_unreachable ();
3677 if (insn)
3678 emit_insn (insn);
3679 else
3680 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3681 TYPE_MODE (integer_type_node), 3,
3682 XEXP (arg1_rtx, 0), Pmode,
3683 XEXP (arg2_rtx, 0), Pmode,
3684 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3685 TYPE_UNSIGNED (sizetype)),
3686 TYPE_MODE (sizetype));
3688 /* Return the value in the proper mode for this function. */
3689 mode = TYPE_MODE (TREE_TYPE (exp));
3690 if (GET_MODE (result) == mode)
3691 return result;
3692 else if (target != 0)
3694 convert_move (target, result, 0);
3695 return target;
3697 else
3698 return convert_to_mode (mode, result, 0);
3700 #endif
3702 return 0;
3705 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3706 if we failed the caller should emit a normal call, otherwise try to get
3707 the result in TARGET, if convenient. */
3709 static rtx
3710 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3712 tree arglist = TREE_OPERAND (exp, 1);
3714 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3715 return 0;
3716 else
3718 tree result = fold_builtin_strcmp (arglist);
3719 if (result)
3720 return expand_expr (result, target, mode, EXPAND_NORMAL);
3723 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3724 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3725 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3727 rtx arg1_rtx, arg2_rtx;
3728 rtx result, insn = NULL_RTX;
3729 tree fndecl, fn;
3731 tree arg1 = TREE_VALUE (arglist);
3732 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3733 int arg1_align
3734 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3735 int arg2_align
3736 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3738 /* If we don't have POINTER_TYPE, call the function. */
3739 if (arg1_align == 0 || arg2_align == 0)
3740 return 0;
3742 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3743 arg1 = builtin_save_expr (arg1);
3744 arg2 = builtin_save_expr (arg2);
3746 arg1_rtx = get_memory_rtx (arg1, NULL);
3747 arg2_rtx = get_memory_rtx (arg2, NULL);
3749 #ifdef HAVE_cmpstrsi
3750 /* Try to call cmpstrsi. */
3751 if (HAVE_cmpstrsi)
3753 enum machine_mode insn_mode
3754 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3756 /* Make a place to write the result of the instruction. */
3757 result = target;
3758 if (! (result != 0
3759 && REG_P (result) && GET_MODE (result) == insn_mode
3760 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3761 result = gen_reg_rtx (insn_mode);
3763 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3764 GEN_INT (MIN (arg1_align, arg2_align)));
3766 #endif
3767 #ifdef HAVE_cmpstrnsi
3768 /* Try to determine at least one length and call cmpstrnsi. */
3769 if (!insn && HAVE_cmpstrnsi)
3771 tree len;
3772 rtx arg3_rtx;
3774 enum machine_mode insn_mode
3775 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3776 tree len1 = c_strlen (arg1, 1);
3777 tree len2 = c_strlen (arg2, 1);
3779 if (len1)
3780 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3781 if (len2)
3782 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3784 /* If we don't have a constant length for the first, use the length
3785 of the second, if we know it. We don't require a constant for
3786 this case; some cost analysis could be done if both are available
3787 but neither is constant. For now, assume they're equally cheap,
3788 unless one has side effects. If both strings have constant lengths,
3789 use the smaller. */
3791 if (!len1)
3792 len = len2;
3793 else if (!len2)
3794 len = len1;
3795 else if (TREE_SIDE_EFFECTS (len1))
3796 len = len2;
3797 else if (TREE_SIDE_EFFECTS (len2))
3798 len = len1;
3799 else if (TREE_CODE (len1) != INTEGER_CST)
3800 len = len2;
3801 else if (TREE_CODE (len2) != INTEGER_CST)
3802 len = len1;
3803 else if (tree_int_cst_lt (len1, len2))
3804 len = len1;
3805 else
3806 len = len2;
3808 /* If both arguments have side effects, we cannot optimize. */
3809 if (!len || TREE_SIDE_EFFECTS (len))
3810 goto do_libcall;
3812 arg3_rtx = expand_normal (len);
3814 /* Make a place to write the result of the instruction. */
3815 result = target;
3816 if (! (result != 0
3817 && REG_P (result) && GET_MODE (result) == insn_mode
3818 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3819 result = gen_reg_rtx (insn_mode);
3821 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3822 GEN_INT (MIN (arg1_align, arg2_align)));
3824 #endif
3826 if (insn)
3828 emit_insn (insn);
3830 /* Return the value in the proper mode for this function. */
3831 mode = TYPE_MODE (TREE_TYPE (exp));
3832 if (GET_MODE (result) == mode)
3833 return result;
3834 if (target == 0)
3835 return convert_to_mode (mode, result, 0);
3836 convert_move (target, result, 0);
3837 return target;
3840 /* Expand the library call ourselves using a stabilized argument
3841 list to avoid re-evaluating the function's arguments twice. */
3842 #ifdef HAVE_cmpstrnsi
3843 do_libcall:
3844 #endif
3845 arglist = build_tree_list (NULL_TREE, arg2);
3846 arglist = tree_cons (NULL_TREE, arg1, arglist);
3847 fndecl = get_callee_fndecl (exp);
3848 fn = build_function_call_expr (fndecl, arglist);
3849 if (TREE_CODE (fn) == CALL_EXPR)
3850 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3851 return expand_call (fn, target, target == const0_rtx);
3853 #endif
3854 return 0;
3857 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3858 if we failed the caller should emit a normal call, otherwise try to get
3859 the result in TARGET, if convenient. */
3861 static rtx
3862 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3864 tree arglist = TREE_OPERAND (exp, 1);
3866 if (!validate_arglist (arglist,
3867 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3868 return 0;
3869 else
3871 tree result = fold_builtin_strncmp (arglist);
3872 if (result)
3873 return expand_expr (result, target, mode, EXPAND_NORMAL);
3876 /* If c_strlen can determine an expression for one of the string
3877 lengths, and it doesn't have side effects, then emit cmpstrnsi
3878 using length MIN(strlen(string)+1, arg3). */
3879 #ifdef HAVE_cmpstrnsi
3880 if (HAVE_cmpstrnsi)
3882 tree arg1 = TREE_VALUE (arglist);
3883 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3884 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3885 tree len, len1, len2;
3886 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3887 rtx result, insn;
3888 tree fndecl, fn;
3890 int arg1_align
3891 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3892 int arg2_align
3893 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3894 enum machine_mode insn_mode
3895 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3897 len1 = c_strlen (arg1, 1);
3898 len2 = c_strlen (arg2, 1);
3900 if (len1)
3901 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3902 if (len2)
3903 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3905 /* If we don't have a constant length for the first, use the length
3906 of the second, if we know it. We don't require a constant for
3907 this case; some cost analysis could be done if both are available
3908 but neither is constant. For now, assume they're equally cheap,
3909 unless one has side effects. If both strings have constant lengths,
3910 use the smaller. */
3912 if (!len1)
3913 len = len2;
3914 else if (!len2)
3915 len = len1;
3916 else if (TREE_SIDE_EFFECTS (len1))
3917 len = len2;
3918 else if (TREE_SIDE_EFFECTS (len2))
3919 len = len1;
3920 else if (TREE_CODE (len1) != INTEGER_CST)
3921 len = len2;
3922 else if (TREE_CODE (len2) != INTEGER_CST)
3923 len = len1;
3924 else if (tree_int_cst_lt (len1, len2))
3925 len = len1;
3926 else
3927 len = len2;
3929 /* If both arguments have side effects, we cannot optimize. */
3930 if (!len || TREE_SIDE_EFFECTS (len))
3931 return 0;
3933 /* The actual new length parameter is MIN(len,arg3). */
3934 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3935 fold_convert (TREE_TYPE (len), arg3));
3937 /* If we don't have POINTER_TYPE, call the function. */
3938 if (arg1_align == 0 || arg2_align == 0)
3939 return 0;
3941 /* Make a place to write the result of the instruction. */
3942 result = target;
3943 if (! (result != 0
3944 && REG_P (result) && GET_MODE (result) == insn_mode
3945 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3946 result = gen_reg_rtx (insn_mode);
3948 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3949 arg1 = builtin_save_expr (arg1);
3950 arg2 = builtin_save_expr (arg2);
3951 len = builtin_save_expr (len);
3953 arg1_rtx = get_memory_rtx (arg1, len);
3954 arg2_rtx = get_memory_rtx (arg2, len);
3955 arg3_rtx = expand_normal (len);
3956 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3957 GEN_INT (MIN (arg1_align, arg2_align)));
3958 if (insn)
3960 emit_insn (insn);
3962 /* Return the value in the proper mode for this function. */
3963 mode = TYPE_MODE (TREE_TYPE (exp));
3964 if (GET_MODE (result) == mode)
3965 return result;
3966 if (target == 0)
3967 return convert_to_mode (mode, result, 0);
3968 convert_move (target, result, 0);
3969 return target;
3972 /* Expand the library call ourselves using a stabilized argument
3973 list to avoid re-evaluating the function's arguments twice. */
3974 arglist = build_tree_list (NULL_TREE, len);
3975 arglist = tree_cons (NULL_TREE, arg2, arglist);
3976 arglist = tree_cons (NULL_TREE, arg1, arglist);
3977 fndecl = get_callee_fndecl (exp);
3978 fn = build_function_call_expr (fndecl, arglist);
3979 if (TREE_CODE (fn) == CALL_EXPR)
3980 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3981 return expand_call (fn, target, target == const0_rtx);
3983 #endif
3984 return 0;
3987 /* Expand expression EXP, which is a call to the strcat builtin.
3988 Return 0 if we failed the caller should emit a normal call,
3989 otherwise try to get the result in TARGET, if convenient. */
3991 static rtx
3992 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3994 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3995 return 0;
3996 else
3998 tree dst = TREE_VALUE (arglist),
3999 src = TREE_VALUE (TREE_CHAIN (arglist));
4000 const char *p = c_getstr (src);
4002 /* If the string length is zero, return the dst parameter. */
4003 if (p && *p == '\0')
4004 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4006 if (!optimize_size)
4008 /* See if we can store by pieces into (dst + strlen(dst)). */
4009 tree newsrc, newdst,
4010 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4011 rtx insns;
4013 /* Stabilize the argument list. */
4014 newsrc = builtin_save_expr (src);
4015 if (newsrc != src)
4016 arglist = build_tree_list (NULL_TREE, newsrc);
4017 else
4018 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4020 dst = builtin_save_expr (dst);
4022 start_sequence ();
4024 /* Create strlen (dst). */
4025 newdst =
4026 build_function_call_expr (strlen_fn,
4027 build_tree_list (NULL_TREE, dst));
4028 /* Create (dst + (cast) strlen (dst)). */
4029 newdst = fold_convert (TREE_TYPE (dst), newdst);
4030 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4032 newdst = builtin_save_expr (newdst);
4033 arglist = tree_cons (NULL_TREE, newdst, arglist);
4035 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4037 end_sequence (); /* Stop sequence. */
4038 return 0;
4041 /* Output the entire sequence. */
4042 insns = get_insns ();
4043 end_sequence ();
4044 emit_insn (insns);
4046 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4049 return 0;
4053 /* Expand expression EXP, which is a call to the strncat builtin.
4054 Return 0 if we failed the caller should emit a normal call,
4055 otherwise try to get the result in TARGET, if convenient. */
4057 static rtx
4058 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4060 if (validate_arglist (arglist,
4061 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4063 tree result = fold_builtin_strncat (arglist);
4064 if (result)
4065 return expand_expr (result, target, mode, EXPAND_NORMAL);
4067 return 0;
4070 /* Expand expression EXP, which is a call to the strspn builtin.
4071 Return 0 if we failed the caller should emit a normal call,
4072 otherwise try to get the result in TARGET, if convenient. */
4074 static rtx
4075 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4077 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4079 tree result = fold_builtin_strspn (arglist);
4080 if (result)
4081 return expand_expr (result, target, mode, EXPAND_NORMAL);
4083 return 0;
4086 /* Expand expression EXP, which is a call to the strcspn builtin.
4087 Return 0 if we failed the caller should emit a normal call,
4088 otherwise try to get the result in TARGET, if convenient. */
4090 static rtx
4091 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4093 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4095 tree result = fold_builtin_strcspn (arglist);
4096 if (result)
4097 return expand_expr (result, target, mode, EXPAND_NORMAL);
4099 return 0;
4102 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4103 if that's convenient. */
4106 expand_builtin_saveregs (void)
4108 rtx val, seq;
4110 /* Don't do __builtin_saveregs more than once in a function.
4111 Save the result of the first call and reuse it. */
4112 if (saveregs_value != 0)
4113 return saveregs_value;
4115 /* When this function is called, it means that registers must be
4116 saved on entry to this function. So we migrate the call to the
4117 first insn of this function. */
4119 start_sequence ();
4121 /* Do whatever the machine needs done in this case. */
4122 val = targetm.calls.expand_builtin_saveregs ();
4124 seq = get_insns ();
4125 end_sequence ();
4127 saveregs_value = val;
4129 /* Put the insns after the NOTE that starts the function. If this
4130 is inside a start_sequence, make the outer-level insn chain current, so
4131 the code is placed at the start of the function. */
4132 push_topmost_sequence ();
4133 emit_insn_after (seq, entry_of_function ());
4134 pop_topmost_sequence ();
4136 return val;
4139 /* __builtin_args_info (N) returns word N of the arg space info
4140 for the current function. The number and meanings of words
4141 is controlled by the definition of CUMULATIVE_ARGS. */
4143 static rtx
4144 expand_builtin_args_info (tree arglist)
4146 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4147 int *word_ptr = (int *) &current_function_args_info;
4149 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4151 if (arglist != 0)
4153 if (!host_integerp (TREE_VALUE (arglist), 0))
4154 error ("argument of %<__builtin_args_info%> must be constant");
4155 else
4157 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4159 if (wordnum < 0 || wordnum >= nwords)
4160 error ("argument of %<__builtin_args_info%> out of range");
4161 else
4162 return GEN_INT (word_ptr[wordnum]);
4165 else
4166 error ("missing argument in %<__builtin_args_info%>");
4168 return const0_rtx;
4171 /* Expand a call to __builtin_next_arg. */
4173 static rtx
4174 expand_builtin_next_arg (void)
4176 /* Checking arguments is already done in fold_builtin_next_arg
4177 that must be called before this function. */
4178 return expand_binop (Pmode, add_optab,
4179 current_function_internal_arg_pointer,
4180 current_function_arg_offset_rtx,
4181 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4184 /* Make it easier for the backends by protecting the valist argument
4185 from multiple evaluations. */
4187 static tree
4188 stabilize_va_list (tree valist, int needs_lvalue)
4190 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4192 if (TREE_SIDE_EFFECTS (valist))
4193 valist = save_expr (valist);
4195 /* For this case, the backends will be expecting a pointer to
4196 TREE_TYPE (va_list_type_node), but it's possible we've
4197 actually been given an array (an actual va_list_type_node).
4198 So fix it. */
4199 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4201 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4202 valist = build_fold_addr_expr_with_type (valist, p1);
4205 else
4207 tree pt;
4209 if (! needs_lvalue)
4211 if (! TREE_SIDE_EFFECTS (valist))
4212 return valist;
4214 pt = build_pointer_type (va_list_type_node);
4215 valist = fold_build1 (ADDR_EXPR, pt, valist);
4216 TREE_SIDE_EFFECTS (valist) = 1;
4219 if (TREE_SIDE_EFFECTS (valist))
4220 valist = save_expr (valist);
4221 valist = build_fold_indirect_ref (valist);
4224 return valist;
4227 /* The "standard" definition of va_list is void*. */
4229 tree
4230 std_build_builtin_va_list (void)
4232 return ptr_type_node;
4235 /* The "standard" implementation of va_start: just assign `nextarg' to
4236 the variable. */
4238 void
4239 std_expand_builtin_va_start (tree valist, rtx nextarg)
4241 tree t;
4243 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4244 make_tree (ptr_type_node, nextarg));
4245 TREE_SIDE_EFFECTS (t) = 1;
4247 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4250 /* Expand ARGLIST, from a call to __builtin_va_start. */
4252 static rtx
4253 expand_builtin_va_start (tree arglist)
4255 rtx nextarg;
4256 tree chain, valist;
4258 chain = TREE_CHAIN (arglist);
4260 if (!chain)
4262 error ("too few arguments to function %<va_start%>");
4263 return const0_rtx;
4266 if (fold_builtin_next_arg (chain))
4267 return const0_rtx;
4269 nextarg = expand_builtin_next_arg ();
4270 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4272 #ifdef EXPAND_BUILTIN_VA_START
4273 EXPAND_BUILTIN_VA_START (valist, nextarg);
4274 #else
4275 std_expand_builtin_va_start (valist, nextarg);
4276 #endif
4278 return const0_rtx;
4281 /* The "standard" implementation of va_arg: read the value from the
4282 current (padded) address and increment by the (padded) size. */
4284 tree
4285 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4287 tree addr, t, type_size, rounded_size, valist_tmp;
4288 unsigned HOST_WIDE_INT align, boundary;
4289 bool indirect;
4291 #ifdef ARGS_GROW_DOWNWARD
4292 /* All of the alignment and movement below is for args-grow-up machines.
4293 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4294 implement their own specialized gimplify_va_arg_expr routines. */
4295 gcc_unreachable ();
4296 #endif
4298 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4299 if (indirect)
4300 type = build_pointer_type (type);
4302 align = PARM_BOUNDARY / BITS_PER_UNIT;
4303 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4305 /* Hoist the valist value into a temporary for the moment. */
4306 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4308 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4309 requires greater alignment, we must perform dynamic alignment. */
4310 if (boundary > align
4311 && !integer_zerop (TYPE_SIZE (type)))
4313 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4314 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4315 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4316 gimplify_and_add (t, pre_p);
4318 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4319 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4320 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4321 gimplify_and_add (t, pre_p);
4323 else
4324 boundary = align;
4326 /* If the actual alignment is less than the alignment of the type,
4327 adjust the type accordingly so that we don't assume strict alignment
4328 when deferencing the pointer. */
4329 boundary *= BITS_PER_UNIT;
4330 if (boundary < TYPE_ALIGN (type))
4332 type = build_variant_type_copy (type);
4333 TYPE_ALIGN (type) = boundary;
4336 /* Compute the rounded size of the type. */
4337 type_size = size_in_bytes (type);
4338 rounded_size = round_up (type_size, align);
4340 /* Reduce rounded_size so it's sharable with the postqueue. */
4341 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4343 /* Get AP. */
4344 addr = valist_tmp;
4345 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4347 /* Small args are padded downward. */
4348 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4349 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4350 size_binop (MINUS_EXPR, rounded_size, type_size));
4351 t = fold_convert (TREE_TYPE (addr), t);
4352 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4355 /* Compute new value for AP. */
4356 t = fold_convert (TREE_TYPE (valist), rounded_size);
4357 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4358 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4359 gimplify_and_add (t, pre_p);
4361 addr = fold_convert (build_pointer_type (type), addr);
4363 if (indirect)
4364 addr = build_va_arg_indirect_ref (addr);
4366 return build_va_arg_indirect_ref (addr);
4369 /* Build an indirect-ref expression over the given TREE, which represents a
4370 piece of a va_arg() expansion. */
4371 tree
4372 build_va_arg_indirect_ref (tree addr)
4374 addr = build_fold_indirect_ref (addr);
4376 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4377 mf_mark (addr);
4379 return addr;
4382 /* Return a dummy expression of type TYPE in order to keep going after an
4383 error. */
4385 static tree
4386 dummy_object (tree type)
4388 tree t = build_int_cst (build_pointer_type (type), 0);
4389 return build1 (INDIRECT_REF, type, t);
4392 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4393 builtin function, but a very special sort of operator. */
4395 enum gimplify_status
4396 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4398 tree promoted_type, want_va_type, have_va_type;
4399 tree valist = TREE_OPERAND (*expr_p, 0);
4400 tree type = TREE_TYPE (*expr_p);
4401 tree t;
4403 /* Verify that valist is of the proper type. */
4404 want_va_type = va_list_type_node;
4405 have_va_type = TREE_TYPE (valist);
4407 if (have_va_type == error_mark_node)
4408 return GS_ERROR;
4410 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4412 /* If va_list is an array type, the argument may have decayed
4413 to a pointer type, e.g. by being passed to another function.
4414 In that case, unwrap both types so that we can compare the
4415 underlying records. */
4416 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4417 || POINTER_TYPE_P (have_va_type))
4419 want_va_type = TREE_TYPE (want_va_type);
4420 have_va_type = TREE_TYPE (have_va_type);
4424 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4426 error ("first argument to %<va_arg%> not of type %<va_list%>");
4427 return GS_ERROR;
4430 /* Generate a diagnostic for requesting data of a type that cannot
4431 be passed through `...' due to type promotion at the call site. */
4432 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4433 != type)
4435 static bool gave_help;
4437 /* Unfortunately, this is merely undefined, rather than a constraint
4438 violation, so we cannot make this an error. If this call is never
4439 executed, the program is still strictly conforming. */
4440 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4441 type, promoted_type);
4442 if (! gave_help)
4444 gave_help = true;
4445 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4446 promoted_type, type);
4449 /* We can, however, treat "undefined" any way we please.
4450 Call abort to encourage the user to fix the program. */
4451 inform ("if this code is reached, the program will abort");
4452 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4453 NULL);
4454 append_to_statement_list (t, pre_p);
4456 /* This is dead code, but go ahead and finish so that the
4457 mode of the result comes out right. */
4458 *expr_p = dummy_object (type);
4459 return GS_ALL_DONE;
4461 else
4463 /* Make it easier for the backends by protecting the valist argument
4464 from multiple evaluations. */
4465 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4467 /* For this case, the backends will be expecting a pointer to
4468 TREE_TYPE (va_list_type_node), but it's possible we've
4469 actually been given an array (an actual va_list_type_node).
4470 So fix it. */
4471 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4473 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4474 valist = build_fold_addr_expr_with_type (valist, p1);
4476 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4478 else
4479 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4481 if (!targetm.gimplify_va_arg_expr)
4482 /* FIXME:Once most targets are converted we should merely
4483 assert this is non-null. */
4484 return GS_ALL_DONE;
4486 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4487 return GS_OK;
4491 /* Expand ARGLIST, from a call to __builtin_va_end. */
4493 static rtx
4494 expand_builtin_va_end (tree arglist)
4496 tree valist = TREE_VALUE (arglist);
4498 /* Evaluate for side effects, if needed. I hate macros that don't
4499 do that. */
4500 if (TREE_SIDE_EFFECTS (valist))
4501 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4503 return const0_rtx;
4506 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4507 builtin rather than just as an assignment in stdarg.h because of the
4508 nastiness of array-type va_list types. */
4510 static rtx
4511 expand_builtin_va_copy (tree arglist)
4513 tree dst, src, t;
4515 dst = TREE_VALUE (arglist);
4516 src = TREE_VALUE (TREE_CHAIN (arglist));
4518 dst = stabilize_va_list (dst, 1);
4519 src = stabilize_va_list (src, 0);
4521 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4523 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4524 TREE_SIDE_EFFECTS (t) = 1;
4525 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4527 else
4529 rtx dstb, srcb, size;
4531 /* Evaluate to pointers. */
4532 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4533 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4534 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4535 VOIDmode, EXPAND_NORMAL);
4537 dstb = convert_memory_address (Pmode, dstb);
4538 srcb = convert_memory_address (Pmode, srcb);
4540 /* "Dereference" to BLKmode memories. */
4541 dstb = gen_rtx_MEM (BLKmode, dstb);
4542 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4543 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4544 srcb = gen_rtx_MEM (BLKmode, srcb);
4545 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4546 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4548 /* Copy. */
4549 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4552 return const0_rtx;
4555 /* Expand a call to one of the builtin functions __builtin_frame_address or
4556 __builtin_return_address. */
4558 static rtx
4559 expand_builtin_frame_address (tree fndecl, tree arglist)
4561 /* The argument must be a nonnegative integer constant.
4562 It counts the number of frames to scan up the stack.
4563 The value is the return address saved in that frame. */
4564 if (arglist == 0)
4565 /* Warning about missing arg was already issued. */
4566 return const0_rtx;
4567 else if (! host_integerp (TREE_VALUE (arglist), 1))
4569 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4570 error ("invalid argument to %<__builtin_frame_address%>");
4571 else
4572 error ("invalid argument to %<__builtin_return_address%>");
4573 return const0_rtx;
4575 else
4577 rtx tem
4578 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4579 tree_low_cst (TREE_VALUE (arglist), 1));
4581 /* Some ports cannot access arbitrary stack frames. */
4582 if (tem == NULL)
4584 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4585 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4586 else
4587 warning (0, "unsupported argument to %<__builtin_return_address%>");
4588 return const0_rtx;
4591 /* For __builtin_frame_address, return what we've got. */
4592 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4593 return tem;
4595 if (!REG_P (tem)
4596 && ! CONSTANT_P (tem))
4597 tem = copy_to_mode_reg (Pmode, tem);
4598 return tem;
4602 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4603 we failed and the caller should emit a normal call, otherwise try to get
4604 the result in TARGET, if convenient. */
4606 static rtx
4607 expand_builtin_alloca (tree arglist, rtx target)
4609 rtx op0;
4610 rtx result;
4612 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4613 should always expand to function calls. These can be intercepted
4614 in libmudflap. */
4615 if (flag_mudflap)
4616 return 0;
4618 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4619 return 0;
4621 /* Compute the argument. */
4622 op0 = expand_normal (TREE_VALUE (arglist));
4624 /* Allocate the desired space. */
4625 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4626 result = convert_memory_address (ptr_mode, result);
4628 return result;
4631 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4632 is the mode to expand with. */
4634 static rtx
4635 expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4637 enum machine_mode mode;
4638 tree arg;
4639 rtx op0;
4641 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4642 return 0;
4644 arg = TREE_VALUE (arglist);
4645 mode = TYPE_MODE (TREE_TYPE (arg));
4646 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4648 target = expand_unop (mode, bswap_optab, op0, target, 1);
4650 gcc_assert (target);
4652 return convert_to_mode (mode, target, 0);
4655 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4656 Return 0 if a normal call should be emitted rather than expanding the
4657 function in-line. If convenient, the result should be placed in TARGET.
4658 SUBTARGET may be used as the target for computing one of EXP's operands. */
4660 static rtx
4661 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4662 rtx subtarget, optab op_optab)
4664 rtx op0;
4665 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4666 return 0;
4668 /* Compute the argument. */
4669 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4670 /* Compute op, into TARGET if possible.
4671 Set TARGET to wherever the result comes back. */
4672 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4673 op_optab, op0, target, 1);
4674 gcc_assert (target);
4676 return convert_to_mode (target_mode, target, 0);
4679 /* If the string passed to fputs is a constant and is one character
4680 long, we attempt to transform this call into __builtin_fputc(). */
4682 static rtx
4683 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4685 /* Verify the arguments in the original call. */
4686 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4688 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4689 unlocked, NULL_TREE);
4690 if (result)
4691 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4693 return 0;
4696 /* Expand a call to __builtin_expect. We return our argument and emit a
4697 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4698 a non-jump context. */
4700 static rtx
4701 expand_builtin_expect (tree arglist, rtx target)
4703 tree exp, c;
4704 rtx note, rtx_c;
4706 if (arglist == NULL_TREE
4707 || TREE_CHAIN (arglist) == NULL_TREE)
4708 return const0_rtx;
4709 exp = TREE_VALUE (arglist);
4710 c = TREE_VALUE (TREE_CHAIN (arglist));
4712 if (TREE_CODE (c) != INTEGER_CST)
4714 error ("second argument to %<__builtin_expect%> must be a constant");
4715 c = integer_zero_node;
4718 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4720 /* Don't bother with expected value notes for integral constants. */
4721 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4723 /* We do need to force this into a register so that we can be
4724 moderately sure to be able to correctly interpret the branch
4725 condition later. */
4726 target = force_reg (GET_MODE (target), target);
4728 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4730 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4731 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4734 return target;
4737 /* Like expand_builtin_expect, except do this in a jump context. This is
4738 called from do_jump if the conditional is a __builtin_expect. Return either
4739 a list of insns to emit the jump or NULL if we cannot optimize
4740 __builtin_expect. We need to optimize this at jump time so that machines
4741 like the PowerPC don't turn the test into a SCC operation, and then jump
4742 based on the test being 0/1. */
4745 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4747 tree arglist = TREE_OPERAND (exp, 1);
4748 tree arg0 = TREE_VALUE (arglist);
4749 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4750 rtx ret = NULL_RTX;
4752 /* Only handle __builtin_expect (test, 0) and
4753 __builtin_expect (test, 1). */
4754 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4755 && (integer_zerop (arg1) || integer_onep (arg1)))
4757 rtx insn, drop_through_label, temp;
4759 /* Expand the jump insns. */
4760 start_sequence ();
4761 do_jump (arg0, if_false_label, if_true_label);
4762 ret = get_insns ();
4764 drop_through_label = get_last_insn ();
4765 if (drop_through_label && NOTE_P (drop_through_label))
4766 drop_through_label = prev_nonnote_insn (drop_through_label);
4767 if (drop_through_label && !LABEL_P (drop_through_label))
4768 drop_through_label = NULL_RTX;
4769 end_sequence ();
4771 if (! if_true_label)
4772 if_true_label = drop_through_label;
4773 if (! if_false_label)
4774 if_false_label = drop_through_label;
4776 /* Go through and add the expect's to each of the conditional jumps. */
4777 insn = ret;
4778 while (insn != NULL_RTX)
4780 rtx next = NEXT_INSN (insn);
4782 if (JUMP_P (insn) && any_condjump_p (insn))
4784 rtx ifelse = SET_SRC (pc_set (insn));
4785 rtx then_dest = XEXP (ifelse, 1);
4786 rtx else_dest = XEXP (ifelse, 2);
4787 int taken = -1;
4789 /* First check if we recognize any of the labels. */
4790 if (GET_CODE (then_dest) == LABEL_REF
4791 && XEXP (then_dest, 0) == if_true_label)
4792 taken = 1;
4793 else if (GET_CODE (then_dest) == LABEL_REF
4794 && XEXP (then_dest, 0) == if_false_label)
4795 taken = 0;
4796 else if (GET_CODE (else_dest) == LABEL_REF
4797 && XEXP (else_dest, 0) == if_false_label)
4798 taken = 1;
4799 else if (GET_CODE (else_dest) == LABEL_REF
4800 && XEXP (else_dest, 0) == if_true_label)
4801 taken = 0;
4802 /* Otherwise check where we drop through. */
4803 else if (else_dest == pc_rtx)
4805 if (next && NOTE_P (next))
4806 next = next_nonnote_insn (next);
4808 if (next && JUMP_P (next)
4809 && any_uncondjump_p (next))
4810 temp = XEXP (SET_SRC (pc_set (next)), 0);
4811 else
4812 temp = next;
4814 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4815 else that can't possibly match either target label. */
4816 if (temp == if_false_label)
4817 taken = 1;
4818 else if (temp == if_true_label)
4819 taken = 0;
4821 else if (then_dest == pc_rtx)
4823 if (next && NOTE_P (next))
4824 next = next_nonnote_insn (next);
4826 if (next && JUMP_P (next)
4827 && any_uncondjump_p (next))
4828 temp = XEXP (SET_SRC (pc_set (next)), 0);
4829 else
4830 temp = next;
4832 if (temp == if_false_label)
4833 taken = 0;
4834 else if (temp == if_true_label)
4835 taken = 1;
4838 if (taken != -1)
4840 /* If the test is expected to fail, reverse the
4841 probabilities. */
4842 if (integer_zerop (arg1))
4843 taken = 1 - taken;
4844 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4848 insn = next;
4852 return ret;
4855 void
4856 expand_builtin_trap (void)
4858 #ifdef HAVE_trap
4859 if (HAVE_trap)
4860 emit_insn (gen_trap ());
4861 else
4862 #endif
4863 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4864 emit_barrier ();
4867 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4868 Return 0 if a normal call should be emitted rather than expanding
4869 the function inline. If convenient, the result should be placed
4870 in TARGET. SUBTARGET may be used as the target for computing
4871 the operand. */
4873 static rtx
4874 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4876 enum machine_mode mode;
4877 tree arg;
4878 rtx op0;
4880 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4881 return 0;
4883 arg = TREE_VALUE (arglist);
4884 mode = TYPE_MODE (TREE_TYPE (arg));
4885 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4886 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4889 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4890 Return NULL is a normal call should be emitted rather than expanding the
4891 function inline. If convenient, the result should be placed in TARGET.
4892 SUBTARGET may be used as the target for computing the operand. */
4894 static rtx
4895 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4897 rtx op0, op1;
4898 tree arg;
4900 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4901 return 0;
4903 arg = TREE_VALUE (arglist);
4904 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4906 arg = TREE_VALUE (TREE_CHAIN (arglist));
4907 op1 = expand_normal (arg);
4909 return expand_copysign (op0, op1, target);
4912 /* Create a new constant string literal and return a char* pointer to it.
4913 The STRING_CST value is the LEN characters at STR. */
4914 tree
4915 build_string_literal (int len, const char *str)
4917 tree t, elem, index, type;
4919 t = build_string (len, str);
4920 elem = build_type_variant (char_type_node, 1, 0);
4921 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4922 type = build_array_type (elem, index);
4923 TREE_TYPE (t) = type;
4924 TREE_CONSTANT (t) = 1;
4925 TREE_INVARIANT (t) = 1;
4926 TREE_READONLY (t) = 1;
4927 TREE_STATIC (t) = 1;
4929 type = build_pointer_type (type);
4930 t = build1 (ADDR_EXPR, type, t);
4932 type = build_pointer_type (elem);
4933 t = build1 (NOP_EXPR, type, t);
4934 return t;
4937 /* Expand EXP, a call to printf or printf_unlocked.
4938 Return 0 if a normal call should be emitted rather than transforming
4939 the function inline. If convenient, the result should be placed in
4940 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4941 call. */
4942 static rtx
4943 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4944 bool unlocked)
4946 tree arglist = TREE_OPERAND (exp, 1);
4947 /* If we're using an unlocked function, assume the other unlocked
4948 functions exist explicitly. */
4949 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4950 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4951 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4952 : implicit_built_in_decls[BUILT_IN_PUTS];
4953 const char *fmt_str;
4954 tree fn, fmt, arg;
4956 /* If the return value is used, don't do the transformation. */
4957 if (target != const0_rtx)
4958 return 0;
4960 /* Verify the required arguments in the original call. */
4961 if (! arglist)
4962 return 0;
4963 fmt = TREE_VALUE (arglist);
4964 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4965 return 0;
4966 arglist = TREE_CHAIN (arglist);
4968 /* Check whether the format is a literal string constant. */
4969 fmt_str = c_getstr (fmt);
4970 if (fmt_str == NULL)
4971 return 0;
4973 if (!init_target_chars())
4974 return 0;
4976 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4977 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4979 if (! arglist
4980 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4981 || TREE_CHAIN (arglist))
4982 return 0;
4983 fn = fn_puts;
4985 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4986 else if (strcmp (fmt_str, target_percent_c) == 0)
4988 if (! arglist
4989 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4990 || TREE_CHAIN (arglist))
4991 return 0;
4992 fn = fn_putchar;
4994 else
4996 /* We can't handle anything else with % args or %% ... yet. */
4997 if (strchr (fmt_str, target_percent))
4998 return 0;
5000 if (arglist)
5001 return 0;
5003 /* If the format specifier was "", printf does nothing. */
5004 if (fmt_str[0] == '\0')
5005 return const0_rtx;
5006 /* If the format specifier has length of 1, call putchar. */
5007 if (fmt_str[1] == '\0')
5009 /* Given printf("c"), (where c is any one character,)
5010 convert "c"[0] to an int and pass that to the replacement
5011 function. */
5012 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5013 arglist = build_tree_list (NULL_TREE, arg);
5014 fn = fn_putchar;
5016 else
5018 /* If the format specifier was "string\n", call puts("string"). */
5019 size_t len = strlen (fmt_str);
5020 if ((unsigned char)fmt_str[len - 1] == target_newline)
5022 /* Create a NUL-terminated string that's one char shorter
5023 than the original, stripping off the trailing '\n'. */
5024 char *newstr = alloca (len);
5025 memcpy (newstr, fmt_str, len - 1);
5026 newstr[len - 1] = 0;
5028 arg = build_string_literal (len, newstr);
5029 arglist = build_tree_list (NULL_TREE, arg);
5030 fn = fn_puts;
5032 else
5033 /* We'd like to arrange to call fputs(string,stdout) here,
5034 but we need stdout and don't have a way to get it yet. */
5035 return 0;
5039 if (!fn)
5040 return 0;
5041 fn = build_function_call_expr (fn, arglist);
5042 if (TREE_CODE (fn) == CALL_EXPR)
5043 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5044 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5047 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5048 Return 0 if a normal call should be emitted rather than transforming
5049 the function inline. If convenient, the result should be placed in
5050 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5051 call. */
5052 static rtx
5053 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5054 bool unlocked)
5056 tree arglist = TREE_OPERAND (exp, 1);
5057 /* If we're using an unlocked function, assume the other unlocked
5058 functions exist explicitly. */
5059 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5060 : implicit_built_in_decls[BUILT_IN_FPUTC];
5061 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5062 : implicit_built_in_decls[BUILT_IN_FPUTS];
5063 const char *fmt_str;
5064 tree fn, fmt, fp, arg;
5066 /* If the return value is used, don't do the transformation. */
5067 if (target != const0_rtx)
5068 return 0;
5070 /* Verify the required arguments in the original call. */
5071 if (! arglist)
5072 return 0;
5073 fp = TREE_VALUE (arglist);
5074 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5075 return 0;
5076 arglist = TREE_CHAIN (arglist);
5077 if (! arglist)
5078 return 0;
5079 fmt = TREE_VALUE (arglist);
5080 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5081 return 0;
5082 arglist = TREE_CHAIN (arglist);
5084 /* Check whether the format is a literal string constant. */
5085 fmt_str = c_getstr (fmt);
5086 if (fmt_str == NULL)
5087 return 0;
5089 if (!init_target_chars())
5090 return 0;
5092 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5093 if (strcmp (fmt_str, target_percent_s) == 0)
5095 if (! arglist
5096 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5097 || TREE_CHAIN (arglist))
5098 return 0;
5099 arg = TREE_VALUE (arglist);
5100 arglist = build_tree_list (NULL_TREE, fp);
5101 arglist = tree_cons (NULL_TREE, arg, arglist);
5102 fn = fn_fputs;
5104 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5105 else if (strcmp (fmt_str, target_percent_c) == 0)
5107 if (! arglist
5108 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5109 || TREE_CHAIN (arglist))
5110 return 0;
5111 arg = TREE_VALUE (arglist);
5112 arglist = build_tree_list (NULL_TREE, fp);
5113 arglist = tree_cons (NULL_TREE, arg, arglist);
5114 fn = fn_fputc;
5116 else
5118 /* We can't handle anything else with % args or %% ... yet. */
5119 if (strchr (fmt_str, target_percent))
5120 return 0;
5122 if (arglist)
5123 return 0;
5125 /* If the format specifier was "", fprintf does nothing. */
5126 if (fmt_str[0] == '\0')
5128 /* Evaluate and ignore FILE* argument for side-effects. */
5129 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5130 return const0_rtx;
5133 /* When "string" doesn't contain %, replace all cases of
5134 fprintf(stream,string) with fputs(string,stream). The fputs
5135 builtin will take care of special cases like length == 1. */
5136 arglist = build_tree_list (NULL_TREE, fp);
5137 arglist = tree_cons (NULL_TREE, fmt, arglist);
5138 fn = fn_fputs;
5141 if (!fn)
5142 return 0;
5143 fn = build_function_call_expr (fn, arglist);
5144 if (TREE_CODE (fn) == CALL_EXPR)
5145 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5146 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5149 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5150 a normal call should be emitted rather than expanding the function
5151 inline. If convenient, the result should be placed in TARGET with
5152 mode MODE. */
5154 static rtx
5155 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5157 tree orig_arglist, dest, fmt;
5158 const char *fmt_str;
5160 orig_arglist = arglist;
5162 /* Verify the required arguments in the original call. */
5163 if (! arglist)
5164 return 0;
5165 dest = TREE_VALUE (arglist);
5166 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5167 return 0;
5168 arglist = TREE_CHAIN (arglist);
5169 if (! arglist)
5170 return 0;
5171 fmt = TREE_VALUE (arglist);
5172 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5173 return 0;
5174 arglist = TREE_CHAIN (arglist);
5176 /* Check whether the format is a literal string constant. */
5177 fmt_str = c_getstr (fmt);
5178 if (fmt_str == NULL)
5179 return 0;
5181 if (!init_target_chars())
5182 return 0;
5184 /* If the format doesn't contain % args or %%, use strcpy. */
5185 if (strchr (fmt_str, target_percent) == 0)
5187 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5188 tree exp;
5190 if (arglist || ! fn)
5191 return 0;
5192 expand_expr (build_function_call_expr (fn, orig_arglist),
5193 const0_rtx, VOIDmode, EXPAND_NORMAL);
5194 if (target == const0_rtx)
5195 return const0_rtx;
5196 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5197 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5199 /* If the format is "%s", use strcpy if the result isn't used. */
5200 else if (strcmp (fmt_str, target_percent_s) == 0)
5202 tree fn, arg, len;
5203 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5205 if (! fn)
5206 return 0;
5208 if (! arglist || TREE_CHAIN (arglist))
5209 return 0;
5210 arg = TREE_VALUE (arglist);
5211 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5212 return 0;
5214 if (target != const0_rtx)
5216 len = c_strlen (arg, 1);
5217 if (! len || TREE_CODE (len) != INTEGER_CST)
5218 return 0;
5220 else
5221 len = NULL_TREE;
5223 arglist = build_tree_list (NULL_TREE, arg);
5224 arglist = tree_cons (NULL_TREE, dest, arglist);
5225 expand_expr (build_function_call_expr (fn, arglist),
5226 const0_rtx, VOIDmode, EXPAND_NORMAL);
5228 if (target == const0_rtx)
5229 return const0_rtx;
5230 return expand_expr (len, target, mode, EXPAND_NORMAL);
5233 return 0;
5236 /* Expand a call to either the entry or exit function profiler. */
5238 static rtx
5239 expand_builtin_profile_func (bool exitp)
5241 rtx this, which;
5243 this = DECL_RTL (current_function_decl);
5244 gcc_assert (MEM_P (this));
5245 this = XEXP (this, 0);
5247 if (exitp)
5248 which = profile_function_exit_libfunc;
5249 else
5250 which = profile_function_entry_libfunc;
5252 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5253 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5255 Pmode);
5257 return const0_rtx;
5260 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5262 static rtx
5263 round_trampoline_addr (rtx tramp)
5265 rtx temp, addend, mask;
5267 /* If we don't need too much alignment, we'll have been guaranteed
5268 proper alignment by get_trampoline_type. */
5269 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5270 return tramp;
5272 /* Round address up to desired boundary. */
5273 temp = gen_reg_rtx (Pmode);
5274 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5275 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5277 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5278 temp, 0, OPTAB_LIB_WIDEN);
5279 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5280 temp, 0, OPTAB_LIB_WIDEN);
5282 return tramp;
5285 static rtx
5286 expand_builtin_init_trampoline (tree arglist)
5288 tree t_tramp, t_func, t_chain;
5289 rtx r_tramp, r_func, r_chain;
5290 #ifdef TRAMPOLINE_TEMPLATE
5291 rtx blktramp;
5292 #endif
5294 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5295 POINTER_TYPE, VOID_TYPE))
5296 return NULL_RTX;
5298 t_tramp = TREE_VALUE (arglist);
5299 arglist = TREE_CHAIN (arglist);
5300 t_func = TREE_VALUE (arglist);
5301 arglist = TREE_CHAIN (arglist);
5302 t_chain = TREE_VALUE (arglist);
5304 r_tramp = expand_normal (t_tramp);
5305 r_func = expand_normal (t_func);
5306 r_chain = expand_normal (t_chain);
5308 /* Generate insns to initialize the trampoline. */
5309 r_tramp = round_trampoline_addr (r_tramp);
5310 #ifdef TRAMPOLINE_TEMPLATE
5311 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5312 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5313 emit_block_move (blktramp, assemble_trampoline_template (),
5314 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5315 #endif
5316 trampolines_created = 1;
5317 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5319 return const0_rtx;
5322 static rtx
5323 expand_builtin_adjust_trampoline (tree arglist)
5325 rtx tramp;
5327 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5328 return NULL_RTX;
5330 tramp = expand_normal (TREE_VALUE (arglist));
5331 tramp = round_trampoline_addr (tramp);
5332 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5333 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5334 #endif
5336 return tramp;
5339 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5340 Return NULL_RTX if a normal call should be emitted rather than expanding
5341 the function in-line. EXP is the expression that is a call to the builtin
5342 function; if convenient, the result should be placed in TARGET. */
5344 static rtx
5345 expand_builtin_signbit (tree exp, rtx target)
5347 const struct real_format *fmt;
5348 enum machine_mode fmode, imode, rmode;
5349 HOST_WIDE_INT hi, lo;
5350 tree arg, arglist;
5351 int word, bitpos;
5352 rtx temp;
5354 arglist = TREE_OPERAND (exp, 1);
5355 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5356 return 0;
5358 arg = TREE_VALUE (arglist);
5359 fmode = TYPE_MODE (TREE_TYPE (arg));
5360 rmode = TYPE_MODE (TREE_TYPE (exp));
5361 fmt = REAL_MODE_FORMAT (fmode);
5363 /* For floating point formats without a sign bit, implement signbit
5364 as "ARG < 0.0". */
5365 bitpos = fmt->signbit_ro;
5366 if (bitpos < 0)
5368 /* But we can't do this if the format supports signed zero. */
5369 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5370 return 0;
5372 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5373 build_real (TREE_TYPE (arg), dconst0));
5374 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5377 temp = expand_normal (arg);
5378 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5380 imode = int_mode_for_mode (fmode);
5381 if (imode == BLKmode)
5382 return 0;
5383 temp = gen_lowpart (imode, temp);
5385 else
5387 imode = word_mode;
5388 /* Handle targets with different FP word orders. */
5389 if (FLOAT_WORDS_BIG_ENDIAN)
5390 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5391 else
5392 word = bitpos / BITS_PER_WORD;
5393 temp = operand_subword_force (temp, word, fmode);
5394 bitpos = bitpos % BITS_PER_WORD;
5397 /* Force the intermediate word_mode (or narrower) result into a
5398 register. This avoids attempting to create paradoxical SUBREGs
5399 of floating point modes below. */
5400 temp = force_reg (imode, temp);
5402 /* If the bitpos is within the "result mode" lowpart, the operation
5403 can be implement with a single bitwise AND. Otherwise, we need
5404 a right shift and an AND. */
5406 if (bitpos < GET_MODE_BITSIZE (rmode))
5408 if (bitpos < HOST_BITS_PER_WIDE_INT)
5410 hi = 0;
5411 lo = (HOST_WIDE_INT) 1 << bitpos;
5413 else
5415 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5416 lo = 0;
5419 if (imode != rmode)
5420 temp = gen_lowpart (rmode, temp);
5421 temp = expand_binop (rmode, and_optab, temp,
5422 immed_double_const (lo, hi, rmode),
5423 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5425 else
5427 /* Perform a logical right shift to place the signbit in the least
5428 significant bit, then truncate the result to the desired mode
5429 and mask just this bit. */
5430 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5431 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5432 temp = gen_lowpart (rmode, temp);
5433 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5434 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5437 return temp;
5440 /* Expand fork or exec calls. TARGET is the desired target of the
5441 call. ARGLIST is the list of arguments of the call. FN is the
5442 identificator of the actual function. IGNORE is nonzero if the
5443 value is to be ignored. */
5445 static rtx
5446 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5448 tree id, decl;
5449 tree call;
5451 /* If we are not profiling, just call the function. */
5452 if (!profile_arc_flag)
5453 return NULL_RTX;
5455 /* Otherwise call the wrapper. This should be equivalent for the rest of
5456 compiler, so the code does not diverge, and the wrapper may run the
5457 code necessary for keeping the profiling sane. */
5459 switch (DECL_FUNCTION_CODE (fn))
5461 case BUILT_IN_FORK:
5462 id = get_identifier ("__gcov_fork");
5463 break;
5465 case BUILT_IN_EXECL:
5466 id = get_identifier ("__gcov_execl");
5467 break;
5469 case BUILT_IN_EXECV:
5470 id = get_identifier ("__gcov_execv");
5471 break;
5473 case BUILT_IN_EXECLP:
5474 id = get_identifier ("__gcov_execlp");
5475 break;
5477 case BUILT_IN_EXECLE:
5478 id = get_identifier ("__gcov_execle");
5479 break;
5481 case BUILT_IN_EXECVP:
5482 id = get_identifier ("__gcov_execvp");
5483 break;
5485 case BUILT_IN_EXECVE:
5486 id = get_identifier ("__gcov_execve");
5487 break;
5489 default:
5490 gcc_unreachable ();
5493 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5494 DECL_EXTERNAL (decl) = 1;
5495 TREE_PUBLIC (decl) = 1;
5496 DECL_ARTIFICIAL (decl) = 1;
5497 TREE_NOTHROW (decl) = 1;
5498 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5499 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5500 call = build_function_call_expr (decl, arglist);
5502 return expand_call (call, target, ignore);
5506 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5507 the pointer in these functions is void*, the tree optimizers may remove
5508 casts. The mode computed in expand_builtin isn't reliable either, due
5509 to __sync_bool_compare_and_swap.
5511 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5512 group of builtins. This gives us log2 of the mode size. */
5514 static inline enum machine_mode
5515 get_builtin_sync_mode (int fcode_diff)
5517 /* The size is not negotiable, so ask not to get BLKmode in return
5518 if the target indicates that a smaller size would be better. */
5519 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5522 /* Expand the memory expression LOC and return the appropriate memory operand
5523 for the builtin_sync operations. */
5525 static rtx
5526 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5528 rtx addr, mem;
5530 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5532 /* Note that we explicitly do not want any alias information for this
5533 memory, so that we kill all other live memories. Otherwise we don't
5534 satisfy the full barrier semantics of the intrinsic. */
5535 mem = validize_mem (gen_rtx_MEM (mode, addr));
5537 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5538 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5539 MEM_VOLATILE_P (mem) = 1;
5541 return mem;
5544 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5545 ARGLIST is the operands list to the function. CODE is the rtx code
5546 that corresponds to the arithmetic or logical operation from the name;
5547 an exception here is that NOT actually means NAND. TARGET is an optional
5548 place for us to store the results; AFTER is true if this is the
5549 fetch_and_xxx form. IGNORE is true if we don't actually care about
5550 the result of the operation at all. */
5552 static rtx
5553 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5554 enum rtx_code code, bool after,
5555 rtx target, bool ignore)
5557 rtx val, mem;
5559 /* Expand the operands. */
5560 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5562 arglist = TREE_CHAIN (arglist);
5563 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5564 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5565 val = convert_to_mode (mode, val, 1);
5567 if (ignore)
5568 return expand_sync_operation (mem, val, code);
5569 else
5570 return expand_sync_fetch_operation (mem, val, code, after, target);
5573 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5574 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5575 true if this is the boolean form. TARGET is a place for us to store the
5576 results; this is NOT optional if IS_BOOL is true. */
5578 static rtx
5579 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5580 bool is_bool, rtx target)
5582 rtx old_val, new_val, mem;
5584 /* Expand the operands. */
5585 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5587 arglist = TREE_CHAIN (arglist);
5588 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5589 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5590 old_val = convert_to_mode (mode, old_val, 1);
5592 arglist = TREE_CHAIN (arglist);
5593 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5594 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5595 new_val = convert_to_mode (mode, new_val, 1);
5597 if (is_bool)
5598 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5599 else
5600 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5603 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5604 general form is actually an atomic exchange, and some targets only
5605 support a reduced form with the second argument being a constant 1.
5606 ARGLIST is the operands list to the function; TARGET is an optional
5607 place for us to store the results. */
5609 static rtx
5610 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5611 rtx target)
5613 rtx val, mem;
5615 /* Expand the operands. */
5616 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5618 arglist = TREE_CHAIN (arglist);
5619 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5620 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5621 val = convert_to_mode (mode, val, 1);
5623 return expand_sync_lock_test_and_set (mem, val, target);
5626 /* Expand the __sync_synchronize intrinsic. */
5628 static void
5629 expand_builtin_synchronize (void)
5631 tree x;
5633 #ifdef HAVE_memory_barrier
5634 if (HAVE_memory_barrier)
5636 emit_insn (gen_memory_barrier ());
5637 return;
5639 #endif
5641 /* If no explicit memory barrier instruction is available, create an
5642 empty asm stmt with a memory clobber. */
5643 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5644 tree_cons (NULL, build_string (6, "memory"), NULL));
5645 ASM_VOLATILE_P (x) = 1;
5646 expand_asm_expr (x);
5649 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5650 to the function. */
5652 static void
5653 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5655 enum insn_code icode;
5656 rtx mem, insn;
5657 rtx val = const0_rtx;
5659 /* Expand the operands. */
5660 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5662 /* If there is an explicit operation in the md file, use it. */
5663 icode = sync_lock_release[mode];
5664 if (icode != CODE_FOR_nothing)
5666 if (!insn_data[icode].operand[1].predicate (val, mode))
5667 val = force_reg (mode, val);
5669 insn = GEN_FCN (icode) (mem, val);
5670 if (insn)
5672 emit_insn (insn);
5673 return;
5677 /* Otherwise we can implement this operation by emitting a barrier
5678 followed by a store of zero. */
5679 expand_builtin_synchronize ();
5680 emit_move_insn (mem, val);
5683 /* Expand an expression EXP that calls a built-in function,
5684 with result going to TARGET if that's convenient
5685 (and in mode MODE if that's convenient).
5686 SUBTARGET may be used as the target for computing one of EXP's operands.
5687 IGNORE is nonzero if the value is to be ignored. */
5690 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5691 int ignore)
5693 tree fndecl = get_callee_fndecl (exp);
5694 tree arglist = TREE_OPERAND (exp, 1);
5695 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5696 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5698 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5699 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5701 /* When not optimizing, generate calls to library functions for a certain
5702 set of builtins. */
5703 if (!optimize
5704 && !called_as_built_in (fndecl)
5705 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5706 && fcode != BUILT_IN_ALLOCA)
5707 return expand_call (exp, target, ignore);
5709 /* The built-in function expanders test for target == const0_rtx
5710 to determine whether the function's result will be ignored. */
5711 if (ignore)
5712 target = const0_rtx;
5714 /* If the result of a pure or const built-in function is ignored, and
5715 none of its arguments are volatile, we can avoid expanding the
5716 built-in call and just evaluate the arguments for side-effects. */
5717 if (target == const0_rtx
5718 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5720 bool volatilep = false;
5721 tree arg;
5723 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5724 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5726 volatilep = true;
5727 break;
5730 if (! volatilep)
5732 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5733 expand_expr (TREE_VALUE (arg), const0_rtx,
5734 VOIDmode, EXPAND_NORMAL);
5735 return const0_rtx;
5739 switch (fcode)
5741 CASE_FLT_FN (BUILT_IN_FABS):
5742 target = expand_builtin_fabs (arglist, target, subtarget);
5743 if (target)
5744 return target;
5745 break;
5747 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5748 target = expand_builtin_copysign (arglist, target, subtarget);
5749 if (target)
5750 return target;
5751 break;
5753 /* Just do a normal library call if we were unable to fold
5754 the values. */
5755 CASE_FLT_FN (BUILT_IN_CABS):
5756 break;
5758 CASE_FLT_FN (BUILT_IN_EXP):
5759 CASE_FLT_FN (BUILT_IN_EXP10):
5760 CASE_FLT_FN (BUILT_IN_POW10):
5761 CASE_FLT_FN (BUILT_IN_EXP2):
5762 CASE_FLT_FN (BUILT_IN_EXPM1):
5763 CASE_FLT_FN (BUILT_IN_LOGB):
5764 CASE_FLT_FN (BUILT_IN_ILOGB):
5765 CASE_FLT_FN (BUILT_IN_LOG):
5766 CASE_FLT_FN (BUILT_IN_LOG10):
5767 CASE_FLT_FN (BUILT_IN_LOG2):
5768 CASE_FLT_FN (BUILT_IN_LOG1P):
5769 CASE_FLT_FN (BUILT_IN_TAN):
5770 CASE_FLT_FN (BUILT_IN_ASIN):
5771 CASE_FLT_FN (BUILT_IN_ACOS):
5772 CASE_FLT_FN (BUILT_IN_ATAN):
5773 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5774 because of possible accuracy problems. */
5775 if (! flag_unsafe_math_optimizations)
5776 break;
5777 CASE_FLT_FN (BUILT_IN_SQRT):
5778 CASE_FLT_FN (BUILT_IN_FLOOR):
5779 CASE_FLT_FN (BUILT_IN_CEIL):
5780 CASE_FLT_FN (BUILT_IN_TRUNC):
5781 CASE_FLT_FN (BUILT_IN_ROUND):
5782 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5783 CASE_FLT_FN (BUILT_IN_RINT):
5784 target = expand_builtin_mathfn (exp, target, subtarget);
5785 if (target)
5786 return target;
5787 break;
5789 CASE_FLT_FN (BUILT_IN_LCEIL):
5790 CASE_FLT_FN (BUILT_IN_LLCEIL):
5791 CASE_FLT_FN (BUILT_IN_LFLOOR):
5792 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5793 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5794 if (target)
5795 return target;
5796 break;
5798 CASE_FLT_FN (BUILT_IN_LRINT):
5799 CASE_FLT_FN (BUILT_IN_LLRINT):
5800 CASE_FLT_FN (BUILT_IN_LROUND):
5801 CASE_FLT_FN (BUILT_IN_LLROUND):
5802 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5803 if (target)
5804 return target;
5805 break;
5807 CASE_FLT_FN (BUILT_IN_POW):
5808 target = expand_builtin_pow (exp, target, subtarget);
5809 if (target)
5810 return target;
5811 break;
5813 CASE_FLT_FN (BUILT_IN_POWI):
5814 target = expand_builtin_powi (exp, target, subtarget);
5815 if (target)
5816 return target;
5817 break;
5819 CASE_FLT_FN (BUILT_IN_ATAN2):
5820 CASE_FLT_FN (BUILT_IN_LDEXP):
5821 if (! flag_unsafe_math_optimizations)
5822 break;
5824 CASE_FLT_FN (BUILT_IN_FMOD):
5825 CASE_FLT_FN (BUILT_IN_REMAINDER):
5826 CASE_FLT_FN (BUILT_IN_DREM):
5827 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5828 if (target)
5829 return target;
5830 break;
5832 CASE_FLT_FN (BUILT_IN_SIN):
5833 CASE_FLT_FN (BUILT_IN_COS):
5834 if (! flag_unsafe_math_optimizations)
5835 break;
5836 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5837 if (target)
5838 return target;
5839 break;
5841 CASE_FLT_FN (BUILT_IN_SINCOS):
5842 if (! flag_unsafe_math_optimizations)
5843 break;
5844 target = expand_builtin_sincos (exp);
5845 if (target)
5846 return target;
5847 break;
5849 case BUILT_IN_APPLY_ARGS:
5850 return expand_builtin_apply_args ();
5852 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5853 FUNCTION with a copy of the parameters described by
5854 ARGUMENTS, and ARGSIZE. It returns a block of memory
5855 allocated on the stack into which is stored all the registers
5856 that might possibly be used for returning the result of a
5857 function. ARGUMENTS is the value returned by
5858 __builtin_apply_args. ARGSIZE is the number of bytes of
5859 arguments that must be copied. ??? How should this value be
5860 computed? We'll also need a safe worst case value for varargs
5861 functions. */
5862 case BUILT_IN_APPLY:
5863 if (!validate_arglist (arglist, POINTER_TYPE,
5864 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5865 && !validate_arglist (arglist, REFERENCE_TYPE,
5866 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5867 return const0_rtx;
5868 else
5870 int i;
5871 tree t;
5872 rtx ops[3];
5874 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5875 ops[i] = expand_normal (TREE_VALUE (t));
5877 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5880 /* __builtin_return (RESULT) causes the function to return the
5881 value described by RESULT. RESULT is address of the block of
5882 memory returned by __builtin_apply. */
5883 case BUILT_IN_RETURN:
5884 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5885 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5886 return const0_rtx;
5888 case BUILT_IN_SAVEREGS:
5889 return expand_builtin_saveregs ();
5891 case BUILT_IN_ARGS_INFO:
5892 return expand_builtin_args_info (arglist);
5894 /* Return the address of the first anonymous stack arg. */
5895 case BUILT_IN_NEXT_ARG:
5896 if (fold_builtin_next_arg (arglist))
5897 return const0_rtx;
5898 return expand_builtin_next_arg ();
5900 case BUILT_IN_CLASSIFY_TYPE:
5901 return expand_builtin_classify_type (arglist);
5903 case BUILT_IN_CONSTANT_P:
5904 return const0_rtx;
5906 case BUILT_IN_FRAME_ADDRESS:
5907 case BUILT_IN_RETURN_ADDRESS:
5908 return expand_builtin_frame_address (fndecl, arglist);
5910 /* Returns the address of the area where the structure is returned.
5911 0 otherwise. */
5912 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5913 if (arglist != 0
5914 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5915 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5916 return const0_rtx;
5917 else
5918 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5920 case BUILT_IN_ALLOCA:
5921 target = expand_builtin_alloca (arglist, target);
5922 if (target)
5923 return target;
5924 break;
5926 case BUILT_IN_STACK_SAVE:
5927 return expand_stack_save ();
5929 case BUILT_IN_STACK_RESTORE:
5930 expand_stack_restore (TREE_VALUE (arglist));
5931 return const0_rtx;
5933 case BUILT_IN_BSWAP32:
5934 case BUILT_IN_BSWAP64:
5935 target = expand_builtin_bswap (arglist, target, subtarget);
5937 if (target)
5938 return target;
5939 break;
5941 CASE_INT_FN (BUILT_IN_FFS):
5942 case BUILT_IN_FFSIMAX:
5943 target = expand_builtin_unop (target_mode, arglist, target,
5944 subtarget, ffs_optab);
5945 if (target)
5946 return target;
5947 break;
5949 CASE_INT_FN (BUILT_IN_CLZ):
5950 case BUILT_IN_CLZIMAX:
5951 target = expand_builtin_unop (target_mode, arglist, target,
5952 subtarget, clz_optab);
5953 if (target)
5954 return target;
5955 break;
5957 CASE_INT_FN (BUILT_IN_CTZ):
5958 case BUILT_IN_CTZIMAX:
5959 target = expand_builtin_unop (target_mode, arglist, target,
5960 subtarget, ctz_optab);
5961 if (target)
5962 return target;
5963 break;
5965 CASE_INT_FN (BUILT_IN_POPCOUNT):
5966 case BUILT_IN_POPCOUNTIMAX:
5967 target = expand_builtin_unop (target_mode, arglist, target,
5968 subtarget, popcount_optab);
5969 if (target)
5970 return target;
5971 break;
5973 CASE_INT_FN (BUILT_IN_PARITY):
5974 case BUILT_IN_PARITYIMAX:
5975 target = expand_builtin_unop (target_mode, arglist, target,
5976 subtarget, parity_optab);
5977 if (target)
5978 return target;
5979 break;
5981 case BUILT_IN_STRLEN:
5982 target = expand_builtin_strlen (arglist, target, target_mode);
5983 if (target)
5984 return target;
5985 break;
5987 case BUILT_IN_STRCPY:
5988 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5989 if (target)
5990 return target;
5991 break;
5993 case BUILT_IN_STRNCPY:
5994 target = expand_builtin_strncpy (exp, target, mode);
5995 if (target)
5996 return target;
5997 break;
5999 case BUILT_IN_STPCPY:
6000 target = expand_builtin_stpcpy (exp, target, mode);
6001 if (target)
6002 return target;
6003 break;
6005 case BUILT_IN_STRCAT:
6006 target = expand_builtin_strcat (fndecl, arglist, target, mode);
6007 if (target)
6008 return target;
6009 break;
6011 case BUILT_IN_STRNCAT:
6012 target = expand_builtin_strncat (arglist, target, mode);
6013 if (target)
6014 return target;
6015 break;
6017 case BUILT_IN_STRSPN:
6018 target = expand_builtin_strspn (arglist, target, mode);
6019 if (target)
6020 return target;
6021 break;
6023 case BUILT_IN_STRCSPN:
6024 target = expand_builtin_strcspn (arglist, target, mode);
6025 if (target)
6026 return target;
6027 break;
6029 case BUILT_IN_STRSTR:
6030 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6031 if (target)
6032 return target;
6033 break;
6035 case BUILT_IN_STRPBRK:
6036 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6037 if (target)
6038 return target;
6039 break;
6041 case BUILT_IN_INDEX:
6042 case BUILT_IN_STRCHR:
6043 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6044 if (target)
6045 return target;
6046 break;
6048 case BUILT_IN_RINDEX:
6049 case BUILT_IN_STRRCHR:
6050 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6051 if (target)
6052 return target;
6053 break;
6055 case BUILT_IN_MEMCPY:
6056 target = expand_builtin_memcpy (exp, target, mode);
6057 if (target)
6058 return target;
6059 break;
6061 case BUILT_IN_MEMPCPY:
6062 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6063 if (target)
6064 return target;
6065 break;
6067 case BUILT_IN_MEMMOVE:
6068 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6069 mode);
6070 if (target)
6071 return target;
6072 break;
6074 case BUILT_IN_BCOPY:
6075 target = expand_builtin_bcopy (exp);
6076 if (target)
6077 return target;
6078 break;
6080 case BUILT_IN_MEMSET:
6081 target = expand_builtin_memset (arglist, target, mode, exp);
6082 if (target)
6083 return target;
6084 break;
6086 case BUILT_IN_BZERO:
6087 target = expand_builtin_bzero (exp);
6088 if (target)
6089 return target;
6090 break;
6092 case BUILT_IN_STRCMP:
6093 target = expand_builtin_strcmp (exp, target, mode);
6094 if (target)
6095 return target;
6096 break;
6098 case BUILT_IN_STRNCMP:
6099 target = expand_builtin_strncmp (exp, target, mode);
6100 if (target)
6101 return target;
6102 break;
6104 case BUILT_IN_BCMP:
6105 case BUILT_IN_MEMCMP:
6106 target = expand_builtin_memcmp (exp, arglist, target, mode);
6107 if (target)
6108 return target;
6109 break;
6111 case BUILT_IN_SETJMP:
6112 /* This should have been lowered to the builtins below. */
6113 gcc_unreachable ();
6115 case BUILT_IN_SETJMP_SETUP:
6116 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6117 and the receiver label. */
6118 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6120 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6121 VOIDmode, EXPAND_NORMAL);
6122 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6123 rtx label_r = label_rtx (label);
6125 /* This is copied from the handling of non-local gotos. */
6126 expand_builtin_setjmp_setup (buf_addr, label_r);
6127 nonlocal_goto_handler_labels
6128 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6129 nonlocal_goto_handler_labels);
6130 /* ??? Do not let expand_label treat us as such since we would
6131 not want to be both on the list of non-local labels and on
6132 the list of forced labels. */
6133 FORCED_LABEL (label) = 0;
6134 return const0_rtx;
6136 break;
6138 case BUILT_IN_SETJMP_DISPATCHER:
6139 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6140 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6142 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6143 rtx label_r = label_rtx (label);
6145 /* Remove the dispatcher label from the list of non-local labels
6146 since the receiver labels have been added to it above. */
6147 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6148 return const0_rtx;
6150 break;
6152 case BUILT_IN_SETJMP_RECEIVER:
6153 /* __builtin_setjmp_receiver is passed the receiver label. */
6154 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6156 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6157 rtx label_r = label_rtx (label);
6159 expand_builtin_setjmp_receiver (label_r);
6160 return const0_rtx;
6162 break;
6164 /* __builtin_longjmp is passed a pointer to an array of five words.
6165 It's similar to the C library longjmp function but works with
6166 __builtin_setjmp above. */
6167 case BUILT_IN_LONGJMP:
6168 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6170 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6171 VOIDmode, EXPAND_NORMAL);
6172 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6174 if (value != const1_rtx)
6176 error ("%<__builtin_longjmp%> second argument must be 1");
6177 return const0_rtx;
6180 expand_builtin_longjmp (buf_addr, value);
6181 return const0_rtx;
6183 break;
6185 case BUILT_IN_NONLOCAL_GOTO:
6186 target = expand_builtin_nonlocal_goto (arglist);
6187 if (target)
6188 return target;
6189 break;
6191 /* This updates the setjmp buffer that is its argument with the value
6192 of the current stack pointer. */
6193 case BUILT_IN_UPDATE_SETJMP_BUF:
6194 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6196 rtx buf_addr
6197 = expand_normal (TREE_VALUE (arglist));
6199 expand_builtin_update_setjmp_buf (buf_addr);
6200 return const0_rtx;
6202 break;
6204 case BUILT_IN_TRAP:
6205 expand_builtin_trap ();
6206 return const0_rtx;
6208 case BUILT_IN_PRINTF:
6209 target = expand_builtin_printf (exp, target, mode, false);
6210 if (target)
6211 return target;
6212 break;
6214 case BUILT_IN_PRINTF_UNLOCKED:
6215 target = expand_builtin_printf (exp, target, mode, true);
6216 if (target)
6217 return target;
6218 break;
6220 case BUILT_IN_FPUTS:
6221 target = expand_builtin_fputs (arglist, target, false);
6222 if (target)
6223 return target;
6224 break;
6225 case BUILT_IN_FPUTS_UNLOCKED:
6226 target = expand_builtin_fputs (arglist, target, true);
6227 if (target)
6228 return target;
6229 break;
6231 case BUILT_IN_FPRINTF:
6232 target = expand_builtin_fprintf (exp, target, mode, false);
6233 if (target)
6234 return target;
6235 break;
6237 case BUILT_IN_FPRINTF_UNLOCKED:
6238 target = expand_builtin_fprintf (exp, target, mode, true);
6239 if (target)
6240 return target;
6241 break;
6243 case BUILT_IN_SPRINTF:
6244 target = expand_builtin_sprintf (arglist, target, mode);
6245 if (target)
6246 return target;
6247 break;
6249 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6250 target = expand_builtin_signbit (exp, target);
6251 if (target)
6252 return target;
6253 break;
6255 /* Various hooks for the DWARF 2 __throw routine. */
6256 case BUILT_IN_UNWIND_INIT:
6257 expand_builtin_unwind_init ();
6258 return const0_rtx;
6259 case BUILT_IN_DWARF_CFA:
6260 return virtual_cfa_rtx;
6261 #ifdef DWARF2_UNWIND_INFO
6262 case BUILT_IN_DWARF_SP_COLUMN:
6263 return expand_builtin_dwarf_sp_column ();
6264 case BUILT_IN_INIT_DWARF_REG_SIZES:
6265 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6266 return const0_rtx;
6267 #endif
6268 case BUILT_IN_FROB_RETURN_ADDR:
6269 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6270 case BUILT_IN_EXTRACT_RETURN_ADDR:
6271 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6272 case BUILT_IN_EH_RETURN:
6273 expand_builtin_eh_return (TREE_VALUE (arglist),
6274 TREE_VALUE (TREE_CHAIN (arglist)));
6275 return const0_rtx;
6276 #ifdef EH_RETURN_DATA_REGNO
6277 case BUILT_IN_EH_RETURN_DATA_REGNO:
6278 return expand_builtin_eh_return_data_regno (arglist);
6279 #endif
6280 case BUILT_IN_EXTEND_POINTER:
6281 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6283 case BUILT_IN_VA_START:
6284 case BUILT_IN_STDARG_START:
6285 return expand_builtin_va_start (arglist);
6286 case BUILT_IN_VA_END:
6287 return expand_builtin_va_end (arglist);
6288 case BUILT_IN_VA_COPY:
6289 return expand_builtin_va_copy (arglist);
6290 case BUILT_IN_EXPECT:
6291 return expand_builtin_expect (arglist, target);
6292 case BUILT_IN_PREFETCH:
6293 expand_builtin_prefetch (arglist);
6294 return const0_rtx;
6296 case BUILT_IN_PROFILE_FUNC_ENTER:
6297 return expand_builtin_profile_func (false);
6298 case BUILT_IN_PROFILE_FUNC_EXIT:
6299 return expand_builtin_profile_func (true);
6301 case BUILT_IN_INIT_TRAMPOLINE:
6302 return expand_builtin_init_trampoline (arglist);
6303 case BUILT_IN_ADJUST_TRAMPOLINE:
6304 return expand_builtin_adjust_trampoline (arglist);
6306 case BUILT_IN_FORK:
6307 case BUILT_IN_EXECL:
6308 case BUILT_IN_EXECV:
6309 case BUILT_IN_EXECLP:
6310 case BUILT_IN_EXECLE:
6311 case BUILT_IN_EXECVP:
6312 case BUILT_IN_EXECVE:
6313 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6314 if (target)
6315 return target;
6316 break;
6318 case BUILT_IN_FETCH_AND_ADD_1:
6319 case BUILT_IN_FETCH_AND_ADD_2:
6320 case BUILT_IN_FETCH_AND_ADD_4:
6321 case BUILT_IN_FETCH_AND_ADD_8:
6322 case BUILT_IN_FETCH_AND_ADD_16:
6323 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6324 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6325 false, target, ignore);
6326 if (target)
6327 return target;
6328 break;
6330 case BUILT_IN_FETCH_AND_SUB_1:
6331 case BUILT_IN_FETCH_AND_SUB_2:
6332 case BUILT_IN_FETCH_AND_SUB_4:
6333 case BUILT_IN_FETCH_AND_SUB_8:
6334 case BUILT_IN_FETCH_AND_SUB_16:
6335 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6336 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6337 false, target, ignore);
6338 if (target)
6339 return target;
6340 break;
6342 case BUILT_IN_FETCH_AND_OR_1:
6343 case BUILT_IN_FETCH_AND_OR_2:
6344 case BUILT_IN_FETCH_AND_OR_4:
6345 case BUILT_IN_FETCH_AND_OR_8:
6346 case BUILT_IN_FETCH_AND_OR_16:
6347 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6348 target = expand_builtin_sync_operation (mode, arglist, IOR,
6349 false, target, ignore);
6350 if (target)
6351 return target;
6352 break;
6354 case BUILT_IN_FETCH_AND_AND_1:
6355 case BUILT_IN_FETCH_AND_AND_2:
6356 case BUILT_IN_FETCH_AND_AND_4:
6357 case BUILT_IN_FETCH_AND_AND_8:
6358 case BUILT_IN_FETCH_AND_AND_16:
6359 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6360 target = expand_builtin_sync_operation (mode, arglist, AND,
6361 false, target, ignore);
6362 if (target)
6363 return target;
6364 break;
6366 case BUILT_IN_FETCH_AND_XOR_1:
6367 case BUILT_IN_FETCH_AND_XOR_2:
6368 case BUILT_IN_FETCH_AND_XOR_4:
6369 case BUILT_IN_FETCH_AND_XOR_8:
6370 case BUILT_IN_FETCH_AND_XOR_16:
6371 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6372 target = expand_builtin_sync_operation (mode, arglist, XOR,
6373 false, target, ignore);
6374 if (target)
6375 return target;
6376 break;
6378 case BUILT_IN_FETCH_AND_NAND_1:
6379 case BUILT_IN_FETCH_AND_NAND_2:
6380 case BUILT_IN_FETCH_AND_NAND_4:
6381 case BUILT_IN_FETCH_AND_NAND_8:
6382 case BUILT_IN_FETCH_AND_NAND_16:
6383 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6384 target = expand_builtin_sync_operation (mode, arglist, NOT,
6385 false, target, ignore);
6386 if (target)
6387 return target;
6388 break;
6390 case BUILT_IN_ADD_AND_FETCH_1:
6391 case BUILT_IN_ADD_AND_FETCH_2:
6392 case BUILT_IN_ADD_AND_FETCH_4:
6393 case BUILT_IN_ADD_AND_FETCH_8:
6394 case BUILT_IN_ADD_AND_FETCH_16:
6395 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6396 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6397 true, target, ignore);
6398 if (target)
6399 return target;
6400 break;
6402 case BUILT_IN_SUB_AND_FETCH_1:
6403 case BUILT_IN_SUB_AND_FETCH_2:
6404 case BUILT_IN_SUB_AND_FETCH_4:
6405 case BUILT_IN_SUB_AND_FETCH_8:
6406 case BUILT_IN_SUB_AND_FETCH_16:
6407 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6408 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6409 true, target, ignore);
6410 if (target)
6411 return target;
6412 break;
6414 case BUILT_IN_OR_AND_FETCH_1:
6415 case BUILT_IN_OR_AND_FETCH_2:
6416 case BUILT_IN_OR_AND_FETCH_4:
6417 case BUILT_IN_OR_AND_FETCH_8:
6418 case BUILT_IN_OR_AND_FETCH_16:
6419 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6420 target = expand_builtin_sync_operation (mode, arglist, IOR,
6421 true, target, ignore);
6422 if (target)
6423 return target;
6424 break;
6426 case BUILT_IN_AND_AND_FETCH_1:
6427 case BUILT_IN_AND_AND_FETCH_2:
6428 case BUILT_IN_AND_AND_FETCH_4:
6429 case BUILT_IN_AND_AND_FETCH_8:
6430 case BUILT_IN_AND_AND_FETCH_16:
6431 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6432 target = expand_builtin_sync_operation (mode, arglist, AND,
6433 true, target, ignore);
6434 if (target)
6435 return target;
6436 break;
6438 case BUILT_IN_XOR_AND_FETCH_1:
6439 case BUILT_IN_XOR_AND_FETCH_2:
6440 case BUILT_IN_XOR_AND_FETCH_4:
6441 case BUILT_IN_XOR_AND_FETCH_8:
6442 case BUILT_IN_XOR_AND_FETCH_16:
6443 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6444 target = expand_builtin_sync_operation (mode, arglist, XOR,
6445 true, target, ignore);
6446 if (target)
6447 return target;
6448 break;
6450 case BUILT_IN_NAND_AND_FETCH_1:
6451 case BUILT_IN_NAND_AND_FETCH_2:
6452 case BUILT_IN_NAND_AND_FETCH_4:
6453 case BUILT_IN_NAND_AND_FETCH_8:
6454 case BUILT_IN_NAND_AND_FETCH_16:
6455 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6456 target = expand_builtin_sync_operation (mode, arglist, NOT,
6457 true, target, ignore);
6458 if (target)
6459 return target;
6460 break;
6462 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6463 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6464 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6465 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6466 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6467 if (mode == VOIDmode)
6468 mode = TYPE_MODE (boolean_type_node);
6469 if (!target || !register_operand (target, mode))
6470 target = gen_reg_rtx (mode);
6472 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6473 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6474 if (target)
6475 return target;
6476 break;
6478 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6479 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6480 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6481 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6482 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6483 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6484 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6485 if (target)
6486 return target;
6487 break;
6489 case BUILT_IN_LOCK_TEST_AND_SET_1:
6490 case BUILT_IN_LOCK_TEST_AND_SET_2:
6491 case BUILT_IN_LOCK_TEST_AND_SET_4:
6492 case BUILT_IN_LOCK_TEST_AND_SET_8:
6493 case BUILT_IN_LOCK_TEST_AND_SET_16:
6494 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6495 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6496 if (target)
6497 return target;
6498 break;
6500 case BUILT_IN_LOCK_RELEASE_1:
6501 case BUILT_IN_LOCK_RELEASE_2:
6502 case BUILT_IN_LOCK_RELEASE_4:
6503 case BUILT_IN_LOCK_RELEASE_8:
6504 case BUILT_IN_LOCK_RELEASE_16:
6505 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6506 expand_builtin_lock_release (mode, arglist);
6507 return const0_rtx;
6509 case BUILT_IN_SYNCHRONIZE:
6510 expand_builtin_synchronize ();
6511 return const0_rtx;
6513 case BUILT_IN_OBJECT_SIZE:
6514 return expand_builtin_object_size (exp);
6516 case BUILT_IN_MEMCPY_CHK:
6517 case BUILT_IN_MEMPCPY_CHK:
6518 case BUILT_IN_MEMMOVE_CHK:
6519 case BUILT_IN_MEMSET_CHK:
6520 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6521 if (target)
6522 return target;
6523 break;
6525 case BUILT_IN_STRCPY_CHK:
6526 case BUILT_IN_STPCPY_CHK:
6527 case BUILT_IN_STRNCPY_CHK:
6528 case BUILT_IN_STRCAT_CHK:
6529 case BUILT_IN_STRNCAT_CHK:
6530 case BUILT_IN_SNPRINTF_CHK:
6531 case BUILT_IN_VSNPRINTF_CHK:
6532 maybe_emit_chk_warning (exp, fcode);
6533 break;
6535 case BUILT_IN_SPRINTF_CHK:
6536 case BUILT_IN_VSPRINTF_CHK:
6537 maybe_emit_sprintf_chk_warning (exp, fcode);
6538 break;
6540 default: /* just do library call, if unknown builtin */
6541 break;
6544 /* The switch statement above can drop through to cause the function
6545 to be called normally. */
6546 return expand_call (exp, target, ignore);
6549 /* Determine whether a tree node represents a call to a built-in
6550 function. If the tree T is a call to a built-in function with
6551 the right number of arguments of the appropriate types, return
6552 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6553 Otherwise the return value is END_BUILTINS. */
6555 enum built_in_function
6556 builtin_mathfn_code (tree t)
6558 tree fndecl, arglist, parmlist;
6559 tree argtype, parmtype;
6561 if (TREE_CODE (t) != CALL_EXPR
6562 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6563 return END_BUILTINS;
6565 fndecl = get_callee_fndecl (t);
6566 if (fndecl == NULL_TREE
6567 || TREE_CODE (fndecl) != FUNCTION_DECL
6568 || ! DECL_BUILT_IN (fndecl)
6569 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6570 return END_BUILTINS;
6572 arglist = TREE_OPERAND (t, 1);
6573 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6574 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6576 /* If a function doesn't take a variable number of arguments,
6577 the last element in the list will have type `void'. */
6578 parmtype = TREE_VALUE (parmlist);
6579 if (VOID_TYPE_P (parmtype))
6581 if (arglist)
6582 return END_BUILTINS;
6583 return DECL_FUNCTION_CODE (fndecl);
6586 if (! arglist)
6587 return END_BUILTINS;
6589 argtype = TREE_TYPE (TREE_VALUE (arglist));
6591 if (SCALAR_FLOAT_TYPE_P (parmtype))
6593 if (! SCALAR_FLOAT_TYPE_P (argtype))
6594 return END_BUILTINS;
6596 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6598 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6599 return END_BUILTINS;
6601 else if (POINTER_TYPE_P (parmtype))
6603 if (! POINTER_TYPE_P (argtype))
6604 return END_BUILTINS;
6606 else if (INTEGRAL_TYPE_P (parmtype))
6608 if (! INTEGRAL_TYPE_P (argtype))
6609 return END_BUILTINS;
6611 else
6612 return END_BUILTINS;
6614 arglist = TREE_CHAIN (arglist);
6617 /* Variable-length argument list. */
6618 return DECL_FUNCTION_CODE (fndecl);
6621 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6622 constant. ARGLIST is the argument list of the call. */
6624 static tree
6625 fold_builtin_constant_p (tree arglist)
6627 if (arglist == 0)
6628 return 0;
6630 arglist = TREE_VALUE (arglist);
6632 /* We return 1 for a numeric type that's known to be a constant
6633 value at compile-time or for an aggregate type that's a
6634 literal constant. */
6635 STRIP_NOPS (arglist);
6637 /* If we know this is a constant, emit the constant of one. */
6638 if (CONSTANT_CLASS_P (arglist)
6639 || (TREE_CODE (arglist) == CONSTRUCTOR
6640 && TREE_CONSTANT (arglist)))
6641 return integer_one_node;
6642 if (TREE_CODE (arglist) == ADDR_EXPR)
6644 tree op = TREE_OPERAND (arglist, 0);
6645 if (TREE_CODE (op) == STRING_CST
6646 || (TREE_CODE (op) == ARRAY_REF
6647 && integer_zerop (TREE_OPERAND (op, 1))
6648 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6649 return integer_one_node;
6652 /* If this expression has side effects, show we don't know it to be a
6653 constant. Likewise if it's a pointer or aggregate type since in
6654 those case we only want literals, since those are only optimized
6655 when generating RTL, not later.
6656 And finally, if we are compiling an initializer, not code, we
6657 need to return a definite result now; there's not going to be any
6658 more optimization done. */
6659 if (TREE_SIDE_EFFECTS (arglist)
6660 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6661 || POINTER_TYPE_P (TREE_TYPE (arglist))
6662 || cfun == 0
6663 || folding_initializer)
6664 return integer_zero_node;
6666 return 0;
6669 /* Fold a call to __builtin_expect, if we expect that a comparison against
6670 the argument will fold to a constant. In practice, this means a true
6671 constant or the address of a non-weak symbol. ARGLIST is the argument
6672 list of the call. */
6674 static tree
6675 fold_builtin_expect (tree arglist)
6677 tree arg, inner;
6679 if (arglist == 0)
6680 return 0;
6682 arg = TREE_VALUE (arglist);
6684 /* If the argument isn't invariant, then there's nothing we can do. */
6685 if (!TREE_INVARIANT (arg))
6686 return 0;
6688 /* If we're looking at an address of a weak decl, then do not fold. */
6689 inner = arg;
6690 STRIP_NOPS (inner);
6691 if (TREE_CODE (inner) == ADDR_EXPR)
6695 inner = TREE_OPERAND (inner, 0);
6697 while (TREE_CODE (inner) == COMPONENT_REF
6698 || TREE_CODE (inner) == ARRAY_REF);
6699 if (DECL_P (inner) && DECL_WEAK (inner))
6700 return 0;
6703 /* Otherwise, ARG already has the proper type for the return value. */
6704 return arg;
6707 /* Fold a call to __builtin_classify_type. */
6709 static tree
6710 fold_builtin_classify_type (tree arglist)
6712 if (arglist == 0)
6713 return build_int_cst (NULL_TREE, no_type_class);
6715 return build_int_cst (NULL_TREE,
6716 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6719 /* Fold a call to __builtin_strlen. */
6721 static tree
6722 fold_builtin_strlen (tree arglist)
6724 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6725 return NULL_TREE;
6726 else
6728 tree len = c_strlen (TREE_VALUE (arglist), 0);
6730 if (len)
6732 /* Convert from the internal "sizetype" type to "size_t". */
6733 if (size_type_node)
6734 len = fold_convert (size_type_node, len);
6735 return len;
6738 return NULL_TREE;
6742 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6744 static tree
6745 fold_builtin_inf (tree type, int warn)
6747 REAL_VALUE_TYPE real;
6749 /* __builtin_inff is intended to be usable to define INFINITY on all
6750 targets. If an infinity is not available, INFINITY expands "to a
6751 positive constant of type float that overflows at translation
6752 time", footnote "In this case, using INFINITY will violate the
6753 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6754 Thus we pedwarn to ensure this constraint violation is
6755 diagnosed. */
6756 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6757 pedwarn ("target format does not support infinity");
6759 real_inf (&real);
6760 return build_real (type, real);
6763 /* Fold a call to __builtin_nan or __builtin_nans. */
6765 static tree
6766 fold_builtin_nan (tree arglist, tree type, int quiet)
6768 REAL_VALUE_TYPE real;
6769 const char *str;
6771 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6772 return 0;
6773 str = c_getstr (TREE_VALUE (arglist));
6774 if (!str)
6775 return 0;
6777 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6778 return 0;
6780 return build_real (type, real);
6783 /* Return true if the floating point expression T has an integer value.
6784 We also allow +Inf, -Inf and NaN to be considered integer values. */
6786 static bool
6787 integer_valued_real_p (tree t)
6789 switch (TREE_CODE (t))
6791 case FLOAT_EXPR:
6792 return true;
6794 case ABS_EXPR:
6795 case SAVE_EXPR:
6796 case NON_LVALUE_EXPR:
6797 return integer_valued_real_p (TREE_OPERAND (t, 0));
6799 case COMPOUND_EXPR:
6800 case MODIFY_EXPR:
6801 case BIND_EXPR:
6802 return integer_valued_real_p (TREE_OPERAND (t, 1));
6804 case PLUS_EXPR:
6805 case MINUS_EXPR:
6806 case MULT_EXPR:
6807 case MIN_EXPR:
6808 case MAX_EXPR:
6809 return integer_valued_real_p (TREE_OPERAND (t, 0))
6810 && integer_valued_real_p (TREE_OPERAND (t, 1));
6812 case COND_EXPR:
6813 return integer_valued_real_p (TREE_OPERAND (t, 1))
6814 && integer_valued_real_p (TREE_OPERAND (t, 2));
6816 case REAL_CST:
6817 if (! TREE_CONSTANT_OVERFLOW (t))
6819 REAL_VALUE_TYPE c, cint;
6821 c = TREE_REAL_CST (t);
6822 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6823 return real_identical (&c, &cint);
6825 break;
6827 case NOP_EXPR:
6829 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6830 if (TREE_CODE (type) == INTEGER_TYPE)
6831 return true;
6832 if (TREE_CODE (type) == REAL_TYPE)
6833 return integer_valued_real_p (TREE_OPERAND (t, 0));
6834 break;
6837 case CALL_EXPR:
6838 switch (builtin_mathfn_code (t))
6840 CASE_FLT_FN (BUILT_IN_CEIL):
6841 CASE_FLT_FN (BUILT_IN_FLOOR):
6842 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6843 CASE_FLT_FN (BUILT_IN_RINT):
6844 CASE_FLT_FN (BUILT_IN_ROUND):
6845 CASE_FLT_FN (BUILT_IN_TRUNC):
6846 return true;
6848 default:
6849 break;
6851 break;
6853 default:
6854 break;
6856 return false;
6859 /* EXP is assumed to be builtin call where truncation can be propagated
6860 across (for instance floor((double)f) == (double)floorf (f).
6861 Do the transformation. */
6863 static tree
6864 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6866 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6867 tree arg;
6869 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6870 return 0;
6872 arg = TREE_VALUE (arglist);
6873 /* Integer rounding functions are idempotent. */
6874 if (fcode == builtin_mathfn_code (arg))
6875 return arg;
6877 /* If argument is already integer valued, and we don't need to worry
6878 about setting errno, there's no need to perform rounding. */
6879 if (! flag_errno_math && integer_valued_real_p (arg))
6880 return arg;
6882 if (optimize)
6884 tree arg0 = strip_float_extensions (arg);
6885 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6886 tree newtype = TREE_TYPE (arg0);
6887 tree decl;
6889 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6890 && (decl = mathfn_built_in (newtype, fcode)))
6892 arglist =
6893 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6894 return fold_convert (ftype,
6895 build_function_call_expr (decl, arglist));
6898 return 0;
6901 /* EXP is assumed to be builtin call which can narrow the FP type of
6902 the argument, for instance lround((double)f) -> lroundf (f). */
6904 static tree
6905 fold_fixed_mathfn (tree fndecl, tree arglist)
6907 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6908 tree arg;
6910 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6911 return 0;
6913 arg = TREE_VALUE (arglist);
6915 /* If argument is already integer valued, and we don't need to worry
6916 about setting errno, there's no need to perform rounding. */
6917 if (! flag_errno_math && integer_valued_real_p (arg))
6918 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6920 if (optimize)
6922 tree ftype = TREE_TYPE (arg);
6923 tree arg0 = strip_float_extensions (arg);
6924 tree newtype = TREE_TYPE (arg0);
6925 tree decl;
6927 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6928 && (decl = mathfn_built_in (newtype, fcode)))
6930 arglist =
6931 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6932 return build_function_call_expr (decl, arglist);
6936 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6937 sizeof (long long) == sizeof (long). */
6938 if (TYPE_PRECISION (long_long_integer_type_node)
6939 == TYPE_PRECISION (long_integer_type_node))
6941 tree newfn = NULL_TREE;
6942 switch (fcode)
6944 CASE_FLT_FN (BUILT_IN_LLCEIL):
6945 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6946 break;
6948 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6949 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6950 break;
6952 CASE_FLT_FN (BUILT_IN_LLROUND):
6953 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6954 break;
6956 CASE_FLT_FN (BUILT_IN_LLRINT):
6957 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6958 break;
6960 default:
6961 break;
6964 if (newfn)
6966 tree newcall = build_function_call_expr (newfn, arglist);
6967 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6971 return 0;
6974 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6975 is the argument list, TYPE is the return type and FNDECL is the
6976 original function DECL. Return NULL_TREE if no if no simplification
6977 can be made. */
6979 static tree
6980 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6982 tree arg;
6984 if (!arglist || TREE_CHAIN (arglist))
6985 return NULL_TREE;
6987 arg = TREE_VALUE (arglist);
6988 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6989 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6990 return NULL_TREE;
6992 /* Evaluate cabs of a constant at compile-time. */
6993 if (flag_unsafe_math_optimizations
6994 && TREE_CODE (arg) == COMPLEX_CST
6995 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6996 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6997 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6998 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
7000 REAL_VALUE_TYPE r, i;
7002 r = TREE_REAL_CST (TREE_REALPART (arg));
7003 i = TREE_REAL_CST (TREE_IMAGPART (arg));
7005 real_arithmetic (&r, MULT_EXPR, &r, &r);
7006 real_arithmetic (&i, MULT_EXPR, &i, &i);
7007 real_arithmetic (&r, PLUS_EXPR, &r, &i);
7008 if (real_sqrt (&r, TYPE_MODE (type), &r)
7009 || ! flag_trapping_math)
7010 return build_real (type, r);
7013 /* If either part is zero, cabs is fabs of the other. */
7014 if (TREE_CODE (arg) == COMPLEX_EXPR
7015 && real_zerop (TREE_OPERAND (arg, 0)))
7016 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
7017 if (TREE_CODE (arg) == COMPLEX_EXPR
7018 && real_zerop (TREE_OPERAND (arg, 1)))
7019 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
7021 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7022 if (TREE_CODE (arg) == NEGATE_EXPR
7023 || TREE_CODE (arg) == CONJ_EXPR)
7025 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
7026 return build_function_call_expr (fndecl, arglist);
7029 /* Don't do this when optimizing for size. */
7030 if (flag_unsafe_math_optimizations
7031 && optimize && !optimize_size)
7033 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7035 if (sqrtfn != NULL_TREE)
7037 tree rpart, ipart, result, arglist;
7039 arg = builtin_save_expr (arg);
7041 rpart = fold_build1 (REALPART_EXPR, type, arg);
7042 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7044 rpart = builtin_save_expr (rpart);
7045 ipart = builtin_save_expr (ipart);
7047 result = fold_build2 (PLUS_EXPR, type,
7048 fold_build2 (MULT_EXPR, type,
7049 rpart, rpart),
7050 fold_build2 (MULT_EXPR, type,
7051 ipart, ipart));
7053 arglist = build_tree_list (NULL_TREE, result);
7054 return build_function_call_expr (sqrtfn, arglist);
7058 return NULL_TREE;
7061 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7062 NULL_TREE if no simplification can be made. */
7064 static tree
7065 fold_builtin_sqrt (tree arglist, tree type)
7068 enum built_in_function fcode;
7069 tree arg = TREE_VALUE (arglist);
7071 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7072 return NULL_TREE;
7074 /* Optimize sqrt of constant value. */
7075 if (TREE_CODE (arg) == REAL_CST
7076 && ! TREE_CONSTANT_OVERFLOW (arg))
7078 REAL_VALUE_TYPE r, x;
7080 x = TREE_REAL_CST (arg);
7081 if (real_sqrt (&r, TYPE_MODE (type), &x)
7082 || (!flag_trapping_math && !flag_errno_math))
7083 return build_real (type, r);
7086 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7087 fcode = builtin_mathfn_code (arg);
7088 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7090 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7091 arg = fold_build2 (MULT_EXPR, type,
7092 TREE_VALUE (TREE_OPERAND (arg, 1)),
7093 build_real (type, dconsthalf));
7094 arglist = build_tree_list (NULL_TREE, arg);
7095 return build_function_call_expr (expfn, arglist);
7098 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7099 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7101 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7103 if (powfn)
7105 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7106 tree tree_root;
7107 /* The inner root was either sqrt or cbrt. */
7108 REAL_VALUE_TYPE dconstroot =
7109 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7111 /* Adjust for the outer root. */
7112 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7113 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7114 tree_root = build_real (type, dconstroot);
7115 arglist = tree_cons (NULL_TREE, arg0,
7116 build_tree_list (NULL_TREE, tree_root));
7117 return build_function_call_expr (powfn, arglist);
7121 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7122 if (flag_unsafe_math_optimizations
7123 && (fcode == BUILT_IN_POW
7124 || fcode == BUILT_IN_POWF
7125 || fcode == BUILT_IN_POWL))
7127 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7128 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7129 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7130 tree narg1;
7131 if (!tree_expr_nonnegative_p (arg0))
7132 arg0 = build1 (ABS_EXPR, type, arg0);
7133 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7134 build_real (type, dconsthalf));
7135 arglist = tree_cons (NULL_TREE, arg0,
7136 build_tree_list (NULL_TREE, narg1));
7137 return build_function_call_expr (powfn, arglist);
7140 return NULL_TREE;
7143 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7144 NULL_TREE if no simplification can be made. */
7145 static tree
7146 fold_builtin_cbrt (tree arglist, tree type)
7148 tree arg = TREE_VALUE (arglist);
7149 const enum built_in_function fcode = builtin_mathfn_code (arg);
7150 tree res;
7152 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7153 return NULL_TREE;
7155 /* Calculate the result when the argument is a constant. */
7156 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7157 return res;
7159 if (flag_unsafe_math_optimizations)
7161 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7162 if (BUILTIN_EXPONENT_P (fcode))
7164 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7165 const REAL_VALUE_TYPE third_trunc =
7166 real_value_truncate (TYPE_MODE (type), dconstthird);
7167 arg = fold_build2 (MULT_EXPR, type,
7168 TREE_VALUE (TREE_OPERAND (arg, 1)),
7169 build_real (type, third_trunc));
7170 arglist = build_tree_list (NULL_TREE, arg);
7171 return build_function_call_expr (expfn, arglist);
7174 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7175 if (BUILTIN_SQRT_P (fcode))
7177 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7179 if (powfn)
7181 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7182 tree tree_root;
7183 REAL_VALUE_TYPE dconstroot = dconstthird;
7185 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7186 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7187 tree_root = build_real (type, dconstroot);
7188 arglist = tree_cons (NULL_TREE, arg0,
7189 build_tree_list (NULL_TREE, tree_root));
7190 return build_function_call_expr (powfn, arglist);
7194 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7195 if (BUILTIN_CBRT_P (fcode))
7197 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7198 if (tree_expr_nonnegative_p (arg0))
7200 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7202 if (powfn)
7204 tree tree_root;
7205 REAL_VALUE_TYPE dconstroot;
7207 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7208 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7209 tree_root = build_real (type, dconstroot);
7210 arglist = tree_cons (NULL_TREE, arg0,
7211 build_tree_list (NULL_TREE, tree_root));
7212 return build_function_call_expr (powfn, arglist);
7217 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7218 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7219 || fcode == BUILT_IN_POWL)
7221 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7222 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7223 if (tree_expr_nonnegative_p (arg00))
7225 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7226 const REAL_VALUE_TYPE dconstroot
7227 = real_value_truncate (TYPE_MODE (type), dconstthird);
7228 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7229 build_real (type, dconstroot));
7230 arglist = tree_cons (NULL_TREE, arg00,
7231 build_tree_list (NULL_TREE, narg01));
7232 return build_function_call_expr (powfn, arglist);
7236 return NULL_TREE;
7239 /* Fold function call to builtin cos, cosf, or cosl. Return
7240 NULL_TREE if no simplification can be made. */
7241 static tree
7242 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7244 tree arg = TREE_VALUE (arglist);
7245 tree res;
7247 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7248 return NULL_TREE;
7250 /* Calculate the result when the argument is a constant. */
7251 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7252 return res;
7254 /* Optimize cos(-x) into cos (x). */
7255 if (TREE_CODE (arg) == NEGATE_EXPR)
7257 tree args = build_tree_list (NULL_TREE,
7258 TREE_OPERAND (arg, 0));
7259 return build_function_call_expr (fndecl, args);
7262 return NULL_TREE;
7265 /* Fold function call to builtin tan, tanf, or tanl. Return
7266 NULL_TREE if no simplification can be made. */
7267 static tree
7268 fold_builtin_tan (tree arglist, tree type)
7270 enum built_in_function fcode;
7271 tree arg = TREE_VALUE (arglist);
7272 tree res;
7274 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7275 return NULL_TREE;
7277 /* Calculate the result when the argument is a constant. */
7278 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7279 return res;
7281 /* Optimize tan(atan(x)) = x. */
7282 fcode = builtin_mathfn_code (arg);
7283 if (flag_unsafe_math_optimizations
7284 && (fcode == BUILT_IN_ATAN
7285 || fcode == BUILT_IN_ATANF
7286 || fcode == BUILT_IN_ATANL))
7287 return TREE_VALUE (TREE_OPERAND (arg, 1));
7289 return NULL_TREE;
7292 /* Fold function call to builtin trunc, truncf or truncl. Return
7293 NULL_TREE if no simplification can be made. */
7295 static tree
7296 fold_builtin_trunc (tree fndecl, tree arglist)
7298 tree arg;
7300 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7301 return 0;
7303 /* Optimize trunc of constant value. */
7304 arg = TREE_VALUE (arglist);
7305 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7307 REAL_VALUE_TYPE r, x;
7308 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7310 x = TREE_REAL_CST (arg);
7311 real_trunc (&r, TYPE_MODE (type), &x);
7312 return build_real (type, r);
7315 return fold_trunc_transparent_mathfn (fndecl, arglist);
7318 /* Fold function call to builtin floor, floorf or floorl. Return
7319 NULL_TREE if no simplification can be made. */
7321 static tree
7322 fold_builtin_floor (tree fndecl, tree arglist)
7324 tree arg;
7326 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7327 return 0;
7329 /* Optimize floor of constant value. */
7330 arg = TREE_VALUE (arglist);
7331 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7333 REAL_VALUE_TYPE x;
7335 x = TREE_REAL_CST (arg);
7336 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7338 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7339 REAL_VALUE_TYPE r;
7341 real_floor (&r, TYPE_MODE (type), &x);
7342 return build_real (type, r);
7346 /* Fold floor (x) where x is nonnegative to trunc (x). */
7347 if (tree_expr_nonnegative_p (arg))
7349 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7350 if (truncfn)
7351 return build_function_call_expr (truncfn, arglist);
7354 return fold_trunc_transparent_mathfn (fndecl, arglist);
7357 /* Fold function call to builtin ceil, ceilf or ceill. Return
7358 NULL_TREE if no simplification can be made. */
7360 static tree
7361 fold_builtin_ceil (tree fndecl, tree arglist)
7363 tree arg;
7365 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7366 return 0;
7368 /* Optimize ceil of constant value. */
7369 arg = TREE_VALUE (arglist);
7370 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7372 REAL_VALUE_TYPE x;
7374 x = TREE_REAL_CST (arg);
7375 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7377 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7378 REAL_VALUE_TYPE r;
7380 real_ceil (&r, TYPE_MODE (type), &x);
7381 return build_real (type, r);
7385 return fold_trunc_transparent_mathfn (fndecl, arglist);
7388 /* Fold function call to builtin round, roundf or roundl. Return
7389 NULL_TREE if no simplification can be made. */
7391 static tree
7392 fold_builtin_round (tree fndecl, tree arglist)
7394 tree arg;
7396 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7397 return 0;
7399 /* Optimize round of constant value. */
7400 arg = TREE_VALUE (arglist);
7401 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7403 REAL_VALUE_TYPE x;
7405 x = TREE_REAL_CST (arg);
7406 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7408 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7409 REAL_VALUE_TYPE r;
7411 real_round (&r, TYPE_MODE (type), &x);
7412 return build_real (type, r);
7416 return fold_trunc_transparent_mathfn (fndecl, arglist);
7419 /* Fold function call to builtin lround, lroundf or lroundl (or the
7420 corresponding long long versions) and other rounding functions.
7421 Return NULL_TREE if no simplification can be made. */
7423 static tree
7424 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7426 tree arg;
7428 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7429 return 0;
7431 /* Optimize lround of constant value. */
7432 arg = TREE_VALUE (arglist);
7433 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7435 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7437 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7439 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7440 tree ftype = TREE_TYPE (arg), result;
7441 HOST_WIDE_INT hi, lo;
7442 REAL_VALUE_TYPE r;
7444 switch (DECL_FUNCTION_CODE (fndecl))
7446 CASE_FLT_FN (BUILT_IN_LFLOOR):
7447 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7448 real_floor (&r, TYPE_MODE (ftype), &x);
7449 break;
7451 CASE_FLT_FN (BUILT_IN_LCEIL):
7452 CASE_FLT_FN (BUILT_IN_LLCEIL):
7453 real_ceil (&r, TYPE_MODE (ftype), &x);
7454 break;
7456 CASE_FLT_FN (BUILT_IN_LROUND):
7457 CASE_FLT_FN (BUILT_IN_LLROUND):
7458 real_round (&r, TYPE_MODE (ftype), &x);
7459 break;
7461 default:
7462 gcc_unreachable ();
7465 REAL_VALUE_TO_INT (&lo, &hi, r);
7466 result = build_int_cst_wide (NULL_TREE, lo, hi);
7467 if (int_fits_type_p (result, itype))
7468 return fold_convert (itype, result);
7472 switch (DECL_FUNCTION_CODE (fndecl))
7474 CASE_FLT_FN (BUILT_IN_LFLOOR):
7475 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7476 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7477 if (tree_expr_nonnegative_p (arg))
7478 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7479 arg);
7480 break;
7481 default:;
7484 return fold_fixed_mathfn (fndecl, arglist);
7487 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7488 and their long and long long variants (i.e. ffsl and ffsll).
7489 Return NULL_TREE if no simplification can be made. */
7491 static tree
7492 fold_builtin_bitop (tree fndecl, tree arglist)
7494 tree arg;
7496 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7497 return NULL_TREE;
7499 /* Optimize for constant argument. */
7500 arg = TREE_VALUE (arglist);
7501 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7503 HOST_WIDE_INT hi, width, result;
7504 unsigned HOST_WIDE_INT lo;
7505 tree type;
7507 type = TREE_TYPE (arg);
7508 width = TYPE_PRECISION (type);
7509 lo = TREE_INT_CST_LOW (arg);
7511 /* Clear all the bits that are beyond the type's precision. */
7512 if (width > HOST_BITS_PER_WIDE_INT)
7514 hi = TREE_INT_CST_HIGH (arg);
7515 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7516 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7518 else
7520 hi = 0;
7521 if (width < HOST_BITS_PER_WIDE_INT)
7522 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7525 switch (DECL_FUNCTION_CODE (fndecl))
7527 CASE_INT_FN (BUILT_IN_FFS):
7528 if (lo != 0)
7529 result = exact_log2 (lo & -lo) + 1;
7530 else if (hi != 0)
7531 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7532 else
7533 result = 0;
7534 break;
7536 CASE_INT_FN (BUILT_IN_CLZ):
7537 if (hi != 0)
7538 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7539 else if (lo != 0)
7540 result = width - floor_log2 (lo) - 1;
7541 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7542 result = width;
7543 break;
7545 CASE_INT_FN (BUILT_IN_CTZ):
7546 if (lo != 0)
7547 result = exact_log2 (lo & -lo);
7548 else if (hi != 0)
7549 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7550 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7551 result = width;
7552 break;
7554 CASE_INT_FN (BUILT_IN_POPCOUNT):
7555 result = 0;
7556 while (lo)
7557 result++, lo &= lo - 1;
7558 while (hi)
7559 result++, hi &= hi - 1;
7560 break;
7562 CASE_INT_FN (BUILT_IN_PARITY):
7563 result = 0;
7564 while (lo)
7565 result++, lo &= lo - 1;
7566 while (hi)
7567 result++, hi &= hi - 1;
7568 result &= 1;
7569 break;
7571 default:
7572 gcc_unreachable ();
7575 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7578 return NULL_TREE;
7581 /* Fold function call to builtin_bswap and the long and long long
7582 variants. Return NULL_TREE if no simplification can be made. */
7583 static tree
7584 fold_builtin_bswap (tree fndecl, tree arglist)
7586 tree arg;
7588 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7589 return 0;
7591 /* Optimize constant value. */
7592 arg = TREE_VALUE (arglist);
7593 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7595 HOST_WIDE_INT hi, width, r_hi = 0;
7596 unsigned HOST_WIDE_INT lo, r_lo = 0;
7597 tree type;
7599 type = TREE_TYPE (arg);
7600 width = TYPE_PRECISION (type);
7601 lo = TREE_INT_CST_LOW (arg);
7602 hi = TREE_INT_CST_HIGH (arg);
7604 switch (DECL_FUNCTION_CODE (fndecl))
7606 case BUILT_IN_BSWAP32:
7607 case BUILT_IN_BSWAP64:
7609 int s;
7611 for (s = 0; s < width; s += 8)
7613 int d = width - s - 8;
7614 unsigned HOST_WIDE_INT byte;
7616 if (s < HOST_BITS_PER_WIDE_INT)
7617 byte = (lo >> s) & 0xff;
7618 else
7619 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7621 if (d < HOST_BITS_PER_WIDE_INT)
7622 r_lo |= byte << d;
7623 else
7624 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7628 break;
7630 default:
7631 gcc_unreachable ();
7634 if (width < HOST_BITS_PER_WIDE_INT)
7635 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7636 else
7637 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7640 return NULL_TREE;
7642 /* Return true if EXPR is the real constant contained in VALUE. */
7644 static bool
7645 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7647 STRIP_NOPS (expr);
7649 return ((TREE_CODE (expr) == REAL_CST
7650 && ! TREE_CONSTANT_OVERFLOW (expr)
7651 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7652 || (TREE_CODE (expr) == COMPLEX_CST
7653 && real_dconstp (TREE_REALPART (expr), value)
7654 && real_zerop (TREE_IMAGPART (expr))));
7657 /* A subroutine of fold_builtin to fold the various logarithmic
7658 functions. Return NULL_TREE if no simplification can me made.
7659 FUNC is the corresponding MPFR logarithm function. */
7661 static tree
7662 fold_builtin_logarithm (tree fndecl, tree arglist,
7663 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7665 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7667 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7668 tree arg = TREE_VALUE (arglist);
7669 tree res;
7670 const enum built_in_function fcode = builtin_mathfn_code (arg);
7672 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7673 instead we'll look for 'e' truncated to MODE. So only do
7674 this if flag_unsafe_math_optimizations is set. */
7675 if (flag_unsafe_math_optimizations && func == mpfr_log)
7677 const REAL_VALUE_TYPE e_truncated =
7678 real_value_truncate (TYPE_MODE (type), dconste);
7679 if (real_dconstp (arg, &e_truncated))
7680 return build_real (type, dconst1);
7683 /* Calculate the result when the argument is a constant. */
7684 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7685 return res;
7687 /* Special case, optimize logN(expN(x)) = x. */
7688 if (flag_unsafe_math_optimizations
7689 && ((func == mpfr_log
7690 && (fcode == BUILT_IN_EXP
7691 || fcode == BUILT_IN_EXPF
7692 || fcode == BUILT_IN_EXPL))
7693 || (func == mpfr_log2
7694 && (fcode == BUILT_IN_EXP2
7695 || fcode == BUILT_IN_EXP2F
7696 || fcode == BUILT_IN_EXP2L))
7697 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7698 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7700 /* Optimize logN(func()) for various exponential functions. We
7701 want to determine the value "x" and the power "exponent" in
7702 order to transform logN(x**exponent) into exponent*logN(x). */
7703 if (flag_unsafe_math_optimizations)
7705 tree exponent = 0, x = 0;
7707 switch (fcode)
7709 CASE_FLT_FN (BUILT_IN_EXP):
7710 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7711 x = build_real (type,
7712 real_value_truncate (TYPE_MODE (type), dconste));
7713 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7714 break;
7715 CASE_FLT_FN (BUILT_IN_EXP2):
7716 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7717 x = build_real (type, dconst2);
7718 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7719 break;
7720 CASE_FLT_FN (BUILT_IN_EXP10):
7721 CASE_FLT_FN (BUILT_IN_POW10):
7722 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7723 x = build_real (type, dconst10);
7724 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7725 break;
7726 CASE_FLT_FN (BUILT_IN_SQRT):
7727 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7728 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7729 exponent = build_real (type, dconsthalf);
7730 break;
7731 CASE_FLT_FN (BUILT_IN_CBRT):
7732 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7733 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7734 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7735 dconstthird));
7736 break;
7737 CASE_FLT_FN (BUILT_IN_POW):
7738 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7739 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7740 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7741 break;
7742 default:
7743 break;
7746 /* Now perform the optimization. */
7747 if (x && exponent)
7749 tree logfn;
7750 arglist = build_tree_list (NULL_TREE, x);
7751 logfn = build_function_call_expr (fndecl, arglist);
7752 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7757 return 0;
7760 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7761 NULL_TREE if no simplification can be made. */
7763 static tree
7764 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7766 tree arg0 = TREE_VALUE (arglist);
7767 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7768 tree res;
7770 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7771 return NULL_TREE;
7773 /* Calculate the result when the argument is a constant. */
7774 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7775 return res;
7777 /* If either argument to hypot has a negate or abs, strip that off.
7778 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7779 if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR
7780 || TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg1) == ABS_EXPR)
7782 tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR
7783 || TREE_CODE (arg0) == ABS_EXPR)
7784 ? TREE_OPERAND (arg0, 0) : arg0;
7785 tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR
7786 || TREE_CODE (arg1) == ABS_EXPR)
7787 ? TREE_OPERAND (arg1, 0) : arg1;
7788 tree narglist = tree_cons (NULL_TREE, narg0,
7789 build_tree_list (NULL_TREE, narg1));
7790 return build_function_call_expr (fndecl, narglist);
7793 /* If either argument is zero, hypot is fabs of the other. */
7794 if (real_zerop (arg0))
7795 return fold_build1 (ABS_EXPR, type, arg1);
7796 else if (real_zerop (arg1))
7797 return fold_build1 (ABS_EXPR, type, arg0);
7799 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7800 if (flag_unsafe_math_optimizations
7801 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7803 REAL_VALUE_TYPE sqrt2;
7805 real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7806 return fold_build2 (MULT_EXPR, type,
7807 fold_build1 (ABS_EXPR, type, arg0),
7808 build_real (type, sqrt2));
7811 return NULL_TREE;
7815 /* Fold a builtin function call to pow, powf, or powl. Return
7816 NULL_TREE if no simplification can be made. */
7817 static tree
7818 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7820 tree arg0 = TREE_VALUE (arglist);
7821 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7822 tree res;
7824 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7825 return NULL_TREE;
7827 /* Calculate the result when the argument is a constant. */
7828 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7829 return res;
7831 /* Optimize pow(1.0,y) = 1.0. */
7832 if (real_onep (arg0))
7833 return omit_one_operand (type, build_real (type, dconst1), arg1);
7835 if (TREE_CODE (arg1) == REAL_CST
7836 && ! TREE_CONSTANT_OVERFLOW (arg1))
7838 REAL_VALUE_TYPE cint;
7839 REAL_VALUE_TYPE c;
7840 HOST_WIDE_INT n;
7842 c = TREE_REAL_CST (arg1);
7844 /* Optimize pow(x,0.0) = 1.0. */
7845 if (REAL_VALUES_EQUAL (c, dconst0))
7846 return omit_one_operand (type, build_real (type, dconst1),
7847 arg0);
7849 /* Optimize pow(x,1.0) = x. */
7850 if (REAL_VALUES_EQUAL (c, dconst1))
7851 return arg0;
7853 /* Optimize pow(x,-1.0) = 1.0/x. */
7854 if (REAL_VALUES_EQUAL (c, dconstm1))
7855 return fold_build2 (RDIV_EXPR, type,
7856 build_real (type, dconst1), arg0);
7858 /* Optimize pow(x,0.5) = sqrt(x). */
7859 if (flag_unsafe_math_optimizations
7860 && REAL_VALUES_EQUAL (c, dconsthalf))
7862 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7864 if (sqrtfn != NULL_TREE)
7866 tree arglist = build_tree_list (NULL_TREE, arg0);
7867 return build_function_call_expr (sqrtfn, arglist);
7871 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
7872 if (flag_unsafe_math_optimizations)
7874 const REAL_VALUE_TYPE dconstroot
7875 = real_value_truncate (TYPE_MODE (type), dconstthird);
7877 if (REAL_VALUES_EQUAL (c, dconstroot))
7879 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
7880 if (cbrtfn != NULL_TREE)
7882 tree arglist = build_tree_list (NULL_TREE, arg0);
7883 return build_function_call_expr (cbrtfn, arglist);
7888 /* Check for an integer exponent. */
7889 n = real_to_integer (&c);
7890 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7891 if (real_identical (&c, &cint))
7893 /* Attempt to evaluate pow at compile-time. */
7894 if (TREE_CODE (arg0) == REAL_CST
7895 && ! TREE_CONSTANT_OVERFLOW (arg0))
7897 REAL_VALUE_TYPE x;
7898 bool inexact;
7900 x = TREE_REAL_CST (arg0);
7901 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7902 if (flag_unsafe_math_optimizations || !inexact)
7903 return build_real (type, x);
7906 /* Strip sign ops from even integer powers. */
7907 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7909 tree narg0 = fold_strip_sign_ops (arg0);
7910 if (narg0)
7912 arglist = build_tree_list (NULL_TREE, arg1);
7913 arglist = tree_cons (NULL_TREE, narg0, arglist);
7914 return build_function_call_expr (fndecl, arglist);
7920 if (flag_unsafe_math_optimizations)
7922 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7924 /* Optimize pow(expN(x),y) = expN(x*y). */
7925 if (BUILTIN_EXPONENT_P (fcode))
7927 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7928 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7929 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7930 arglist = build_tree_list (NULL_TREE, arg);
7931 return build_function_call_expr (expfn, arglist);
7934 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7935 if (BUILTIN_SQRT_P (fcode))
7937 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7938 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7939 build_real (type, dconsthalf));
7941 arglist = tree_cons (NULL_TREE, narg0,
7942 build_tree_list (NULL_TREE, narg1));
7943 return build_function_call_expr (fndecl, arglist);
7946 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7947 if (BUILTIN_CBRT_P (fcode))
7949 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7950 if (tree_expr_nonnegative_p (arg))
7952 const REAL_VALUE_TYPE dconstroot
7953 = real_value_truncate (TYPE_MODE (type), dconstthird);
7954 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7955 build_real (type, dconstroot));
7956 arglist = tree_cons (NULL_TREE, arg,
7957 build_tree_list (NULL_TREE, narg1));
7958 return build_function_call_expr (fndecl, arglist);
7962 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7963 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7964 || fcode == BUILT_IN_POWL)
7966 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7967 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7968 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7969 arglist = tree_cons (NULL_TREE, arg00,
7970 build_tree_list (NULL_TREE, narg1));
7971 return build_function_call_expr (fndecl, arglist);
7975 return NULL_TREE;
7978 /* Fold a builtin function call to powi, powif, or powil. Return
7979 NULL_TREE if no simplification can be made. */
7980 static tree
7981 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7983 tree arg0 = TREE_VALUE (arglist);
7984 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7986 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7987 return NULL_TREE;
7989 /* Optimize pow(1.0,y) = 1.0. */
7990 if (real_onep (arg0))
7991 return omit_one_operand (type, build_real (type, dconst1), arg1);
7993 if (host_integerp (arg1, 0))
7995 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7997 /* Evaluate powi at compile-time. */
7998 if (TREE_CODE (arg0) == REAL_CST
7999 && ! TREE_CONSTANT_OVERFLOW (arg0))
8001 REAL_VALUE_TYPE x;
8002 x = TREE_REAL_CST (arg0);
8003 real_powi (&x, TYPE_MODE (type), &x, c);
8004 return build_real (type, x);
8007 /* Optimize pow(x,0) = 1.0. */
8008 if (c == 0)
8009 return omit_one_operand (type, build_real (type, dconst1),
8010 arg0);
8012 /* Optimize pow(x,1) = x. */
8013 if (c == 1)
8014 return arg0;
8016 /* Optimize pow(x,-1) = 1.0/x. */
8017 if (c == -1)
8018 return fold_build2 (RDIV_EXPR, type,
8019 build_real (type, dconst1), arg0);
8022 return NULL_TREE;
8025 /* A subroutine of fold_builtin to fold the various exponent
8026 functions. Return NULL_TREE if no simplification can me made.
8027 FUNC is the corresponding MPFR exponent function. */
8029 static tree
8030 fold_builtin_exponent (tree fndecl, tree arglist,
8031 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8033 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8035 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8036 tree arg = TREE_VALUE (arglist);
8037 tree res;
8039 /* Calculate the result when the argument is a constant. */
8040 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8041 return res;
8043 /* Optimize expN(logN(x)) = x. */
8044 if (flag_unsafe_math_optimizations)
8046 const enum built_in_function fcode = builtin_mathfn_code (arg);
8048 if ((func == mpfr_exp
8049 && (fcode == BUILT_IN_LOG
8050 || fcode == BUILT_IN_LOGF
8051 || fcode == BUILT_IN_LOGL))
8052 || (func == mpfr_exp2
8053 && (fcode == BUILT_IN_LOG2
8054 || fcode == BUILT_IN_LOG2F
8055 || fcode == BUILT_IN_LOG2L))
8056 || (func == mpfr_exp10
8057 && (fcode == BUILT_IN_LOG10
8058 || fcode == BUILT_IN_LOG10F
8059 || fcode == BUILT_IN_LOG10L)))
8060 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8064 return 0;
8067 /* Return true if VAR is a VAR_DECL or a component thereof. */
8069 static bool
8070 var_decl_component_p (tree var)
8072 tree inner = var;
8073 while (handled_component_p (inner))
8074 inner = TREE_OPERAND (inner, 0);
8075 return SSA_VAR_P (inner);
8078 /* Fold function call to builtin memset. Return
8079 NULL_TREE if no simplification can be made. */
8081 static tree
8082 fold_builtin_memset (tree arglist, tree type, bool ignore)
8084 tree dest, c, len, var, ret;
8085 unsigned HOST_WIDE_INT length, cval;
8087 if (!validate_arglist (arglist,
8088 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8089 return 0;
8091 dest = TREE_VALUE (arglist);
8092 c = TREE_VALUE (TREE_CHAIN (arglist));
8093 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8095 if (! host_integerp (len, 1))
8096 return 0;
8098 /* If the LEN parameter is zero, return DEST. */
8099 if (integer_zerop (len))
8100 return omit_one_operand (type, dest, c);
8102 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8103 return 0;
8105 var = dest;
8106 STRIP_NOPS (var);
8107 if (TREE_CODE (var) != ADDR_EXPR)
8108 return 0;
8110 var = TREE_OPERAND (var, 0);
8111 if (TREE_THIS_VOLATILE (var))
8112 return 0;
8114 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8115 && !POINTER_TYPE_P (TREE_TYPE (var)))
8116 return 0;
8118 if (! var_decl_component_p (var))
8119 return 0;
8121 length = tree_low_cst (len, 1);
8122 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8123 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8124 < (int) length)
8125 return 0;
8127 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8128 return 0;
8130 if (integer_zerop (c))
8131 cval = 0;
8132 else
8134 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8135 return 0;
8137 cval = tree_low_cst (c, 1);
8138 cval &= 0xff;
8139 cval |= cval << 8;
8140 cval |= cval << 16;
8141 cval |= (cval << 31) << 1;
8144 ret = build_int_cst_type (TREE_TYPE (var), cval);
8145 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
8146 if (ignore)
8147 return ret;
8149 return omit_one_operand (type, dest, ret);
8152 /* Fold function call to builtin memset. Return
8153 NULL_TREE if no simplification can be made. */
8155 static tree
8156 fold_builtin_bzero (tree arglist, bool ignore)
8158 tree dest, size, newarglist;
8160 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8161 return 0;
8163 if (!ignore)
8164 return 0;
8166 dest = TREE_VALUE (arglist);
8167 size = TREE_VALUE (TREE_CHAIN (arglist));
8169 /* New argument list transforming bzero(ptr x, int y) to
8170 memset(ptr x, int 0, size_t y). This is done this way
8171 so that if it isn't expanded inline, we fallback to
8172 calling bzero instead of memset. */
8174 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8175 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8176 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8177 return fold_builtin_memset (newarglist, void_type_node, ignore);
8180 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8181 NULL_TREE if no simplification can be made.
8182 If ENDP is 0, return DEST (like memcpy).
8183 If ENDP is 1, return DEST+LEN (like mempcpy).
8184 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8185 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8186 (memmove). */
8188 static tree
8189 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8191 tree dest, src, len, destvar, srcvar, expr;
8192 unsigned HOST_WIDE_INT length;
8194 if (! validate_arglist (arglist,
8195 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8196 return 0;
8198 dest = TREE_VALUE (arglist);
8199 src = TREE_VALUE (TREE_CHAIN (arglist));
8200 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8202 /* If the LEN parameter is zero, return DEST. */
8203 if (integer_zerop (len))
8204 return omit_one_operand (type, dest, src);
8206 /* If SRC and DEST are the same (and not volatile), return
8207 DEST{,+LEN,+LEN-1}. */
8208 if (operand_equal_p (src, dest, 0))
8209 expr = len;
8210 else
8212 if (endp == 3)
8214 unsigned int src_align
8215 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8216 unsigned int dest_align
8217 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8218 /* Both DEST and SRC must be pointer types.
8219 ??? This is what old code did. Is the testing for pointer types
8220 really mandatory?
8222 If either SRC is readonly or length is 1, we can use memcpy. */
8223 if (dest_align && src_align
8224 && (readonly_data_expr (src)
8225 || integer_onep (len)))
8227 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8228 if (!fn)
8229 return 0;
8230 return build_function_call_expr (fn, arglist);
8233 if (! host_integerp (len, 1))
8234 return 0;
8236 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8237 return 0;
8239 destvar = dest;
8240 STRIP_NOPS (destvar);
8241 if (TREE_CODE (destvar) != ADDR_EXPR)
8242 return 0;
8244 destvar = TREE_OPERAND (destvar, 0);
8245 if (TREE_THIS_VOLATILE (destvar))
8246 return 0;
8248 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8249 && !POINTER_TYPE_P (TREE_TYPE (destvar))
8250 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8251 return 0;
8253 if (! var_decl_component_p (destvar))
8254 return 0;
8256 srcvar = src;
8257 STRIP_NOPS (srcvar);
8258 if (TREE_CODE (srcvar) != ADDR_EXPR)
8259 return 0;
8261 srcvar = TREE_OPERAND (srcvar, 0);
8262 if (TREE_THIS_VOLATILE (srcvar))
8263 return 0;
8265 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8266 && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8267 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8268 return 0;
8270 if (! var_decl_component_p (srcvar))
8271 return 0;
8273 length = tree_low_cst (len, 1);
8274 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8275 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8276 < (int) length
8277 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8278 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8279 < (int) length)
8280 return 0;
8282 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8283 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8284 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8285 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8286 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8287 else
8288 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8289 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8292 if (ignore)
8293 return expr;
8295 if (endp == 0 || endp == 3)
8296 return omit_one_operand (type, dest, expr);
8298 if (expr == len)
8299 expr = 0;
8301 if (endp == 2)
8302 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8303 ssize_int (1));
8305 len = fold_convert (TREE_TYPE (dest), len);
8306 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8307 dest = fold_convert (type, dest);
8308 if (expr)
8309 dest = omit_one_operand (type, dest, expr);
8310 return dest;
8313 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8314 simplification can be made. */
8316 static tree
8317 fold_builtin_bcopy (tree arglist, bool ignore)
8319 tree src, dest, size, newarglist;
8321 if (!validate_arglist (arglist,
8322 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8323 return 0;
8325 if (! ignore)
8326 return 0;
8328 src = TREE_VALUE (arglist);
8329 dest = TREE_VALUE (TREE_CHAIN (arglist));
8330 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8332 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8333 memmove(ptr y, ptr x, size_t z). This is done this way
8334 so that if it isn't expanded inline, we fallback to
8335 calling bcopy instead of memmove. */
8337 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8338 newarglist = tree_cons (NULL_TREE, src, newarglist);
8339 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8341 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8344 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8345 the length of the string to be copied. Return NULL_TREE if no
8346 simplification can be made. */
8348 tree
8349 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8351 tree dest, src, fn;
8353 if (!validate_arglist (arglist,
8354 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8355 return 0;
8357 dest = TREE_VALUE (arglist);
8358 src = TREE_VALUE (TREE_CHAIN (arglist));
8360 /* If SRC and DEST are the same (and not volatile), return DEST. */
8361 if (operand_equal_p (src, dest, 0))
8362 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8364 if (optimize_size)
8365 return 0;
8367 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8368 if (!fn)
8369 return 0;
8371 if (!len)
8373 len = c_strlen (src, 1);
8374 if (! len || TREE_SIDE_EFFECTS (len))
8375 return 0;
8378 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8379 arglist = build_tree_list (NULL_TREE, len);
8380 arglist = tree_cons (NULL_TREE, src, arglist);
8381 arglist = tree_cons (NULL_TREE, dest, arglist);
8382 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8383 build_function_call_expr (fn, arglist));
8386 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8387 the length of the source string. Return NULL_TREE if no simplification
8388 can be made. */
8390 tree
8391 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8393 tree dest, src, len, fn;
8395 if (!validate_arglist (arglist,
8396 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8397 return 0;
8399 dest = TREE_VALUE (arglist);
8400 src = TREE_VALUE (TREE_CHAIN (arglist));
8401 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8403 /* If the LEN parameter is zero, return DEST. */
8404 if (integer_zerop (len))
8405 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8407 /* We can't compare slen with len as constants below if len is not a
8408 constant. */
8409 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8410 return 0;
8412 if (!slen)
8413 slen = c_strlen (src, 1);
8415 /* Now, we must be passed a constant src ptr parameter. */
8416 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8417 return 0;
8419 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8421 /* We do not support simplification of this case, though we do
8422 support it when expanding trees into RTL. */
8423 /* FIXME: generate a call to __builtin_memset. */
8424 if (tree_int_cst_lt (slen, len))
8425 return 0;
8427 /* OK transform into builtin memcpy. */
8428 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8429 if (!fn)
8430 return 0;
8431 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8432 build_function_call_expr (fn, arglist));
8435 /* Fold function call to builtin memcmp. Return
8436 NULL_TREE if no simplification can be made. */
8438 static tree
8439 fold_builtin_memcmp (tree arglist)
8441 tree arg1, arg2, len;
8442 const char *p1, *p2;
8444 if (!validate_arglist (arglist,
8445 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8446 return 0;
8448 arg1 = TREE_VALUE (arglist);
8449 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8450 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8452 /* If the LEN parameter is zero, return zero. */
8453 if (integer_zerop (len))
8454 return omit_two_operands (integer_type_node, integer_zero_node,
8455 arg1, arg2);
8457 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8458 if (operand_equal_p (arg1, arg2, 0))
8459 return omit_one_operand (integer_type_node, integer_zero_node, len);
8461 p1 = c_getstr (arg1);
8462 p2 = c_getstr (arg2);
8464 /* If all arguments are constant, and the value of len is not greater
8465 than the lengths of arg1 and arg2, evaluate at compile-time. */
8466 if (host_integerp (len, 1) && p1 && p2
8467 && compare_tree_int (len, strlen (p1) + 1) <= 0
8468 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8470 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8472 if (r > 0)
8473 return integer_one_node;
8474 else if (r < 0)
8475 return integer_minus_one_node;
8476 else
8477 return integer_zero_node;
8480 /* If len parameter is one, return an expression corresponding to
8481 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8482 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8484 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8485 tree cst_uchar_ptr_node
8486 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8488 tree ind1 = fold_convert (integer_type_node,
8489 build1 (INDIRECT_REF, cst_uchar_node,
8490 fold_convert (cst_uchar_ptr_node,
8491 arg1)));
8492 tree ind2 = fold_convert (integer_type_node,
8493 build1 (INDIRECT_REF, cst_uchar_node,
8494 fold_convert (cst_uchar_ptr_node,
8495 arg2)));
8496 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8499 return 0;
8502 /* Fold function call to builtin strcmp. Return
8503 NULL_TREE if no simplification can be made. */
8505 static tree
8506 fold_builtin_strcmp (tree arglist)
8508 tree arg1, arg2;
8509 const char *p1, *p2;
8511 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8512 return 0;
8514 arg1 = TREE_VALUE (arglist);
8515 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8517 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8518 if (operand_equal_p (arg1, arg2, 0))
8519 return integer_zero_node;
8521 p1 = c_getstr (arg1);
8522 p2 = c_getstr (arg2);
8524 if (p1 && p2)
8526 const int i = strcmp (p1, p2);
8527 if (i < 0)
8528 return integer_minus_one_node;
8529 else if (i > 0)
8530 return integer_one_node;
8531 else
8532 return integer_zero_node;
8535 /* If the second arg is "", return *(const unsigned char*)arg1. */
8536 if (p2 && *p2 == '\0')
8538 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8539 tree cst_uchar_ptr_node
8540 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8542 return fold_convert (integer_type_node,
8543 build1 (INDIRECT_REF, cst_uchar_node,
8544 fold_convert (cst_uchar_ptr_node,
8545 arg1)));
8548 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8549 if (p1 && *p1 == '\0')
8551 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8552 tree cst_uchar_ptr_node
8553 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8555 tree temp = fold_convert (integer_type_node,
8556 build1 (INDIRECT_REF, cst_uchar_node,
8557 fold_convert (cst_uchar_ptr_node,
8558 arg2)));
8559 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8562 return 0;
8565 /* Fold function call to builtin strncmp. Return
8566 NULL_TREE if no simplification can be made. */
8568 static tree
8569 fold_builtin_strncmp (tree arglist)
8571 tree arg1, arg2, len;
8572 const char *p1, *p2;
8574 if (!validate_arglist (arglist,
8575 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8576 return 0;
8578 arg1 = TREE_VALUE (arglist);
8579 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8580 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8582 /* If the LEN parameter is zero, return zero. */
8583 if (integer_zerop (len))
8584 return omit_two_operands (integer_type_node, integer_zero_node,
8585 arg1, arg2);
8587 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8588 if (operand_equal_p (arg1, arg2, 0))
8589 return omit_one_operand (integer_type_node, integer_zero_node, len);
8591 p1 = c_getstr (arg1);
8592 p2 = c_getstr (arg2);
8594 if (host_integerp (len, 1) && p1 && p2)
8596 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8597 if (i > 0)
8598 return integer_one_node;
8599 else if (i < 0)
8600 return integer_minus_one_node;
8601 else
8602 return integer_zero_node;
8605 /* If the second arg is "", and the length is greater than zero,
8606 return *(const unsigned char*)arg1. */
8607 if (p2 && *p2 == '\0'
8608 && TREE_CODE (len) == INTEGER_CST
8609 && tree_int_cst_sgn (len) == 1)
8611 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8612 tree cst_uchar_ptr_node
8613 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8615 return fold_convert (integer_type_node,
8616 build1 (INDIRECT_REF, cst_uchar_node,
8617 fold_convert (cst_uchar_ptr_node,
8618 arg1)));
8621 /* If the first arg is "", and the length is greater than zero,
8622 return -*(const unsigned char*)arg2. */
8623 if (p1 && *p1 == '\0'
8624 && TREE_CODE (len) == INTEGER_CST
8625 && tree_int_cst_sgn (len) == 1)
8627 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8628 tree cst_uchar_ptr_node
8629 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8631 tree temp = fold_convert (integer_type_node,
8632 build1 (INDIRECT_REF, cst_uchar_node,
8633 fold_convert (cst_uchar_ptr_node,
8634 arg2)));
8635 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8638 /* If len parameter is one, return an expression corresponding to
8639 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8640 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8642 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8643 tree cst_uchar_ptr_node
8644 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8646 tree ind1 = fold_convert (integer_type_node,
8647 build1 (INDIRECT_REF, cst_uchar_node,
8648 fold_convert (cst_uchar_ptr_node,
8649 arg1)));
8650 tree ind2 = fold_convert (integer_type_node,
8651 build1 (INDIRECT_REF, cst_uchar_node,
8652 fold_convert (cst_uchar_ptr_node,
8653 arg2)));
8654 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8657 return 0;
8660 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8661 NULL_TREE if no simplification can be made. */
8663 static tree
8664 fold_builtin_signbit (tree fndecl, tree arglist)
8666 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8667 tree arg, temp;
8669 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8670 return NULL_TREE;
8672 arg = TREE_VALUE (arglist);
8674 /* If ARG is a compile-time constant, determine the result. */
8675 if (TREE_CODE (arg) == REAL_CST
8676 && !TREE_CONSTANT_OVERFLOW (arg))
8678 REAL_VALUE_TYPE c;
8680 c = TREE_REAL_CST (arg);
8681 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8682 return fold_convert (type, temp);
8685 /* If ARG is non-negative, the result is always zero. */
8686 if (tree_expr_nonnegative_p (arg))
8687 return omit_one_operand (type, integer_zero_node, arg);
8689 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8690 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8691 return fold_build2 (LT_EXPR, type, arg,
8692 build_real (TREE_TYPE (arg), dconst0));
8694 return NULL_TREE;
8697 /* Fold function call to builtin copysign, copysignf or copysignl.
8698 Return NULL_TREE if no simplification can be made. */
8700 static tree
8701 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8703 tree arg1, arg2, tem;
8705 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8706 return NULL_TREE;
8708 arg1 = TREE_VALUE (arglist);
8709 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8711 /* copysign(X,X) is X. */
8712 if (operand_equal_p (arg1, arg2, 0))
8713 return fold_convert (type, arg1);
8715 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8716 if (TREE_CODE (arg1) == REAL_CST
8717 && TREE_CODE (arg2) == REAL_CST
8718 && !TREE_CONSTANT_OVERFLOW (arg1)
8719 && !TREE_CONSTANT_OVERFLOW (arg2))
8721 REAL_VALUE_TYPE c1, c2;
8723 c1 = TREE_REAL_CST (arg1);
8724 c2 = TREE_REAL_CST (arg2);
8725 /* c1.sign := c2.sign. */
8726 real_copysign (&c1, &c2);
8727 return build_real (type, c1);
8730 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8731 Remember to evaluate Y for side-effects. */
8732 if (tree_expr_nonnegative_p (arg2))
8733 return omit_one_operand (type,
8734 fold_build1 (ABS_EXPR, type, arg1),
8735 arg2);
8737 /* Strip sign changing operations for the first argument. */
8738 tem = fold_strip_sign_ops (arg1);
8739 if (tem)
8741 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8742 return build_function_call_expr (fndecl, arglist);
8745 return NULL_TREE;
8748 /* Fold a call to builtin isascii. */
8750 static tree
8751 fold_builtin_isascii (tree arglist)
8753 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8754 return 0;
8755 else
8757 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8758 tree arg = TREE_VALUE (arglist);
8760 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8761 build_int_cst (NULL_TREE,
8762 ~ (unsigned HOST_WIDE_INT) 0x7f));
8763 return fold_build2 (EQ_EXPR, integer_type_node,
8764 arg, integer_zero_node);
8768 /* Fold a call to builtin toascii. */
8770 static tree
8771 fold_builtin_toascii (tree arglist)
8773 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8774 return 0;
8775 else
8777 /* Transform toascii(c) -> (c & 0x7f). */
8778 tree arg = TREE_VALUE (arglist);
8780 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8781 build_int_cst (NULL_TREE, 0x7f));
8785 /* Fold a call to builtin isdigit. */
8787 static tree
8788 fold_builtin_isdigit (tree arglist)
8790 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8791 return 0;
8792 else
8794 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8795 /* According to the C standard, isdigit is unaffected by locale.
8796 However, it definitely is affected by the target character set. */
8797 tree arg;
8798 unsigned HOST_WIDE_INT target_digit0
8799 = lang_hooks.to_target_charset ('0');
8801 if (target_digit0 == 0)
8802 return NULL_TREE;
8804 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8805 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8806 build_int_cst (unsigned_type_node, target_digit0));
8807 return fold_build2 (LE_EXPR, integer_type_node, arg,
8808 build_int_cst (unsigned_type_node, 9));
8812 /* Fold a call to fabs, fabsf or fabsl. */
8814 static tree
8815 fold_builtin_fabs (tree arglist, tree type)
8817 tree arg;
8819 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8820 return 0;
8822 arg = TREE_VALUE (arglist);
8823 arg = fold_convert (type, arg);
8824 if (TREE_CODE (arg) == REAL_CST)
8825 return fold_abs_const (arg, type);
8826 return fold_build1 (ABS_EXPR, type, arg);
8829 /* Fold a call to abs, labs, llabs or imaxabs. */
8831 static tree
8832 fold_builtin_abs (tree arglist, tree type)
8834 tree arg;
8836 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8837 return 0;
8839 arg = TREE_VALUE (arglist);
8840 arg = fold_convert (type, arg);
8841 if (TREE_CODE (arg) == INTEGER_CST)
8842 return fold_abs_const (arg, type);
8843 return fold_build1 (ABS_EXPR, type, arg);
8846 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8847 EXP is the CALL_EXPR for the call. */
8849 static tree
8850 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8852 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8853 tree arg;
8854 REAL_VALUE_TYPE r;
8856 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8858 /* Check that we have exactly one argument. */
8859 if (arglist == 0)
8861 error ("too few arguments to function %qs",
8862 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8863 return error_mark_node;
8865 else if (TREE_CHAIN (arglist) != 0)
8867 error ("too many arguments to function %qs",
8868 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8869 return error_mark_node;
8871 else
8873 error ("non-floating-point argument to function %qs",
8874 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8875 return error_mark_node;
8879 arg = TREE_VALUE (arglist);
8880 switch (builtin_index)
8882 case BUILT_IN_ISINF:
8883 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8884 return omit_one_operand (type, integer_zero_node, arg);
8886 if (TREE_CODE (arg) == REAL_CST)
8888 r = TREE_REAL_CST (arg);
8889 if (real_isinf (&r))
8890 return real_compare (GT_EXPR, &r, &dconst0)
8891 ? integer_one_node : integer_minus_one_node;
8892 else
8893 return integer_zero_node;
8896 return NULL_TREE;
8898 case BUILT_IN_FINITE:
8899 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8900 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8901 return omit_one_operand (type, integer_one_node, arg);
8903 if (TREE_CODE (arg) == REAL_CST)
8905 r = TREE_REAL_CST (arg);
8906 return real_isinf (&r) || real_isnan (&r)
8907 ? integer_zero_node : integer_one_node;
8910 return NULL_TREE;
8912 case BUILT_IN_ISNAN:
8913 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8914 return omit_one_operand (type, integer_zero_node, arg);
8916 if (TREE_CODE (arg) == REAL_CST)
8918 r = TREE_REAL_CST (arg);
8919 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8922 arg = builtin_save_expr (arg);
8923 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8925 default:
8926 gcc_unreachable ();
8930 /* Fold a call to an unordered comparison function such as
8931 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8932 being called and ARGLIST is the argument list for the call.
8933 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8934 the opposite of the desired result. UNORDERED_CODE is used
8935 for modes that can hold NaNs and ORDERED_CODE is used for
8936 the rest. */
8938 static tree
8939 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8940 enum tree_code unordered_code,
8941 enum tree_code ordered_code)
8943 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8944 enum tree_code code;
8945 tree arg0, arg1;
8946 tree type0, type1;
8947 enum tree_code code0, code1;
8948 tree cmp_type = NULL_TREE;
8950 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8952 /* Check that we have exactly two arguments. */
8953 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8955 error ("too few arguments to function %qs",
8956 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8957 return error_mark_node;
8959 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8961 error ("too many arguments to function %qs",
8962 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8963 return error_mark_node;
8967 arg0 = TREE_VALUE (arglist);
8968 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8970 type0 = TREE_TYPE (arg0);
8971 type1 = TREE_TYPE (arg1);
8973 code0 = TREE_CODE (type0);
8974 code1 = TREE_CODE (type1);
8976 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8977 /* Choose the wider of two real types. */
8978 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8979 ? type0 : type1;
8980 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8981 cmp_type = type0;
8982 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8983 cmp_type = type1;
8984 else
8986 error ("non-floating-point argument to function %qs",
8987 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8988 return error_mark_node;
8991 arg0 = fold_convert (cmp_type, arg0);
8992 arg1 = fold_convert (cmp_type, arg1);
8994 if (unordered_code == UNORDERED_EXPR)
8996 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8997 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8998 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9001 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9002 : ordered_code;
9003 return fold_build1 (TRUTH_NOT_EXPR, type,
9004 fold_build2 (code, type, arg0, arg1));
9007 /* Used by constant folding to simplify calls to builtin functions. EXP is
9008 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9009 result of the function call is ignored. This function returns NULL_TREE
9010 if no simplification was possible. */
9012 static tree
9013 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9015 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9016 enum built_in_function fcode;
9018 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9019 return targetm.fold_builtin (fndecl, arglist, ignore);
9021 fcode = DECL_FUNCTION_CODE (fndecl);
9022 switch (fcode)
9024 case BUILT_IN_FPUTS:
9025 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9027 case BUILT_IN_FPUTS_UNLOCKED:
9028 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9030 case BUILT_IN_STRSTR:
9031 return fold_builtin_strstr (arglist, type);
9033 case BUILT_IN_STRCAT:
9034 return fold_builtin_strcat (arglist);
9036 case BUILT_IN_STRNCAT:
9037 return fold_builtin_strncat (arglist);
9039 case BUILT_IN_STRSPN:
9040 return fold_builtin_strspn (arglist);
9042 case BUILT_IN_STRCSPN:
9043 return fold_builtin_strcspn (arglist);
9045 case BUILT_IN_STRCHR:
9046 case BUILT_IN_INDEX:
9047 return fold_builtin_strchr (arglist, type);
9049 case BUILT_IN_STRRCHR:
9050 case BUILT_IN_RINDEX:
9051 return fold_builtin_strrchr (arglist, type);
9053 case BUILT_IN_STRCPY:
9054 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9056 case BUILT_IN_STRNCPY:
9057 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9059 case BUILT_IN_STRCMP:
9060 return fold_builtin_strcmp (arglist);
9062 case BUILT_IN_STRNCMP:
9063 return fold_builtin_strncmp (arglist);
9065 case BUILT_IN_STRPBRK:
9066 return fold_builtin_strpbrk (arglist, type);
9068 case BUILT_IN_BCMP:
9069 case BUILT_IN_MEMCMP:
9070 return fold_builtin_memcmp (arglist);
9072 case BUILT_IN_SPRINTF:
9073 return fold_builtin_sprintf (arglist, ignore);
9075 case BUILT_IN_CONSTANT_P:
9077 tree val;
9079 val = fold_builtin_constant_p (arglist);
9080 /* Gimplification will pull the CALL_EXPR for the builtin out of
9081 an if condition. When not optimizing, we'll not CSE it back.
9082 To avoid link error types of regressions, return false now. */
9083 if (!val && !optimize)
9084 val = integer_zero_node;
9086 return val;
9089 case BUILT_IN_EXPECT:
9090 return fold_builtin_expect (arglist);
9092 case BUILT_IN_CLASSIFY_TYPE:
9093 return fold_builtin_classify_type (arglist);
9095 case BUILT_IN_STRLEN:
9096 return fold_builtin_strlen (arglist);
9098 CASE_FLT_FN (BUILT_IN_FABS):
9099 return fold_builtin_fabs (arglist, type);
9101 case BUILT_IN_ABS:
9102 case BUILT_IN_LABS:
9103 case BUILT_IN_LLABS:
9104 case BUILT_IN_IMAXABS:
9105 return fold_builtin_abs (arglist, type);
9107 CASE_FLT_FN (BUILT_IN_CONJ):
9108 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9109 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9110 break;
9112 CASE_FLT_FN (BUILT_IN_CREAL):
9113 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9114 return non_lvalue (fold_build1 (REALPART_EXPR, type,
9115 TREE_VALUE (arglist)));
9116 break;
9118 CASE_FLT_FN (BUILT_IN_CIMAG):
9119 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9120 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9121 TREE_VALUE (arglist)));
9122 break;
9124 CASE_FLT_FN (BUILT_IN_CABS):
9125 return fold_builtin_cabs (arglist, type, fndecl);
9127 CASE_FLT_FN (BUILT_IN_SQRT):
9128 return fold_builtin_sqrt (arglist, type);
9130 CASE_FLT_FN (BUILT_IN_CBRT):
9131 return fold_builtin_cbrt (arglist, type);
9133 CASE_FLT_FN (BUILT_IN_ASIN):
9134 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9135 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9136 &dconstm1, &dconst1, true);
9137 break;
9139 CASE_FLT_FN (BUILT_IN_ACOS):
9140 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9141 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9142 &dconstm1, &dconst1, true);
9143 break;
9145 CASE_FLT_FN (BUILT_IN_ATAN):
9146 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9147 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9148 NULL, NULL, 0);
9149 break;
9151 CASE_FLT_FN (BUILT_IN_ASINH):
9152 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9153 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9154 NULL, NULL, 0);
9155 break;
9157 CASE_FLT_FN (BUILT_IN_ACOSH):
9158 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9159 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9160 &dconst1, NULL, true);
9161 break;
9163 CASE_FLT_FN (BUILT_IN_ATANH):
9164 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9165 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9166 &dconstm1, &dconst1, false);
9167 break;
9169 CASE_FLT_FN (BUILT_IN_SIN):
9170 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9171 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9172 NULL, NULL, 0);
9173 break;
9175 CASE_FLT_FN (BUILT_IN_COS):
9176 return fold_builtin_cos (arglist, type, fndecl);
9178 CASE_FLT_FN (BUILT_IN_TAN):
9179 return fold_builtin_tan (arglist, type);
9181 CASE_FLT_FN (BUILT_IN_SINCOS):
9182 if (validate_arglist (arglist, REAL_TYPE, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9183 return do_mpfr_sincos (TREE_VALUE (arglist), TREE_VALUE (TREE_CHAIN (arglist)),
9184 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
9185 break;
9187 CASE_FLT_FN (BUILT_IN_SINH):
9188 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9189 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9190 NULL, NULL, 0);
9191 break;
9193 CASE_FLT_FN (BUILT_IN_COSH):
9194 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9195 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_cosh,
9196 NULL, NULL, 0);
9197 break;
9199 CASE_FLT_FN (BUILT_IN_TANH):
9200 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9201 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9202 NULL, NULL, 0);
9203 break;
9205 CASE_FLT_FN (BUILT_IN_ERF):
9206 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9207 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9208 NULL, NULL, 0);
9209 break;
9211 CASE_FLT_FN (BUILT_IN_ERFC):
9212 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9213 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9214 NULL, NULL, 0);
9215 break;
9217 CASE_FLT_FN (BUILT_IN_TGAMMA):
9218 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9219 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9220 NULL, NULL, 0);
9221 break;
9223 CASE_FLT_FN (BUILT_IN_EXP):
9224 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9226 CASE_FLT_FN (BUILT_IN_EXP2):
9227 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9229 CASE_FLT_FN (BUILT_IN_EXP10):
9230 CASE_FLT_FN (BUILT_IN_POW10):
9231 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9233 CASE_FLT_FN (BUILT_IN_EXPM1):
9234 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9235 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9236 NULL, NULL, 0);
9237 break;
9239 CASE_FLT_FN (BUILT_IN_LOG):
9240 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9242 CASE_FLT_FN (BUILT_IN_LOG2):
9243 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9245 CASE_FLT_FN (BUILT_IN_LOG10):
9246 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9248 CASE_FLT_FN (BUILT_IN_LOG1P):
9249 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9250 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9251 &dconstm1, NULL, false);
9252 break;
9254 CASE_FLT_FN (BUILT_IN_ATAN2):
9255 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9256 return do_mpfr_arg2 (TREE_VALUE (arglist),
9257 TREE_VALUE (TREE_CHAIN (arglist)),
9258 type, mpfr_atan2);
9259 break;
9261 CASE_FLT_FN (BUILT_IN_FMA):
9262 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9263 return do_mpfr_arg3 (TREE_VALUE (arglist),
9264 TREE_VALUE (TREE_CHAIN (arglist)),
9265 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9266 type, mpfr_fma);
9267 break;
9269 CASE_FLT_FN (BUILT_IN_FMIN):
9270 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9271 return do_mpfr_arg2 (TREE_VALUE (arglist),
9272 TREE_VALUE (TREE_CHAIN (arglist)),
9273 type, mpfr_min);
9274 break;
9276 CASE_FLT_FN (BUILT_IN_FMAX):
9277 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9278 return do_mpfr_arg2 (TREE_VALUE (arglist),
9279 TREE_VALUE (TREE_CHAIN (arglist)),
9280 type, mpfr_max);
9281 break;
9283 CASE_FLT_FN (BUILT_IN_HYPOT):
9284 return fold_builtin_hypot (fndecl, arglist, type);
9286 CASE_FLT_FN (BUILT_IN_POW):
9287 return fold_builtin_pow (fndecl, arglist, type);
9289 CASE_FLT_FN (BUILT_IN_POWI):
9290 return fold_builtin_powi (fndecl, arglist, type);
9292 CASE_FLT_FN (BUILT_IN_INF):
9293 case BUILT_IN_INFD32:
9294 case BUILT_IN_INFD64:
9295 case BUILT_IN_INFD128:
9296 return fold_builtin_inf (type, true);
9298 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9299 return fold_builtin_inf (type, false);
9301 CASE_FLT_FN (BUILT_IN_NAN):
9302 case BUILT_IN_NAND32:
9303 case BUILT_IN_NAND64:
9304 case BUILT_IN_NAND128:
9305 return fold_builtin_nan (arglist, type, true);
9307 CASE_FLT_FN (BUILT_IN_NANS):
9308 return fold_builtin_nan (arglist, type, false);
9310 CASE_FLT_FN (BUILT_IN_FLOOR):
9311 return fold_builtin_floor (fndecl, arglist);
9313 CASE_FLT_FN (BUILT_IN_CEIL):
9314 return fold_builtin_ceil (fndecl, arglist);
9316 CASE_FLT_FN (BUILT_IN_TRUNC):
9317 return fold_builtin_trunc (fndecl, arglist);
9319 CASE_FLT_FN (BUILT_IN_ROUND):
9320 return fold_builtin_round (fndecl, arglist);
9322 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9323 CASE_FLT_FN (BUILT_IN_RINT):
9324 return fold_trunc_transparent_mathfn (fndecl, arglist);
9326 CASE_FLT_FN (BUILT_IN_LCEIL):
9327 CASE_FLT_FN (BUILT_IN_LLCEIL):
9328 CASE_FLT_FN (BUILT_IN_LFLOOR):
9329 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9330 CASE_FLT_FN (BUILT_IN_LROUND):
9331 CASE_FLT_FN (BUILT_IN_LLROUND):
9332 return fold_builtin_int_roundingfn (fndecl, arglist);
9334 CASE_FLT_FN (BUILT_IN_LRINT):
9335 CASE_FLT_FN (BUILT_IN_LLRINT):
9336 return fold_fixed_mathfn (fndecl, arglist);
9338 case BUILT_IN_BSWAP32:
9339 case BUILT_IN_BSWAP64:
9340 return fold_builtin_bswap (fndecl, arglist);
9342 CASE_INT_FN (BUILT_IN_FFS):
9343 CASE_INT_FN (BUILT_IN_CLZ):
9344 CASE_INT_FN (BUILT_IN_CTZ):
9345 CASE_INT_FN (BUILT_IN_POPCOUNT):
9346 CASE_INT_FN (BUILT_IN_PARITY):
9347 return fold_builtin_bitop (fndecl, arglist);
9349 case BUILT_IN_MEMSET:
9350 return fold_builtin_memset (arglist, type, ignore);
9352 case BUILT_IN_MEMCPY:
9353 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9355 case BUILT_IN_MEMPCPY:
9356 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9358 case BUILT_IN_MEMMOVE:
9359 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9361 case BUILT_IN_BZERO:
9362 return fold_builtin_bzero (arglist, ignore);
9364 case BUILT_IN_BCOPY:
9365 return fold_builtin_bcopy (arglist, ignore);
9367 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9368 return fold_builtin_signbit (fndecl, arglist);
9370 case BUILT_IN_ISASCII:
9371 return fold_builtin_isascii (arglist);
9373 case BUILT_IN_TOASCII:
9374 return fold_builtin_toascii (arglist);
9376 case BUILT_IN_ISDIGIT:
9377 return fold_builtin_isdigit (arglist);
9379 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9380 return fold_builtin_copysign (fndecl, arglist, type);
9382 CASE_FLT_FN (BUILT_IN_FINITE):
9383 case BUILT_IN_FINITED32:
9384 case BUILT_IN_FINITED64:
9385 case BUILT_IN_FINITED128:
9386 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9388 CASE_FLT_FN (BUILT_IN_ISINF):
9389 case BUILT_IN_ISINFD32:
9390 case BUILT_IN_ISINFD64:
9391 case BUILT_IN_ISINFD128:
9392 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9394 CASE_FLT_FN (BUILT_IN_ISNAN):
9395 case BUILT_IN_ISNAND32:
9396 case BUILT_IN_ISNAND64:
9397 case BUILT_IN_ISNAND128:
9398 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9400 case BUILT_IN_ISGREATER:
9401 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9402 case BUILT_IN_ISGREATEREQUAL:
9403 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9404 case BUILT_IN_ISLESS:
9405 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9406 case BUILT_IN_ISLESSEQUAL:
9407 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9408 case BUILT_IN_ISLESSGREATER:
9409 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9410 case BUILT_IN_ISUNORDERED:
9411 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9412 NOP_EXPR);
9414 /* We do the folding for va_start in the expander. */
9415 case BUILT_IN_VA_START:
9416 break;
9418 case BUILT_IN_OBJECT_SIZE:
9419 return fold_builtin_object_size (arglist);
9420 case BUILT_IN_MEMCPY_CHK:
9421 case BUILT_IN_MEMPCPY_CHK:
9422 case BUILT_IN_MEMMOVE_CHK:
9423 case BUILT_IN_MEMSET_CHK:
9424 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9425 DECL_FUNCTION_CODE (fndecl));
9426 case BUILT_IN_STRCPY_CHK:
9427 case BUILT_IN_STPCPY_CHK:
9428 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9429 DECL_FUNCTION_CODE (fndecl));
9430 case BUILT_IN_STRNCPY_CHK:
9431 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9432 case BUILT_IN_STRCAT_CHK:
9433 return fold_builtin_strcat_chk (fndecl, arglist);
9434 case BUILT_IN_STRNCAT_CHK:
9435 return fold_builtin_strncat_chk (fndecl, arglist);
9436 case BUILT_IN_SPRINTF_CHK:
9437 case BUILT_IN_VSPRINTF_CHK:
9438 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9439 case BUILT_IN_SNPRINTF_CHK:
9440 case BUILT_IN_VSNPRINTF_CHK:
9441 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9442 DECL_FUNCTION_CODE (fndecl));
9444 case BUILT_IN_PRINTF:
9445 case BUILT_IN_PRINTF_UNLOCKED:
9446 case BUILT_IN_VPRINTF:
9447 case BUILT_IN_PRINTF_CHK:
9448 case BUILT_IN_VPRINTF_CHK:
9449 return fold_builtin_printf (fndecl, arglist, ignore,
9450 DECL_FUNCTION_CODE (fndecl));
9452 case BUILT_IN_FPRINTF:
9453 case BUILT_IN_FPRINTF_UNLOCKED:
9454 case BUILT_IN_VFPRINTF:
9455 case BUILT_IN_FPRINTF_CHK:
9456 case BUILT_IN_VFPRINTF_CHK:
9457 return fold_builtin_fprintf (fndecl, arglist, ignore,
9458 DECL_FUNCTION_CODE (fndecl));
9460 default:
9461 break;
9464 return 0;
9467 /* A wrapper function for builtin folding that prevents warnings for
9468 "statement without effect" and the like, caused by removing the
9469 call node earlier than the warning is generated. */
9471 tree
9472 fold_builtin (tree fndecl, tree arglist, bool ignore)
9474 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9475 if (exp && !ignore)
9477 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9478 TREE_NO_WARNING (exp) = 1;
9481 return exp;
9484 /* Conveniently construct a function call expression. */
9486 tree
9487 build_function_call_expr (tree fn, tree arglist)
9489 tree call_expr;
9491 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9492 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9493 call_expr, arglist, NULL_TREE);
9496 /* This function validates the types of a function call argument list
9497 represented as a tree chain of parameters against a specified list
9498 of tree_codes. If the last specifier is a 0, that represents an
9499 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9501 static int
9502 validate_arglist (tree arglist, ...)
9504 enum tree_code code;
9505 int res = 0;
9506 va_list ap;
9508 va_start (ap, arglist);
9512 code = va_arg (ap, enum tree_code);
9513 switch (code)
9515 case 0:
9516 /* This signifies an ellipses, any further arguments are all ok. */
9517 res = 1;
9518 goto end;
9519 case VOID_TYPE:
9520 /* This signifies an endlink, if no arguments remain, return
9521 true, otherwise return false. */
9522 res = arglist == 0;
9523 goto end;
9524 default:
9525 /* If no parameters remain or the parameter's code does not
9526 match the specified code, return false. Otherwise continue
9527 checking any remaining arguments. */
9528 if (arglist == 0)
9529 goto end;
9530 if (code == POINTER_TYPE)
9532 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9533 goto end;
9535 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9536 goto end;
9537 break;
9539 arglist = TREE_CHAIN (arglist);
9541 while (1);
9543 /* We need gotos here since we can only have one VA_CLOSE in a
9544 function. */
9545 end: ;
9546 va_end (ap);
9548 return res;
9551 /* Default target-specific builtin expander that does nothing. */
9554 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9555 rtx target ATTRIBUTE_UNUSED,
9556 rtx subtarget ATTRIBUTE_UNUSED,
9557 enum machine_mode mode ATTRIBUTE_UNUSED,
9558 int ignore ATTRIBUTE_UNUSED)
9560 return NULL_RTX;
9563 /* Returns true is EXP represents data that would potentially reside
9564 in a readonly section. */
9566 static bool
9567 readonly_data_expr (tree exp)
9569 STRIP_NOPS (exp);
9571 if (TREE_CODE (exp) != ADDR_EXPR)
9572 return false;
9574 exp = get_base_address (TREE_OPERAND (exp, 0));
9575 if (!exp)
9576 return false;
9578 /* Make sure we call decl_readonly_section only for trees it
9579 can handle (since it returns true for everything it doesn't
9580 understand). */
9581 if (TREE_CODE (exp) == STRING_CST
9582 || TREE_CODE (exp) == CONSTRUCTOR
9583 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9584 return decl_readonly_section (exp, 0);
9585 else
9586 return false;
9589 /* Simplify a call to the strstr builtin.
9591 Return 0 if no simplification was possible, otherwise return the
9592 simplified form of the call as a tree.
9594 The simplified form may be a constant or other expression which
9595 computes the same value, but in a more efficient manner (including
9596 calls to other builtin functions).
9598 The call may contain arguments which need to be evaluated, but
9599 which are not useful to determine the result of the call. In
9600 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9601 COMPOUND_EXPR will be an argument which must be evaluated.
9602 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9603 COMPOUND_EXPR in the chain will contain the tree for the simplified
9604 form of the builtin function call. */
9606 static tree
9607 fold_builtin_strstr (tree arglist, tree type)
9609 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9610 return 0;
9611 else
9613 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9614 tree fn;
9615 const char *p1, *p2;
9617 p2 = c_getstr (s2);
9618 if (p2 == NULL)
9619 return 0;
9621 p1 = c_getstr (s1);
9622 if (p1 != NULL)
9624 const char *r = strstr (p1, p2);
9625 tree tem;
9627 if (r == NULL)
9628 return build_int_cst (TREE_TYPE (s1), 0);
9630 /* Return an offset into the constant string argument. */
9631 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9632 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9633 return fold_convert (type, tem);
9636 /* The argument is const char *, and the result is char *, so we need
9637 a type conversion here to avoid a warning. */
9638 if (p2[0] == '\0')
9639 return fold_convert (type, s1);
9641 if (p2[1] != '\0')
9642 return 0;
9644 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9645 if (!fn)
9646 return 0;
9648 /* New argument list transforming strstr(s1, s2) to
9649 strchr(s1, s2[0]). */
9650 arglist = build_tree_list (NULL_TREE,
9651 build_int_cst (NULL_TREE, p2[0]));
9652 arglist = tree_cons (NULL_TREE, s1, arglist);
9653 return build_function_call_expr (fn, arglist);
9657 /* Simplify a call to the strchr builtin.
9659 Return 0 if no simplification was possible, otherwise return the
9660 simplified form of the call as a tree.
9662 The simplified form may be a constant or other expression which
9663 computes the same value, but in a more efficient manner (including
9664 calls to other builtin functions).
9666 The call may contain arguments which need to be evaluated, but
9667 which are not useful to determine the result of the call. In
9668 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9669 COMPOUND_EXPR will be an argument which must be evaluated.
9670 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9671 COMPOUND_EXPR in the chain will contain the tree for the simplified
9672 form of the builtin function call. */
9674 static tree
9675 fold_builtin_strchr (tree arglist, tree type)
9677 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9678 return 0;
9679 else
9681 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9682 const char *p1;
9684 if (TREE_CODE (s2) != INTEGER_CST)
9685 return 0;
9687 p1 = c_getstr (s1);
9688 if (p1 != NULL)
9690 char c;
9691 const char *r;
9692 tree tem;
9694 if (target_char_cast (s2, &c))
9695 return 0;
9697 r = strchr (p1, c);
9699 if (r == NULL)
9700 return build_int_cst (TREE_TYPE (s1), 0);
9702 /* Return an offset into the constant string argument. */
9703 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9704 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9705 return fold_convert (type, tem);
9707 return 0;
9711 /* Simplify a call to the strrchr builtin.
9713 Return 0 if no simplification was possible, otherwise return the
9714 simplified form of the call as a tree.
9716 The simplified form may be a constant or other expression which
9717 computes the same value, but in a more efficient manner (including
9718 calls to other builtin functions).
9720 The call may contain arguments which need to be evaluated, but
9721 which are not useful to determine the result of the call. In
9722 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9723 COMPOUND_EXPR will be an argument which must be evaluated.
9724 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9725 COMPOUND_EXPR in the chain will contain the tree for the simplified
9726 form of the builtin function call. */
9728 static tree
9729 fold_builtin_strrchr (tree arglist, tree type)
9731 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9732 return 0;
9733 else
9735 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9736 tree fn;
9737 const char *p1;
9739 if (TREE_CODE (s2) != INTEGER_CST)
9740 return 0;
9742 p1 = c_getstr (s1);
9743 if (p1 != NULL)
9745 char c;
9746 const char *r;
9747 tree tem;
9749 if (target_char_cast (s2, &c))
9750 return 0;
9752 r = strrchr (p1, c);
9754 if (r == NULL)
9755 return build_int_cst (TREE_TYPE (s1), 0);
9757 /* Return an offset into the constant string argument. */
9758 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9759 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9760 return fold_convert (type, tem);
9763 if (! integer_zerop (s2))
9764 return 0;
9766 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9767 if (!fn)
9768 return 0;
9770 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9771 return build_function_call_expr (fn, arglist);
9775 /* Simplify a call to the strpbrk builtin.
9777 Return 0 if no simplification was possible, otherwise return the
9778 simplified form of the call as a tree.
9780 The simplified form may be a constant or other expression which
9781 computes the same value, but in a more efficient manner (including
9782 calls to other builtin functions).
9784 The call may contain arguments which need to be evaluated, but
9785 which are not useful to determine the result of the call. In
9786 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9787 COMPOUND_EXPR will be an argument which must be evaluated.
9788 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9789 COMPOUND_EXPR in the chain will contain the tree for the simplified
9790 form of the builtin function call. */
9792 static tree
9793 fold_builtin_strpbrk (tree arglist, tree type)
9795 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9796 return 0;
9797 else
9799 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9800 tree fn;
9801 const char *p1, *p2;
9803 p2 = c_getstr (s2);
9804 if (p2 == NULL)
9805 return 0;
9807 p1 = c_getstr (s1);
9808 if (p1 != NULL)
9810 const char *r = strpbrk (p1, p2);
9811 tree tem;
9813 if (r == NULL)
9814 return build_int_cst (TREE_TYPE (s1), 0);
9816 /* Return an offset into the constant string argument. */
9817 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9818 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9819 return fold_convert (type, tem);
9822 if (p2[0] == '\0')
9823 /* strpbrk(x, "") == NULL.
9824 Evaluate and ignore s1 in case it had side-effects. */
9825 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9827 if (p2[1] != '\0')
9828 return 0; /* Really call strpbrk. */
9830 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9831 if (!fn)
9832 return 0;
9834 /* New argument list transforming strpbrk(s1, s2) to
9835 strchr(s1, s2[0]). */
9836 arglist = build_tree_list (NULL_TREE,
9837 build_int_cst (NULL_TREE, p2[0]));
9838 arglist = tree_cons (NULL_TREE, s1, arglist);
9839 return build_function_call_expr (fn, arglist);
9843 /* Simplify a call to the strcat builtin.
9845 Return 0 if no simplification was possible, otherwise return the
9846 simplified form of the call as a tree.
9848 The simplified form may be a constant or other expression which
9849 computes the same value, but in a more efficient manner (including
9850 calls to other builtin functions).
9852 The call may contain arguments which need to be evaluated, but
9853 which are not useful to determine the result of the call. In
9854 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9855 COMPOUND_EXPR will be an argument which must be evaluated.
9856 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9857 COMPOUND_EXPR in the chain will contain the tree for the simplified
9858 form of the builtin function call. */
9860 static tree
9861 fold_builtin_strcat (tree arglist)
9863 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9864 return 0;
9865 else
9867 tree dst = TREE_VALUE (arglist),
9868 src = TREE_VALUE (TREE_CHAIN (arglist));
9869 const char *p = c_getstr (src);
9871 /* If the string length is zero, return the dst parameter. */
9872 if (p && *p == '\0')
9873 return dst;
9875 return 0;
9879 /* Simplify a call to the strncat builtin.
9881 Return 0 if no simplification was possible, otherwise return the
9882 simplified form of the call as a tree.
9884 The simplified form may be a constant or other expression which
9885 computes the same value, but in a more efficient manner (including
9886 calls to other builtin functions).
9888 The call may contain arguments which need to be evaluated, but
9889 which are not useful to determine the result of the call. In
9890 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9891 COMPOUND_EXPR will be an argument which must be evaluated.
9892 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9893 COMPOUND_EXPR in the chain will contain the tree for the simplified
9894 form of the builtin function call. */
9896 static tree
9897 fold_builtin_strncat (tree arglist)
9899 if (!validate_arglist (arglist,
9900 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9901 return 0;
9902 else
9904 tree dst = TREE_VALUE (arglist);
9905 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9906 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9907 const char *p = c_getstr (src);
9909 /* If the requested length is zero, or the src parameter string
9910 length is zero, return the dst parameter. */
9911 if (integer_zerop (len) || (p && *p == '\0'))
9912 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9914 /* If the requested len is greater than or equal to the string
9915 length, call strcat. */
9916 if (TREE_CODE (len) == INTEGER_CST && p
9917 && compare_tree_int (len, strlen (p)) >= 0)
9919 tree newarglist
9920 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9921 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9923 /* If the replacement _DECL isn't initialized, don't do the
9924 transformation. */
9925 if (!fn)
9926 return 0;
9928 return build_function_call_expr (fn, newarglist);
9930 return 0;
9934 /* Simplify a call to the strspn builtin.
9936 Return 0 if no simplification was possible, otherwise return the
9937 simplified form of the call as a tree.
9939 The simplified form may be a constant or other expression which
9940 computes the same value, but in a more efficient manner (including
9941 calls to other builtin functions).
9943 The call may contain arguments which need to be evaluated, but
9944 which are not useful to determine the result of the call. In
9945 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9946 COMPOUND_EXPR will be an argument which must be evaluated.
9947 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9948 COMPOUND_EXPR in the chain will contain the tree for the simplified
9949 form of the builtin function call. */
9951 static tree
9952 fold_builtin_strspn (tree arglist)
9954 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9955 return 0;
9956 else
9958 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9959 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9961 /* If both arguments are constants, evaluate at compile-time. */
9962 if (p1 && p2)
9964 const size_t r = strspn (p1, p2);
9965 return size_int (r);
9968 /* If either argument is "", return 0. */
9969 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9970 /* Evaluate and ignore both arguments in case either one has
9971 side-effects. */
9972 return omit_two_operands (integer_type_node, integer_zero_node,
9973 s1, s2);
9974 return 0;
9978 /* Simplify a call to the strcspn builtin.
9980 Return 0 if no simplification was possible, otherwise return the
9981 simplified form of the call as a tree.
9983 The simplified form may be a constant or other expression which
9984 computes the same value, but in a more efficient manner (including
9985 calls to other builtin functions).
9987 The call may contain arguments which need to be evaluated, but
9988 which are not useful to determine the result of the call. In
9989 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9990 COMPOUND_EXPR will be an argument which must be evaluated.
9991 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9992 COMPOUND_EXPR in the chain will contain the tree for the simplified
9993 form of the builtin function call. */
9995 static tree
9996 fold_builtin_strcspn (tree arglist)
9998 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9999 return 0;
10000 else
10002 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10003 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10005 /* If both arguments are constants, evaluate at compile-time. */
10006 if (p1 && p2)
10008 const size_t r = strcspn (p1, p2);
10009 return size_int (r);
10012 /* If the first argument is "", return 0. */
10013 if (p1 && *p1 == '\0')
10015 /* Evaluate and ignore argument s2 in case it has
10016 side-effects. */
10017 return omit_one_operand (integer_type_node,
10018 integer_zero_node, s2);
10021 /* If the second argument is "", return __builtin_strlen(s1). */
10022 if (p2 && *p2 == '\0')
10024 tree newarglist = build_tree_list (NULL_TREE, s1),
10025 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10027 /* If the replacement _DECL isn't initialized, don't do the
10028 transformation. */
10029 if (!fn)
10030 return 0;
10032 return build_function_call_expr (fn, newarglist);
10034 return 0;
10038 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10039 by the builtin will be ignored. UNLOCKED is true is true if this
10040 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10041 the known length of the string. Return NULL_TREE if no simplification
10042 was possible. */
10044 tree
10045 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10047 tree fn;
10048 /* If we're using an unlocked function, assume the other unlocked
10049 functions exist explicitly. */
10050 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10051 : implicit_built_in_decls[BUILT_IN_FPUTC];
10052 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10053 : implicit_built_in_decls[BUILT_IN_FWRITE];
10055 /* If the return value is used, don't do the transformation. */
10056 if (!ignore)
10057 return 0;
10059 /* Verify the arguments in the original call. */
10060 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10061 return 0;
10063 if (! len)
10064 len = c_strlen (TREE_VALUE (arglist), 0);
10066 /* Get the length of the string passed to fputs. If the length
10067 can't be determined, punt. */
10068 if (!len
10069 || TREE_CODE (len) != INTEGER_CST)
10070 return 0;
10072 switch (compare_tree_int (len, 1))
10074 case -1: /* length is 0, delete the call entirely . */
10075 return omit_one_operand (integer_type_node, integer_zero_node,
10076 TREE_VALUE (TREE_CHAIN (arglist)));
10078 case 0: /* length is 1, call fputc. */
10080 const char *p = c_getstr (TREE_VALUE (arglist));
10082 if (p != NULL)
10084 /* New argument list transforming fputs(string, stream) to
10085 fputc(string[0], stream). */
10086 arglist = build_tree_list (NULL_TREE,
10087 TREE_VALUE (TREE_CHAIN (arglist)));
10088 arglist = tree_cons (NULL_TREE,
10089 build_int_cst (NULL_TREE, p[0]),
10090 arglist);
10091 fn = fn_fputc;
10092 break;
10095 /* FALLTHROUGH */
10096 case 1: /* length is greater than 1, call fwrite. */
10098 tree string_arg;
10100 /* If optimizing for size keep fputs. */
10101 if (optimize_size)
10102 return 0;
10103 string_arg = TREE_VALUE (arglist);
10104 /* New argument list transforming fputs(string, stream) to
10105 fwrite(string, 1, len, stream). */
10106 arglist = build_tree_list (NULL_TREE,
10107 TREE_VALUE (TREE_CHAIN (arglist)));
10108 arglist = tree_cons (NULL_TREE, len, arglist);
10109 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10110 arglist = tree_cons (NULL_TREE, string_arg, arglist);
10111 fn = fn_fwrite;
10112 break;
10114 default:
10115 gcc_unreachable ();
10118 /* If the replacement _DECL isn't initialized, don't do the
10119 transformation. */
10120 if (!fn)
10121 return 0;
10123 /* These optimizations are only performed when the result is ignored,
10124 hence there's no need to cast the result to integer_type_node. */
10125 return build_function_call_expr (fn, arglist);
10128 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10129 produced. False otherwise. This is done so that we don't output the error
10130 or warning twice or three times. */
10131 bool
10132 fold_builtin_next_arg (tree arglist)
10134 tree fntype = TREE_TYPE (current_function_decl);
10136 if (TYPE_ARG_TYPES (fntype) == 0
10137 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10138 == void_type_node))
10140 error ("%<va_start%> used in function with fixed args");
10141 return true;
10143 else if (!arglist)
10145 /* Evidently an out of date version of <stdarg.h>; can't validate
10146 va_start's second argument, but can still work as intended. */
10147 warning (0, "%<__builtin_next_arg%> called without an argument");
10148 return true;
10150 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10151 when we checked the arguments and if needed issued a warning. */
10152 else if (!TREE_CHAIN (arglist)
10153 || !integer_zerop (TREE_VALUE (arglist))
10154 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10155 || TREE_CHAIN (TREE_CHAIN (arglist)))
10157 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10158 tree arg = TREE_VALUE (arglist);
10160 if (TREE_CHAIN (arglist))
10162 error ("%<va_start%> used with too many arguments");
10163 return true;
10166 /* Strip off all nops for the sake of the comparison. This
10167 is not quite the same as STRIP_NOPS. It does more.
10168 We must also strip off INDIRECT_EXPR for C++ reference
10169 parameters. */
10170 while (TREE_CODE (arg) == NOP_EXPR
10171 || TREE_CODE (arg) == CONVERT_EXPR
10172 || TREE_CODE (arg) == NON_LVALUE_EXPR
10173 || TREE_CODE (arg) == INDIRECT_REF)
10174 arg = TREE_OPERAND (arg, 0);
10175 if (arg != last_parm)
10177 /* FIXME: Sometimes with the tree optimizers we can get the
10178 not the last argument even though the user used the last
10179 argument. We just warn and set the arg to be the last
10180 argument so that we will get wrong-code because of
10181 it. */
10182 warning (0, "second parameter of %<va_start%> not last named argument");
10184 /* We want to verify the second parameter just once before the tree
10185 optimizers are run and then avoid keeping it in the tree,
10186 as otherwise we could warn even for correct code like:
10187 void foo (int i, ...)
10188 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10189 TREE_VALUE (arglist) = integer_zero_node;
10190 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10192 return false;
10196 /* Simplify a call to the sprintf builtin.
10198 Return 0 if no simplification was possible, otherwise return the
10199 simplified form of the call as a tree. If IGNORED is true, it means that
10200 the caller does not use the returned value of the function. */
10202 static tree
10203 fold_builtin_sprintf (tree arglist, int ignored)
10205 tree call, retval, dest, fmt;
10206 const char *fmt_str = NULL;
10208 /* Verify the required arguments in the original call. We deal with two
10209 types of sprintf() calls: 'sprintf (str, fmt)' and
10210 'sprintf (dest, "%s", orig)'. */
10211 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10212 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10213 VOID_TYPE))
10214 return NULL_TREE;
10216 /* Get the destination string and the format specifier. */
10217 dest = TREE_VALUE (arglist);
10218 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10220 /* Check whether the format is a literal string constant. */
10221 fmt_str = c_getstr (fmt);
10222 if (fmt_str == NULL)
10223 return NULL_TREE;
10225 call = NULL_TREE;
10226 retval = NULL_TREE;
10228 if (!init_target_chars())
10229 return 0;
10231 /* If the format doesn't contain % args or %%, use strcpy. */
10232 if (strchr (fmt_str, target_percent) == NULL)
10234 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10236 if (!fn)
10237 return NULL_TREE;
10239 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10240 'format' is known to contain no % formats. */
10241 arglist = build_tree_list (NULL_TREE, fmt);
10242 arglist = tree_cons (NULL_TREE, dest, arglist);
10243 call = build_function_call_expr (fn, arglist);
10244 if (!ignored)
10245 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10248 /* If the format is "%s", use strcpy if the result isn't used. */
10249 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10251 tree fn, orig;
10252 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10254 if (!fn)
10255 return NULL_TREE;
10257 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10258 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10259 arglist = build_tree_list (NULL_TREE, orig);
10260 arglist = tree_cons (NULL_TREE, dest, arglist);
10261 if (!ignored)
10263 retval = c_strlen (orig, 1);
10264 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10265 return NULL_TREE;
10267 call = build_function_call_expr (fn, arglist);
10270 if (call && retval)
10272 retval = fold_convert
10273 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10274 retval);
10275 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10277 else
10278 return call;
10281 /* Expand a call to __builtin_object_size. */
10284 expand_builtin_object_size (tree exp)
10286 tree ost;
10287 int object_size_type;
10288 tree fndecl = get_callee_fndecl (exp);
10289 tree arglist = TREE_OPERAND (exp, 1);
10290 location_t locus = EXPR_LOCATION (exp);
10292 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10294 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10295 &locus, fndecl);
10296 expand_builtin_trap ();
10297 return const0_rtx;
10300 ost = TREE_VALUE (TREE_CHAIN (arglist));
10301 STRIP_NOPS (ost);
10303 if (TREE_CODE (ost) != INTEGER_CST
10304 || tree_int_cst_sgn (ost) < 0
10305 || compare_tree_int (ost, 3) > 0)
10307 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10308 &locus, fndecl);
10309 expand_builtin_trap ();
10310 return const0_rtx;
10313 object_size_type = tree_low_cst (ost, 0);
10315 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10318 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10319 FCODE is the BUILT_IN_* to use.
10320 Return 0 if we failed; the caller should emit a normal call,
10321 otherwise try to get the result in TARGET, if convenient (and in
10322 mode MODE if that's convenient). */
10324 static rtx
10325 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10326 enum built_in_function fcode)
10328 tree arglist = TREE_OPERAND (exp, 1);
10329 tree dest, src, len, size;
10331 if (!validate_arglist (arglist,
10332 POINTER_TYPE,
10333 fcode == BUILT_IN_MEMSET_CHK
10334 ? INTEGER_TYPE : POINTER_TYPE,
10335 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10336 return 0;
10338 dest = TREE_VALUE (arglist);
10339 src = TREE_VALUE (TREE_CHAIN (arglist));
10340 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10341 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10343 if (! host_integerp (size, 1))
10344 return 0;
10346 if (host_integerp (len, 1) || integer_all_onesp (size))
10348 tree fn;
10350 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10352 location_t locus = EXPR_LOCATION (exp);
10353 warning (0, "%Hcall to %D will always overflow destination buffer",
10354 &locus, get_callee_fndecl (exp));
10355 return 0;
10358 arglist = build_tree_list (NULL_TREE, len);
10359 arglist = tree_cons (NULL_TREE, src, arglist);
10360 arglist = tree_cons (NULL_TREE, dest, arglist);
10362 fn = NULL_TREE;
10363 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10364 mem{cpy,pcpy,move,set} is available. */
10365 switch (fcode)
10367 case BUILT_IN_MEMCPY_CHK:
10368 fn = built_in_decls[BUILT_IN_MEMCPY];
10369 break;
10370 case BUILT_IN_MEMPCPY_CHK:
10371 fn = built_in_decls[BUILT_IN_MEMPCPY];
10372 break;
10373 case BUILT_IN_MEMMOVE_CHK:
10374 fn = built_in_decls[BUILT_IN_MEMMOVE];
10375 break;
10376 case BUILT_IN_MEMSET_CHK:
10377 fn = built_in_decls[BUILT_IN_MEMSET];
10378 break;
10379 default:
10380 break;
10383 if (! fn)
10384 return 0;
10386 fn = build_function_call_expr (fn, arglist);
10387 if (TREE_CODE (fn) == CALL_EXPR)
10388 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10389 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10391 else if (fcode == BUILT_IN_MEMSET_CHK)
10392 return 0;
10393 else
10395 unsigned int dest_align
10396 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10398 /* If DEST is not a pointer type, call the normal function. */
10399 if (dest_align == 0)
10400 return 0;
10402 /* If SRC and DEST are the same (and not volatile), do nothing. */
10403 if (operand_equal_p (src, dest, 0))
10405 tree expr;
10407 if (fcode != BUILT_IN_MEMPCPY_CHK)
10409 /* Evaluate and ignore LEN in case it has side-effects. */
10410 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10411 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10414 len = fold_convert (TREE_TYPE (dest), len);
10415 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10416 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10419 /* __memmove_chk special case. */
10420 if (fcode == BUILT_IN_MEMMOVE_CHK)
10422 unsigned int src_align
10423 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10425 if (src_align == 0)
10426 return 0;
10428 /* If src is categorized for a readonly section we can use
10429 normal __memcpy_chk. */
10430 if (readonly_data_expr (src))
10432 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10433 if (!fn)
10434 return 0;
10435 fn = build_function_call_expr (fn, arglist);
10436 if (TREE_CODE (fn) == CALL_EXPR)
10437 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10438 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10441 return 0;
10445 /* Emit warning if a buffer overflow is detected at compile time. */
10447 static void
10448 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10450 int arg_mask, is_strlen = 0;
10451 tree arglist = TREE_OPERAND (exp, 1), a;
10452 tree len, size;
10453 location_t locus;
10455 switch (fcode)
10457 case BUILT_IN_STRCPY_CHK:
10458 case BUILT_IN_STPCPY_CHK:
10459 /* For __strcat_chk the warning will be emitted only if overflowing
10460 by at least strlen (dest) + 1 bytes. */
10461 case BUILT_IN_STRCAT_CHK:
10462 arg_mask = 6;
10463 is_strlen = 1;
10464 break;
10465 case BUILT_IN_STRNCAT_CHK:
10466 /* For __strncat_chk the warning will be emitted only if overflowing
10467 by at least strlen (dest) + 1 bytes. */
10468 arg_mask = 12;
10469 break;
10470 case BUILT_IN_STRNCPY_CHK:
10471 arg_mask = 12;
10472 break;
10473 case BUILT_IN_SNPRINTF_CHK:
10474 case BUILT_IN_VSNPRINTF_CHK:
10475 arg_mask = 10;
10476 break;
10477 default:
10478 gcc_unreachable ();
10481 len = NULL_TREE;
10482 size = NULL_TREE;
10483 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10484 if (arg_mask & 1)
10486 if (len)
10487 size = a;
10488 else
10489 len = a;
10492 if (!len || !size)
10493 return;
10495 len = TREE_VALUE (len);
10496 size = TREE_VALUE (size);
10498 if (! host_integerp (size, 1) || integer_all_onesp (size))
10499 return;
10501 if (is_strlen)
10503 len = c_strlen (len, 1);
10504 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10505 return;
10507 else if (fcode == BUILT_IN_STRNCAT_CHK)
10509 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10510 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10511 return;
10512 src = c_strlen (src, 1);
10513 if (! src || ! host_integerp (src, 1))
10515 locus = EXPR_LOCATION (exp);
10516 warning (0, "%Hcall to %D might overflow destination buffer",
10517 &locus, get_callee_fndecl (exp));
10518 return;
10520 else if (tree_int_cst_lt (src, size))
10521 return;
10523 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10524 return;
10526 locus = EXPR_LOCATION (exp);
10527 warning (0, "%Hcall to %D will always overflow destination buffer",
10528 &locus, get_callee_fndecl (exp));
10531 /* Emit warning if a buffer overflow is detected at compile time
10532 in __sprintf_chk/__vsprintf_chk calls. */
10534 static void
10535 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10537 tree arglist = TREE_OPERAND (exp, 1);
10538 tree dest, size, len, fmt, flag;
10539 const char *fmt_str;
10541 /* Verify the required arguments in the original call. */
10542 if (! arglist)
10543 return;
10544 dest = TREE_VALUE (arglist);
10545 arglist = TREE_CHAIN (arglist);
10546 if (! arglist)
10547 return;
10548 flag = TREE_VALUE (arglist);
10549 arglist = TREE_CHAIN (arglist);
10550 if (! arglist)
10551 return;
10552 size = TREE_VALUE (arglist);
10553 arglist = TREE_CHAIN (arglist);
10554 if (! arglist)
10555 return;
10556 fmt = TREE_VALUE (arglist);
10557 arglist = TREE_CHAIN (arglist);
10559 if (! host_integerp (size, 1) || integer_all_onesp (size))
10560 return;
10562 /* Check whether the format is a literal string constant. */
10563 fmt_str = c_getstr (fmt);
10564 if (fmt_str == NULL)
10565 return;
10567 if (!init_target_chars())
10568 return;
10570 /* If the format doesn't contain % args or %%, we know its size. */
10571 if (strchr (fmt_str, target_percent) == 0)
10572 len = build_int_cstu (size_type_node, strlen (fmt_str));
10573 /* If the format is "%s" and first ... argument is a string literal,
10574 we know it too. */
10575 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10577 tree arg;
10579 if (! arglist)
10580 return;
10581 arg = TREE_VALUE (arglist);
10582 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10583 return;
10585 len = c_strlen (arg, 1);
10586 if (!len || ! host_integerp (len, 1))
10587 return;
10589 else
10590 return;
10592 if (! tree_int_cst_lt (len, size))
10594 location_t locus = EXPR_LOCATION (exp);
10595 warning (0, "%Hcall to %D will always overflow destination buffer",
10596 &locus, get_callee_fndecl (exp));
10600 /* Fold a call to __builtin_object_size, if possible. */
10602 tree
10603 fold_builtin_object_size (tree arglist)
10605 tree ptr, ost, ret = 0;
10606 int object_size_type;
10608 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10609 return 0;
10611 ptr = TREE_VALUE (arglist);
10612 ost = TREE_VALUE (TREE_CHAIN (arglist));
10613 STRIP_NOPS (ost);
10615 if (TREE_CODE (ost) != INTEGER_CST
10616 || tree_int_cst_sgn (ost) < 0
10617 || compare_tree_int (ost, 3) > 0)
10618 return 0;
10620 object_size_type = tree_low_cst (ost, 0);
10622 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10623 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10624 and (size_t) 0 for types 2 and 3. */
10625 if (TREE_SIDE_EFFECTS (ptr))
10626 return fold_convert (size_type_node,
10627 object_size_type < 2
10628 ? integer_minus_one_node : integer_zero_node);
10630 if (TREE_CODE (ptr) == ADDR_EXPR)
10631 ret = build_int_cstu (size_type_node,
10632 compute_builtin_object_size (ptr, object_size_type));
10634 else if (TREE_CODE (ptr) == SSA_NAME)
10636 unsigned HOST_WIDE_INT bytes;
10638 /* If object size is not known yet, delay folding until
10639 later. Maybe subsequent passes will help determining
10640 it. */
10641 bytes = compute_builtin_object_size (ptr, object_size_type);
10642 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10643 ? -1 : 0))
10644 ret = build_int_cstu (size_type_node, bytes);
10647 if (ret)
10649 ret = force_fit_type (ret, -1, false, false);
10650 if (TREE_CONSTANT_OVERFLOW (ret))
10651 ret = 0;
10654 return ret;
10657 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10658 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10659 code of the builtin. If MAXLEN is not NULL, it is maximum length
10660 passed as third argument. */
10662 tree
10663 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10664 enum built_in_function fcode)
10666 tree dest, src, len, size, fn;
10668 if (!validate_arglist (arglist,
10669 POINTER_TYPE,
10670 fcode == BUILT_IN_MEMSET_CHK
10671 ? INTEGER_TYPE : POINTER_TYPE,
10672 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10673 return 0;
10675 dest = TREE_VALUE (arglist);
10676 /* Actually val for __memset_chk, but it doesn't matter. */
10677 src = TREE_VALUE (TREE_CHAIN (arglist));
10678 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10679 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10681 /* If SRC and DEST are the same (and not volatile), return DEST
10682 (resp. DEST+LEN for __mempcpy_chk). */
10683 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10685 if (fcode != BUILT_IN_MEMPCPY_CHK)
10686 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10687 else
10689 tree temp = fold_convert (TREE_TYPE (dest), len);
10690 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10691 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10695 if (! host_integerp (size, 1))
10696 return 0;
10698 if (! integer_all_onesp (size))
10700 if (! host_integerp (len, 1))
10702 /* If LEN is not constant, try MAXLEN too.
10703 For MAXLEN only allow optimizing into non-_ocs function
10704 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10705 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10707 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10709 /* (void) __mempcpy_chk () can be optimized into
10710 (void) __memcpy_chk (). */
10711 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10712 if (!fn)
10713 return 0;
10715 return build_function_call_expr (fn, arglist);
10717 return 0;
10720 else
10721 maxlen = len;
10723 if (tree_int_cst_lt (size, maxlen))
10724 return 0;
10727 arglist = build_tree_list (NULL_TREE, len);
10728 arglist = tree_cons (NULL_TREE, src, arglist);
10729 arglist = tree_cons (NULL_TREE, dest, arglist);
10731 fn = NULL_TREE;
10732 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10733 mem{cpy,pcpy,move,set} is available. */
10734 switch (fcode)
10736 case BUILT_IN_MEMCPY_CHK:
10737 fn = built_in_decls[BUILT_IN_MEMCPY];
10738 break;
10739 case BUILT_IN_MEMPCPY_CHK:
10740 fn = built_in_decls[BUILT_IN_MEMPCPY];
10741 break;
10742 case BUILT_IN_MEMMOVE_CHK:
10743 fn = built_in_decls[BUILT_IN_MEMMOVE];
10744 break;
10745 case BUILT_IN_MEMSET_CHK:
10746 fn = built_in_decls[BUILT_IN_MEMSET];
10747 break;
10748 default:
10749 break;
10752 if (!fn)
10753 return 0;
10755 return build_function_call_expr (fn, arglist);
10758 /* Fold a call to the __st[rp]cpy_chk builtin.
10759 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10760 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10761 strings passed as second argument. */
10763 tree
10764 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10765 enum built_in_function fcode)
10767 tree dest, src, size, len, fn;
10769 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10770 VOID_TYPE))
10771 return 0;
10773 dest = TREE_VALUE (arglist);
10774 src = TREE_VALUE (TREE_CHAIN (arglist));
10775 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10777 /* If SRC and DEST are the same (and not volatile), return DEST. */
10778 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10779 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10781 if (! host_integerp (size, 1))
10782 return 0;
10784 if (! integer_all_onesp (size))
10786 len = c_strlen (src, 1);
10787 if (! len || ! host_integerp (len, 1))
10789 /* If LEN is not constant, try MAXLEN too.
10790 For MAXLEN only allow optimizing into non-_ocs function
10791 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10792 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10794 if (fcode == BUILT_IN_STPCPY_CHK)
10796 if (! ignore)
10797 return 0;
10799 /* If return value of __stpcpy_chk is ignored,
10800 optimize into __strcpy_chk. */
10801 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10802 if (!fn)
10803 return 0;
10805 return build_function_call_expr (fn, arglist);
10808 if (! len || TREE_SIDE_EFFECTS (len))
10809 return 0;
10811 /* If c_strlen returned something, but not a constant,
10812 transform __strcpy_chk into __memcpy_chk. */
10813 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10814 if (!fn)
10815 return 0;
10817 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10818 arglist = build_tree_list (NULL_TREE, size);
10819 arglist = tree_cons (NULL_TREE, len, arglist);
10820 arglist = tree_cons (NULL_TREE, src, arglist);
10821 arglist = tree_cons (NULL_TREE, dest, arglist);
10822 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10823 build_function_call_expr (fn, arglist));
10826 else
10827 maxlen = len;
10829 if (! tree_int_cst_lt (maxlen, size))
10830 return 0;
10833 arglist = build_tree_list (NULL_TREE, src);
10834 arglist = tree_cons (NULL_TREE, dest, arglist);
10836 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10837 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10838 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10839 if (!fn)
10840 return 0;
10842 return build_function_call_expr (fn, arglist);
10845 /* Fold a call to the __strncpy_chk builtin.
10846 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10848 tree
10849 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10851 tree dest, src, size, len, fn;
10853 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10854 INTEGER_TYPE, VOID_TYPE))
10855 return 0;
10857 dest = TREE_VALUE (arglist);
10858 src = TREE_VALUE (TREE_CHAIN (arglist));
10859 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10860 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10862 if (! host_integerp (size, 1))
10863 return 0;
10865 if (! integer_all_onesp (size))
10867 if (! host_integerp (len, 1))
10869 /* If LEN is not constant, try MAXLEN too.
10870 For MAXLEN only allow optimizing into non-_ocs function
10871 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10872 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10873 return 0;
10875 else
10876 maxlen = len;
10878 if (tree_int_cst_lt (size, maxlen))
10879 return 0;
10882 arglist = build_tree_list (NULL_TREE, len);
10883 arglist = tree_cons (NULL_TREE, src, arglist);
10884 arglist = tree_cons (NULL_TREE, dest, arglist);
10886 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10887 fn = built_in_decls[BUILT_IN_STRNCPY];
10888 if (!fn)
10889 return 0;
10891 return build_function_call_expr (fn, arglist);
10894 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10896 static tree
10897 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10899 tree dest, src, size, fn;
10900 const char *p;
10902 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10903 VOID_TYPE))
10904 return 0;
10906 dest = TREE_VALUE (arglist);
10907 src = TREE_VALUE (TREE_CHAIN (arglist));
10908 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10910 p = c_getstr (src);
10911 /* If the SRC parameter is "", return DEST. */
10912 if (p && *p == '\0')
10913 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10915 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10916 return 0;
10918 arglist = build_tree_list (NULL_TREE, src);
10919 arglist = tree_cons (NULL_TREE, dest, arglist);
10921 /* If __builtin_strcat_chk is used, assume strcat is available. */
10922 fn = built_in_decls[BUILT_IN_STRCAT];
10923 if (!fn)
10924 return 0;
10926 return build_function_call_expr (fn, arglist);
10929 /* Fold a call to the __strncat_chk builtin EXP. */
10931 static tree
10932 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10934 tree dest, src, size, len, fn;
10935 const char *p;
10937 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10938 INTEGER_TYPE, VOID_TYPE))
10939 return 0;
10941 dest = TREE_VALUE (arglist);
10942 src = TREE_VALUE (TREE_CHAIN (arglist));
10943 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10944 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10946 p = c_getstr (src);
10947 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10948 if (p && *p == '\0')
10949 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10950 else if (integer_zerop (len))
10951 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10953 if (! host_integerp (size, 1))
10954 return 0;
10956 if (! integer_all_onesp (size))
10958 tree src_len = c_strlen (src, 1);
10959 if (src_len
10960 && host_integerp (src_len, 1)
10961 && host_integerp (len, 1)
10962 && ! tree_int_cst_lt (len, src_len))
10964 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10965 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10966 if (!fn)
10967 return 0;
10969 arglist = build_tree_list (NULL_TREE, size);
10970 arglist = tree_cons (NULL_TREE, src, arglist);
10971 arglist = tree_cons (NULL_TREE, dest, arglist);
10972 return build_function_call_expr (fn, arglist);
10974 return 0;
10977 arglist = build_tree_list (NULL_TREE, len);
10978 arglist = tree_cons (NULL_TREE, src, arglist);
10979 arglist = tree_cons (NULL_TREE, dest, arglist);
10981 /* If __builtin_strncat_chk is used, assume strncat is available. */
10982 fn = built_in_decls[BUILT_IN_STRNCAT];
10983 if (!fn)
10984 return 0;
10986 return build_function_call_expr (fn, arglist);
10989 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10990 a normal call should be emitted rather than expanding the function
10991 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10993 static tree
10994 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10996 tree dest, size, len, fn, fmt, flag;
10997 const char *fmt_str;
10999 /* Verify the required arguments in the original call. */
11000 if (! arglist)
11001 return 0;
11002 dest = TREE_VALUE (arglist);
11003 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11004 return 0;
11005 arglist = TREE_CHAIN (arglist);
11006 if (! arglist)
11007 return 0;
11008 flag = TREE_VALUE (arglist);
11009 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11010 return 0;
11011 arglist = TREE_CHAIN (arglist);
11012 if (! arglist)
11013 return 0;
11014 size = TREE_VALUE (arglist);
11015 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11016 return 0;
11017 arglist = TREE_CHAIN (arglist);
11018 if (! arglist)
11019 return 0;
11020 fmt = TREE_VALUE (arglist);
11021 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11022 return 0;
11023 arglist = TREE_CHAIN (arglist);
11025 if (! host_integerp (size, 1))
11026 return 0;
11028 len = NULL_TREE;
11030 if (!init_target_chars())
11031 return 0;
11033 /* Check whether the format is a literal string constant. */
11034 fmt_str = c_getstr (fmt);
11035 if (fmt_str != NULL)
11037 /* If the format doesn't contain % args or %%, we know the size. */
11038 if (strchr (fmt_str, target_percent) == 0)
11040 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11041 len = build_int_cstu (size_type_node, strlen (fmt_str));
11043 /* If the format is "%s" and first ... argument is a string literal,
11044 we know the size too. */
11045 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11047 tree arg;
11049 if (arglist && !TREE_CHAIN (arglist))
11051 arg = TREE_VALUE (arglist);
11052 if (POINTER_TYPE_P (TREE_TYPE (arg)))
11054 len = c_strlen (arg, 1);
11055 if (! len || ! host_integerp (len, 1))
11056 len = NULL_TREE;
11062 if (! integer_all_onesp (size))
11064 if (! len || ! tree_int_cst_lt (len, size))
11065 return 0;
11068 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11069 or if format doesn't contain % chars or is "%s". */
11070 if (! integer_zerop (flag))
11072 if (fmt_str == NULL)
11073 return 0;
11074 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11075 return 0;
11078 arglist = tree_cons (NULL_TREE, fmt, arglist);
11079 arglist = tree_cons (NULL_TREE, dest, arglist);
11081 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11082 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11083 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11084 if (!fn)
11085 return 0;
11087 return build_function_call_expr (fn, arglist);
11090 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11091 a normal call should be emitted rather than expanding the function
11092 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11093 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11094 passed as second argument. */
11096 tree
11097 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11098 enum built_in_function fcode)
11100 tree dest, size, len, fn, fmt, flag;
11101 const char *fmt_str;
11103 /* Verify the required arguments in the original call. */
11104 if (! arglist)
11105 return 0;
11106 dest = TREE_VALUE (arglist);
11107 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11108 return 0;
11109 arglist = TREE_CHAIN (arglist);
11110 if (! arglist)
11111 return 0;
11112 len = TREE_VALUE (arglist);
11113 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11114 return 0;
11115 arglist = TREE_CHAIN (arglist);
11116 if (! arglist)
11117 return 0;
11118 flag = TREE_VALUE (arglist);
11119 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11120 return 0;
11121 arglist = TREE_CHAIN (arglist);
11122 if (! arglist)
11123 return 0;
11124 size = TREE_VALUE (arglist);
11125 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11126 return 0;
11127 arglist = TREE_CHAIN (arglist);
11128 if (! arglist)
11129 return 0;
11130 fmt = TREE_VALUE (arglist);
11131 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11132 return 0;
11133 arglist = TREE_CHAIN (arglist);
11135 if (! host_integerp (size, 1))
11136 return 0;
11138 if (! integer_all_onesp (size))
11140 if (! host_integerp (len, 1))
11142 /* If LEN is not constant, try MAXLEN too.
11143 For MAXLEN only allow optimizing into non-_ocs function
11144 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11145 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11146 return 0;
11148 else
11149 maxlen = len;
11151 if (tree_int_cst_lt (size, maxlen))
11152 return 0;
11155 if (!init_target_chars())
11156 return 0;
11158 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11159 or if format doesn't contain % chars or is "%s". */
11160 if (! integer_zerop (flag))
11162 fmt_str = c_getstr (fmt);
11163 if (fmt_str == NULL)
11164 return 0;
11165 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11166 return 0;
11169 arglist = tree_cons (NULL_TREE, fmt, arglist);
11170 arglist = tree_cons (NULL_TREE, len, arglist);
11171 arglist = tree_cons (NULL_TREE, dest, arglist);
11173 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11174 available. */
11175 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11176 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11177 if (!fn)
11178 return 0;
11180 return build_function_call_expr (fn, arglist);
11183 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11185 Return 0 if no simplification was possible, otherwise return the
11186 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11187 code of the function to be simplified. */
11189 static tree
11190 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11191 enum built_in_function fcode)
11193 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11194 const char *fmt_str = NULL;
11196 /* If the return value is used, don't do the transformation. */
11197 if (! ignore)
11198 return 0;
11200 /* Verify the required arguments in the original call. */
11201 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11203 tree flag;
11205 if (! arglist)
11206 return 0;
11207 flag = TREE_VALUE (arglist);
11208 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11209 || TREE_SIDE_EFFECTS (flag))
11210 return 0;
11211 arglist = TREE_CHAIN (arglist);
11214 if (! arglist)
11215 return 0;
11216 fmt = TREE_VALUE (arglist);
11217 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11218 return 0;
11219 arglist = TREE_CHAIN (arglist);
11221 /* Check whether the format is a literal string constant. */
11222 fmt_str = c_getstr (fmt);
11223 if (fmt_str == NULL)
11224 return NULL_TREE;
11226 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11228 /* If we're using an unlocked function, assume the other
11229 unlocked functions exist explicitly. */
11230 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11231 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11233 else
11235 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11236 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11239 if (!init_target_chars())
11240 return 0;
11242 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11244 const char *str;
11246 if (strcmp (fmt_str, target_percent_s) == 0)
11248 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11249 return 0;
11251 if (! arglist
11252 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11253 || TREE_CHAIN (arglist))
11254 return 0;
11256 str = c_getstr (TREE_VALUE (arglist));
11257 if (str == NULL)
11258 return 0;
11260 else
11262 /* The format specifier doesn't contain any '%' characters. */
11263 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11264 && arglist)
11265 return 0;
11266 str = fmt_str;
11269 /* If the string was "", printf does nothing. */
11270 if (str[0] == '\0')
11271 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11273 /* If the string has length of 1, call putchar. */
11274 if (str[1] == '\0')
11276 /* Given printf("c"), (where c is any one character,)
11277 convert "c"[0] to an int and pass that to the replacement
11278 function. */
11279 arg = build_int_cst (NULL_TREE, str[0]);
11280 arglist = build_tree_list (NULL_TREE, arg);
11281 fn = fn_putchar;
11283 else
11285 /* If the string was "string\n", call puts("string"). */
11286 size_t len = strlen (str);
11287 if ((unsigned char)str[len - 1] == target_newline)
11289 /* Create a NUL-terminated string that's one char shorter
11290 than the original, stripping off the trailing '\n'. */
11291 char *newstr = alloca (len);
11292 memcpy (newstr, str, len - 1);
11293 newstr[len - 1] = 0;
11295 arg = build_string_literal (len, newstr);
11296 arglist = build_tree_list (NULL_TREE, arg);
11297 fn = fn_puts;
11299 else
11300 /* We'd like to arrange to call fputs(string,stdout) here,
11301 but we need stdout and don't have a way to get it yet. */
11302 return 0;
11306 /* The other optimizations can be done only on the non-va_list variants. */
11307 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11308 return 0;
11310 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11311 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11313 if (! arglist
11314 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11315 || TREE_CHAIN (arglist))
11316 return 0;
11317 fn = fn_puts;
11320 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11321 else if (strcmp (fmt_str, target_percent_c) == 0)
11323 if (! arglist
11324 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11325 || TREE_CHAIN (arglist))
11326 return 0;
11327 fn = fn_putchar;
11330 if (!fn)
11331 return 0;
11333 call = build_function_call_expr (fn, arglist);
11334 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11337 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11339 Return 0 if no simplification was possible, otherwise return the
11340 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11341 code of the function to be simplified. */
11343 static tree
11344 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11345 enum built_in_function fcode)
11347 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11348 const char *fmt_str = NULL;
11350 /* If the return value is used, don't do the transformation. */
11351 if (! ignore)
11352 return 0;
11354 /* Verify the required arguments in the original call. */
11355 if (! arglist)
11356 return 0;
11357 fp = TREE_VALUE (arglist);
11358 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11359 return 0;
11360 arglist = TREE_CHAIN (arglist);
11362 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11364 tree flag;
11366 if (! arglist)
11367 return 0;
11368 flag = TREE_VALUE (arglist);
11369 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11370 || TREE_SIDE_EFFECTS (flag))
11371 return 0;
11372 arglist = TREE_CHAIN (arglist);
11375 if (! arglist)
11376 return 0;
11377 fmt = TREE_VALUE (arglist);
11378 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11379 return 0;
11380 arglist = TREE_CHAIN (arglist);
11382 /* Check whether the format is a literal string constant. */
11383 fmt_str = c_getstr (fmt);
11384 if (fmt_str == NULL)
11385 return NULL_TREE;
11387 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11389 /* If we're using an unlocked function, assume the other
11390 unlocked functions exist explicitly. */
11391 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11392 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11394 else
11396 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11397 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11400 if (!init_target_chars())
11401 return 0;
11403 /* If the format doesn't contain % args or %%, use strcpy. */
11404 if (strchr (fmt_str, target_percent) == NULL)
11406 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11407 && arglist)
11408 return 0;
11410 /* If the format specifier was "", fprintf does nothing. */
11411 if (fmt_str[0] == '\0')
11413 /* If FP has side-effects, just wait until gimplification is
11414 done. */
11415 if (TREE_SIDE_EFFECTS (fp))
11416 return 0;
11418 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11421 /* When "string" doesn't contain %, replace all cases of
11422 fprintf (fp, string) with fputs (string, fp). The fputs
11423 builtin will take care of special cases like length == 1. */
11424 arglist = build_tree_list (NULL_TREE, fp);
11425 arglist = tree_cons (NULL_TREE, fmt, arglist);
11426 fn = fn_fputs;
11429 /* The other optimizations can be done only on the non-va_list variants. */
11430 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11431 return 0;
11433 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11434 else if (strcmp (fmt_str, target_percent_s) == 0)
11436 if (! arglist
11437 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11438 || TREE_CHAIN (arglist))
11439 return 0;
11440 arg = TREE_VALUE (arglist);
11441 arglist = build_tree_list (NULL_TREE, fp);
11442 arglist = tree_cons (NULL_TREE, arg, arglist);
11443 fn = fn_fputs;
11446 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11447 else if (strcmp (fmt_str, target_percent_c) == 0)
11449 if (! arglist
11450 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11451 || TREE_CHAIN (arglist))
11452 return 0;
11453 arg = TREE_VALUE (arglist);
11454 arglist = build_tree_list (NULL_TREE, fp);
11455 arglist = tree_cons (NULL_TREE, arg, arglist);
11456 fn = fn_fputc;
11459 if (!fn)
11460 return 0;
11462 call = build_function_call_expr (fn, arglist);
11463 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11466 /* Initialize format string characters in the target charset. */
11468 static bool
11469 init_target_chars (void)
11471 static bool init;
11472 if (!init)
11474 target_newline = lang_hooks.to_target_charset ('\n');
11475 target_percent = lang_hooks.to_target_charset ('%');
11476 target_c = lang_hooks.to_target_charset ('c');
11477 target_s = lang_hooks.to_target_charset ('s');
11478 if (target_newline == 0 || target_percent == 0 || target_c == 0
11479 || target_s == 0)
11480 return false;
11482 target_percent_c[0] = target_percent;
11483 target_percent_c[1] = target_c;
11484 target_percent_c[2] = '\0';
11486 target_percent_s[0] = target_percent;
11487 target_percent_s[1] = target_s;
11488 target_percent_s[2] = '\0';
11490 target_percent_s_newline[0] = target_percent;
11491 target_percent_s_newline[1] = target_s;
11492 target_percent_s_newline[2] = target_newline;
11493 target_percent_s_newline[3] = '\0';
11495 init = true;
11497 return true;
11500 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11501 and no overflow/underflow occurred. INEXACT is true if M was not
11502 exacly calculated. TYPE is the tree type for the result. This
11503 function assumes that you cleared the MPFR flags and then
11504 calculated M to see if anything subsequently set a flag prior to
11505 entering this function. Return NULL_TREE if any checks fail. */
11507 static tree
11508 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11510 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11511 overflow/underflow occurred. If -frounding-math, proceed iff the
11512 result of calling FUNC was exact. */
11513 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11514 && (!flag_rounding_math || !inexact))
11516 REAL_VALUE_TYPE rr;
11518 real_from_mpfr (&rr, m);
11519 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11520 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11521 but the mpft_t is not, then we underflowed in the
11522 conversion. */
11523 if (!real_isnan (&rr) && !real_isinf (&rr)
11524 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11526 REAL_VALUE_TYPE rmode;
11528 real_convert (&rmode, TYPE_MODE (type), &rr);
11529 /* Proceed iff the specified mode can hold the value. */
11530 if (real_identical (&rmode, &rr))
11531 return build_real (type, rmode);
11534 return NULL_TREE;
11537 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11538 FUNC on it and return the resulting value as a tree with type TYPE.
11539 If MIN and/or MAX are not NULL, then the supplied ARG must be
11540 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11541 acceptable values, otherwise they are not. The mpfr precision is
11542 set to the precision of TYPE. We assume that function FUNC returns
11543 zero if the result could be calculated exactly within the requested
11544 precision. */
11546 static tree
11547 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11548 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11549 bool inclusive)
11551 tree result = NULL_TREE;
11553 STRIP_NOPS (arg);
11555 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11557 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11559 if (!real_isnan (ra) && !real_isinf (ra)
11560 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11561 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11563 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11564 int inexact;
11565 mpfr_t m;
11567 mpfr_init2 (m, prec);
11568 mpfr_from_real (m, ra);
11569 mpfr_clear_flags();
11570 inexact = func (m, m, GMP_RNDN);
11571 result = do_mpfr_ckconv (m, type, inexact);
11572 mpfr_clear (m);
11576 return result;
11579 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11580 FUNC on it and return the resulting value as a tree with type TYPE.
11581 The mpfr precision is set to the precision of TYPE. We assume that
11582 function FUNC returns zero if the result could be calculated
11583 exactly within the requested precision. */
11585 static tree
11586 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11587 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11589 tree result = NULL_TREE;
11591 STRIP_NOPS (arg1);
11592 STRIP_NOPS (arg2);
11594 if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11595 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
11597 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11598 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11600 if (!real_isnan (ra1) && !real_isinf (ra1)
11601 && !real_isnan (ra2) && !real_isinf (ra2))
11603 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11604 int inexact;
11605 mpfr_t m1, m2;
11607 mpfr_inits2 (prec, m1, m2, NULL);
11608 mpfr_from_real (m1, ra1);
11609 mpfr_from_real (m2, ra2);
11610 mpfr_clear_flags();
11611 inexact = func (m1, m1, m2, GMP_RNDN);
11612 result = do_mpfr_ckconv (m1, type, inexact);
11613 mpfr_clears (m1, m2, NULL);
11617 return result;
11620 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11621 FUNC on it and return the resulting value as a tree with type TYPE.
11622 The mpfr precision is set to the precision of TYPE. We assume that
11623 function FUNC returns zero if the result could be calculated
11624 exactly within the requested precision. */
11626 static tree
11627 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11628 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11630 tree result = NULL_TREE;
11632 STRIP_NOPS (arg1);
11633 STRIP_NOPS (arg2);
11634 STRIP_NOPS (arg3);
11636 if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11637 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2)
11638 && TREE_CODE (arg3) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg3))
11640 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11641 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11642 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11644 if (!real_isnan (ra1) && !real_isinf (ra1)
11645 && !real_isnan (ra2) && !real_isinf (ra2)
11646 && !real_isnan (ra3) && !real_isinf (ra3))
11648 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11649 int inexact;
11650 mpfr_t m1, m2, m3;
11652 mpfr_inits2 (prec, m1, m2, m3, NULL);
11653 mpfr_from_real (m1, ra1);
11654 mpfr_from_real (m2, ra2);
11655 mpfr_from_real (m3, ra3);
11656 mpfr_clear_flags();
11657 inexact = func (m1, m1, m2, m3, GMP_RNDN);
11658 result = do_mpfr_ckconv (m1, type, inexact);
11659 mpfr_clears (m1, m2, m3, NULL);
11663 return result;
11666 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11667 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11668 The type is taken from the type of ARG and is used for setting the
11669 precision of the calculation and results. */
11671 static tree
11672 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11674 tree result = NULL_TREE;
11676 STRIP_NOPS (arg);
11678 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11680 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11682 if (!real_isnan (ra) && !real_isinf (ra))
11684 tree const type = TREE_TYPE (arg);
11685 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11686 tree result_s, result_c;
11687 int inexact;
11688 mpfr_t m, ms, mc;
11690 mpfr_inits2 (prec, m, ms, mc, NULL);
11691 mpfr_from_real (m, ra);
11692 mpfr_clear_flags();
11693 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11694 result_s = do_mpfr_ckconv (ms, type, inexact);
11695 result_c = do_mpfr_ckconv (mc, type, inexact);
11696 mpfr_clears (m, ms, mc, NULL);
11697 if (result_s && result_c)
11699 /* Dereference the sin/cos pointer arguments. */
11700 arg_sinp = build_fold_indirect_ref (arg_sinp);
11701 arg_cosp = build_fold_indirect_ref (arg_cosp);
11702 /* Proceed if valid pointer type were passed in. */
11703 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11704 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11706 /* Set the values. */
11707 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp, result_s);
11708 TREE_SIDE_EFFECTS (result_s) = 1;
11709 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp, result_c);
11710 TREE_SIDE_EFFECTS (result_c) = 1;
11711 /* Combine the assignments into a compound expr. */
11712 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11713 result_s, result_c));
11718 return result;