* config/i386/i386.h (GENERAL_REGNO_P): Use STACK_POINTER_REGNUM.
[official-gcc.git] / gcc / builtins.c
blobecd946176998c54df17691cbea3137e758de2b7a
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);
209 /* Return true if NODE should be considered for inline expansion regardless
210 of the optimization level. This means whenever a function is invoked with
211 its "internal" name, which normally contains the prefix "__builtin". */
213 static bool called_as_built_in (tree node)
215 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
216 if (strncmp (name, "__builtin_", 10) == 0)
217 return true;
218 if (strncmp (name, "__sync_", 7) == 0)
219 return true;
220 return false;
223 /* Return the alignment in bits of EXP, a pointer valued expression.
224 But don't return more than MAX_ALIGN no matter what.
225 The alignment returned is, by default, the alignment of the thing that
226 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
228 Otherwise, look at the expression to see if we can do better, i.e., if the
229 expression is actually pointing at an object whose alignment is tighter. */
231 static int
232 get_pointer_alignment (tree exp, unsigned int max_align)
234 unsigned int align, inner;
236 /* We rely on TER to compute accurate alignment information. */
237 if (!(optimize && flag_tree_ter))
238 return 0;
240 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
241 return 0;
243 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
244 align = MIN (align, max_align);
246 while (1)
248 switch (TREE_CODE (exp))
250 case NOP_EXPR:
251 case CONVERT_EXPR:
252 case NON_LVALUE_EXPR:
253 exp = TREE_OPERAND (exp, 0);
254 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
255 return align;
257 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
258 align = MIN (inner, max_align);
259 break;
261 case PLUS_EXPR:
262 /* If sum of pointer + int, restrict our maximum alignment to that
263 imposed by the integer. If not, we can't do any better than
264 ALIGN. */
265 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
266 return align;
268 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
269 & (max_align / BITS_PER_UNIT - 1))
270 != 0)
271 max_align >>= 1;
273 exp = TREE_OPERAND (exp, 0);
274 break;
276 case ADDR_EXPR:
277 /* See what we are pointing at and look at its alignment. */
278 exp = TREE_OPERAND (exp, 0);
279 inner = max_align;
280 if (handled_component_p (exp))
282 HOST_WIDE_INT bitsize, bitpos;
283 tree offset;
284 enum machine_mode mode;
285 int unsignedp, volatilep;
287 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
288 &mode, &unsignedp, &volatilep, true);
289 if (bitpos)
290 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
291 if (offset && TREE_CODE (offset) == PLUS_EXPR
292 && host_integerp (TREE_OPERAND (offset, 1), 1))
294 /* Any overflow in calculating offset_bits won't change
295 the alignment. */
296 unsigned offset_bits
297 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
298 * BITS_PER_UNIT);
300 if (offset_bits)
301 inner = MIN (inner, (offset_bits & -offset_bits));
302 offset = TREE_OPERAND (offset, 0);
304 if (offset && TREE_CODE (offset) == MULT_EXPR
305 && host_integerp (TREE_OPERAND (offset, 1), 1))
307 /* Any overflow in calculating offset_factor won't change
308 the alignment. */
309 unsigned offset_factor
310 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
311 * BITS_PER_UNIT);
313 if (offset_factor)
314 inner = MIN (inner, (offset_factor & -offset_factor));
316 else if (offset)
317 inner = MIN (inner, BITS_PER_UNIT);
319 if (TREE_CODE (exp) == FUNCTION_DECL)
320 align = FUNCTION_BOUNDARY;
321 else if (DECL_P (exp))
322 align = MIN (inner, DECL_ALIGN (exp));
323 #ifdef CONSTANT_ALIGNMENT
324 else if (CONSTANT_CLASS_P (exp))
325 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
326 #endif
327 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
328 || TREE_CODE (exp) == INDIRECT_REF)
329 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
330 else
331 align = MIN (align, inner);
332 return MIN (align, max_align);
334 default:
335 return align;
340 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
341 way, because it could contain a zero byte in the middle.
342 TREE_STRING_LENGTH is the size of the character array, not the string.
344 ONLY_VALUE should be nonzero if the result is not going to be emitted
345 into the instruction stream and zero if it is going to be expanded.
346 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
347 is returned, otherwise NULL, since
348 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
349 evaluate the side-effects.
351 The value returned is of type `ssizetype'.
353 Unfortunately, string_constant can't access the values of const char
354 arrays with initializers, so neither can we do so here. */
356 tree
357 c_strlen (tree src, int only_value)
359 tree offset_node;
360 HOST_WIDE_INT offset;
361 int max;
362 const char *ptr;
364 STRIP_NOPS (src);
365 if (TREE_CODE (src) == COND_EXPR
366 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
368 tree len1, len2;
370 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
371 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
372 if (tree_int_cst_equal (len1, len2))
373 return len1;
376 if (TREE_CODE (src) == COMPOUND_EXPR
377 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
378 return c_strlen (TREE_OPERAND (src, 1), only_value);
380 src = string_constant (src, &offset_node);
381 if (src == 0)
382 return 0;
384 max = TREE_STRING_LENGTH (src) - 1;
385 ptr = TREE_STRING_POINTER (src);
387 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
389 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
390 compute the offset to the following null if we don't know where to
391 start searching for it. */
392 int i;
394 for (i = 0; i < max; i++)
395 if (ptr[i] == 0)
396 return 0;
398 /* We don't know the starting offset, but we do know that the string
399 has no internal zero bytes. We can assume that the offset falls
400 within the bounds of the string; otherwise, the programmer deserves
401 what he gets. Subtract the offset from the length of the string,
402 and return that. This would perhaps not be valid if we were dealing
403 with named arrays in addition to literal string constants. */
405 return size_diffop (size_int (max), offset_node);
408 /* We have a known offset into the string. Start searching there for
409 a null character if we can represent it as a single HOST_WIDE_INT. */
410 if (offset_node == 0)
411 offset = 0;
412 else if (! host_integerp (offset_node, 0))
413 offset = -1;
414 else
415 offset = tree_low_cst (offset_node, 0);
417 /* If the offset is known to be out of bounds, warn, and call strlen at
418 runtime. */
419 if (offset < 0 || offset > max)
421 warning (0, "offset outside bounds of constant string");
422 return 0;
425 /* Use strlen to search for the first zero byte. Since any strings
426 constructed with build_string will have nulls appended, we win even
427 if we get handed something like (char[4])"abcd".
429 Since OFFSET is our starting index into the string, no further
430 calculation is needed. */
431 return ssize_int (strlen (ptr + offset));
434 /* Return a char pointer for a C string if it is a string constant
435 or sum of string constant and integer constant. */
437 static const char *
438 c_getstr (tree src)
440 tree offset_node;
442 src = string_constant (src, &offset_node);
443 if (src == 0)
444 return 0;
446 if (offset_node == 0)
447 return TREE_STRING_POINTER (src);
448 else if (!host_integerp (offset_node, 1)
449 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
450 return 0;
452 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
455 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
456 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
458 static rtx
459 c_readstr (const char *str, enum machine_mode mode)
461 HOST_WIDE_INT c[2];
462 HOST_WIDE_INT ch;
463 unsigned int i, j;
465 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
467 c[0] = 0;
468 c[1] = 0;
469 ch = 1;
470 for (i = 0; i < GET_MODE_SIZE (mode); i++)
472 j = i;
473 if (WORDS_BIG_ENDIAN)
474 j = GET_MODE_SIZE (mode) - i - 1;
475 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
476 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
477 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
478 j *= BITS_PER_UNIT;
479 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
481 if (ch)
482 ch = (unsigned char) str[i];
483 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
485 return immed_double_const (c[0], c[1], mode);
488 /* Cast a target constant CST to target CHAR and if that value fits into
489 host char type, return zero and put that value into variable pointed to by
490 P. */
492 static int
493 target_char_cast (tree cst, char *p)
495 unsigned HOST_WIDE_INT val, hostval;
497 if (!host_integerp (cst, 1)
498 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
499 return 1;
501 val = tree_low_cst (cst, 1);
502 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
503 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
505 hostval = val;
506 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
507 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
509 if (val != hostval)
510 return 1;
512 *p = hostval;
513 return 0;
516 /* Similar to save_expr, but assumes that arbitrary code is not executed
517 in between the multiple evaluations. In particular, we assume that a
518 non-addressable local variable will not be modified. */
520 static tree
521 builtin_save_expr (tree exp)
523 if (TREE_ADDRESSABLE (exp) == 0
524 && (TREE_CODE (exp) == PARM_DECL
525 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
526 return exp;
528 return save_expr (exp);
531 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
532 times to get the address of either a higher stack frame, or a return
533 address located within it (depending on FNDECL_CODE). */
535 static rtx
536 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
538 int i;
540 #ifdef INITIAL_FRAME_ADDRESS_RTX
541 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
542 #else
543 rtx tem;
545 /* For a zero count with __builtin_return_address, we don't care what
546 frame address we return, because target-specific definitions will
547 override us. Therefore frame pointer elimination is OK, and using
548 the soft frame pointer is OK.
550 For a non-zero count, or a zero count with __builtin_frame_address,
551 we require a stable offset from the current frame pointer to the
552 previous one, so we must use the hard frame pointer, and
553 we must disable frame pointer elimination. */
554 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
555 tem = frame_pointer_rtx;
556 else
558 tem = hard_frame_pointer_rtx;
560 /* Tell reload not to eliminate the frame pointer. */
561 current_function_accesses_prior_frames = 1;
563 #endif
565 /* Some machines need special handling before we can access
566 arbitrary frames. For example, on the SPARC, we must first flush
567 all register windows to the stack. */
568 #ifdef SETUP_FRAME_ADDRESSES
569 if (count > 0)
570 SETUP_FRAME_ADDRESSES ();
571 #endif
573 /* On the SPARC, the return address is not in the frame, it is in a
574 register. There is no way to access it off of the current frame
575 pointer, but it can be accessed off the previous frame pointer by
576 reading the value from the register window save area. */
577 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
578 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
579 count--;
580 #endif
582 /* Scan back COUNT frames to the specified frame. */
583 for (i = 0; i < count; i++)
585 /* Assume the dynamic chain pointer is in the word that the
586 frame address points to, unless otherwise specified. */
587 #ifdef DYNAMIC_CHAIN_ADDRESS
588 tem = DYNAMIC_CHAIN_ADDRESS (tem);
589 #endif
590 tem = memory_address (Pmode, tem);
591 tem = gen_frame_mem (Pmode, tem);
592 tem = copy_to_reg (tem);
595 /* For __builtin_frame_address, return what we've got. But, on
596 the SPARC for example, we may have to add a bias. */
597 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
598 #ifdef FRAME_ADDR_RTX
599 return FRAME_ADDR_RTX (tem);
600 #else
601 return tem;
602 #endif
604 /* For __builtin_return_address, get the return address from that frame. */
605 #ifdef RETURN_ADDR_RTX
606 tem = RETURN_ADDR_RTX (count, tem);
607 #else
608 tem = memory_address (Pmode,
609 plus_constant (tem, GET_MODE_SIZE (Pmode)));
610 tem = gen_frame_mem (Pmode, tem);
611 #endif
612 return tem;
615 /* Alias set used for setjmp buffer. */
616 static HOST_WIDE_INT setjmp_alias_set = -1;
618 /* Construct the leading half of a __builtin_setjmp call. Control will
619 return to RECEIVER_LABEL. This is also called directly by the SJLJ
620 exception handling code. */
622 void
623 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
625 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
626 rtx stack_save;
627 rtx mem;
629 if (setjmp_alias_set == -1)
630 setjmp_alias_set = new_alias_set ();
632 buf_addr = convert_memory_address (Pmode, buf_addr);
634 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
636 /* We store the frame pointer and the address of receiver_label in
637 the buffer and use the rest of it for the stack save area, which
638 is machine-dependent. */
640 mem = gen_rtx_MEM (Pmode, buf_addr);
641 set_mem_alias_set (mem, setjmp_alias_set);
642 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
644 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
645 set_mem_alias_set (mem, setjmp_alias_set);
647 emit_move_insn (validize_mem (mem),
648 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
650 stack_save = gen_rtx_MEM (sa_mode,
651 plus_constant (buf_addr,
652 2 * GET_MODE_SIZE (Pmode)));
653 set_mem_alias_set (stack_save, setjmp_alias_set);
654 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
656 /* If there is further processing to do, do it. */
657 #ifdef HAVE_builtin_setjmp_setup
658 if (HAVE_builtin_setjmp_setup)
659 emit_insn (gen_builtin_setjmp_setup (buf_addr));
660 #endif
662 /* Tell optimize_save_area_alloca that extra work is going to
663 need to go on during alloca. */
664 current_function_calls_setjmp = 1;
666 /* Set this so all the registers get saved in our frame; we need to be
667 able to copy the saved values for any registers from frames we unwind. */
668 current_function_has_nonlocal_label = 1;
671 /* Construct the trailing part of a __builtin_setjmp call. This is
672 also called directly by the SJLJ exception handling code. */
674 void
675 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
677 /* Clobber the FP when we get here, so we have to make sure it's
678 marked as used by this function. */
679 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
681 /* Mark the static chain as clobbered here so life information
682 doesn't get messed up for it. */
683 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
685 /* Now put in the code to restore the frame pointer, and argument
686 pointer, if needed. */
687 #ifdef HAVE_nonlocal_goto
688 if (! HAVE_nonlocal_goto)
689 #endif
691 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
692 /* This might change the hard frame pointer in ways that aren't
693 apparent to early optimization passes, so force a clobber. */
694 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
697 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
698 if (fixed_regs[ARG_POINTER_REGNUM])
700 #ifdef ELIMINABLE_REGS
701 size_t i;
702 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
704 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
705 if (elim_regs[i].from == ARG_POINTER_REGNUM
706 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
707 break;
709 if (i == ARRAY_SIZE (elim_regs))
710 #endif
712 /* Now restore our arg pointer from the address at which it
713 was saved in our stack frame. */
714 emit_move_insn (virtual_incoming_args_rtx,
715 copy_to_reg (get_arg_pointer_save_area (cfun)));
718 #endif
720 #ifdef HAVE_builtin_setjmp_receiver
721 if (HAVE_builtin_setjmp_receiver)
722 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
723 else
724 #endif
725 #ifdef HAVE_nonlocal_goto_receiver
726 if (HAVE_nonlocal_goto_receiver)
727 emit_insn (gen_nonlocal_goto_receiver ());
728 else
729 #endif
730 { /* Nothing */ }
732 /* @@@ This is a kludge. Not all machine descriptions define a blockage
733 insn, but we must not allow the code we just generated to be reordered
734 by scheduling. Specifically, the update of the frame pointer must
735 happen immediately, not later. So emit an ASM_INPUT to act as blockage
736 insn. */
737 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
740 /* __builtin_longjmp is passed a pointer to an array of five words (not
741 all will be used on all machines). It operates similarly to the C
742 library function of the same name, but is more efficient. Much of
743 the code below is copied from the handling of non-local gotos. */
745 static void
746 expand_builtin_longjmp (rtx buf_addr, rtx value)
748 rtx fp, lab, stack, insn, last;
749 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
751 if (setjmp_alias_set == -1)
752 setjmp_alias_set = new_alias_set ();
754 buf_addr = convert_memory_address (Pmode, buf_addr);
756 buf_addr = force_reg (Pmode, buf_addr);
758 /* We used to store value in static_chain_rtx, but that fails if pointers
759 are smaller than integers. We instead require that the user must pass
760 a second argument of 1, because that is what builtin_setjmp will
761 return. This also makes EH slightly more efficient, since we are no
762 longer copying around a value that we don't care about. */
763 gcc_assert (value == const1_rtx);
765 last = get_last_insn ();
766 #ifdef HAVE_builtin_longjmp
767 if (HAVE_builtin_longjmp)
768 emit_insn (gen_builtin_longjmp (buf_addr));
769 else
770 #endif
772 fp = gen_rtx_MEM (Pmode, buf_addr);
773 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
774 GET_MODE_SIZE (Pmode)));
776 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
777 2 * GET_MODE_SIZE (Pmode)));
778 set_mem_alias_set (fp, setjmp_alias_set);
779 set_mem_alias_set (lab, setjmp_alias_set);
780 set_mem_alias_set (stack, setjmp_alias_set);
782 /* Pick up FP, label, and SP from the block and jump. This code is
783 from expand_goto in stmt.c; see there for detailed comments. */
784 #ifdef HAVE_nonlocal_goto
785 if (HAVE_nonlocal_goto)
786 /* We have to pass a value to the nonlocal_goto pattern that will
787 get copied into the static_chain pointer, but it does not matter
788 what that value is, because builtin_setjmp does not use it. */
789 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
790 else
791 #endif
793 lab = copy_to_reg (lab);
795 emit_insn (gen_rtx_CLOBBER (VOIDmode,
796 gen_rtx_MEM (BLKmode,
797 gen_rtx_SCRATCH (VOIDmode))));
798 emit_insn (gen_rtx_CLOBBER (VOIDmode,
799 gen_rtx_MEM (BLKmode,
800 hard_frame_pointer_rtx)));
802 emit_move_insn (hard_frame_pointer_rtx, fp);
803 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
805 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
806 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
807 emit_indirect_jump (lab);
811 /* Search backwards and mark the jump insn as a non-local goto.
812 Note that this precludes the use of __builtin_longjmp to a
813 __builtin_setjmp target in the same function. However, we've
814 already cautioned the user that these functions are for
815 internal exception handling use only. */
816 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
818 gcc_assert (insn != last);
820 if (JUMP_P (insn))
822 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
823 REG_NOTES (insn));
824 break;
826 else if (CALL_P (insn))
827 break;
831 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
832 and the address of the save area. */
834 static rtx
835 expand_builtin_nonlocal_goto (tree arglist)
837 tree t_label, t_save_area;
838 rtx r_label, r_save_area, r_fp, r_sp, insn;
840 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
841 return NULL_RTX;
843 t_label = TREE_VALUE (arglist);
844 arglist = TREE_CHAIN (arglist);
845 t_save_area = TREE_VALUE (arglist);
847 r_label = expand_normal (t_label);
848 r_label = convert_memory_address (Pmode, r_label);
849 r_save_area = expand_normal (t_save_area);
850 r_save_area = convert_memory_address (Pmode, r_save_area);
851 r_fp = gen_rtx_MEM (Pmode, r_save_area);
852 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
853 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
855 current_function_has_nonlocal_goto = 1;
857 #ifdef HAVE_nonlocal_goto
858 /* ??? We no longer need to pass the static chain value, afaik. */
859 if (HAVE_nonlocal_goto)
860 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
861 else
862 #endif
864 r_label = copy_to_reg (r_label);
866 emit_insn (gen_rtx_CLOBBER (VOIDmode,
867 gen_rtx_MEM (BLKmode,
868 gen_rtx_SCRATCH (VOIDmode))));
870 emit_insn (gen_rtx_CLOBBER (VOIDmode,
871 gen_rtx_MEM (BLKmode,
872 hard_frame_pointer_rtx)));
874 /* Restore frame pointer for containing function.
875 This sets the actual hard register used for the frame pointer
876 to the location of the function's incoming static chain info.
877 The non-local goto handler will then adjust it to contain the
878 proper value and reload the argument pointer, if needed. */
879 emit_move_insn (hard_frame_pointer_rtx, r_fp);
880 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
882 /* USE of hard_frame_pointer_rtx added for consistency;
883 not clear if really needed. */
884 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
885 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
886 emit_indirect_jump (r_label);
889 /* Search backwards to the jump insn and mark it as a
890 non-local goto. */
891 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
893 if (JUMP_P (insn))
895 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
896 const0_rtx, REG_NOTES (insn));
897 break;
899 else if (CALL_P (insn))
900 break;
903 return const0_rtx;
906 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
907 (not all will be used on all machines) that was passed to __builtin_setjmp.
908 It updates the stack pointer in that block to correspond to the current
909 stack pointer. */
911 static void
912 expand_builtin_update_setjmp_buf (rtx buf_addr)
914 enum machine_mode sa_mode = Pmode;
915 rtx stack_save;
918 #ifdef HAVE_save_stack_nonlocal
919 if (HAVE_save_stack_nonlocal)
920 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
921 #endif
922 #ifdef STACK_SAVEAREA_MODE
923 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
924 #endif
926 stack_save
927 = gen_rtx_MEM (sa_mode,
928 memory_address
929 (sa_mode,
930 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
932 #ifdef HAVE_setjmp
933 if (HAVE_setjmp)
934 emit_insn (gen_setjmp ());
935 #endif
937 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
940 /* Expand a call to __builtin_prefetch. For a target that does not support
941 data prefetch, evaluate the memory address argument in case it has side
942 effects. */
944 static void
945 expand_builtin_prefetch (tree arglist)
947 tree arg0, arg1, arg2;
948 rtx op0, op1, op2;
950 if (!validate_arglist (arglist, POINTER_TYPE, 0))
951 return;
953 arg0 = TREE_VALUE (arglist);
954 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
955 zero (read) and argument 2 (locality) defaults to 3 (high degree of
956 locality). */
957 if (TREE_CHAIN (arglist))
959 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
960 if (TREE_CHAIN (TREE_CHAIN (arglist)))
961 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
962 else
963 arg2 = build_int_cst (NULL_TREE, 3);
965 else
967 arg1 = integer_zero_node;
968 arg2 = build_int_cst (NULL_TREE, 3);
971 /* Argument 0 is an address. */
972 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
974 /* Argument 1 (read/write flag) must be a compile-time constant int. */
975 if (TREE_CODE (arg1) != INTEGER_CST)
977 error ("second argument to %<__builtin_prefetch%> must be a constant");
978 arg1 = integer_zero_node;
980 op1 = expand_normal (arg1);
981 /* Argument 1 must be either zero or one. */
982 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
984 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
985 " using zero");
986 op1 = const0_rtx;
989 /* Argument 2 (locality) must be a compile-time constant int. */
990 if (TREE_CODE (arg2) != INTEGER_CST)
992 error ("third argument to %<__builtin_prefetch%> must be a constant");
993 arg2 = integer_zero_node;
995 op2 = expand_normal (arg2);
996 /* Argument 2 must be 0, 1, 2, or 3. */
997 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
999 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1000 op2 = const0_rtx;
1003 #ifdef HAVE_prefetch
1004 if (HAVE_prefetch)
1006 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1007 (op0,
1008 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1009 || (GET_MODE (op0) != Pmode))
1011 op0 = convert_memory_address (Pmode, op0);
1012 op0 = force_reg (Pmode, op0);
1014 emit_insn (gen_prefetch (op0, op1, op2));
1016 #endif
1018 /* Don't do anything with direct references to volatile memory, but
1019 generate code to handle other side effects. */
1020 if (!MEM_P (op0) && side_effects_p (op0))
1021 emit_insn (op0);
1024 /* Get a MEM rtx for expression EXP which is the address of an operand
1025 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1026 the maximum length of the block of memory that might be accessed or
1027 NULL if unknown. */
1029 static rtx
1030 get_memory_rtx (tree exp, tree len)
1032 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1033 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1035 /* Get an expression we can use to find the attributes to assign to MEM.
1036 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1037 we can. First remove any nops. */
1038 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1039 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1040 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1041 exp = TREE_OPERAND (exp, 0);
1043 if (TREE_CODE (exp) == ADDR_EXPR)
1044 exp = TREE_OPERAND (exp, 0);
1045 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1046 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1047 else
1048 exp = NULL;
1050 /* Honor attributes derived from exp, except for the alias set
1051 (as builtin stringops may alias with anything) and the size
1052 (as stringops may access multiple array elements). */
1053 if (exp)
1055 set_mem_attributes (mem, exp, 0);
1057 /* Allow the string and memory builtins to overflow from one
1058 field into another, see http://gcc.gnu.org/PR23561.
1059 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1060 memory accessed by the string or memory builtin will fit
1061 within the field. */
1062 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1064 tree mem_expr = MEM_EXPR (mem);
1065 HOST_WIDE_INT offset = -1, length = -1;
1066 tree inner = exp;
1068 while (TREE_CODE (inner) == ARRAY_REF
1069 || TREE_CODE (inner) == NOP_EXPR
1070 || TREE_CODE (inner) == CONVERT_EXPR
1071 || TREE_CODE (inner) == NON_LVALUE_EXPR
1072 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1073 || TREE_CODE (inner) == SAVE_EXPR)
1074 inner = TREE_OPERAND (inner, 0);
1076 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1078 if (MEM_OFFSET (mem)
1079 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1080 offset = INTVAL (MEM_OFFSET (mem));
1082 if (offset >= 0 && len && host_integerp (len, 0))
1083 length = tree_low_cst (len, 0);
1085 while (TREE_CODE (inner) == COMPONENT_REF)
1087 tree field = TREE_OPERAND (inner, 1);
1088 gcc_assert (! DECL_BIT_FIELD (field));
1089 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1090 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1092 if (length >= 0
1093 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1094 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1096 HOST_WIDE_INT size
1097 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1098 /* If we can prove the memory starting at XEXP (mem, 0)
1099 and ending at XEXP (mem, 0) + LENGTH will fit into
1100 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1101 if (offset <= size
1102 && length <= size
1103 && offset + length <= size)
1104 break;
1107 if (offset >= 0
1108 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1109 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1110 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1111 / BITS_PER_UNIT;
1112 else
1114 offset = -1;
1115 length = -1;
1118 mem_expr = TREE_OPERAND (mem_expr, 0);
1119 inner = TREE_OPERAND (inner, 0);
1122 if (mem_expr == NULL)
1123 offset = -1;
1124 if (mem_expr != MEM_EXPR (mem))
1126 set_mem_expr (mem, mem_expr);
1127 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1130 set_mem_alias_set (mem, 0);
1131 set_mem_size (mem, NULL_RTX);
1134 return mem;
1137 /* Built-in functions to perform an untyped call and return. */
1139 /* For each register that may be used for calling a function, this
1140 gives a mode used to copy the register's value. VOIDmode indicates
1141 the register is not used for calling a function. If the machine
1142 has register windows, this gives only the outbound registers.
1143 INCOMING_REGNO gives the corresponding inbound register. */
1144 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1146 /* For each register that may be used for returning values, this gives
1147 a mode used to copy the register's value. VOIDmode indicates the
1148 register is not used for returning values. If the machine has
1149 register windows, this gives only the outbound registers.
1150 INCOMING_REGNO gives the corresponding inbound register. */
1151 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1153 /* For each register that may be used for calling a function, this
1154 gives the offset of that register into the block returned by
1155 __builtin_apply_args. 0 indicates that the register is not
1156 used for calling a function. */
1157 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1159 /* Return the size required for the block returned by __builtin_apply_args,
1160 and initialize apply_args_mode. */
1162 static int
1163 apply_args_size (void)
1165 static int size = -1;
1166 int align;
1167 unsigned int regno;
1168 enum machine_mode mode;
1170 /* The values computed by this function never change. */
1171 if (size < 0)
1173 /* The first value is the incoming arg-pointer. */
1174 size = GET_MODE_SIZE (Pmode);
1176 /* The second value is the structure value address unless this is
1177 passed as an "invisible" first argument. */
1178 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1179 size += GET_MODE_SIZE (Pmode);
1181 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1182 if (FUNCTION_ARG_REGNO_P (regno))
1184 mode = reg_raw_mode[regno];
1186 gcc_assert (mode != VOIDmode);
1188 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1189 if (size % align != 0)
1190 size = CEIL (size, align) * align;
1191 apply_args_reg_offset[regno] = size;
1192 size += GET_MODE_SIZE (mode);
1193 apply_args_mode[regno] = mode;
1195 else
1197 apply_args_mode[regno] = VOIDmode;
1198 apply_args_reg_offset[regno] = 0;
1201 return size;
1204 /* Return the size required for the block returned by __builtin_apply,
1205 and initialize apply_result_mode. */
1207 static int
1208 apply_result_size (void)
1210 static int size = -1;
1211 int align, regno;
1212 enum machine_mode mode;
1214 /* The values computed by this function never change. */
1215 if (size < 0)
1217 size = 0;
1219 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1220 if (FUNCTION_VALUE_REGNO_P (regno))
1222 mode = reg_raw_mode[regno];
1224 gcc_assert (mode != VOIDmode);
1226 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1227 if (size % align != 0)
1228 size = CEIL (size, align) * align;
1229 size += GET_MODE_SIZE (mode);
1230 apply_result_mode[regno] = mode;
1232 else
1233 apply_result_mode[regno] = VOIDmode;
1235 /* Allow targets that use untyped_call and untyped_return to override
1236 the size so that machine-specific information can be stored here. */
1237 #ifdef APPLY_RESULT_SIZE
1238 size = APPLY_RESULT_SIZE;
1239 #endif
1241 return size;
1244 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1245 /* Create a vector describing the result block RESULT. If SAVEP is true,
1246 the result block is used to save the values; otherwise it is used to
1247 restore the values. */
1249 static rtx
1250 result_vector (int savep, rtx result)
1252 int regno, size, align, nelts;
1253 enum machine_mode mode;
1254 rtx reg, mem;
1255 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1257 size = nelts = 0;
1258 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1259 if ((mode = apply_result_mode[regno]) != VOIDmode)
1261 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1262 if (size % align != 0)
1263 size = CEIL (size, align) * align;
1264 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1265 mem = adjust_address (result, mode, size);
1266 savevec[nelts++] = (savep
1267 ? gen_rtx_SET (VOIDmode, mem, reg)
1268 : gen_rtx_SET (VOIDmode, reg, mem));
1269 size += GET_MODE_SIZE (mode);
1271 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1273 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1275 /* Save the state required to perform an untyped call with the same
1276 arguments as were passed to the current function. */
1278 static rtx
1279 expand_builtin_apply_args_1 (void)
1281 rtx registers, tem;
1282 int size, align, regno;
1283 enum machine_mode mode;
1284 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1286 /* Create a block where the arg-pointer, structure value address,
1287 and argument registers can be saved. */
1288 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1290 /* Walk past the arg-pointer and structure value address. */
1291 size = GET_MODE_SIZE (Pmode);
1292 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1293 size += GET_MODE_SIZE (Pmode);
1295 /* Save each register used in calling a function to the block. */
1296 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1297 if ((mode = apply_args_mode[regno]) != VOIDmode)
1299 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1300 if (size % align != 0)
1301 size = CEIL (size, align) * align;
1303 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1305 emit_move_insn (adjust_address (registers, mode, size), tem);
1306 size += GET_MODE_SIZE (mode);
1309 /* Save the arg pointer to the block. */
1310 tem = copy_to_reg (virtual_incoming_args_rtx);
1311 #ifdef STACK_GROWS_DOWNWARD
1312 /* We need the pointer as the caller actually passed them to us, not
1313 as we might have pretended they were passed. Make sure it's a valid
1314 operand, as emit_move_insn isn't expected to handle a PLUS. */
1316 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1317 NULL_RTX);
1318 #endif
1319 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1321 size = GET_MODE_SIZE (Pmode);
1323 /* Save the structure value address unless this is passed as an
1324 "invisible" first argument. */
1325 if (struct_incoming_value)
1327 emit_move_insn (adjust_address (registers, Pmode, size),
1328 copy_to_reg (struct_incoming_value));
1329 size += GET_MODE_SIZE (Pmode);
1332 /* Return the address of the block. */
1333 return copy_addr_to_reg (XEXP (registers, 0));
1336 /* __builtin_apply_args returns block of memory allocated on
1337 the stack into which is stored the arg pointer, structure
1338 value address, static chain, and all the registers that might
1339 possibly be used in performing a function call. The code is
1340 moved to the start of the function so the incoming values are
1341 saved. */
1343 static rtx
1344 expand_builtin_apply_args (void)
1346 /* Don't do __builtin_apply_args more than once in a function.
1347 Save the result of the first call and reuse it. */
1348 if (apply_args_value != 0)
1349 return apply_args_value;
1351 /* When this function is called, it means that registers must be
1352 saved on entry to this function. So we migrate the
1353 call to the first insn of this function. */
1354 rtx temp;
1355 rtx seq;
1357 start_sequence ();
1358 temp = expand_builtin_apply_args_1 ();
1359 seq = get_insns ();
1360 end_sequence ();
1362 apply_args_value = temp;
1364 /* Put the insns after the NOTE that starts the function.
1365 If this is inside a start_sequence, make the outer-level insn
1366 chain current, so the code is placed at the start of the
1367 function. */
1368 push_topmost_sequence ();
1369 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1370 pop_topmost_sequence ();
1371 return temp;
1375 /* Perform an untyped call and save the state required to perform an
1376 untyped return of whatever value was returned by the given function. */
1378 static rtx
1379 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1381 int size, align, regno;
1382 enum machine_mode mode;
1383 rtx incoming_args, result, reg, dest, src, call_insn;
1384 rtx old_stack_level = 0;
1385 rtx call_fusage = 0;
1386 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1388 arguments = convert_memory_address (Pmode, arguments);
1390 /* Create a block where the return registers can be saved. */
1391 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1393 /* Fetch the arg pointer from the ARGUMENTS block. */
1394 incoming_args = gen_reg_rtx (Pmode);
1395 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1396 #ifndef STACK_GROWS_DOWNWARD
1397 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1398 incoming_args, 0, OPTAB_LIB_WIDEN);
1399 #endif
1401 /* Push a new argument block and copy the arguments. Do not allow
1402 the (potential) memcpy call below to interfere with our stack
1403 manipulations. */
1404 do_pending_stack_adjust ();
1405 NO_DEFER_POP;
1407 /* Save the stack with nonlocal if available. */
1408 #ifdef HAVE_save_stack_nonlocal
1409 if (HAVE_save_stack_nonlocal)
1410 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1411 else
1412 #endif
1413 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1415 /* Allocate a block of memory onto the stack and copy the memory
1416 arguments to the outgoing arguments address. */
1417 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1418 dest = virtual_outgoing_args_rtx;
1419 #ifndef STACK_GROWS_DOWNWARD
1420 if (GET_CODE (argsize) == CONST_INT)
1421 dest = plus_constant (dest, -INTVAL (argsize));
1422 else
1423 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1424 #endif
1425 dest = gen_rtx_MEM (BLKmode, dest);
1426 set_mem_align (dest, PARM_BOUNDARY);
1427 src = gen_rtx_MEM (BLKmode, incoming_args);
1428 set_mem_align (src, PARM_BOUNDARY);
1429 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1431 /* Refer to the argument block. */
1432 apply_args_size ();
1433 arguments = gen_rtx_MEM (BLKmode, arguments);
1434 set_mem_align (arguments, PARM_BOUNDARY);
1436 /* Walk past the arg-pointer and structure value address. */
1437 size = GET_MODE_SIZE (Pmode);
1438 if (struct_value)
1439 size += GET_MODE_SIZE (Pmode);
1441 /* Restore each of the registers previously saved. Make USE insns
1442 for each of these registers for use in making the call. */
1443 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1444 if ((mode = apply_args_mode[regno]) != VOIDmode)
1446 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1447 if (size % align != 0)
1448 size = CEIL (size, align) * align;
1449 reg = gen_rtx_REG (mode, regno);
1450 emit_move_insn (reg, adjust_address (arguments, mode, size));
1451 use_reg (&call_fusage, reg);
1452 size += GET_MODE_SIZE (mode);
1455 /* Restore the structure value address unless this is passed as an
1456 "invisible" first argument. */
1457 size = GET_MODE_SIZE (Pmode);
1458 if (struct_value)
1460 rtx value = gen_reg_rtx (Pmode);
1461 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1462 emit_move_insn (struct_value, value);
1463 if (REG_P (struct_value))
1464 use_reg (&call_fusage, struct_value);
1465 size += GET_MODE_SIZE (Pmode);
1468 /* All arguments and registers used for the call are set up by now! */
1469 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1471 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1472 and we don't want to load it into a register as an optimization,
1473 because prepare_call_address already did it if it should be done. */
1474 if (GET_CODE (function) != SYMBOL_REF)
1475 function = memory_address (FUNCTION_MODE, function);
1477 /* Generate the actual call instruction and save the return value. */
1478 #ifdef HAVE_untyped_call
1479 if (HAVE_untyped_call)
1480 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1481 result, result_vector (1, result)));
1482 else
1483 #endif
1484 #ifdef HAVE_call_value
1485 if (HAVE_call_value)
1487 rtx valreg = 0;
1489 /* Locate the unique return register. It is not possible to
1490 express a call that sets more than one return register using
1491 call_value; use untyped_call for that. In fact, untyped_call
1492 only needs to save the return registers in the given block. */
1493 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1494 if ((mode = apply_result_mode[regno]) != VOIDmode)
1496 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1498 valreg = gen_rtx_REG (mode, regno);
1501 emit_call_insn (GEN_CALL_VALUE (valreg,
1502 gen_rtx_MEM (FUNCTION_MODE, function),
1503 const0_rtx, NULL_RTX, const0_rtx));
1505 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1507 else
1508 #endif
1509 gcc_unreachable ();
1511 /* Find the CALL insn we just emitted, and attach the register usage
1512 information. */
1513 call_insn = last_call_insn ();
1514 add_function_usage_to (call_insn, call_fusage);
1516 /* Restore the stack. */
1517 #ifdef HAVE_save_stack_nonlocal
1518 if (HAVE_save_stack_nonlocal)
1519 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1520 else
1521 #endif
1522 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1524 OK_DEFER_POP;
1526 /* Return the address of the result block. */
1527 result = copy_addr_to_reg (XEXP (result, 0));
1528 return convert_memory_address (ptr_mode, result);
1531 /* Perform an untyped return. */
1533 static void
1534 expand_builtin_return (rtx result)
1536 int size, align, regno;
1537 enum machine_mode mode;
1538 rtx reg;
1539 rtx call_fusage = 0;
1541 result = convert_memory_address (Pmode, result);
1543 apply_result_size ();
1544 result = gen_rtx_MEM (BLKmode, result);
1546 #ifdef HAVE_untyped_return
1547 if (HAVE_untyped_return)
1549 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1550 emit_barrier ();
1551 return;
1553 #endif
1555 /* Restore the return value and note that each value is used. */
1556 size = 0;
1557 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1558 if ((mode = apply_result_mode[regno]) != VOIDmode)
1560 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1561 if (size % align != 0)
1562 size = CEIL (size, align) * align;
1563 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1564 emit_move_insn (reg, adjust_address (result, mode, size));
1566 push_to_sequence (call_fusage);
1567 emit_insn (gen_rtx_USE (VOIDmode, reg));
1568 call_fusage = get_insns ();
1569 end_sequence ();
1570 size += GET_MODE_SIZE (mode);
1573 /* Put the USE insns before the return. */
1574 emit_insn (call_fusage);
1576 /* Return whatever values was restored by jumping directly to the end
1577 of the function. */
1578 expand_naked_return ();
1581 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1583 static enum type_class
1584 type_to_class (tree type)
1586 switch (TREE_CODE (type))
1588 case VOID_TYPE: return void_type_class;
1589 case INTEGER_TYPE: return integer_type_class;
1590 case ENUMERAL_TYPE: return enumeral_type_class;
1591 case BOOLEAN_TYPE: return boolean_type_class;
1592 case POINTER_TYPE: return pointer_type_class;
1593 case REFERENCE_TYPE: return reference_type_class;
1594 case OFFSET_TYPE: return offset_type_class;
1595 case REAL_TYPE: return real_type_class;
1596 case COMPLEX_TYPE: return complex_type_class;
1597 case FUNCTION_TYPE: return function_type_class;
1598 case METHOD_TYPE: return method_type_class;
1599 case RECORD_TYPE: return record_type_class;
1600 case UNION_TYPE:
1601 case QUAL_UNION_TYPE: return union_type_class;
1602 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1603 ? string_type_class : array_type_class);
1604 case LANG_TYPE: return lang_type_class;
1605 default: return no_type_class;
1609 /* Expand a call to __builtin_classify_type with arguments found in
1610 ARGLIST. */
1612 static rtx
1613 expand_builtin_classify_type (tree arglist)
1615 if (arglist != 0)
1616 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1617 return GEN_INT (no_type_class);
1620 /* This helper macro, meant to be used in mathfn_built_in below,
1621 determines which among a set of three builtin math functions is
1622 appropriate for a given type mode. The `F' and `L' cases are
1623 automatically generated from the `double' case. */
1624 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1625 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1626 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1627 fcodel = BUILT_IN_MATHFN##L ; break;
1629 /* Return mathematic function equivalent to FN but operating directly
1630 on TYPE, if available. If we can't do the conversion, return zero. */
1631 tree
1632 mathfn_built_in (tree type, enum built_in_function fn)
1634 enum built_in_function fcode, fcodef, fcodel;
1636 switch (fn)
1638 CASE_MATHFN (BUILT_IN_ACOS)
1639 CASE_MATHFN (BUILT_IN_ACOSH)
1640 CASE_MATHFN (BUILT_IN_ASIN)
1641 CASE_MATHFN (BUILT_IN_ASINH)
1642 CASE_MATHFN (BUILT_IN_ATAN)
1643 CASE_MATHFN (BUILT_IN_ATAN2)
1644 CASE_MATHFN (BUILT_IN_ATANH)
1645 CASE_MATHFN (BUILT_IN_CBRT)
1646 CASE_MATHFN (BUILT_IN_CEIL)
1647 CASE_MATHFN (BUILT_IN_COPYSIGN)
1648 CASE_MATHFN (BUILT_IN_COS)
1649 CASE_MATHFN (BUILT_IN_COSH)
1650 CASE_MATHFN (BUILT_IN_DREM)
1651 CASE_MATHFN (BUILT_IN_ERF)
1652 CASE_MATHFN (BUILT_IN_ERFC)
1653 CASE_MATHFN (BUILT_IN_EXP)
1654 CASE_MATHFN (BUILT_IN_EXP10)
1655 CASE_MATHFN (BUILT_IN_EXP2)
1656 CASE_MATHFN (BUILT_IN_EXPM1)
1657 CASE_MATHFN (BUILT_IN_FABS)
1658 CASE_MATHFN (BUILT_IN_FDIM)
1659 CASE_MATHFN (BUILT_IN_FLOOR)
1660 CASE_MATHFN (BUILT_IN_FMA)
1661 CASE_MATHFN (BUILT_IN_FMAX)
1662 CASE_MATHFN (BUILT_IN_FMIN)
1663 CASE_MATHFN (BUILT_IN_FMOD)
1664 CASE_MATHFN (BUILT_IN_FREXP)
1665 CASE_MATHFN (BUILT_IN_GAMMA)
1666 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1667 CASE_MATHFN (BUILT_IN_HYPOT)
1668 CASE_MATHFN (BUILT_IN_ILOGB)
1669 CASE_MATHFN (BUILT_IN_INF)
1670 CASE_MATHFN (BUILT_IN_J0)
1671 CASE_MATHFN (BUILT_IN_J1)
1672 CASE_MATHFN (BUILT_IN_JN)
1673 CASE_MATHFN (BUILT_IN_LCEIL)
1674 CASE_MATHFN (BUILT_IN_LDEXP)
1675 CASE_MATHFN (BUILT_IN_LFLOOR)
1676 CASE_MATHFN (BUILT_IN_LGAMMA)
1677 CASE_MATHFN (BUILT_IN_LLCEIL)
1678 CASE_MATHFN (BUILT_IN_LLFLOOR)
1679 CASE_MATHFN (BUILT_IN_LLRINT)
1680 CASE_MATHFN (BUILT_IN_LLROUND)
1681 CASE_MATHFN (BUILT_IN_LOG)
1682 CASE_MATHFN (BUILT_IN_LOG10)
1683 CASE_MATHFN (BUILT_IN_LOG1P)
1684 CASE_MATHFN (BUILT_IN_LOG2)
1685 CASE_MATHFN (BUILT_IN_LOGB)
1686 CASE_MATHFN (BUILT_IN_LRINT)
1687 CASE_MATHFN (BUILT_IN_LROUND)
1688 CASE_MATHFN (BUILT_IN_MODF)
1689 CASE_MATHFN (BUILT_IN_NAN)
1690 CASE_MATHFN (BUILT_IN_NANS)
1691 CASE_MATHFN (BUILT_IN_NEARBYINT)
1692 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1693 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1694 CASE_MATHFN (BUILT_IN_POW)
1695 CASE_MATHFN (BUILT_IN_POWI)
1696 CASE_MATHFN (BUILT_IN_POW10)
1697 CASE_MATHFN (BUILT_IN_REMAINDER)
1698 CASE_MATHFN (BUILT_IN_REMQUO)
1699 CASE_MATHFN (BUILT_IN_RINT)
1700 CASE_MATHFN (BUILT_IN_ROUND)
1701 CASE_MATHFN (BUILT_IN_SCALB)
1702 CASE_MATHFN (BUILT_IN_SCALBLN)
1703 CASE_MATHFN (BUILT_IN_SCALBN)
1704 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1705 CASE_MATHFN (BUILT_IN_SIN)
1706 CASE_MATHFN (BUILT_IN_SINCOS)
1707 CASE_MATHFN (BUILT_IN_SINH)
1708 CASE_MATHFN (BUILT_IN_SQRT)
1709 CASE_MATHFN (BUILT_IN_TAN)
1710 CASE_MATHFN (BUILT_IN_TANH)
1711 CASE_MATHFN (BUILT_IN_TGAMMA)
1712 CASE_MATHFN (BUILT_IN_TRUNC)
1713 CASE_MATHFN (BUILT_IN_Y0)
1714 CASE_MATHFN (BUILT_IN_Y1)
1715 CASE_MATHFN (BUILT_IN_YN)
1717 default:
1718 return 0;
1721 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1722 return implicit_built_in_decls[fcode];
1723 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1724 return implicit_built_in_decls[fcodef];
1725 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1726 return implicit_built_in_decls[fcodel];
1727 else
1728 return 0;
1731 /* If errno must be maintained, expand the RTL to check if the result,
1732 TARGET, of a built-in function call, EXP, is NaN, and if so set
1733 errno to EDOM. */
1735 static void
1736 expand_errno_check (tree exp, rtx target)
1738 rtx lab = gen_label_rtx ();
1740 /* Test the result; if it is NaN, set errno=EDOM because
1741 the argument was not in the domain. */
1742 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1743 0, lab);
1745 #ifdef TARGET_EDOM
1746 /* If this built-in doesn't throw an exception, set errno directly. */
1747 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1749 #ifdef GEN_ERRNO_RTX
1750 rtx errno_rtx = GEN_ERRNO_RTX;
1751 #else
1752 rtx errno_rtx
1753 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1754 #endif
1755 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1756 emit_label (lab);
1757 return;
1759 #endif
1761 /* We can't set errno=EDOM directly; let the library call do it.
1762 Pop the arguments right away in case the call gets deleted. */
1763 NO_DEFER_POP;
1764 expand_call (exp, target, 0);
1765 OK_DEFER_POP;
1766 emit_label (lab);
1770 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1771 Return 0 if a normal call should be emitted rather than expanding the
1772 function in-line. EXP is the expression that is a call to the builtin
1773 function; if convenient, the result should be placed in TARGET.
1774 SUBTARGET may be used as the target for computing one of EXP's operands. */
1776 static rtx
1777 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1779 optab builtin_optab;
1780 rtx op0, insns, before_call;
1781 tree fndecl = get_callee_fndecl (exp);
1782 tree arglist = TREE_OPERAND (exp, 1);
1783 enum machine_mode mode;
1784 bool errno_set = false;
1785 tree arg, narg;
1787 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1788 return 0;
1790 arg = TREE_VALUE (arglist);
1792 switch (DECL_FUNCTION_CODE (fndecl))
1794 CASE_FLT_FN (BUILT_IN_SQRT):
1795 errno_set = ! tree_expr_nonnegative_p (arg);
1796 builtin_optab = sqrt_optab;
1797 break;
1798 CASE_FLT_FN (BUILT_IN_EXP):
1799 errno_set = true; builtin_optab = exp_optab; break;
1800 CASE_FLT_FN (BUILT_IN_EXP10):
1801 CASE_FLT_FN (BUILT_IN_POW10):
1802 errno_set = true; builtin_optab = exp10_optab; break;
1803 CASE_FLT_FN (BUILT_IN_EXP2):
1804 errno_set = true; builtin_optab = exp2_optab; break;
1805 CASE_FLT_FN (BUILT_IN_EXPM1):
1806 errno_set = true; builtin_optab = expm1_optab; break;
1807 CASE_FLT_FN (BUILT_IN_LOGB):
1808 errno_set = true; builtin_optab = logb_optab; break;
1809 CASE_FLT_FN (BUILT_IN_ILOGB):
1810 errno_set = true; builtin_optab = ilogb_optab; break;
1811 CASE_FLT_FN (BUILT_IN_LOG):
1812 errno_set = true; builtin_optab = log_optab; break;
1813 CASE_FLT_FN (BUILT_IN_LOG10):
1814 errno_set = true; builtin_optab = log10_optab; break;
1815 CASE_FLT_FN (BUILT_IN_LOG2):
1816 errno_set = true; builtin_optab = log2_optab; break;
1817 CASE_FLT_FN (BUILT_IN_LOG1P):
1818 errno_set = true; builtin_optab = log1p_optab; break;
1819 CASE_FLT_FN (BUILT_IN_ASIN):
1820 builtin_optab = asin_optab; break;
1821 CASE_FLT_FN (BUILT_IN_ACOS):
1822 builtin_optab = acos_optab; break;
1823 CASE_FLT_FN (BUILT_IN_TAN):
1824 builtin_optab = tan_optab; break;
1825 CASE_FLT_FN (BUILT_IN_ATAN):
1826 builtin_optab = atan_optab; break;
1827 CASE_FLT_FN (BUILT_IN_FLOOR):
1828 builtin_optab = floor_optab; break;
1829 CASE_FLT_FN (BUILT_IN_CEIL):
1830 builtin_optab = ceil_optab; break;
1831 CASE_FLT_FN (BUILT_IN_TRUNC):
1832 builtin_optab = btrunc_optab; break;
1833 CASE_FLT_FN (BUILT_IN_ROUND):
1834 builtin_optab = round_optab; break;
1835 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1836 builtin_optab = nearbyint_optab; break;
1837 CASE_FLT_FN (BUILT_IN_RINT):
1838 builtin_optab = rint_optab; break;
1839 default:
1840 gcc_unreachable ();
1843 /* Make a suitable register to place result in. */
1844 mode = TYPE_MODE (TREE_TYPE (exp));
1846 if (! flag_errno_math || ! HONOR_NANS (mode))
1847 errno_set = false;
1849 /* Before working hard, check whether the instruction is available. */
1850 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1852 target = gen_reg_rtx (mode);
1854 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1855 need to expand the argument again. This way, we will not perform
1856 side-effects more the once. */
1857 narg = builtin_save_expr (arg);
1858 if (narg != arg)
1860 arg = narg;
1861 arglist = build_tree_list (NULL_TREE, arg);
1862 exp = build_function_call_expr (fndecl, arglist);
1865 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1867 start_sequence ();
1869 /* Compute into TARGET.
1870 Set TARGET to wherever the result comes back. */
1871 target = expand_unop (mode, builtin_optab, op0, target, 0);
1873 if (target != 0)
1875 if (errno_set)
1876 expand_errno_check (exp, target);
1878 /* Output the entire sequence. */
1879 insns = get_insns ();
1880 end_sequence ();
1881 emit_insn (insns);
1882 return target;
1885 /* If we were unable to expand via the builtin, stop the sequence
1886 (without outputting the insns) and call to the library function
1887 with the stabilized argument list. */
1888 end_sequence ();
1891 before_call = get_last_insn ();
1893 target = expand_call (exp, target, target == const0_rtx);
1895 /* If this is a sqrt operation and we don't care about errno, try to
1896 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1897 This allows the semantics of the libcall to be visible to the RTL
1898 optimizers. */
1899 if (builtin_optab == sqrt_optab && !errno_set)
1901 /* Search backwards through the insns emitted by expand_call looking
1902 for the instruction with the REG_RETVAL note. */
1903 rtx last = get_last_insn ();
1904 while (last != before_call)
1906 if (find_reg_note (last, REG_RETVAL, NULL))
1908 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1909 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1910 two elements, i.e. symbol_ref(sqrt) and the operand. */
1911 if (note
1912 && GET_CODE (note) == EXPR_LIST
1913 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1914 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1915 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1917 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1918 /* Check operand is a register with expected mode. */
1919 if (operand
1920 && REG_P (operand)
1921 && GET_MODE (operand) == mode)
1923 /* Replace the REG_EQUAL note with a SQRT rtx. */
1924 rtx equiv = gen_rtx_SQRT (mode, operand);
1925 set_unique_reg_note (last, REG_EQUAL, equiv);
1928 break;
1930 last = PREV_INSN (last);
1934 return target;
1937 /* Expand a call to the builtin binary math functions (pow and atan2).
1938 Return 0 if a normal call should be emitted rather than expanding the
1939 function in-line. EXP is the expression that is a call to the builtin
1940 function; if convenient, the result should be placed in TARGET.
1941 SUBTARGET may be used as the target for computing one of EXP's
1942 operands. */
1944 static rtx
1945 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1947 optab builtin_optab;
1948 rtx op0, op1, insns;
1949 int op1_type = REAL_TYPE;
1950 tree fndecl = get_callee_fndecl (exp);
1951 tree arglist = TREE_OPERAND (exp, 1);
1952 tree arg0, arg1, temp, narg;
1953 enum machine_mode mode;
1954 bool errno_set = true;
1955 bool stable = true;
1957 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1958 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1959 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1960 op1_type = INTEGER_TYPE;
1962 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1963 return 0;
1965 arg0 = TREE_VALUE (arglist);
1966 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1968 switch (DECL_FUNCTION_CODE (fndecl))
1970 CASE_FLT_FN (BUILT_IN_POW):
1971 builtin_optab = pow_optab; break;
1972 CASE_FLT_FN (BUILT_IN_ATAN2):
1973 builtin_optab = atan2_optab; break;
1974 CASE_FLT_FN (BUILT_IN_LDEXP):
1975 builtin_optab = ldexp_optab; break;
1976 CASE_FLT_FN (BUILT_IN_FMOD):
1977 builtin_optab = fmod_optab; break;
1978 CASE_FLT_FN (BUILT_IN_REMAINDER):
1979 CASE_FLT_FN (BUILT_IN_DREM):
1980 builtin_optab = remainder_optab; break;
1981 default:
1982 gcc_unreachable ();
1985 /* Make a suitable register to place result in. */
1986 mode = TYPE_MODE (TREE_TYPE (exp));
1988 /* Before working hard, check whether the instruction is available. */
1989 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1990 return 0;
1992 target = gen_reg_rtx (mode);
1994 if (! flag_errno_math || ! HONOR_NANS (mode))
1995 errno_set = false;
1997 /* Always stabilize the argument list. */
1998 narg = builtin_save_expr (arg1);
1999 if (narg != arg1)
2001 arg1 = narg;
2002 temp = build_tree_list (NULL_TREE, narg);
2003 stable = false;
2005 else
2006 temp = TREE_CHAIN (arglist);
2008 narg = builtin_save_expr (arg0);
2009 if (narg != arg0)
2011 arg0 = narg;
2012 arglist = tree_cons (NULL_TREE, narg, temp);
2013 stable = false;
2015 else if (! stable)
2016 arglist = tree_cons (NULL_TREE, arg0, temp);
2018 if (! stable)
2019 exp = build_function_call_expr (fndecl, arglist);
2021 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2022 op1 = expand_normal (arg1);
2024 start_sequence ();
2026 /* Compute into TARGET.
2027 Set TARGET to wherever the result comes back. */
2028 target = expand_binop (mode, builtin_optab, op0, op1,
2029 target, 0, OPTAB_DIRECT);
2031 /* If we were unable to expand via the builtin, stop the sequence
2032 (without outputting the insns) and call to the library function
2033 with the stabilized argument list. */
2034 if (target == 0)
2036 end_sequence ();
2037 return expand_call (exp, target, target == const0_rtx);
2040 if (errno_set)
2041 expand_errno_check (exp, target);
2043 /* Output the entire sequence. */
2044 insns = get_insns ();
2045 end_sequence ();
2046 emit_insn (insns);
2048 return target;
2051 /* Expand a call to the builtin sin and cos math functions.
2052 Return 0 if a normal call should be emitted rather than expanding the
2053 function in-line. EXP is the expression that is a call to the builtin
2054 function; if convenient, the result should be placed in TARGET.
2055 SUBTARGET may be used as the target for computing one of EXP's
2056 operands. */
2058 static rtx
2059 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2061 optab builtin_optab;
2062 rtx op0, insns;
2063 tree fndecl = get_callee_fndecl (exp);
2064 tree arglist = TREE_OPERAND (exp, 1);
2065 enum machine_mode mode;
2066 tree arg, narg;
2068 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2069 return 0;
2071 arg = TREE_VALUE (arglist);
2073 switch (DECL_FUNCTION_CODE (fndecl))
2075 CASE_FLT_FN (BUILT_IN_SIN):
2076 CASE_FLT_FN (BUILT_IN_COS):
2077 builtin_optab = sincos_optab; break;
2078 default:
2079 gcc_unreachable ();
2082 /* Make a suitable register to place result in. */
2083 mode = TYPE_MODE (TREE_TYPE (exp));
2085 /* Check if sincos insn is available, otherwise fallback
2086 to sin or cos insn. */
2087 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2088 switch (DECL_FUNCTION_CODE (fndecl))
2090 CASE_FLT_FN (BUILT_IN_SIN):
2091 builtin_optab = sin_optab; break;
2092 CASE_FLT_FN (BUILT_IN_COS):
2093 builtin_optab = cos_optab; break;
2094 default:
2095 gcc_unreachable ();
2099 /* Before working hard, check whether the instruction is available. */
2100 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2102 target = gen_reg_rtx (mode);
2104 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2105 need to expand the argument again. This way, we will not perform
2106 side-effects more the once. */
2107 narg = save_expr (arg);
2108 if (narg != arg)
2110 arg = narg;
2111 arglist = build_tree_list (NULL_TREE, arg);
2112 exp = build_function_call_expr (fndecl, arglist);
2115 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2117 start_sequence ();
2119 /* Compute into TARGET.
2120 Set TARGET to wherever the result comes back. */
2121 if (builtin_optab == sincos_optab)
2123 int result;
2125 switch (DECL_FUNCTION_CODE (fndecl))
2127 CASE_FLT_FN (BUILT_IN_SIN):
2128 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2129 break;
2130 CASE_FLT_FN (BUILT_IN_COS):
2131 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2132 break;
2133 default:
2134 gcc_unreachable ();
2136 gcc_assert (result);
2138 else
2140 target = expand_unop (mode, builtin_optab, op0, target, 0);
2143 if (target != 0)
2145 /* Output the entire sequence. */
2146 insns = get_insns ();
2147 end_sequence ();
2148 emit_insn (insns);
2149 return target;
2152 /* If we were unable to expand via the builtin, stop the sequence
2153 (without outputting the insns) and call to the library function
2154 with the stabilized argument list. */
2155 end_sequence ();
2158 target = expand_call (exp, target, target == const0_rtx);
2160 return target;
2163 /* Expand a call to the builtin sincos math function.
2164 Return 0 if a normal call should be emitted rather than expanding the
2165 function in-line. EXP is the expression that is a call to the builtin
2166 function. */
2168 static rtx
2169 expand_builtin_sincos (tree exp)
2171 rtx op0, op1, op2, target1, target2;
2172 tree arglist = TREE_OPERAND (exp, 1);
2173 enum machine_mode mode;
2174 tree arg, sinp, cosp;
2175 int result;
2177 if (!validate_arglist (arglist, REAL_TYPE,
2178 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2179 return 0;
2181 arg = TREE_VALUE (arglist);
2182 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2183 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2185 /* Make a suitable register to place result in. */
2186 mode = TYPE_MODE (TREE_TYPE (arg));
2188 /* Check if sincos insn is available, otherwise emit the call. */
2189 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2190 return NULL_RTX;
2192 target1 = gen_reg_rtx (mode);
2193 target2 = gen_reg_rtx (mode);
2195 op0 = expand_normal (arg);
2196 op1 = expand_normal (build_fold_indirect_ref (sinp));
2197 op2 = expand_normal (build_fold_indirect_ref (cosp));
2199 /* Compute into target1 and target2.
2200 Set TARGET to wherever the result comes back. */
2201 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2202 gcc_assert (result);
2204 /* Move target1 and target2 to the memory locations indicated
2205 by op1 and op2. */
2206 emit_move_insn (op1, target1);
2207 emit_move_insn (op2, target2);
2209 return const0_rtx;
2212 /* Expand a call to one of the builtin rounding functions gcc defines
2213 as an extension (lfloor and lceil). As these are gcc extensions we
2214 do not need to worry about setting errno to EDOM.
2215 If expanding via optab fails, lower expression to (int)(floor(x)).
2216 EXP is the expression that is a call to the builtin function;
2217 if convenient, the result should be placed in TARGET. SUBTARGET may
2218 be used as the target for computing one of EXP's operands. */
2220 static rtx
2221 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2223 optab builtin_optab;
2224 rtx op0, insns, tmp;
2225 tree fndecl = get_callee_fndecl (exp);
2226 tree arglist = TREE_OPERAND (exp, 1);
2227 enum built_in_function fallback_fn;
2228 tree fallback_fndecl;
2229 enum machine_mode mode;
2230 tree arg, narg;
2232 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2233 gcc_unreachable ();
2235 arg = TREE_VALUE (arglist);
2237 switch (DECL_FUNCTION_CODE (fndecl))
2239 CASE_FLT_FN (BUILT_IN_LCEIL):
2240 CASE_FLT_FN (BUILT_IN_LLCEIL):
2241 builtin_optab = lceil_optab;
2242 fallback_fn = BUILT_IN_CEIL;
2243 break;
2245 CASE_FLT_FN (BUILT_IN_LFLOOR):
2246 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2247 builtin_optab = lfloor_optab;
2248 fallback_fn = BUILT_IN_FLOOR;
2249 break;
2251 default:
2252 gcc_unreachable ();
2255 /* Make a suitable register to place result in. */
2256 mode = TYPE_MODE (TREE_TYPE (exp));
2258 /* Before working hard, check whether the instruction is available. */
2259 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2261 target = gen_reg_rtx (mode);
2263 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2264 need to expand the argument again. This way, we will not perform
2265 side-effects more the once. */
2266 narg = builtin_save_expr (arg);
2267 if (narg != arg)
2269 arg = narg;
2270 arglist = build_tree_list (NULL_TREE, arg);
2271 exp = build_function_call_expr (fndecl, arglist);
2274 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2276 start_sequence ();
2278 /* Compute into TARGET.
2279 Set TARGET to wherever the result comes back. */
2280 target = expand_unop (mode, builtin_optab, op0, target, 0);
2282 if (target != 0)
2284 /* Output the entire sequence. */
2285 insns = get_insns ();
2286 end_sequence ();
2287 emit_insn (insns);
2288 return target;
2291 /* If we were unable to expand via the builtin, stop the sequence
2292 (without outputting the insns). */
2293 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 unary builtin. The arguments are in ARGLIST.
4632 Return 0 if a normal call should be emitted rather than expanding the
4633 function in-line. If convenient, the result should be placed in TARGET.
4634 SUBTARGET may be used as the target for computing one of EXP's operands. */
4636 static rtx
4637 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4638 rtx subtarget, optab op_optab)
4640 rtx op0;
4641 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4642 return 0;
4644 /* Compute the argument. */
4645 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4646 /* Compute op, into TARGET if possible.
4647 Set TARGET to wherever the result comes back. */
4648 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4649 op_optab, op0, target, 1);
4650 gcc_assert (target);
4652 return convert_to_mode (target_mode, target, 0);
4655 /* If the string passed to fputs is a constant and is one character
4656 long, we attempt to transform this call into __builtin_fputc(). */
4658 static rtx
4659 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4661 /* Verify the arguments in the original call. */
4662 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4664 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4665 unlocked, NULL_TREE);
4666 if (result)
4667 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4669 return 0;
4672 /* Expand a call to __builtin_expect. We return our argument and emit a
4673 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4674 a non-jump context. */
4676 static rtx
4677 expand_builtin_expect (tree arglist, rtx target)
4679 tree exp, c;
4680 rtx note, rtx_c;
4682 if (arglist == NULL_TREE
4683 || TREE_CHAIN (arglist) == NULL_TREE)
4684 return const0_rtx;
4685 exp = TREE_VALUE (arglist);
4686 c = TREE_VALUE (TREE_CHAIN (arglist));
4688 if (TREE_CODE (c) != INTEGER_CST)
4690 error ("second argument to %<__builtin_expect%> must be a constant");
4691 c = integer_zero_node;
4694 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4696 /* Don't bother with expected value notes for integral constants. */
4697 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4699 /* We do need to force this into a register so that we can be
4700 moderately sure to be able to correctly interpret the branch
4701 condition later. */
4702 target = force_reg (GET_MODE (target), target);
4704 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4706 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4707 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4710 return target;
4713 /* Like expand_builtin_expect, except do this in a jump context. This is
4714 called from do_jump if the conditional is a __builtin_expect. Return either
4715 a list of insns to emit the jump or NULL if we cannot optimize
4716 __builtin_expect. We need to optimize this at jump time so that machines
4717 like the PowerPC don't turn the test into a SCC operation, and then jump
4718 based on the test being 0/1. */
4721 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4723 tree arglist = TREE_OPERAND (exp, 1);
4724 tree arg0 = TREE_VALUE (arglist);
4725 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4726 rtx ret = NULL_RTX;
4728 /* Only handle __builtin_expect (test, 0) and
4729 __builtin_expect (test, 1). */
4730 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4731 && (integer_zerop (arg1) || integer_onep (arg1)))
4733 rtx insn, drop_through_label, temp;
4735 /* Expand the jump insns. */
4736 start_sequence ();
4737 do_jump (arg0, if_false_label, if_true_label);
4738 ret = get_insns ();
4740 drop_through_label = get_last_insn ();
4741 if (drop_through_label && NOTE_P (drop_through_label))
4742 drop_through_label = prev_nonnote_insn (drop_through_label);
4743 if (drop_through_label && !LABEL_P (drop_through_label))
4744 drop_through_label = NULL_RTX;
4745 end_sequence ();
4747 if (! if_true_label)
4748 if_true_label = drop_through_label;
4749 if (! if_false_label)
4750 if_false_label = drop_through_label;
4752 /* Go through and add the expect's to each of the conditional jumps. */
4753 insn = ret;
4754 while (insn != NULL_RTX)
4756 rtx next = NEXT_INSN (insn);
4758 if (JUMP_P (insn) && any_condjump_p (insn))
4760 rtx ifelse = SET_SRC (pc_set (insn));
4761 rtx then_dest = XEXP (ifelse, 1);
4762 rtx else_dest = XEXP (ifelse, 2);
4763 int taken = -1;
4765 /* First check if we recognize any of the labels. */
4766 if (GET_CODE (then_dest) == LABEL_REF
4767 && XEXP (then_dest, 0) == if_true_label)
4768 taken = 1;
4769 else if (GET_CODE (then_dest) == LABEL_REF
4770 && XEXP (then_dest, 0) == if_false_label)
4771 taken = 0;
4772 else if (GET_CODE (else_dest) == LABEL_REF
4773 && XEXP (else_dest, 0) == if_false_label)
4774 taken = 1;
4775 else if (GET_CODE (else_dest) == LABEL_REF
4776 && XEXP (else_dest, 0) == if_true_label)
4777 taken = 0;
4778 /* Otherwise check where we drop through. */
4779 else if (else_dest == pc_rtx)
4781 if (next && NOTE_P (next))
4782 next = next_nonnote_insn (next);
4784 if (next && JUMP_P (next)
4785 && any_uncondjump_p (next))
4786 temp = XEXP (SET_SRC (pc_set (next)), 0);
4787 else
4788 temp = next;
4790 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4791 else that can't possibly match either target label. */
4792 if (temp == if_false_label)
4793 taken = 1;
4794 else if (temp == if_true_label)
4795 taken = 0;
4797 else if (then_dest == pc_rtx)
4799 if (next && NOTE_P (next))
4800 next = next_nonnote_insn (next);
4802 if (next && JUMP_P (next)
4803 && any_uncondjump_p (next))
4804 temp = XEXP (SET_SRC (pc_set (next)), 0);
4805 else
4806 temp = next;
4808 if (temp == if_false_label)
4809 taken = 0;
4810 else if (temp == if_true_label)
4811 taken = 1;
4814 if (taken != -1)
4816 /* If the test is expected to fail, reverse the
4817 probabilities. */
4818 if (integer_zerop (arg1))
4819 taken = 1 - taken;
4820 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4824 insn = next;
4828 return ret;
4831 void
4832 expand_builtin_trap (void)
4834 #ifdef HAVE_trap
4835 if (HAVE_trap)
4836 emit_insn (gen_trap ());
4837 else
4838 #endif
4839 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4840 emit_barrier ();
4843 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4844 Return 0 if a normal call should be emitted rather than expanding
4845 the function inline. If convenient, the result should be placed
4846 in TARGET. SUBTARGET may be used as the target for computing
4847 the operand. */
4849 static rtx
4850 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4852 enum machine_mode mode;
4853 tree arg;
4854 rtx op0;
4856 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4857 return 0;
4859 arg = TREE_VALUE (arglist);
4860 mode = TYPE_MODE (TREE_TYPE (arg));
4861 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4862 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4865 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4866 Return NULL is a normal call should be emitted rather than expanding the
4867 function inline. If convenient, the result should be placed in TARGET.
4868 SUBTARGET may be used as the target for computing the operand. */
4870 static rtx
4871 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4873 rtx op0, op1;
4874 tree arg;
4876 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4877 return 0;
4879 arg = TREE_VALUE (arglist);
4880 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4882 arg = TREE_VALUE (TREE_CHAIN (arglist));
4883 op1 = expand_normal (arg);
4885 return expand_copysign (op0, op1, target);
4888 /* Create a new constant string literal and return a char* pointer to it.
4889 The STRING_CST value is the LEN characters at STR. */
4890 tree
4891 build_string_literal (int len, const char *str)
4893 tree t, elem, index, type;
4895 t = build_string (len, str);
4896 elem = build_type_variant (char_type_node, 1, 0);
4897 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4898 type = build_array_type (elem, index);
4899 TREE_TYPE (t) = type;
4900 TREE_CONSTANT (t) = 1;
4901 TREE_INVARIANT (t) = 1;
4902 TREE_READONLY (t) = 1;
4903 TREE_STATIC (t) = 1;
4905 type = build_pointer_type (type);
4906 t = build1 (ADDR_EXPR, type, t);
4908 type = build_pointer_type (elem);
4909 t = build1 (NOP_EXPR, type, t);
4910 return t;
4913 /* Expand EXP, a call to printf or printf_unlocked.
4914 Return 0 if a normal call should be emitted rather than transforming
4915 the function inline. If convenient, the result should be placed in
4916 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4917 call. */
4918 static rtx
4919 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4920 bool unlocked)
4922 tree arglist = TREE_OPERAND (exp, 1);
4923 /* If we're using an unlocked function, assume the other unlocked
4924 functions exist explicitly. */
4925 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4926 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4927 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4928 : implicit_built_in_decls[BUILT_IN_PUTS];
4929 const char *fmt_str;
4930 tree fn, fmt, arg;
4932 /* If the return value is used, don't do the transformation. */
4933 if (target != const0_rtx)
4934 return 0;
4936 /* Verify the required arguments in the original call. */
4937 if (! arglist)
4938 return 0;
4939 fmt = TREE_VALUE (arglist);
4940 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4941 return 0;
4942 arglist = TREE_CHAIN (arglist);
4944 /* Check whether the format is a literal string constant. */
4945 fmt_str = c_getstr (fmt);
4946 if (fmt_str == NULL)
4947 return 0;
4949 if (!init_target_chars())
4950 return 0;
4952 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4953 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4955 if (! arglist
4956 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4957 || TREE_CHAIN (arglist))
4958 return 0;
4959 fn = fn_puts;
4961 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4962 else if (strcmp (fmt_str, target_percent_c) == 0)
4964 if (! arglist
4965 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4966 || TREE_CHAIN (arglist))
4967 return 0;
4968 fn = fn_putchar;
4970 else
4972 /* We can't handle anything else with % args or %% ... yet. */
4973 if (strchr (fmt_str, target_percent))
4974 return 0;
4976 if (arglist)
4977 return 0;
4979 /* If the format specifier was "", printf does nothing. */
4980 if (fmt_str[0] == '\0')
4981 return const0_rtx;
4982 /* If the format specifier has length of 1, call putchar. */
4983 if (fmt_str[1] == '\0')
4985 /* Given printf("c"), (where c is any one character,)
4986 convert "c"[0] to an int and pass that to the replacement
4987 function. */
4988 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4989 arglist = build_tree_list (NULL_TREE, arg);
4990 fn = fn_putchar;
4992 else
4994 /* If the format specifier was "string\n", call puts("string"). */
4995 size_t len = strlen (fmt_str);
4996 if ((unsigned char)fmt_str[len - 1] == target_newline)
4998 /* Create a NUL-terminated string that's one char shorter
4999 than the original, stripping off the trailing '\n'. */
5000 char *newstr = alloca (len);
5001 memcpy (newstr, fmt_str, len - 1);
5002 newstr[len - 1] = 0;
5004 arg = build_string_literal (len, newstr);
5005 arglist = build_tree_list (NULL_TREE, arg);
5006 fn = fn_puts;
5008 else
5009 /* We'd like to arrange to call fputs(string,stdout) here,
5010 but we need stdout and don't have a way to get it yet. */
5011 return 0;
5015 if (!fn)
5016 return 0;
5017 fn = build_function_call_expr (fn, arglist);
5018 if (TREE_CODE (fn) == CALL_EXPR)
5019 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5020 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5023 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5024 Return 0 if a normal call should be emitted rather than transforming
5025 the function inline. If convenient, the result should be placed in
5026 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5027 call. */
5028 static rtx
5029 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5030 bool unlocked)
5032 tree arglist = TREE_OPERAND (exp, 1);
5033 /* If we're using an unlocked function, assume the other unlocked
5034 functions exist explicitly. */
5035 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5036 : implicit_built_in_decls[BUILT_IN_FPUTC];
5037 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5038 : implicit_built_in_decls[BUILT_IN_FPUTS];
5039 const char *fmt_str;
5040 tree fn, fmt, fp, arg;
5042 /* If the return value is used, don't do the transformation. */
5043 if (target != const0_rtx)
5044 return 0;
5046 /* Verify the required arguments in the original call. */
5047 if (! arglist)
5048 return 0;
5049 fp = TREE_VALUE (arglist);
5050 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5051 return 0;
5052 arglist = TREE_CHAIN (arglist);
5053 if (! arglist)
5054 return 0;
5055 fmt = TREE_VALUE (arglist);
5056 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5057 return 0;
5058 arglist = TREE_CHAIN (arglist);
5060 /* Check whether the format is a literal string constant. */
5061 fmt_str = c_getstr (fmt);
5062 if (fmt_str == NULL)
5063 return 0;
5065 if (!init_target_chars())
5066 return 0;
5068 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5069 if (strcmp (fmt_str, target_percent_s) == 0)
5071 if (! arglist
5072 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5073 || TREE_CHAIN (arglist))
5074 return 0;
5075 arg = TREE_VALUE (arglist);
5076 arglist = build_tree_list (NULL_TREE, fp);
5077 arglist = tree_cons (NULL_TREE, arg, arglist);
5078 fn = fn_fputs;
5080 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5081 else if (strcmp (fmt_str, target_percent_c) == 0)
5083 if (! arglist
5084 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5085 || TREE_CHAIN (arglist))
5086 return 0;
5087 arg = TREE_VALUE (arglist);
5088 arglist = build_tree_list (NULL_TREE, fp);
5089 arglist = tree_cons (NULL_TREE, arg, arglist);
5090 fn = fn_fputc;
5092 else
5094 /* We can't handle anything else with % args or %% ... yet. */
5095 if (strchr (fmt_str, target_percent))
5096 return 0;
5098 if (arglist)
5099 return 0;
5101 /* If the format specifier was "", fprintf does nothing. */
5102 if (fmt_str[0] == '\0')
5104 /* Evaluate and ignore FILE* argument for side-effects. */
5105 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5106 return const0_rtx;
5109 /* When "string" doesn't contain %, replace all cases of
5110 fprintf(stream,string) with fputs(string,stream). The fputs
5111 builtin will take care of special cases like length == 1. */
5112 arglist = build_tree_list (NULL_TREE, fp);
5113 arglist = tree_cons (NULL_TREE, fmt, arglist);
5114 fn = fn_fputs;
5117 if (!fn)
5118 return 0;
5119 fn = build_function_call_expr (fn, arglist);
5120 if (TREE_CODE (fn) == CALL_EXPR)
5121 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5122 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5125 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5126 a normal call should be emitted rather than expanding the function
5127 inline. If convenient, the result should be placed in TARGET with
5128 mode MODE. */
5130 static rtx
5131 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5133 tree orig_arglist, dest, fmt;
5134 const char *fmt_str;
5136 orig_arglist = arglist;
5138 /* Verify the required arguments in the original call. */
5139 if (! arglist)
5140 return 0;
5141 dest = TREE_VALUE (arglist);
5142 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5143 return 0;
5144 arglist = TREE_CHAIN (arglist);
5145 if (! arglist)
5146 return 0;
5147 fmt = TREE_VALUE (arglist);
5148 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5149 return 0;
5150 arglist = TREE_CHAIN (arglist);
5152 /* Check whether the format is a literal string constant. */
5153 fmt_str = c_getstr (fmt);
5154 if (fmt_str == NULL)
5155 return 0;
5157 if (!init_target_chars())
5158 return 0;
5160 /* If the format doesn't contain % args or %%, use strcpy. */
5161 if (strchr (fmt_str, target_percent) == 0)
5163 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5164 tree exp;
5166 if (arglist || ! fn)
5167 return 0;
5168 expand_expr (build_function_call_expr (fn, orig_arglist),
5169 const0_rtx, VOIDmode, EXPAND_NORMAL);
5170 if (target == const0_rtx)
5171 return const0_rtx;
5172 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5173 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5175 /* If the format is "%s", use strcpy if the result isn't used. */
5176 else if (strcmp (fmt_str, target_percent_s) == 0)
5178 tree fn, arg, len;
5179 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5181 if (! fn)
5182 return 0;
5184 if (! arglist || TREE_CHAIN (arglist))
5185 return 0;
5186 arg = TREE_VALUE (arglist);
5187 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5188 return 0;
5190 if (target != const0_rtx)
5192 len = c_strlen (arg, 1);
5193 if (! len || TREE_CODE (len) != INTEGER_CST)
5194 return 0;
5196 else
5197 len = NULL_TREE;
5199 arglist = build_tree_list (NULL_TREE, arg);
5200 arglist = tree_cons (NULL_TREE, dest, arglist);
5201 expand_expr (build_function_call_expr (fn, arglist),
5202 const0_rtx, VOIDmode, EXPAND_NORMAL);
5204 if (target == const0_rtx)
5205 return const0_rtx;
5206 return expand_expr (len, target, mode, EXPAND_NORMAL);
5209 return 0;
5212 /* Expand a call to either the entry or exit function profiler. */
5214 static rtx
5215 expand_builtin_profile_func (bool exitp)
5217 rtx this, which;
5219 this = DECL_RTL (current_function_decl);
5220 gcc_assert (MEM_P (this));
5221 this = XEXP (this, 0);
5223 if (exitp)
5224 which = profile_function_exit_libfunc;
5225 else
5226 which = profile_function_entry_libfunc;
5228 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5229 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5231 Pmode);
5233 return const0_rtx;
5236 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5238 static rtx
5239 round_trampoline_addr (rtx tramp)
5241 rtx temp, addend, mask;
5243 /* If we don't need too much alignment, we'll have been guaranteed
5244 proper alignment by get_trampoline_type. */
5245 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5246 return tramp;
5248 /* Round address up to desired boundary. */
5249 temp = gen_reg_rtx (Pmode);
5250 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5251 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5253 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5254 temp, 0, OPTAB_LIB_WIDEN);
5255 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5256 temp, 0, OPTAB_LIB_WIDEN);
5258 return tramp;
5261 static rtx
5262 expand_builtin_init_trampoline (tree arglist)
5264 tree t_tramp, t_func, t_chain;
5265 rtx r_tramp, r_func, r_chain;
5266 #ifdef TRAMPOLINE_TEMPLATE
5267 rtx blktramp;
5268 #endif
5270 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5271 POINTER_TYPE, VOID_TYPE))
5272 return NULL_RTX;
5274 t_tramp = TREE_VALUE (arglist);
5275 arglist = TREE_CHAIN (arglist);
5276 t_func = TREE_VALUE (arglist);
5277 arglist = TREE_CHAIN (arglist);
5278 t_chain = TREE_VALUE (arglist);
5280 r_tramp = expand_normal (t_tramp);
5281 r_func = expand_normal (t_func);
5282 r_chain = expand_normal (t_chain);
5284 /* Generate insns to initialize the trampoline. */
5285 r_tramp = round_trampoline_addr (r_tramp);
5286 #ifdef TRAMPOLINE_TEMPLATE
5287 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5288 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5289 emit_block_move (blktramp, assemble_trampoline_template (),
5290 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5291 #endif
5292 trampolines_created = 1;
5293 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5295 return const0_rtx;
5298 static rtx
5299 expand_builtin_adjust_trampoline (tree arglist)
5301 rtx tramp;
5303 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5304 return NULL_RTX;
5306 tramp = expand_normal (TREE_VALUE (arglist));
5307 tramp = round_trampoline_addr (tramp);
5308 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5309 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5310 #endif
5312 return tramp;
5315 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5316 Return NULL_RTX if a normal call should be emitted rather than expanding
5317 the function in-line. EXP is the expression that is a call to the builtin
5318 function; if convenient, the result should be placed in TARGET. */
5320 static rtx
5321 expand_builtin_signbit (tree exp, rtx target)
5323 const struct real_format *fmt;
5324 enum machine_mode fmode, imode, rmode;
5325 HOST_WIDE_INT hi, lo;
5326 tree arg, arglist;
5327 int word, bitpos;
5328 rtx temp;
5330 arglist = TREE_OPERAND (exp, 1);
5331 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5332 return 0;
5334 arg = TREE_VALUE (arglist);
5335 fmode = TYPE_MODE (TREE_TYPE (arg));
5336 rmode = TYPE_MODE (TREE_TYPE (exp));
5337 fmt = REAL_MODE_FORMAT (fmode);
5339 /* For floating point formats without a sign bit, implement signbit
5340 as "ARG < 0.0". */
5341 bitpos = fmt->signbit_ro;
5342 if (bitpos < 0)
5344 /* But we can't do this if the format supports signed zero. */
5345 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5346 return 0;
5348 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5349 build_real (TREE_TYPE (arg), dconst0));
5350 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5353 temp = expand_normal (arg);
5354 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5356 imode = int_mode_for_mode (fmode);
5357 if (imode == BLKmode)
5358 return 0;
5359 temp = gen_lowpart (imode, temp);
5361 else
5363 imode = word_mode;
5364 /* Handle targets with different FP word orders. */
5365 if (FLOAT_WORDS_BIG_ENDIAN)
5366 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5367 else
5368 word = bitpos / BITS_PER_WORD;
5369 temp = operand_subword_force (temp, word, fmode);
5370 bitpos = bitpos % BITS_PER_WORD;
5373 /* Force the intermediate word_mode (or narrower) result into a
5374 register. This avoids attempting to create paradoxical SUBREGs
5375 of floating point modes below. */
5376 temp = force_reg (imode, temp);
5378 /* If the bitpos is within the "result mode" lowpart, the operation
5379 can be implement with a single bitwise AND. Otherwise, we need
5380 a right shift and an AND. */
5382 if (bitpos < GET_MODE_BITSIZE (rmode))
5384 if (bitpos < HOST_BITS_PER_WIDE_INT)
5386 hi = 0;
5387 lo = (HOST_WIDE_INT) 1 << bitpos;
5389 else
5391 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5392 lo = 0;
5395 if (imode != rmode)
5396 temp = gen_lowpart (rmode, temp);
5397 temp = expand_binop (rmode, and_optab, temp,
5398 immed_double_const (lo, hi, rmode),
5399 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5401 else
5403 /* Perform a logical right shift to place the signbit in the least
5404 significant bit, then truncate the result to the desired mode
5405 and mask just this bit. */
5406 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5407 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5408 temp = gen_lowpart (rmode, temp);
5409 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5410 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5413 return temp;
5416 /* Expand fork or exec calls. TARGET is the desired target of the
5417 call. ARGLIST is the list of arguments of the call. FN is the
5418 identificator of the actual function. IGNORE is nonzero if the
5419 value is to be ignored. */
5421 static rtx
5422 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5424 tree id, decl;
5425 tree call;
5427 /* If we are not profiling, just call the function. */
5428 if (!profile_arc_flag)
5429 return NULL_RTX;
5431 /* Otherwise call the wrapper. This should be equivalent for the rest of
5432 compiler, so the code does not diverge, and the wrapper may run the
5433 code necessary for keeping the profiling sane. */
5435 switch (DECL_FUNCTION_CODE (fn))
5437 case BUILT_IN_FORK:
5438 id = get_identifier ("__gcov_fork");
5439 break;
5441 case BUILT_IN_EXECL:
5442 id = get_identifier ("__gcov_execl");
5443 break;
5445 case BUILT_IN_EXECV:
5446 id = get_identifier ("__gcov_execv");
5447 break;
5449 case BUILT_IN_EXECLP:
5450 id = get_identifier ("__gcov_execlp");
5451 break;
5453 case BUILT_IN_EXECLE:
5454 id = get_identifier ("__gcov_execle");
5455 break;
5457 case BUILT_IN_EXECVP:
5458 id = get_identifier ("__gcov_execvp");
5459 break;
5461 case BUILT_IN_EXECVE:
5462 id = get_identifier ("__gcov_execve");
5463 break;
5465 default:
5466 gcc_unreachable ();
5469 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5470 DECL_EXTERNAL (decl) = 1;
5471 TREE_PUBLIC (decl) = 1;
5472 DECL_ARTIFICIAL (decl) = 1;
5473 TREE_NOTHROW (decl) = 1;
5474 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5475 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5476 call = build_function_call_expr (decl, arglist);
5478 return expand_call (call, target, ignore);
5482 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5483 the pointer in these functions is void*, the tree optimizers may remove
5484 casts. The mode computed in expand_builtin isn't reliable either, due
5485 to __sync_bool_compare_and_swap.
5487 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5488 group of builtins. This gives us log2 of the mode size. */
5490 static inline enum machine_mode
5491 get_builtin_sync_mode (int fcode_diff)
5493 /* The size is not negotiable, so ask not to get BLKmode in return
5494 if the target indicates that a smaller size would be better. */
5495 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5498 /* Expand the memory expression LOC and return the appropriate memory operand
5499 for the builtin_sync operations. */
5501 static rtx
5502 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5504 rtx addr, mem;
5506 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5508 /* Note that we explicitly do not want any alias information for this
5509 memory, so that we kill all other live memories. Otherwise we don't
5510 satisfy the full barrier semantics of the intrinsic. */
5511 mem = validize_mem (gen_rtx_MEM (mode, addr));
5513 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5514 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5515 MEM_VOLATILE_P (mem) = 1;
5517 return mem;
5520 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5521 ARGLIST is the operands list to the function. CODE is the rtx code
5522 that corresponds to the arithmetic or logical operation from the name;
5523 an exception here is that NOT actually means NAND. TARGET is an optional
5524 place for us to store the results; AFTER is true if this is the
5525 fetch_and_xxx form. IGNORE is true if we don't actually care about
5526 the result of the operation at all. */
5528 static rtx
5529 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5530 enum rtx_code code, bool after,
5531 rtx target, bool ignore)
5533 rtx val, mem;
5535 /* Expand the operands. */
5536 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5538 arglist = TREE_CHAIN (arglist);
5539 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5540 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5541 val = convert_to_mode (mode, val, 1);
5543 if (ignore)
5544 return expand_sync_operation (mem, val, code);
5545 else
5546 return expand_sync_fetch_operation (mem, val, code, after, target);
5549 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5550 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5551 true if this is the boolean form. TARGET is a place for us to store the
5552 results; this is NOT optional if IS_BOOL is true. */
5554 static rtx
5555 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5556 bool is_bool, rtx target)
5558 rtx old_val, new_val, mem;
5560 /* Expand the operands. */
5561 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5563 arglist = TREE_CHAIN (arglist);
5564 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5565 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5566 old_val = convert_to_mode (mode, old_val, 1);
5568 arglist = TREE_CHAIN (arglist);
5569 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5570 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5571 new_val = convert_to_mode (mode, new_val, 1);
5573 if (is_bool)
5574 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5575 else
5576 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5579 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5580 general form is actually an atomic exchange, and some targets only
5581 support a reduced form with the second argument being a constant 1.
5582 ARGLIST is the operands list to the function; TARGET is an optional
5583 place for us to store the results. */
5585 static rtx
5586 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5587 rtx target)
5589 rtx val, mem;
5591 /* Expand the operands. */
5592 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5594 arglist = TREE_CHAIN (arglist);
5595 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5596 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5597 val = convert_to_mode (mode, val, 1);
5599 return expand_sync_lock_test_and_set (mem, val, target);
5602 /* Expand the __sync_synchronize intrinsic. */
5604 static void
5605 expand_builtin_synchronize (void)
5607 tree x;
5609 #ifdef HAVE_memory_barrier
5610 if (HAVE_memory_barrier)
5612 emit_insn (gen_memory_barrier ());
5613 return;
5615 #endif
5617 /* If no explicit memory barrier instruction is available, create an
5618 empty asm stmt with a memory clobber. */
5619 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5620 tree_cons (NULL, build_string (6, "memory"), NULL));
5621 ASM_VOLATILE_P (x) = 1;
5622 expand_asm_expr (x);
5625 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5626 to the function. */
5628 static void
5629 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5631 enum insn_code icode;
5632 rtx mem, insn;
5633 rtx val = const0_rtx;
5635 /* Expand the operands. */
5636 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5638 /* If there is an explicit operation in the md file, use it. */
5639 icode = sync_lock_release[mode];
5640 if (icode != CODE_FOR_nothing)
5642 if (!insn_data[icode].operand[1].predicate (val, mode))
5643 val = force_reg (mode, val);
5645 insn = GEN_FCN (icode) (mem, val);
5646 if (insn)
5648 emit_insn (insn);
5649 return;
5653 /* Otherwise we can implement this operation by emitting a barrier
5654 followed by a store of zero. */
5655 expand_builtin_synchronize ();
5656 emit_move_insn (mem, val);
5659 /* Expand an expression EXP that calls a built-in function,
5660 with result going to TARGET if that's convenient
5661 (and in mode MODE if that's convenient).
5662 SUBTARGET may be used as the target for computing one of EXP's operands.
5663 IGNORE is nonzero if the value is to be ignored. */
5666 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5667 int ignore)
5669 tree fndecl = get_callee_fndecl (exp);
5670 tree arglist = TREE_OPERAND (exp, 1);
5671 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5672 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5674 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5675 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5677 /* When not optimizing, generate calls to library functions for a certain
5678 set of builtins. */
5679 if (!optimize
5680 && !called_as_built_in (fndecl)
5681 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5682 && fcode != BUILT_IN_ALLOCA)
5683 return expand_call (exp, target, ignore);
5685 /* The built-in function expanders test for target == const0_rtx
5686 to determine whether the function's result will be ignored. */
5687 if (ignore)
5688 target = const0_rtx;
5690 /* If the result of a pure or const built-in function is ignored, and
5691 none of its arguments are volatile, we can avoid expanding the
5692 built-in call and just evaluate the arguments for side-effects. */
5693 if (target == const0_rtx
5694 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5696 bool volatilep = false;
5697 tree arg;
5699 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5700 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5702 volatilep = true;
5703 break;
5706 if (! volatilep)
5708 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5709 expand_expr (TREE_VALUE (arg), const0_rtx,
5710 VOIDmode, EXPAND_NORMAL);
5711 return const0_rtx;
5715 switch (fcode)
5717 CASE_FLT_FN (BUILT_IN_FABS):
5718 target = expand_builtin_fabs (arglist, target, subtarget);
5719 if (target)
5720 return target;
5721 break;
5723 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5724 target = expand_builtin_copysign (arglist, target, subtarget);
5725 if (target)
5726 return target;
5727 break;
5729 /* Just do a normal library call if we were unable to fold
5730 the values. */
5731 CASE_FLT_FN (BUILT_IN_CABS):
5732 break;
5734 CASE_FLT_FN (BUILT_IN_EXP):
5735 CASE_FLT_FN (BUILT_IN_EXP10):
5736 CASE_FLT_FN (BUILT_IN_POW10):
5737 CASE_FLT_FN (BUILT_IN_EXP2):
5738 CASE_FLT_FN (BUILT_IN_EXPM1):
5739 CASE_FLT_FN (BUILT_IN_LOGB):
5740 CASE_FLT_FN (BUILT_IN_ILOGB):
5741 CASE_FLT_FN (BUILT_IN_LOG):
5742 CASE_FLT_FN (BUILT_IN_LOG10):
5743 CASE_FLT_FN (BUILT_IN_LOG2):
5744 CASE_FLT_FN (BUILT_IN_LOG1P):
5745 CASE_FLT_FN (BUILT_IN_TAN):
5746 CASE_FLT_FN (BUILT_IN_ASIN):
5747 CASE_FLT_FN (BUILT_IN_ACOS):
5748 CASE_FLT_FN (BUILT_IN_ATAN):
5749 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5750 because of possible accuracy problems. */
5751 if (! flag_unsafe_math_optimizations)
5752 break;
5753 CASE_FLT_FN (BUILT_IN_SQRT):
5754 CASE_FLT_FN (BUILT_IN_FLOOR):
5755 CASE_FLT_FN (BUILT_IN_CEIL):
5756 CASE_FLT_FN (BUILT_IN_TRUNC):
5757 CASE_FLT_FN (BUILT_IN_ROUND):
5758 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5759 CASE_FLT_FN (BUILT_IN_RINT):
5760 target = expand_builtin_mathfn (exp, target, subtarget);
5761 if (target)
5762 return target;
5763 break;
5765 CASE_FLT_FN (BUILT_IN_LCEIL):
5766 CASE_FLT_FN (BUILT_IN_LLCEIL):
5767 CASE_FLT_FN (BUILT_IN_LFLOOR):
5768 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5769 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5770 if (target)
5771 return target;
5772 break;
5774 CASE_FLT_FN (BUILT_IN_LRINT):
5775 CASE_FLT_FN (BUILT_IN_LLRINT):
5776 CASE_FLT_FN (BUILT_IN_LROUND):
5777 CASE_FLT_FN (BUILT_IN_LLROUND):
5778 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5779 if (target)
5780 return target;
5781 break;
5783 CASE_FLT_FN (BUILT_IN_POW):
5784 target = expand_builtin_pow (exp, target, subtarget);
5785 if (target)
5786 return target;
5787 break;
5789 CASE_FLT_FN (BUILT_IN_POWI):
5790 target = expand_builtin_powi (exp, target, subtarget);
5791 if (target)
5792 return target;
5793 break;
5795 CASE_FLT_FN (BUILT_IN_ATAN2):
5796 CASE_FLT_FN (BUILT_IN_LDEXP):
5797 if (! flag_unsafe_math_optimizations)
5798 break;
5800 CASE_FLT_FN (BUILT_IN_FMOD):
5801 CASE_FLT_FN (BUILT_IN_REMAINDER):
5802 CASE_FLT_FN (BUILT_IN_DREM):
5803 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5804 if (target)
5805 return target;
5806 break;
5808 CASE_FLT_FN (BUILT_IN_SIN):
5809 CASE_FLT_FN (BUILT_IN_COS):
5810 if (! flag_unsafe_math_optimizations)
5811 break;
5812 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5813 if (target)
5814 return target;
5815 break;
5817 CASE_FLT_FN (BUILT_IN_SINCOS):
5818 if (! flag_unsafe_math_optimizations)
5819 break;
5820 target = expand_builtin_sincos (exp);
5821 if (target)
5822 return target;
5823 break;
5825 case BUILT_IN_APPLY_ARGS:
5826 return expand_builtin_apply_args ();
5828 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5829 FUNCTION with a copy of the parameters described by
5830 ARGUMENTS, and ARGSIZE. It returns a block of memory
5831 allocated on the stack into which is stored all the registers
5832 that might possibly be used for returning the result of a
5833 function. ARGUMENTS is the value returned by
5834 __builtin_apply_args. ARGSIZE is the number of bytes of
5835 arguments that must be copied. ??? How should this value be
5836 computed? We'll also need a safe worst case value for varargs
5837 functions. */
5838 case BUILT_IN_APPLY:
5839 if (!validate_arglist (arglist, POINTER_TYPE,
5840 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5841 && !validate_arglist (arglist, REFERENCE_TYPE,
5842 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5843 return const0_rtx;
5844 else
5846 int i;
5847 tree t;
5848 rtx ops[3];
5850 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5851 ops[i] = expand_normal (TREE_VALUE (t));
5853 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5856 /* __builtin_return (RESULT) causes the function to return the
5857 value described by RESULT. RESULT is address of the block of
5858 memory returned by __builtin_apply. */
5859 case BUILT_IN_RETURN:
5860 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5861 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5862 return const0_rtx;
5864 case BUILT_IN_SAVEREGS:
5865 return expand_builtin_saveregs ();
5867 case BUILT_IN_ARGS_INFO:
5868 return expand_builtin_args_info (arglist);
5870 /* Return the address of the first anonymous stack arg. */
5871 case BUILT_IN_NEXT_ARG:
5872 if (fold_builtin_next_arg (arglist))
5873 return const0_rtx;
5874 return expand_builtin_next_arg ();
5876 case BUILT_IN_CLASSIFY_TYPE:
5877 return expand_builtin_classify_type (arglist);
5879 case BUILT_IN_CONSTANT_P:
5880 return const0_rtx;
5882 case BUILT_IN_FRAME_ADDRESS:
5883 case BUILT_IN_RETURN_ADDRESS:
5884 return expand_builtin_frame_address (fndecl, arglist);
5886 /* Returns the address of the area where the structure is returned.
5887 0 otherwise. */
5888 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5889 if (arglist != 0
5890 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5891 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5892 return const0_rtx;
5893 else
5894 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5896 case BUILT_IN_ALLOCA:
5897 target = expand_builtin_alloca (arglist, target);
5898 if (target)
5899 return target;
5900 break;
5902 case BUILT_IN_STACK_SAVE:
5903 return expand_stack_save ();
5905 case BUILT_IN_STACK_RESTORE:
5906 expand_stack_restore (TREE_VALUE (arglist));
5907 return const0_rtx;
5909 CASE_INT_FN (BUILT_IN_FFS):
5910 case BUILT_IN_FFSIMAX:
5911 target = expand_builtin_unop (target_mode, arglist, target,
5912 subtarget, ffs_optab);
5913 if (target)
5914 return target;
5915 break;
5917 CASE_INT_FN (BUILT_IN_CLZ):
5918 case BUILT_IN_CLZIMAX:
5919 target = expand_builtin_unop (target_mode, arglist, target,
5920 subtarget, clz_optab);
5921 if (target)
5922 return target;
5923 break;
5925 CASE_INT_FN (BUILT_IN_CTZ):
5926 case BUILT_IN_CTZIMAX:
5927 target = expand_builtin_unop (target_mode, arglist, target,
5928 subtarget, ctz_optab);
5929 if (target)
5930 return target;
5931 break;
5933 CASE_INT_FN (BUILT_IN_POPCOUNT):
5934 case BUILT_IN_POPCOUNTIMAX:
5935 target = expand_builtin_unop (target_mode, arglist, target,
5936 subtarget, popcount_optab);
5937 if (target)
5938 return target;
5939 break;
5941 CASE_INT_FN (BUILT_IN_PARITY):
5942 case BUILT_IN_PARITYIMAX:
5943 target = expand_builtin_unop (target_mode, arglist, target,
5944 subtarget, parity_optab);
5945 if (target)
5946 return target;
5947 break;
5949 case BUILT_IN_STRLEN:
5950 target = expand_builtin_strlen (arglist, target, target_mode);
5951 if (target)
5952 return target;
5953 break;
5955 case BUILT_IN_STRCPY:
5956 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5957 if (target)
5958 return target;
5959 break;
5961 case BUILT_IN_STRNCPY:
5962 target = expand_builtin_strncpy (exp, target, mode);
5963 if (target)
5964 return target;
5965 break;
5967 case BUILT_IN_STPCPY:
5968 target = expand_builtin_stpcpy (exp, target, mode);
5969 if (target)
5970 return target;
5971 break;
5973 case BUILT_IN_STRCAT:
5974 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5975 if (target)
5976 return target;
5977 break;
5979 case BUILT_IN_STRNCAT:
5980 target = expand_builtin_strncat (arglist, target, mode);
5981 if (target)
5982 return target;
5983 break;
5985 case BUILT_IN_STRSPN:
5986 target = expand_builtin_strspn (arglist, target, mode);
5987 if (target)
5988 return target;
5989 break;
5991 case BUILT_IN_STRCSPN:
5992 target = expand_builtin_strcspn (arglist, target, mode);
5993 if (target)
5994 return target;
5995 break;
5997 case BUILT_IN_STRSTR:
5998 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_STRPBRK:
6004 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6005 if (target)
6006 return target;
6007 break;
6009 case BUILT_IN_INDEX:
6010 case BUILT_IN_STRCHR:
6011 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6012 if (target)
6013 return target;
6014 break;
6016 case BUILT_IN_RINDEX:
6017 case BUILT_IN_STRRCHR:
6018 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6019 if (target)
6020 return target;
6021 break;
6023 case BUILT_IN_MEMCPY:
6024 target = expand_builtin_memcpy (exp, target, mode);
6025 if (target)
6026 return target;
6027 break;
6029 case BUILT_IN_MEMPCPY:
6030 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6031 if (target)
6032 return target;
6033 break;
6035 case BUILT_IN_MEMMOVE:
6036 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6037 mode);
6038 if (target)
6039 return target;
6040 break;
6042 case BUILT_IN_BCOPY:
6043 target = expand_builtin_bcopy (exp);
6044 if (target)
6045 return target;
6046 break;
6048 case BUILT_IN_MEMSET:
6049 target = expand_builtin_memset (arglist, target, mode, exp);
6050 if (target)
6051 return target;
6052 break;
6054 case BUILT_IN_BZERO:
6055 target = expand_builtin_bzero (exp);
6056 if (target)
6057 return target;
6058 break;
6060 case BUILT_IN_STRCMP:
6061 target = expand_builtin_strcmp (exp, target, mode);
6062 if (target)
6063 return target;
6064 break;
6066 case BUILT_IN_STRNCMP:
6067 target = expand_builtin_strncmp (exp, target, mode);
6068 if (target)
6069 return target;
6070 break;
6072 case BUILT_IN_BCMP:
6073 case BUILT_IN_MEMCMP:
6074 target = expand_builtin_memcmp (exp, arglist, target, mode);
6075 if (target)
6076 return target;
6077 break;
6079 case BUILT_IN_SETJMP:
6080 /* This should have been lowered to the builtins below. */
6081 gcc_unreachable ();
6083 case BUILT_IN_SETJMP_SETUP:
6084 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6085 and the receiver label. */
6086 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6088 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6089 VOIDmode, EXPAND_NORMAL);
6090 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6091 rtx label_r = label_rtx (label);
6093 /* This is copied from the handling of non-local gotos. */
6094 expand_builtin_setjmp_setup (buf_addr, label_r);
6095 nonlocal_goto_handler_labels
6096 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6097 nonlocal_goto_handler_labels);
6098 /* ??? Do not let expand_label treat us as such since we would
6099 not want to be both on the list of non-local labels and on
6100 the list of forced labels. */
6101 FORCED_LABEL (label) = 0;
6102 return const0_rtx;
6104 break;
6106 case BUILT_IN_SETJMP_DISPATCHER:
6107 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6108 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6110 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6111 rtx label_r = label_rtx (label);
6113 /* Remove the dispatcher label from the list of non-local labels
6114 since the receiver labels have been added to it above. */
6115 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6116 return const0_rtx;
6118 break;
6120 case BUILT_IN_SETJMP_RECEIVER:
6121 /* __builtin_setjmp_receiver is passed the receiver label. */
6122 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6124 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6125 rtx label_r = label_rtx (label);
6127 expand_builtin_setjmp_receiver (label_r);
6128 return const0_rtx;
6130 break;
6132 /* __builtin_longjmp is passed a pointer to an array of five words.
6133 It's similar to the C library longjmp function but works with
6134 __builtin_setjmp above. */
6135 case BUILT_IN_LONGJMP:
6136 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6138 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6139 VOIDmode, EXPAND_NORMAL);
6140 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6142 if (value != const1_rtx)
6144 error ("%<__builtin_longjmp%> second argument must be 1");
6145 return const0_rtx;
6148 expand_builtin_longjmp (buf_addr, value);
6149 return const0_rtx;
6151 break;
6153 case BUILT_IN_NONLOCAL_GOTO:
6154 target = expand_builtin_nonlocal_goto (arglist);
6155 if (target)
6156 return target;
6157 break;
6159 /* This updates the setjmp buffer that is its argument with the value
6160 of the current stack pointer. */
6161 case BUILT_IN_UPDATE_SETJMP_BUF:
6162 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6164 rtx buf_addr
6165 = expand_normal (TREE_VALUE (arglist));
6167 expand_builtin_update_setjmp_buf (buf_addr);
6168 return const0_rtx;
6170 break;
6172 case BUILT_IN_TRAP:
6173 expand_builtin_trap ();
6174 return const0_rtx;
6176 case BUILT_IN_PRINTF:
6177 target = expand_builtin_printf (exp, target, mode, false);
6178 if (target)
6179 return target;
6180 break;
6182 case BUILT_IN_PRINTF_UNLOCKED:
6183 target = expand_builtin_printf (exp, target, mode, true);
6184 if (target)
6185 return target;
6186 break;
6188 case BUILT_IN_FPUTS:
6189 target = expand_builtin_fputs (arglist, target, false);
6190 if (target)
6191 return target;
6192 break;
6193 case BUILT_IN_FPUTS_UNLOCKED:
6194 target = expand_builtin_fputs (arglist, target, true);
6195 if (target)
6196 return target;
6197 break;
6199 case BUILT_IN_FPRINTF:
6200 target = expand_builtin_fprintf (exp, target, mode, false);
6201 if (target)
6202 return target;
6203 break;
6205 case BUILT_IN_FPRINTF_UNLOCKED:
6206 target = expand_builtin_fprintf (exp, target, mode, true);
6207 if (target)
6208 return target;
6209 break;
6211 case BUILT_IN_SPRINTF:
6212 target = expand_builtin_sprintf (arglist, target, mode);
6213 if (target)
6214 return target;
6215 break;
6217 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6218 target = expand_builtin_signbit (exp, target);
6219 if (target)
6220 return target;
6221 break;
6223 /* Various hooks for the DWARF 2 __throw routine. */
6224 case BUILT_IN_UNWIND_INIT:
6225 expand_builtin_unwind_init ();
6226 return const0_rtx;
6227 case BUILT_IN_DWARF_CFA:
6228 return virtual_cfa_rtx;
6229 #ifdef DWARF2_UNWIND_INFO
6230 case BUILT_IN_DWARF_SP_COLUMN:
6231 return expand_builtin_dwarf_sp_column ();
6232 case BUILT_IN_INIT_DWARF_REG_SIZES:
6233 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6234 return const0_rtx;
6235 #endif
6236 case BUILT_IN_FROB_RETURN_ADDR:
6237 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6238 case BUILT_IN_EXTRACT_RETURN_ADDR:
6239 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6240 case BUILT_IN_EH_RETURN:
6241 expand_builtin_eh_return (TREE_VALUE (arglist),
6242 TREE_VALUE (TREE_CHAIN (arglist)));
6243 return const0_rtx;
6244 #ifdef EH_RETURN_DATA_REGNO
6245 case BUILT_IN_EH_RETURN_DATA_REGNO:
6246 return expand_builtin_eh_return_data_regno (arglist);
6247 #endif
6248 case BUILT_IN_EXTEND_POINTER:
6249 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6251 case BUILT_IN_VA_START:
6252 case BUILT_IN_STDARG_START:
6253 return expand_builtin_va_start (arglist);
6254 case BUILT_IN_VA_END:
6255 return expand_builtin_va_end (arglist);
6256 case BUILT_IN_VA_COPY:
6257 return expand_builtin_va_copy (arglist);
6258 case BUILT_IN_EXPECT:
6259 return expand_builtin_expect (arglist, target);
6260 case BUILT_IN_PREFETCH:
6261 expand_builtin_prefetch (arglist);
6262 return const0_rtx;
6264 case BUILT_IN_PROFILE_FUNC_ENTER:
6265 return expand_builtin_profile_func (false);
6266 case BUILT_IN_PROFILE_FUNC_EXIT:
6267 return expand_builtin_profile_func (true);
6269 case BUILT_IN_INIT_TRAMPOLINE:
6270 return expand_builtin_init_trampoline (arglist);
6271 case BUILT_IN_ADJUST_TRAMPOLINE:
6272 return expand_builtin_adjust_trampoline (arglist);
6274 case BUILT_IN_FORK:
6275 case BUILT_IN_EXECL:
6276 case BUILT_IN_EXECV:
6277 case BUILT_IN_EXECLP:
6278 case BUILT_IN_EXECLE:
6279 case BUILT_IN_EXECVP:
6280 case BUILT_IN_EXECVE:
6281 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6282 if (target)
6283 return target;
6284 break;
6286 case BUILT_IN_FETCH_AND_ADD_1:
6287 case BUILT_IN_FETCH_AND_ADD_2:
6288 case BUILT_IN_FETCH_AND_ADD_4:
6289 case BUILT_IN_FETCH_AND_ADD_8:
6290 case BUILT_IN_FETCH_AND_ADD_16:
6291 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6292 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6293 false, target, ignore);
6294 if (target)
6295 return target;
6296 break;
6298 case BUILT_IN_FETCH_AND_SUB_1:
6299 case BUILT_IN_FETCH_AND_SUB_2:
6300 case BUILT_IN_FETCH_AND_SUB_4:
6301 case BUILT_IN_FETCH_AND_SUB_8:
6302 case BUILT_IN_FETCH_AND_SUB_16:
6303 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6304 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6305 false, target, ignore);
6306 if (target)
6307 return target;
6308 break;
6310 case BUILT_IN_FETCH_AND_OR_1:
6311 case BUILT_IN_FETCH_AND_OR_2:
6312 case BUILT_IN_FETCH_AND_OR_4:
6313 case BUILT_IN_FETCH_AND_OR_8:
6314 case BUILT_IN_FETCH_AND_OR_16:
6315 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6316 target = expand_builtin_sync_operation (mode, arglist, IOR,
6317 false, target, ignore);
6318 if (target)
6319 return target;
6320 break;
6322 case BUILT_IN_FETCH_AND_AND_1:
6323 case BUILT_IN_FETCH_AND_AND_2:
6324 case BUILT_IN_FETCH_AND_AND_4:
6325 case BUILT_IN_FETCH_AND_AND_8:
6326 case BUILT_IN_FETCH_AND_AND_16:
6327 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6328 target = expand_builtin_sync_operation (mode, arglist, AND,
6329 false, target, ignore);
6330 if (target)
6331 return target;
6332 break;
6334 case BUILT_IN_FETCH_AND_XOR_1:
6335 case BUILT_IN_FETCH_AND_XOR_2:
6336 case BUILT_IN_FETCH_AND_XOR_4:
6337 case BUILT_IN_FETCH_AND_XOR_8:
6338 case BUILT_IN_FETCH_AND_XOR_16:
6339 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6340 target = expand_builtin_sync_operation (mode, arglist, XOR,
6341 false, target, ignore);
6342 if (target)
6343 return target;
6344 break;
6346 case BUILT_IN_FETCH_AND_NAND_1:
6347 case BUILT_IN_FETCH_AND_NAND_2:
6348 case BUILT_IN_FETCH_AND_NAND_4:
6349 case BUILT_IN_FETCH_AND_NAND_8:
6350 case BUILT_IN_FETCH_AND_NAND_16:
6351 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6352 target = expand_builtin_sync_operation (mode, arglist, NOT,
6353 false, target, ignore);
6354 if (target)
6355 return target;
6356 break;
6358 case BUILT_IN_ADD_AND_FETCH_1:
6359 case BUILT_IN_ADD_AND_FETCH_2:
6360 case BUILT_IN_ADD_AND_FETCH_4:
6361 case BUILT_IN_ADD_AND_FETCH_8:
6362 case BUILT_IN_ADD_AND_FETCH_16:
6363 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6364 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6365 true, target, ignore);
6366 if (target)
6367 return target;
6368 break;
6370 case BUILT_IN_SUB_AND_FETCH_1:
6371 case BUILT_IN_SUB_AND_FETCH_2:
6372 case BUILT_IN_SUB_AND_FETCH_4:
6373 case BUILT_IN_SUB_AND_FETCH_8:
6374 case BUILT_IN_SUB_AND_FETCH_16:
6375 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6376 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6377 true, target, ignore);
6378 if (target)
6379 return target;
6380 break;
6382 case BUILT_IN_OR_AND_FETCH_1:
6383 case BUILT_IN_OR_AND_FETCH_2:
6384 case BUILT_IN_OR_AND_FETCH_4:
6385 case BUILT_IN_OR_AND_FETCH_8:
6386 case BUILT_IN_OR_AND_FETCH_16:
6387 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6388 target = expand_builtin_sync_operation (mode, arglist, IOR,
6389 true, target, ignore);
6390 if (target)
6391 return target;
6392 break;
6394 case BUILT_IN_AND_AND_FETCH_1:
6395 case BUILT_IN_AND_AND_FETCH_2:
6396 case BUILT_IN_AND_AND_FETCH_4:
6397 case BUILT_IN_AND_AND_FETCH_8:
6398 case BUILT_IN_AND_AND_FETCH_16:
6399 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6400 target = expand_builtin_sync_operation (mode, arglist, AND,
6401 true, target, ignore);
6402 if (target)
6403 return target;
6404 break;
6406 case BUILT_IN_XOR_AND_FETCH_1:
6407 case BUILT_IN_XOR_AND_FETCH_2:
6408 case BUILT_IN_XOR_AND_FETCH_4:
6409 case BUILT_IN_XOR_AND_FETCH_8:
6410 case BUILT_IN_XOR_AND_FETCH_16:
6411 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6412 target = expand_builtin_sync_operation (mode, arglist, XOR,
6413 true, target, ignore);
6414 if (target)
6415 return target;
6416 break;
6418 case BUILT_IN_NAND_AND_FETCH_1:
6419 case BUILT_IN_NAND_AND_FETCH_2:
6420 case BUILT_IN_NAND_AND_FETCH_4:
6421 case BUILT_IN_NAND_AND_FETCH_8:
6422 case BUILT_IN_NAND_AND_FETCH_16:
6423 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6424 target = expand_builtin_sync_operation (mode, arglist, NOT,
6425 true, target, ignore);
6426 if (target)
6427 return target;
6428 break;
6430 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6431 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6432 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6433 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6434 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6435 if (mode == VOIDmode)
6436 mode = TYPE_MODE (boolean_type_node);
6437 if (!target || !register_operand (target, mode))
6438 target = gen_reg_rtx (mode);
6440 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6441 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6442 if (target)
6443 return target;
6444 break;
6446 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6447 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6448 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6449 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6450 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6451 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6452 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6453 if (target)
6454 return target;
6455 break;
6457 case BUILT_IN_LOCK_TEST_AND_SET_1:
6458 case BUILT_IN_LOCK_TEST_AND_SET_2:
6459 case BUILT_IN_LOCK_TEST_AND_SET_4:
6460 case BUILT_IN_LOCK_TEST_AND_SET_8:
6461 case BUILT_IN_LOCK_TEST_AND_SET_16:
6462 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6463 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6464 if (target)
6465 return target;
6466 break;
6468 case BUILT_IN_LOCK_RELEASE_1:
6469 case BUILT_IN_LOCK_RELEASE_2:
6470 case BUILT_IN_LOCK_RELEASE_4:
6471 case BUILT_IN_LOCK_RELEASE_8:
6472 case BUILT_IN_LOCK_RELEASE_16:
6473 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6474 expand_builtin_lock_release (mode, arglist);
6475 return const0_rtx;
6477 case BUILT_IN_SYNCHRONIZE:
6478 expand_builtin_synchronize ();
6479 return const0_rtx;
6481 case BUILT_IN_OBJECT_SIZE:
6482 return expand_builtin_object_size (exp);
6484 case BUILT_IN_MEMCPY_CHK:
6485 case BUILT_IN_MEMPCPY_CHK:
6486 case BUILT_IN_MEMMOVE_CHK:
6487 case BUILT_IN_MEMSET_CHK:
6488 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6489 if (target)
6490 return target;
6491 break;
6493 case BUILT_IN_STRCPY_CHK:
6494 case BUILT_IN_STPCPY_CHK:
6495 case BUILT_IN_STRNCPY_CHK:
6496 case BUILT_IN_STRCAT_CHK:
6497 case BUILT_IN_STRNCAT_CHK:
6498 case BUILT_IN_SNPRINTF_CHK:
6499 case BUILT_IN_VSNPRINTF_CHK:
6500 maybe_emit_chk_warning (exp, fcode);
6501 break;
6503 case BUILT_IN_SPRINTF_CHK:
6504 case BUILT_IN_VSPRINTF_CHK:
6505 maybe_emit_sprintf_chk_warning (exp, fcode);
6506 break;
6508 default: /* just do library call, if unknown builtin */
6509 break;
6512 /* The switch statement above can drop through to cause the function
6513 to be called normally. */
6514 return expand_call (exp, target, ignore);
6517 /* Determine whether a tree node represents a call to a built-in
6518 function. If the tree T is a call to a built-in function with
6519 the right number of arguments of the appropriate types, return
6520 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6521 Otherwise the return value is END_BUILTINS. */
6523 enum built_in_function
6524 builtin_mathfn_code (tree t)
6526 tree fndecl, arglist, parmlist;
6527 tree argtype, parmtype;
6529 if (TREE_CODE (t) != CALL_EXPR
6530 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6531 return END_BUILTINS;
6533 fndecl = get_callee_fndecl (t);
6534 if (fndecl == NULL_TREE
6535 || TREE_CODE (fndecl) != FUNCTION_DECL
6536 || ! DECL_BUILT_IN (fndecl)
6537 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6538 return END_BUILTINS;
6540 arglist = TREE_OPERAND (t, 1);
6541 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6542 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6544 /* If a function doesn't take a variable number of arguments,
6545 the last element in the list will have type `void'. */
6546 parmtype = TREE_VALUE (parmlist);
6547 if (VOID_TYPE_P (parmtype))
6549 if (arglist)
6550 return END_BUILTINS;
6551 return DECL_FUNCTION_CODE (fndecl);
6554 if (! arglist)
6555 return END_BUILTINS;
6557 argtype = TREE_TYPE (TREE_VALUE (arglist));
6559 if (SCALAR_FLOAT_TYPE_P (parmtype))
6561 if (! SCALAR_FLOAT_TYPE_P (argtype))
6562 return END_BUILTINS;
6564 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6566 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6567 return END_BUILTINS;
6569 else if (POINTER_TYPE_P (parmtype))
6571 if (! POINTER_TYPE_P (argtype))
6572 return END_BUILTINS;
6574 else if (INTEGRAL_TYPE_P (parmtype))
6576 if (! INTEGRAL_TYPE_P (argtype))
6577 return END_BUILTINS;
6579 else
6580 return END_BUILTINS;
6582 arglist = TREE_CHAIN (arglist);
6585 /* Variable-length argument list. */
6586 return DECL_FUNCTION_CODE (fndecl);
6589 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6590 constant. ARGLIST is the argument list of the call. */
6592 static tree
6593 fold_builtin_constant_p (tree arglist)
6595 if (arglist == 0)
6596 return 0;
6598 arglist = TREE_VALUE (arglist);
6600 /* We return 1 for a numeric type that's known to be a constant
6601 value at compile-time or for an aggregate type that's a
6602 literal constant. */
6603 STRIP_NOPS (arglist);
6605 /* If we know this is a constant, emit the constant of one. */
6606 if (CONSTANT_CLASS_P (arglist)
6607 || (TREE_CODE (arglist) == CONSTRUCTOR
6608 && TREE_CONSTANT (arglist)))
6609 return integer_one_node;
6610 if (TREE_CODE (arglist) == ADDR_EXPR)
6612 tree op = TREE_OPERAND (arglist, 0);
6613 if (TREE_CODE (op) == STRING_CST
6614 || (TREE_CODE (op) == ARRAY_REF
6615 && integer_zerop (TREE_OPERAND (op, 1))
6616 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6617 return integer_one_node;
6620 /* If this expression has side effects, show we don't know it to be a
6621 constant. Likewise if it's a pointer or aggregate type since in
6622 those case we only want literals, since those are only optimized
6623 when generating RTL, not later.
6624 And finally, if we are compiling an initializer, not code, we
6625 need to return a definite result now; there's not going to be any
6626 more optimization done. */
6627 if (TREE_SIDE_EFFECTS (arglist)
6628 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6629 || POINTER_TYPE_P (TREE_TYPE (arglist))
6630 || cfun == 0
6631 || folding_initializer)
6632 return integer_zero_node;
6634 return 0;
6637 /* Fold a call to __builtin_expect, if we expect that a comparison against
6638 the argument will fold to a constant. In practice, this means a true
6639 constant or the address of a non-weak symbol. ARGLIST is the argument
6640 list of the call. */
6642 static tree
6643 fold_builtin_expect (tree arglist)
6645 tree arg, inner;
6647 if (arglist == 0)
6648 return 0;
6650 arg = TREE_VALUE (arglist);
6652 /* If the argument isn't invariant, then there's nothing we can do. */
6653 if (!TREE_INVARIANT (arg))
6654 return 0;
6656 /* If we're looking at an address of a weak decl, then do not fold. */
6657 inner = arg;
6658 STRIP_NOPS (inner);
6659 if (TREE_CODE (inner) == ADDR_EXPR)
6663 inner = TREE_OPERAND (inner, 0);
6665 while (TREE_CODE (inner) == COMPONENT_REF
6666 || TREE_CODE (inner) == ARRAY_REF);
6667 if (DECL_P (inner) && DECL_WEAK (inner))
6668 return 0;
6671 /* Otherwise, ARG already has the proper type for the return value. */
6672 return arg;
6675 /* Fold a call to __builtin_classify_type. */
6677 static tree
6678 fold_builtin_classify_type (tree arglist)
6680 if (arglist == 0)
6681 return build_int_cst (NULL_TREE, no_type_class);
6683 return build_int_cst (NULL_TREE,
6684 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6687 /* Fold a call to __builtin_strlen. */
6689 static tree
6690 fold_builtin_strlen (tree arglist)
6692 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6693 return NULL_TREE;
6694 else
6696 tree len = c_strlen (TREE_VALUE (arglist), 0);
6698 if (len)
6700 /* Convert from the internal "sizetype" type to "size_t". */
6701 if (size_type_node)
6702 len = fold_convert (size_type_node, len);
6703 return len;
6706 return NULL_TREE;
6710 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6712 static tree
6713 fold_builtin_inf (tree type, int warn)
6715 REAL_VALUE_TYPE real;
6717 /* __builtin_inff is intended to be usable to define INFINITY on all
6718 targets. If an infinity is not available, INFINITY expands "to a
6719 positive constant of type float that overflows at translation
6720 time", footnote "In this case, using INFINITY will violate the
6721 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6722 Thus we pedwarn to ensure this constraint violation is
6723 diagnosed. */
6724 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6725 pedwarn ("target format does not support infinity");
6727 real_inf (&real);
6728 return build_real (type, real);
6731 /* Fold a call to __builtin_nan or __builtin_nans. */
6733 static tree
6734 fold_builtin_nan (tree arglist, tree type, int quiet)
6736 REAL_VALUE_TYPE real;
6737 const char *str;
6739 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6740 return 0;
6741 str = c_getstr (TREE_VALUE (arglist));
6742 if (!str)
6743 return 0;
6745 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6746 return 0;
6748 return build_real (type, real);
6751 /* Return true if the floating point expression T has an integer value.
6752 We also allow +Inf, -Inf and NaN to be considered integer values. */
6754 static bool
6755 integer_valued_real_p (tree t)
6757 switch (TREE_CODE (t))
6759 case FLOAT_EXPR:
6760 return true;
6762 case ABS_EXPR:
6763 case SAVE_EXPR:
6764 case NON_LVALUE_EXPR:
6765 return integer_valued_real_p (TREE_OPERAND (t, 0));
6767 case COMPOUND_EXPR:
6768 case MODIFY_EXPR:
6769 case BIND_EXPR:
6770 return integer_valued_real_p (TREE_OPERAND (t, 1));
6772 case PLUS_EXPR:
6773 case MINUS_EXPR:
6774 case MULT_EXPR:
6775 case MIN_EXPR:
6776 case MAX_EXPR:
6777 return integer_valued_real_p (TREE_OPERAND (t, 0))
6778 && integer_valued_real_p (TREE_OPERAND (t, 1));
6780 case COND_EXPR:
6781 return integer_valued_real_p (TREE_OPERAND (t, 1))
6782 && integer_valued_real_p (TREE_OPERAND (t, 2));
6784 case REAL_CST:
6785 if (! TREE_CONSTANT_OVERFLOW (t))
6787 REAL_VALUE_TYPE c, cint;
6789 c = TREE_REAL_CST (t);
6790 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6791 return real_identical (&c, &cint);
6793 break;
6795 case NOP_EXPR:
6797 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6798 if (TREE_CODE (type) == INTEGER_TYPE)
6799 return true;
6800 if (TREE_CODE (type) == REAL_TYPE)
6801 return integer_valued_real_p (TREE_OPERAND (t, 0));
6802 break;
6805 case CALL_EXPR:
6806 switch (builtin_mathfn_code (t))
6808 CASE_FLT_FN (BUILT_IN_CEIL):
6809 CASE_FLT_FN (BUILT_IN_FLOOR):
6810 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6811 CASE_FLT_FN (BUILT_IN_RINT):
6812 CASE_FLT_FN (BUILT_IN_ROUND):
6813 CASE_FLT_FN (BUILT_IN_TRUNC):
6814 return true;
6816 default:
6817 break;
6819 break;
6821 default:
6822 break;
6824 return false;
6827 /* EXP is assumed to be builtin call where truncation can be propagated
6828 across (for instance floor((double)f) == (double)floorf (f).
6829 Do the transformation. */
6831 static tree
6832 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6834 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6835 tree arg;
6837 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6838 return 0;
6840 arg = TREE_VALUE (arglist);
6841 /* Integer rounding functions are idempotent. */
6842 if (fcode == builtin_mathfn_code (arg))
6843 return arg;
6845 /* If argument is already integer valued, and we don't need to worry
6846 about setting errno, there's no need to perform rounding. */
6847 if (! flag_errno_math && integer_valued_real_p (arg))
6848 return arg;
6850 if (optimize)
6852 tree arg0 = strip_float_extensions (arg);
6853 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6854 tree newtype = TREE_TYPE (arg0);
6855 tree decl;
6857 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6858 && (decl = mathfn_built_in (newtype, fcode)))
6860 arglist =
6861 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6862 return fold_convert (ftype,
6863 build_function_call_expr (decl, arglist));
6866 return 0;
6869 /* EXP is assumed to be builtin call which can narrow the FP type of
6870 the argument, for instance lround((double)f) -> lroundf (f). */
6872 static tree
6873 fold_fixed_mathfn (tree fndecl, tree arglist)
6875 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6876 tree arg;
6878 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6879 return 0;
6881 arg = TREE_VALUE (arglist);
6883 /* If argument is already integer valued, and we don't need to worry
6884 about setting errno, there's no need to perform rounding. */
6885 if (! flag_errno_math && integer_valued_real_p (arg))
6886 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6888 if (optimize)
6890 tree ftype = TREE_TYPE (arg);
6891 tree arg0 = strip_float_extensions (arg);
6892 tree newtype = TREE_TYPE (arg0);
6893 tree decl;
6895 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6896 && (decl = mathfn_built_in (newtype, fcode)))
6898 arglist =
6899 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6900 return build_function_call_expr (decl, arglist);
6904 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6905 sizeof (long long) == sizeof (long). */
6906 if (TYPE_PRECISION (long_long_integer_type_node)
6907 == TYPE_PRECISION (long_integer_type_node))
6909 tree newfn = NULL_TREE;
6910 switch (fcode)
6912 CASE_FLT_FN (BUILT_IN_LLCEIL):
6913 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6914 break;
6916 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6917 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6918 break;
6920 CASE_FLT_FN (BUILT_IN_LLROUND):
6921 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6922 break;
6924 CASE_FLT_FN (BUILT_IN_LLRINT):
6925 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6926 break;
6928 default:
6929 break;
6932 if (newfn)
6934 tree newcall = build_function_call_expr (newfn, arglist);
6935 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6939 return 0;
6942 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6943 is the argument list, TYPE is the return type and FNDECL is the
6944 original function DECL. Return NULL_TREE if no if no simplification
6945 can be made. */
6947 static tree
6948 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6950 tree arg;
6952 if (!arglist || TREE_CHAIN (arglist))
6953 return NULL_TREE;
6955 arg = TREE_VALUE (arglist);
6956 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6957 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6958 return NULL_TREE;
6960 /* Evaluate cabs of a constant at compile-time. */
6961 if (flag_unsafe_math_optimizations
6962 && TREE_CODE (arg) == COMPLEX_CST
6963 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6964 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6965 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6966 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6968 REAL_VALUE_TYPE r, i;
6970 r = TREE_REAL_CST (TREE_REALPART (arg));
6971 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6973 real_arithmetic (&r, MULT_EXPR, &r, &r);
6974 real_arithmetic (&i, MULT_EXPR, &i, &i);
6975 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6976 if (real_sqrt (&r, TYPE_MODE (type), &r)
6977 || ! flag_trapping_math)
6978 return build_real (type, r);
6981 /* If either part is zero, cabs is fabs of the other. */
6982 if (TREE_CODE (arg) == COMPLEX_EXPR
6983 && real_zerop (TREE_OPERAND (arg, 0)))
6984 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6985 if (TREE_CODE (arg) == COMPLEX_EXPR
6986 && real_zerop (TREE_OPERAND (arg, 1)))
6987 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6989 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6990 if (TREE_CODE (arg) == NEGATE_EXPR
6991 || TREE_CODE (arg) == CONJ_EXPR)
6993 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6994 return build_function_call_expr (fndecl, arglist);
6997 /* Don't do this when optimizing for size. */
6998 if (flag_unsafe_math_optimizations
6999 && optimize && !optimize_size)
7001 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7003 if (sqrtfn != NULL_TREE)
7005 tree rpart, ipart, result, arglist;
7007 arg = builtin_save_expr (arg);
7009 rpart = fold_build1 (REALPART_EXPR, type, arg);
7010 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7012 rpart = builtin_save_expr (rpart);
7013 ipart = builtin_save_expr (ipart);
7015 result = fold_build2 (PLUS_EXPR, type,
7016 fold_build2 (MULT_EXPR, type,
7017 rpart, rpart),
7018 fold_build2 (MULT_EXPR, type,
7019 ipart, ipart));
7021 arglist = build_tree_list (NULL_TREE, result);
7022 return build_function_call_expr (sqrtfn, arglist);
7026 return NULL_TREE;
7029 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7030 NULL_TREE if no simplification can be made. */
7032 static tree
7033 fold_builtin_sqrt (tree arglist, tree type)
7036 enum built_in_function fcode;
7037 tree arg = TREE_VALUE (arglist);
7039 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7040 return NULL_TREE;
7042 /* Optimize sqrt of constant value. */
7043 if (TREE_CODE (arg) == REAL_CST
7044 && ! TREE_CONSTANT_OVERFLOW (arg))
7046 REAL_VALUE_TYPE r, x;
7048 x = TREE_REAL_CST (arg);
7049 if (real_sqrt (&r, TYPE_MODE (type), &x)
7050 || (!flag_trapping_math && !flag_errno_math))
7051 return build_real (type, r);
7054 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7055 fcode = builtin_mathfn_code (arg);
7056 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7058 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7059 arg = fold_build2 (MULT_EXPR, type,
7060 TREE_VALUE (TREE_OPERAND (arg, 1)),
7061 build_real (type, dconsthalf));
7062 arglist = build_tree_list (NULL_TREE, arg);
7063 return build_function_call_expr (expfn, arglist);
7066 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7067 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7069 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7071 if (powfn)
7073 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7074 tree tree_root;
7075 /* The inner root was either sqrt or cbrt. */
7076 REAL_VALUE_TYPE dconstroot =
7077 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7079 /* Adjust for the outer root. */
7080 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7081 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7082 tree_root = build_real (type, dconstroot);
7083 arglist = tree_cons (NULL_TREE, arg0,
7084 build_tree_list (NULL_TREE, tree_root));
7085 return build_function_call_expr (powfn, arglist);
7089 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7090 if (flag_unsafe_math_optimizations
7091 && (fcode == BUILT_IN_POW
7092 || fcode == BUILT_IN_POWF
7093 || fcode == BUILT_IN_POWL))
7095 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7096 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7097 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7098 tree narg1;
7099 if (!tree_expr_nonnegative_p (arg0))
7100 arg0 = build1 (ABS_EXPR, type, arg0);
7101 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7102 build_real (type, dconsthalf));
7103 arglist = tree_cons (NULL_TREE, arg0,
7104 build_tree_list (NULL_TREE, narg1));
7105 return build_function_call_expr (powfn, arglist);
7108 return NULL_TREE;
7111 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7112 NULL_TREE if no simplification can be made. */
7113 static tree
7114 fold_builtin_cbrt (tree arglist, tree type)
7116 tree arg = TREE_VALUE (arglist);
7117 const enum built_in_function fcode = builtin_mathfn_code (arg);
7118 tree res;
7120 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7121 return NULL_TREE;
7123 /* Calculate the result when the argument is a constant. */
7124 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7125 return res;
7127 if (flag_unsafe_math_optimizations)
7129 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7130 if (BUILTIN_EXPONENT_P (fcode))
7132 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7133 const REAL_VALUE_TYPE third_trunc =
7134 real_value_truncate (TYPE_MODE (type), dconstthird);
7135 arg = fold_build2 (MULT_EXPR, type,
7136 TREE_VALUE (TREE_OPERAND (arg, 1)),
7137 build_real (type, third_trunc));
7138 arglist = build_tree_list (NULL_TREE, arg);
7139 return build_function_call_expr (expfn, arglist);
7142 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7143 if (BUILTIN_SQRT_P (fcode))
7145 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7147 if (powfn)
7149 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7150 tree tree_root;
7151 REAL_VALUE_TYPE dconstroot = dconstthird;
7153 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7154 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7155 tree_root = build_real (type, dconstroot);
7156 arglist = tree_cons (NULL_TREE, arg0,
7157 build_tree_list (NULL_TREE, tree_root));
7158 return build_function_call_expr (powfn, arglist);
7162 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7163 if (BUILTIN_CBRT_P (fcode))
7165 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7166 if (tree_expr_nonnegative_p (arg0))
7168 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7170 if (powfn)
7172 tree tree_root;
7173 REAL_VALUE_TYPE dconstroot;
7175 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7176 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7177 tree_root = build_real (type, dconstroot);
7178 arglist = tree_cons (NULL_TREE, arg0,
7179 build_tree_list (NULL_TREE, tree_root));
7180 return build_function_call_expr (powfn, arglist);
7185 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7186 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7187 || fcode == BUILT_IN_POWL)
7189 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7190 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7191 if (tree_expr_nonnegative_p (arg00))
7193 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7194 const REAL_VALUE_TYPE dconstroot
7195 = real_value_truncate (TYPE_MODE (type), dconstthird);
7196 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7197 build_real (type, dconstroot));
7198 arglist = tree_cons (NULL_TREE, arg00,
7199 build_tree_list (NULL_TREE, narg01));
7200 return build_function_call_expr (powfn, arglist);
7204 return NULL_TREE;
7207 /* Fold function call to builtin cos, cosf, or cosl. Return
7208 NULL_TREE if no simplification can be made. */
7209 static tree
7210 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7212 tree arg = TREE_VALUE (arglist);
7213 tree res;
7215 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7216 return NULL_TREE;
7218 /* Calculate the result when the argument is a constant. */
7219 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7220 return res;
7222 /* Optimize cos(-x) into cos (x). */
7223 if (TREE_CODE (arg) == NEGATE_EXPR)
7225 tree args = build_tree_list (NULL_TREE,
7226 TREE_OPERAND (arg, 0));
7227 return build_function_call_expr (fndecl, args);
7230 return NULL_TREE;
7233 /* Fold function call to builtin tan, tanf, or tanl. Return
7234 NULL_TREE if no simplification can be made. */
7235 static tree
7236 fold_builtin_tan (tree arglist, tree type)
7238 enum built_in_function fcode;
7239 tree arg = TREE_VALUE (arglist);
7240 tree res;
7242 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7243 return NULL_TREE;
7245 /* Calculate the result when the argument is a constant. */
7246 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7247 return res;
7249 /* Optimize tan(atan(x)) = x. */
7250 fcode = builtin_mathfn_code (arg);
7251 if (flag_unsafe_math_optimizations
7252 && (fcode == BUILT_IN_ATAN
7253 || fcode == BUILT_IN_ATANF
7254 || fcode == BUILT_IN_ATANL))
7255 return TREE_VALUE (TREE_OPERAND (arg, 1));
7257 return NULL_TREE;
7260 /* Fold function call to builtin trunc, truncf or truncl. Return
7261 NULL_TREE if no simplification can be made. */
7263 static tree
7264 fold_builtin_trunc (tree fndecl, tree arglist)
7266 tree arg;
7268 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7269 return 0;
7271 /* Optimize trunc of constant value. */
7272 arg = TREE_VALUE (arglist);
7273 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7275 REAL_VALUE_TYPE r, x;
7276 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7278 x = TREE_REAL_CST (arg);
7279 real_trunc (&r, TYPE_MODE (type), &x);
7280 return build_real (type, r);
7283 return fold_trunc_transparent_mathfn (fndecl, arglist);
7286 /* Fold function call to builtin floor, floorf or floorl. Return
7287 NULL_TREE if no simplification can be made. */
7289 static tree
7290 fold_builtin_floor (tree fndecl, tree arglist)
7292 tree arg;
7294 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7295 return 0;
7297 /* Optimize floor of constant value. */
7298 arg = TREE_VALUE (arglist);
7299 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7301 REAL_VALUE_TYPE x;
7303 x = TREE_REAL_CST (arg);
7304 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7306 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7307 REAL_VALUE_TYPE r;
7309 real_floor (&r, TYPE_MODE (type), &x);
7310 return build_real (type, r);
7314 /* Fold floor (x) where x is nonnegative to trunc (x). */
7315 if (tree_expr_nonnegative_p (arg))
7316 return build_function_call_expr (mathfn_built_in (TREE_TYPE (arg),
7317 BUILT_IN_TRUNC),
7318 arglist);
7320 return fold_trunc_transparent_mathfn (fndecl, arglist);
7323 /* Fold function call to builtin ceil, ceilf or ceill. Return
7324 NULL_TREE if no simplification can be made. */
7326 static tree
7327 fold_builtin_ceil (tree fndecl, tree arglist)
7329 tree arg;
7331 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7332 return 0;
7334 /* Optimize ceil of constant value. */
7335 arg = TREE_VALUE (arglist);
7336 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7338 REAL_VALUE_TYPE x;
7340 x = TREE_REAL_CST (arg);
7341 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7343 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7344 REAL_VALUE_TYPE r;
7346 real_ceil (&r, TYPE_MODE (type), &x);
7347 return build_real (type, r);
7351 return fold_trunc_transparent_mathfn (fndecl, arglist);
7354 /* Fold function call to builtin round, roundf or roundl. Return
7355 NULL_TREE if no simplification can be made. */
7357 static tree
7358 fold_builtin_round (tree fndecl, tree arglist)
7360 tree arg;
7362 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7363 return 0;
7365 /* Optimize round of constant value. */
7366 arg = TREE_VALUE (arglist);
7367 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7369 REAL_VALUE_TYPE x;
7371 x = TREE_REAL_CST (arg);
7372 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7374 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7375 REAL_VALUE_TYPE r;
7377 real_round (&r, TYPE_MODE (type), &x);
7378 return build_real (type, r);
7382 return fold_trunc_transparent_mathfn (fndecl, arglist);
7385 /* Fold function call to builtin lround, lroundf or lroundl (or the
7386 corresponding long long versions) and other rounding functions.
7387 Return NULL_TREE if no simplification can be made. */
7389 static tree
7390 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7392 tree arg;
7394 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7395 return 0;
7397 /* Optimize lround of constant value. */
7398 arg = TREE_VALUE (arglist);
7399 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7401 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7403 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7405 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7406 tree ftype = TREE_TYPE (arg), result;
7407 HOST_WIDE_INT hi, lo;
7408 REAL_VALUE_TYPE r;
7410 switch (DECL_FUNCTION_CODE (fndecl))
7412 CASE_FLT_FN (BUILT_IN_LFLOOR):
7413 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7414 real_floor (&r, TYPE_MODE (ftype), &x);
7415 break;
7417 CASE_FLT_FN (BUILT_IN_LCEIL):
7418 CASE_FLT_FN (BUILT_IN_LLCEIL):
7419 real_ceil (&r, TYPE_MODE (ftype), &x);
7420 break;
7422 CASE_FLT_FN (BUILT_IN_LROUND):
7423 CASE_FLT_FN (BUILT_IN_LLROUND):
7424 real_round (&r, TYPE_MODE (ftype), &x);
7425 break;
7427 default:
7428 gcc_unreachable ();
7431 REAL_VALUE_TO_INT (&lo, &hi, r);
7432 result = build_int_cst_wide (NULL_TREE, lo, hi);
7433 if (int_fits_type_p (result, itype))
7434 return fold_convert (itype, result);
7438 switch (DECL_FUNCTION_CODE (fndecl))
7440 CASE_FLT_FN (BUILT_IN_LFLOOR):
7441 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7442 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7443 if (tree_expr_nonnegative_p (arg))
7444 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7445 arg);
7446 break;
7447 default:;
7450 return fold_fixed_mathfn (fndecl, arglist);
7453 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7454 and their long and long long variants (i.e. ffsl and ffsll).
7455 Return NULL_TREE if no simplification can be made. */
7457 static tree
7458 fold_builtin_bitop (tree fndecl, tree arglist)
7460 tree arg;
7462 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7463 return NULL_TREE;
7465 /* Optimize for constant argument. */
7466 arg = TREE_VALUE (arglist);
7467 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7469 HOST_WIDE_INT hi, width, result;
7470 unsigned HOST_WIDE_INT lo;
7471 tree type;
7473 type = TREE_TYPE (arg);
7474 width = TYPE_PRECISION (type);
7475 lo = TREE_INT_CST_LOW (arg);
7477 /* Clear all the bits that are beyond the type's precision. */
7478 if (width > HOST_BITS_PER_WIDE_INT)
7480 hi = TREE_INT_CST_HIGH (arg);
7481 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7482 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7484 else
7486 hi = 0;
7487 if (width < HOST_BITS_PER_WIDE_INT)
7488 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7491 switch (DECL_FUNCTION_CODE (fndecl))
7493 CASE_INT_FN (BUILT_IN_FFS):
7494 if (lo != 0)
7495 result = exact_log2 (lo & -lo) + 1;
7496 else if (hi != 0)
7497 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7498 else
7499 result = 0;
7500 break;
7502 CASE_INT_FN (BUILT_IN_CLZ):
7503 if (hi != 0)
7504 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7505 else if (lo != 0)
7506 result = width - floor_log2 (lo) - 1;
7507 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7508 result = width;
7509 break;
7511 CASE_INT_FN (BUILT_IN_CTZ):
7512 if (lo != 0)
7513 result = exact_log2 (lo & -lo);
7514 else if (hi != 0)
7515 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7516 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7517 result = width;
7518 break;
7520 CASE_INT_FN (BUILT_IN_POPCOUNT):
7521 result = 0;
7522 while (lo)
7523 result++, lo &= lo - 1;
7524 while (hi)
7525 result++, hi &= hi - 1;
7526 break;
7528 CASE_INT_FN (BUILT_IN_PARITY):
7529 result = 0;
7530 while (lo)
7531 result++, lo &= lo - 1;
7532 while (hi)
7533 result++, hi &= hi - 1;
7534 result &= 1;
7535 break;
7537 default:
7538 gcc_unreachable ();
7541 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7544 return NULL_TREE;
7547 /* Return true if EXPR is the real constant contained in VALUE. */
7549 static bool
7550 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7552 STRIP_NOPS (expr);
7554 return ((TREE_CODE (expr) == REAL_CST
7555 && ! TREE_CONSTANT_OVERFLOW (expr)
7556 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7557 || (TREE_CODE (expr) == COMPLEX_CST
7558 && real_dconstp (TREE_REALPART (expr), value)
7559 && real_zerop (TREE_IMAGPART (expr))));
7562 /* A subroutine of fold_builtin to fold the various logarithmic
7563 functions. Return NULL_TREE if no simplification can me made.
7564 FUNC is the corresponding MPFR logarithm function. */
7566 static tree
7567 fold_builtin_logarithm (tree fndecl, tree arglist,
7568 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7570 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7572 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7573 tree arg = TREE_VALUE (arglist);
7574 tree res;
7575 const enum built_in_function fcode = builtin_mathfn_code (arg);
7577 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7578 instead we'll look for 'e' truncated to MODE. So only do
7579 this if flag_unsafe_math_optimizations is set. */
7580 if (flag_unsafe_math_optimizations && func == mpfr_log)
7582 const REAL_VALUE_TYPE e_truncated =
7583 real_value_truncate (TYPE_MODE (type), dconste);
7584 if (real_dconstp (arg, &e_truncated))
7585 return build_real (type, dconst1);
7588 /* Calculate the result when the argument is a constant. */
7589 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7590 return res;
7592 /* Special case, optimize logN(expN(x)) = x. */
7593 if (flag_unsafe_math_optimizations
7594 && ((func == mpfr_log
7595 && (fcode == BUILT_IN_EXP
7596 || fcode == BUILT_IN_EXPF
7597 || fcode == BUILT_IN_EXPL))
7598 || (func == mpfr_log2
7599 && (fcode == BUILT_IN_EXP2
7600 || fcode == BUILT_IN_EXP2F
7601 || fcode == BUILT_IN_EXP2L))
7602 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7603 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7605 /* Optimize logN(func()) for various exponential functions. We
7606 want to determine the value "x" and the power "exponent" in
7607 order to transform logN(x**exponent) into exponent*logN(x). */
7608 if (flag_unsafe_math_optimizations)
7610 tree exponent = 0, x = 0;
7612 switch (fcode)
7614 CASE_FLT_FN (BUILT_IN_EXP):
7615 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7616 x = build_real (type,
7617 real_value_truncate (TYPE_MODE (type), dconste));
7618 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7619 break;
7620 CASE_FLT_FN (BUILT_IN_EXP2):
7621 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7622 x = build_real (type, dconst2);
7623 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7624 break;
7625 CASE_FLT_FN (BUILT_IN_EXP10):
7626 CASE_FLT_FN (BUILT_IN_POW10):
7627 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7628 x = build_real (type, dconst10);
7629 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7630 break;
7631 CASE_FLT_FN (BUILT_IN_SQRT):
7632 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7633 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7634 exponent = build_real (type, dconsthalf);
7635 break;
7636 CASE_FLT_FN (BUILT_IN_CBRT):
7637 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7638 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7639 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7640 dconstthird));
7641 break;
7642 CASE_FLT_FN (BUILT_IN_POW):
7643 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7644 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7645 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7646 break;
7647 default:
7648 break;
7651 /* Now perform the optimization. */
7652 if (x && exponent)
7654 tree logfn;
7655 arglist = build_tree_list (NULL_TREE, x);
7656 logfn = build_function_call_expr (fndecl, arglist);
7657 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7662 return 0;
7665 /* Fold a builtin function call to pow, powf, or powl. Return
7666 NULL_TREE if no simplification can be made. */
7667 static tree
7668 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7670 tree arg0 = TREE_VALUE (arglist);
7671 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7673 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7674 return NULL_TREE;
7676 /* Optimize pow(1.0,y) = 1.0. */
7677 if (real_onep (arg0))
7678 return omit_one_operand (type, build_real (type, dconst1), arg1);
7680 if (TREE_CODE (arg1) == REAL_CST
7681 && ! TREE_CONSTANT_OVERFLOW (arg1))
7683 REAL_VALUE_TYPE cint;
7684 REAL_VALUE_TYPE c;
7685 HOST_WIDE_INT n;
7687 c = TREE_REAL_CST (arg1);
7689 /* Optimize pow(x,0.0) = 1.0. */
7690 if (REAL_VALUES_EQUAL (c, dconst0))
7691 return omit_one_operand (type, build_real (type, dconst1),
7692 arg0);
7694 /* Optimize pow(x,1.0) = x. */
7695 if (REAL_VALUES_EQUAL (c, dconst1))
7696 return arg0;
7698 /* Optimize pow(x,-1.0) = 1.0/x. */
7699 if (REAL_VALUES_EQUAL (c, dconstm1))
7700 return fold_build2 (RDIV_EXPR, type,
7701 build_real (type, dconst1), arg0);
7703 /* Optimize pow(x,0.5) = sqrt(x). */
7704 if (flag_unsafe_math_optimizations
7705 && REAL_VALUES_EQUAL (c, dconsthalf))
7707 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7709 if (sqrtfn != NULL_TREE)
7711 tree arglist = build_tree_list (NULL_TREE, arg0);
7712 return build_function_call_expr (sqrtfn, arglist);
7716 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
7717 if (flag_unsafe_math_optimizations)
7719 const REAL_VALUE_TYPE dconstroot
7720 = real_value_truncate (TYPE_MODE (type), dconstthird);
7722 if (REAL_VALUES_EQUAL (c, dconstroot))
7724 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
7725 if (cbrtfn != NULL_TREE)
7727 tree arglist = build_tree_list (NULL_TREE, arg0);
7728 return build_function_call_expr (cbrtfn, arglist);
7733 /* Check for an integer exponent. */
7734 n = real_to_integer (&c);
7735 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7736 if (real_identical (&c, &cint))
7738 /* Attempt to evaluate pow at compile-time. */
7739 if (TREE_CODE (arg0) == REAL_CST
7740 && ! TREE_CONSTANT_OVERFLOW (arg0))
7742 REAL_VALUE_TYPE x;
7743 bool inexact;
7745 x = TREE_REAL_CST (arg0);
7746 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7747 if (flag_unsafe_math_optimizations || !inexact)
7748 return build_real (type, x);
7751 /* Strip sign ops from even integer powers. */
7752 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7754 tree narg0 = fold_strip_sign_ops (arg0);
7755 if (narg0)
7757 arglist = build_tree_list (NULL_TREE, arg1);
7758 arglist = tree_cons (NULL_TREE, narg0, arglist);
7759 return build_function_call_expr (fndecl, arglist);
7765 if (flag_unsafe_math_optimizations)
7767 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7769 /* Optimize pow(expN(x),y) = expN(x*y). */
7770 if (BUILTIN_EXPONENT_P (fcode))
7772 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7773 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7774 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7775 arglist = build_tree_list (NULL_TREE, arg);
7776 return build_function_call_expr (expfn, arglist);
7779 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7780 if (BUILTIN_SQRT_P (fcode))
7782 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7783 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7784 build_real (type, dconsthalf));
7786 arglist = tree_cons (NULL_TREE, narg0,
7787 build_tree_list (NULL_TREE, narg1));
7788 return build_function_call_expr (fndecl, arglist);
7791 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7792 if (BUILTIN_CBRT_P (fcode))
7794 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7795 if (tree_expr_nonnegative_p (arg))
7797 const REAL_VALUE_TYPE dconstroot
7798 = real_value_truncate (TYPE_MODE (type), dconstthird);
7799 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7800 build_real (type, dconstroot));
7801 arglist = tree_cons (NULL_TREE, arg,
7802 build_tree_list (NULL_TREE, narg1));
7803 return build_function_call_expr (fndecl, arglist);
7807 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7808 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7809 || fcode == BUILT_IN_POWL)
7811 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7812 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7813 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7814 arglist = tree_cons (NULL_TREE, arg00,
7815 build_tree_list (NULL_TREE, narg1));
7816 return build_function_call_expr (fndecl, arglist);
7820 return NULL_TREE;
7823 /* Fold a builtin function call to powi, powif, or powil. Return
7824 NULL_TREE if no simplification can be made. */
7825 static tree
7826 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7828 tree arg0 = TREE_VALUE (arglist);
7829 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7831 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7832 return NULL_TREE;
7834 /* Optimize pow(1.0,y) = 1.0. */
7835 if (real_onep (arg0))
7836 return omit_one_operand (type, build_real (type, dconst1), arg1);
7838 if (host_integerp (arg1, 0))
7840 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7842 /* Evaluate powi at compile-time. */
7843 if (TREE_CODE (arg0) == REAL_CST
7844 && ! TREE_CONSTANT_OVERFLOW (arg0))
7846 REAL_VALUE_TYPE x;
7847 x = TREE_REAL_CST (arg0);
7848 real_powi (&x, TYPE_MODE (type), &x, c);
7849 return build_real (type, x);
7852 /* Optimize pow(x,0) = 1.0. */
7853 if (c == 0)
7854 return omit_one_operand (type, build_real (type, dconst1),
7855 arg0);
7857 /* Optimize pow(x,1) = x. */
7858 if (c == 1)
7859 return arg0;
7861 /* Optimize pow(x,-1) = 1.0/x. */
7862 if (c == -1)
7863 return fold_build2 (RDIV_EXPR, type,
7864 build_real (type, dconst1), arg0);
7867 return NULL_TREE;
7870 /* A subroutine of fold_builtin to fold the various exponent
7871 functions. Return NULL_TREE if no simplification can me made.
7872 FUNC is the corresponding MPFR exponent function. */
7874 static tree
7875 fold_builtin_exponent (tree fndecl, tree arglist,
7876 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7878 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7880 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7881 tree arg = TREE_VALUE (arglist);
7882 tree res;
7884 /* Calculate the result when the argument is a constant. */
7885 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
7886 return res;
7888 /* Optimize expN(logN(x)) = x. */
7889 if (flag_unsafe_math_optimizations)
7891 const enum built_in_function fcode = builtin_mathfn_code (arg);
7893 if ((func == mpfr_exp
7894 && (fcode == BUILT_IN_LOG
7895 || fcode == BUILT_IN_LOGF
7896 || fcode == BUILT_IN_LOGL))
7897 || (func == mpfr_exp2
7898 && (fcode == BUILT_IN_LOG2
7899 || fcode == BUILT_IN_LOG2F
7900 || fcode == BUILT_IN_LOG2L))
7901 || (func == mpfr_exp10
7902 && (fcode == BUILT_IN_LOG10
7903 || fcode == BUILT_IN_LOG10F
7904 || fcode == BUILT_IN_LOG10L)))
7905 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7909 return 0;
7912 /* Return true if VAR is a VAR_DECL or a component thereof. */
7914 static bool
7915 var_decl_component_p (tree var)
7917 tree inner = var;
7918 while (handled_component_p (inner))
7919 inner = TREE_OPERAND (inner, 0);
7920 return SSA_VAR_P (inner);
7923 /* Fold function call to builtin memset. Return
7924 NULL_TREE if no simplification can be made. */
7926 static tree
7927 fold_builtin_memset (tree arglist, tree type, bool ignore)
7929 tree dest, c, len, var, ret;
7930 unsigned HOST_WIDE_INT length, cval;
7932 if (!validate_arglist (arglist,
7933 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
7934 return 0;
7936 dest = TREE_VALUE (arglist);
7937 c = TREE_VALUE (TREE_CHAIN (arglist));
7938 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7940 if (! host_integerp (len, 1))
7941 return 0;
7943 /* If the LEN parameter is zero, return DEST. */
7944 if (integer_zerop (len))
7945 return omit_one_operand (type, dest, c);
7947 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
7948 return 0;
7950 var = dest;
7951 STRIP_NOPS (var);
7952 if (TREE_CODE (var) != ADDR_EXPR)
7953 return 0;
7955 var = TREE_OPERAND (var, 0);
7956 if (TREE_THIS_VOLATILE (var))
7957 return 0;
7959 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
7960 && !POINTER_TYPE_P (TREE_TYPE (var)))
7961 return 0;
7963 if (! var_decl_component_p (var))
7964 return 0;
7966 length = tree_low_cst (len, 1);
7967 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
7968 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
7969 < (int) length)
7970 return 0;
7972 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
7973 return 0;
7975 if (integer_zerop (c))
7976 cval = 0;
7977 else
7979 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
7980 return 0;
7982 cval = tree_low_cst (c, 1);
7983 cval &= 0xff;
7984 cval |= cval << 8;
7985 cval |= cval << 16;
7986 cval |= (cval << 31) << 1;
7989 ret = build_int_cst_type (TREE_TYPE (var), cval);
7990 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
7991 if (ignore)
7992 return ret;
7994 return omit_one_operand (type, dest, ret);
7997 /* Fold function call to builtin memset. Return
7998 NULL_TREE if no simplification can be made. */
8000 static tree
8001 fold_builtin_bzero (tree arglist, bool ignore)
8003 tree dest, size, newarglist;
8005 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8006 return 0;
8008 if (!ignore)
8009 return 0;
8011 dest = TREE_VALUE (arglist);
8012 size = TREE_VALUE (TREE_CHAIN (arglist));
8014 /* New argument list transforming bzero(ptr x, int y) to
8015 memset(ptr x, int 0, size_t y). This is done this way
8016 so that if it isn't expanded inline, we fallback to
8017 calling bzero instead of memset. */
8019 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8020 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8021 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8022 return fold_builtin_memset (newarglist, void_type_node, ignore);
8025 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8026 NULL_TREE if no simplification can be made.
8027 If ENDP is 0, return DEST (like memcpy).
8028 If ENDP is 1, return DEST+LEN (like mempcpy).
8029 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8030 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8031 (memmove). */
8033 static tree
8034 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8036 tree dest, src, len, destvar, srcvar, expr;
8037 unsigned HOST_WIDE_INT length;
8039 if (! validate_arglist (arglist,
8040 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8041 return 0;
8043 dest = TREE_VALUE (arglist);
8044 src = TREE_VALUE (TREE_CHAIN (arglist));
8045 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8047 /* If the LEN parameter is zero, return DEST. */
8048 if (integer_zerop (len))
8049 return omit_one_operand (type, dest, src);
8051 /* If SRC and DEST are the same (and not volatile), return
8052 DEST{,+LEN,+LEN-1}. */
8053 if (operand_equal_p (src, dest, 0))
8054 expr = len;
8055 else
8057 if (endp == 3)
8059 unsigned int src_align
8060 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8061 unsigned int dest_align
8062 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8063 /* Both DEST and SRC must be pointer types.
8064 ??? This is what old code did. Is the testing for pointer types
8065 really mandatory?
8067 If either SRC is readonly or length is 1, we can use memcpy. */
8068 if (dest_align && src_align
8069 && (readonly_data_expr (src)
8070 || integer_onep (len)))
8072 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8073 if (!fn)
8074 return 0;
8075 return build_function_call_expr (fn, arglist);
8078 if (! host_integerp (len, 1))
8079 return 0;
8081 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8082 return 0;
8084 destvar = dest;
8085 STRIP_NOPS (destvar);
8086 if (TREE_CODE (destvar) != ADDR_EXPR)
8087 return 0;
8089 destvar = TREE_OPERAND (destvar, 0);
8090 if (TREE_THIS_VOLATILE (destvar))
8091 return 0;
8093 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8094 && !POINTER_TYPE_P (TREE_TYPE (destvar))
8095 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8096 return 0;
8098 if (! var_decl_component_p (destvar))
8099 return 0;
8101 srcvar = src;
8102 STRIP_NOPS (srcvar);
8103 if (TREE_CODE (srcvar) != ADDR_EXPR)
8104 return 0;
8106 srcvar = TREE_OPERAND (srcvar, 0);
8107 if (TREE_THIS_VOLATILE (srcvar))
8108 return 0;
8110 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8111 && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8112 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8113 return 0;
8115 if (! var_decl_component_p (srcvar))
8116 return 0;
8118 length = tree_low_cst (len, 1);
8119 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8120 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8121 < (int) length
8122 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8123 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8124 < (int) length)
8125 return 0;
8127 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8128 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8129 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8130 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8131 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8132 else
8133 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8134 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8137 if (ignore)
8138 return expr;
8140 if (endp == 0 || endp == 3)
8141 return omit_one_operand (type, dest, expr);
8143 if (expr == len)
8144 expr = 0;
8146 if (endp == 2)
8147 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8148 ssize_int (1));
8150 len = fold_convert (TREE_TYPE (dest), len);
8151 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8152 dest = fold_convert (type, dest);
8153 if (expr)
8154 dest = omit_one_operand (type, dest, expr);
8155 return dest;
8158 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8159 simplification can be made. */
8161 static tree
8162 fold_builtin_bcopy (tree arglist, bool ignore)
8164 tree src, dest, size, newarglist;
8166 if (!validate_arglist (arglist,
8167 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8168 return 0;
8170 if (! ignore)
8171 return 0;
8173 src = TREE_VALUE (arglist);
8174 dest = TREE_VALUE (TREE_CHAIN (arglist));
8175 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8177 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8178 memmove(ptr y, ptr x, size_t z). This is done this way
8179 so that if it isn't expanded inline, we fallback to
8180 calling bcopy instead of memmove. */
8182 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8183 newarglist = tree_cons (NULL_TREE, src, newarglist);
8184 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8186 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8189 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8190 the length of the string to be copied. Return NULL_TREE if no
8191 simplification can be made. */
8193 tree
8194 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8196 tree dest, src, fn;
8198 if (!validate_arglist (arglist,
8199 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8200 return 0;
8202 dest = TREE_VALUE (arglist);
8203 src = TREE_VALUE (TREE_CHAIN (arglist));
8205 /* If SRC and DEST are the same (and not volatile), return DEST. */
8206 if (operand_equal_p (src, dest, 0))
8207 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8209 if (optimize_size)
8210 return 0;
8212 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8213 if (!fn)
8214 return 0;
8216 if (!len)
8218 len = c_strlen (src, 1);
8219 if (! len || TREE_SIDE_EFFECTS (len))
8220 return 0;
8223 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8224 arglist = build_tree_list (NULL_TREE, len);
8225 arglist = tree_cons (NULL_TREE, src, arglist);
8226 arglist = tree_cons (NULL_TREE, dest, arglist);
8227 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8228 build_function_call_expr (fn, arglist));
8231 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8232 the length of the source string. Return NULL_TREE if no simplification
8233 can be made. */
8235 tree
8236 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8238 tree dest, src, len, fn;
8240 if (!validate_arglist (arglist,
8241 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8242 return 0;
8244 dest = TREE_VALUE (arglist);
8245 src = TREE_VALUE (TREE_CHAIN (arglist));
8246 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8248 /* If the LEN parameter is zero, return DEST. */
8249 if (integer_zerop (len))
8250 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8252 /* We can't compare slen with len as constants below if len is not a
8253 constant. */
8254 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8255 return 0;
8257 if (!slen)
8258 slen = c_strlen (src, 1);
8260 /* Now, we must be passed a constant src ptr parameter. */
8261 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8262 return 0;
8264 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8266 /* We do not support simplification of this case, though we do
8267 support it when expanding trees into RTL. */
8268 /* FIXME: generate a call to __builtin_memset. */
8269 if (tree_int_cst_lt (slen, len))
8270 return 0;
8272 /* OK transform into builtin memcpy. */
8273 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8274 if (!fn)
8275 return 0;
8276 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8277 build_function_call_expr (fn, arglist));
8280 /* Fold function call to builtin memcmp. Return
8281 NULL_TREE if no simplification can be made. */
8283 static tree
8284 fold_builtin_memcmp (tree arglist)
8286 tree arg1, arg2, len;
8287 const char *p1, *p2;
8289 if (!validate_arglist (arglist,
8290 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8291 return 0;
8293 arg1 = TREE_VALUE (arglist);
8294 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8295 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8297 /* If the LEN parameter is zero, return zero. */
8298 if (integer_zerop (len))
8299 return omit_two_operands (integer_type_node, integer_zero_node,
8300 arg1, arg2);
8302 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8303 if (operand_equal_p (arg1, arg2, 0))
8304 return omit_one_operand (integer_type_node, integer_zero_node, len);
8306 p1 = c_getstr (arg1);
8307 p2 = c_getstr (arg2);
8309 /* If all arguments are constant, and the value of len is not greater
8310 than the lengths of arg1 and arg2, evaluate at compile-time. */
8311 if (host_integerp (len, 1) && p1 && p2
8312 && compare_tree_int (len, strlen (p1) + 1) <= 0
8313 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8315 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8317 if (r > 0)
8318 return integer_one_node;
8319 else if (r < 0)
8320 return integer_minus_one_node;
8321 else
8322 return integer_zero_node;
8325 /* If len parameter is one, return an expression corresponding to
8326 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8327 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8329 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8330 tree cst_uchar_ptr_node
8331 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8333 tree ind1 = fold_convert (integer_type_node,
8334 build1 (INDIRECT_REF, cst_uchar_node,
8335 fold_convert (cst_uchar_ptr_node,
8336 arg1)));
8337 tree ind2 = fold_convert (integer_type_node,
8338 build1 (INDIRECT_REF, cst_uchar_node,
8339 fold_convert (cst_uchar_ptr_node,
8340 arg2)));
8341 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8344 return 0;
8347 /* Fold function call to builtin strcmp. Return
8348 NULL_TREE if no simplification can be made. */
8350 static tree
8351 fold_builtin_strcmp (tree arglist)
8353 tree arg1, arg2;
8354 const char *p1, *p2;
8356 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8357 return 0;
8359 arg1 = TREE_VALUE (arglist);
8360 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8362 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8363 if (operand_equal_p (arg1, arg2, 0))
8364 return integer_zero_node;
8366 p1 = c_getstr (arg1);
8367 p2 = c_getstr (arg2);
8369 if (p1 && p2)
8371 const int i = strcmp (p1, p2);
8372 if (i < 0)
8373 return integer_minus_one_node;
8374 else if (i > 0)
8375 return integer_one_node;
8376 else
8377 return integer_zero_node;
8380 /* If the second arg is "", return *(const unsigned char*)arg1. */
8381 if (p2 && *p2 == '\0')
8383 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8384 tree cst_uchar_ptr_node
8385 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8387 return fold_convert (integer_type_node,
8388 build1 (INDIRECT_REF, cst_uchar_node,
8389 fold_convert (cst_uchar_ptr_node,
8390 arg1)));
8393 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8394 if (p1 && *p1 == '\0')
8396 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8397 tree cst_uchar_ptr_node
8398 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8400 tree temp = fold_convert (integer_type_node,
8401 build1 (INDIRECT_REF, cst_uchar_node,
8402 fold_convert (cst_uchar_ptr_node,
8403 arg2)));
8404 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8407 return 0;
8410 /* Fold function call to builtin strncmp. Return
8411 NULL_TREE if no simplification can be made. */
8413 static tree
8414 fold_builtin_strncmp (tree arglist)
8416 tree arg1, arg2, len;
8417 const char *p1, *p2;
8419 if (!validate_arglist (arglist,
8420 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8421 return 0;
8423 arg1 = TREE_VALUE (arglist);
8424 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8425 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8427 /* If the LEN parameter is zero, return zero. */
8428 if (integer_zerop (len))
8429 return omit_two_operands (integer_type_node, integer_zero_node,
8430 arg1, arg2);
8432 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8433 if (operand_equal_p (arg1, arg2, 0))
8434 return omit_one_operand (integer_type_node, integer_zero_node, len);
8436 p1 = c_getstr (arg1);
8437 p2 = c_getstr (arg2);
8439 if (host_integerp (len, 1) && p1 && p2)
8441 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8442 if (i > 0)
8443 return integer_one_node;
8444 else if (i < 0)
8445 return integer_minus_one_node;
8446 else
8447 return integer_zero_node;
8450 /* If the second arg is "", and the length is greater than zero,
8451 return *(const unsigned char*)arg1. */
8452 if (p2 && *p2 == '\0'
8453 && TREE_CODE (len) == INTEGER_CST
8454 && tree_int_cst_sgn (len) == 1)
8456 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8457 tree cst_uchar_ptr_node
8458 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8460 return fold_convert (integer_type_node,
8461 build1 (INDIRECT_REF, cst_uchar_node,
8462 fold_convert (cst_uchar_ptr_node,
8463 arg1)));
8466 /* If the first arg is "", and the length is greater than zero,
8467 return -*(const unsigned char*)arg2. */
8468 if (p1 && *p1 == '\0'
8469 && TREE_CODE (len) == INTEGER_CST
8470 && tree_int_cst_sgn (len) == 1)
8472 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8473 tree cst_uchar_ptr_node
8474 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8476 tree temp = fold_convert (integer_type_node,
8477 build1 (INDIRECT_REF, cst_uchar_node,
8478 fold_convert (cst_uchar_ptr_node,
8479 arg2)));
8480 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8483 /* If len parameter is one, return an expression corresponding to
8484 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8485 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8487 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8488 tree cst_uchar_ptr_node
8489 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8491 tree ind1 = fold_convert (integer_type_node,
8492 build1 (INDIRECT_REF, cst_uchar_node,
8493 fold_convert (cst_uchar_ptr_node,
8494 arg1)));
8495 tree ind2 = fold_convert (integer_type_node,
8496 build1 (INDIRECT_REF, cst_uchar_node,
8497 fold_convert (cst_uchar_ptr_node,
8498 arg2)));
8499 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8502 return 0;
8505 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8506 NULL_TREE if no simplification can be made. */
8508 static tree
8509 fold_builtin_signbit (tree fndecl, tree arglist)
8511 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8512 tree arg, temp;
8514 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8515 return NULL_TREE;
8517 arg = TREE_VALUE (arglist);
8519 /* If ARG is a compile-time constant, determine the result. */
8520 if (TREE_CODE (arg) == REAL_CST
8521 && !TREE_CONSTANT_OVERFLOW (arg))
8523 REAL_VALUE_TYPE c;
8525 c = TREE_REAL_CST (arg);
8526 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8527 return fold_convert (type, temp);
8530 /* If ARG is non-negative, the result is always zero. */
8531 if (tree_expr_nonnegative_p (arg))
8532 return omit_one_operand (type, integer_zero_node, arg);
8534 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8535 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8536 return fold_build2 (LT_EXPR, type, arg,
8537 build_real (TREE_TYPE (arg), dconst0));
8539 return NULL_TREE;
8542 /* Fold function call to builtin copysign, copysignf or copysignl.
8543 Return NULL_TREE if no simplification can be made. */
8545 static tree
8546 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8548 tree arg1, arg2, tem;
8550 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8551 return NULL_TREE;
8553 arg1 = TREE_VALUE (arglist);
8554 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8556 /* copysign(X,X) is X. */
8557 if (operand_equal_p (arg1, arg2, 0))
8558 return fold_convert (type, arg1);
8560 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8561 if (TREE_CODE (arg1) == REAL_CST
8562 && TREE_CODE (arg2) == REAL_CST
8563 && !TREE_CONSTANT_OVERFLOW (arg1)
8564 && !TREE_CONSTANT_OVERFLOW (arg2))
8566 REAL_VALUE_TYPE c1, c2;
8568 c1 = TREE_REAL_CST (arg1);
8569 c2 = TREE_REAL_CST (arg2);
8570 /* c1.sign := c2.sign. */
8571 real_copysign (&c1, &c2);
8572 return build_real (type, c1);
8575 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8576 Remember to evaluate Y for side-effects. */
8577 if (tree_expr_nonnegative_p (arg2))
8578 return omit_one_operand (type,
8579 fold_build1 (ABS_EXPR, type, arg1),
8580 arg2);
8582 /* Strip sign changing operations for the first argument. */
8583 tem = fold_strip_sign_ops (arg1);
8584 if (tem)
8586 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8587 return build_function_call_expr (fndecl, arglist);
8590 return NULL_TREE;
8593 /* Fold a call to builtin isascii. */
8595 static tree
8596 fold_builtin_isascii (tree arglist)
8598 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8599 return 0;
8600 else
8602 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8603 tree arg = TREE_VALUE (arglist);
8605 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8606 build_int_cst (NULL_TREE,
8607 ~ (unsigned HOST_WIDE_INT) 0x7f));
8608 arg = fold_build2 (EQ_EXPR, integer_type_node,
8609 arg, integer_zero_node);
8611 if (in_gimple_form && !TREE_CONSTANT (arg))
8612 return NULL_TREE;
8613 else
8614 return arg;
8618 /* Fold a call to builtin toascii. */
8620 static tree
8621 fold_builtin_toascii (tree arglist)
8623 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8624 return 0;
8625 else
8627 /* Transform toascii(c) -> (c & 0x7f). */
8628 tree arg = TREE_VALUE (arglist);
8630 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8631 build_int_cst (NULL_TREE, 0x7f));
8635 /* Fold a call to builtin isdigit. */
8637 static tree
8638 fold_builtin_isdigit (tree arglist)
8640 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8641 return 0;
8642 else
8644 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8645 /* According to the C standard, isdigit is unaffected by locale.
8646 However, it definitely is affected by the target character set. */
8647 tree arg;
8648 unsigned HOST_WIDE_INT target_digit0
8649 = lang_hooks.to_target_charset ('0');
8651 if (target_digit0 == 0)
8652 return NULL_TREE;
8654 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8655 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8656 build_int_cst (unsigned_type_node, target_digit0));
8657 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8658 build_int_cst (unsigned_type_node, 9));
8659 if (in_gimple_form && !TREE_CONSTANT (arg))
8660 return NULL_TREE;
8661 else
8662 return arg;
8666 /* Fold a call to fabs, fabsf or fabsl. */
8668 static tree
8669 fold_builtin_fabs (tree arglist, tree type)
8671 tree arg;
8673 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8674 return 0;
8676 arg = TREE_VALUE (arglist);
8677 arg = fold_convert (type, arg);
8678 if (TREE_CODE (arg) == REAL_CST)
8679 return fold_abs_const (arg, type);
8680 return fold_build1 (ABS_EXPR, type, arg);
8683 /* Fold a call to abs, labs, llabs or imaxabs. */
8685 static tree
8686 fold_builtin_abs (tree arglist, tree type)
8688 tree arg;
8690 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8691 return 0;
8693 arg = TREE_VALUE (arglist);
8694 arg = fold_convert (type, arg);
8695 if (TREE_CODE (arg) == INTEGER_CST)
8696 return fold_abs_const (arg, type);
8697 return fold_build1 (ABS_EXPR, type, arg);
8700 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8701 EXP is the CALL_EXPR for the call. */
8703 static tree
8704 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8706 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8707 tree arg;
8708 REAL_VALUE_TYPE r;
8710 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8712 /* Check that we have exactly one argument. */
8713 if (arglist == 0)
8715 error ("too few arguments to function %qs",
8716 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8717 return error_mark_node;
8719 else if (TREE_CHAIN (arglist) != 0)
8721 error ("too many arguments to function %qs",
8722 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8723 return error_mark_node;
8725 else
8727 error ("non-floating-point argument to function %qs",
8728 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8729 return error_mark_node;
8733 arg = TREE_VALUE (arglist);
8734 switch (builtin_index)
8736 case BUILT_IN_ISINF:
8737 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8738 return omit_one_operand (type, integer_zero_node, arg);
8740 if (TREE_CODE (arg) == REAL_CST)
8742 r = TREE_REAL_CST (arg);
8743 if (real_isinf (&r))
8744 return real_compare (GT_EXPR, &r, &dconst0)
8745 ? integer_one_node : integer_minus_one_node;
8746 else
8747 return integer_zero_node;
8750 return NULL_TREE;
8752 case BUILT_IN_FINITE:
8753 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8754 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8755 return omit_one_operand (type, integer_one_node, arg);
8757 if (TREE_CODE (arg) == REAL_CST)
8759 r = TREE_REAL_CST (arg);
8760 return real_isinf (&r) || real_isnan (&r)
8761 ? integer_zero_node : integer_one_node;
8764 return NULL_TREE;
8766 case BUILT_IN_ISNAN:
8767 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8768 return omit_one_operand (type, integer_zero_node, arg);
8770 if (TREE_CODE (arg) == REAL_CST)
8772 r = TREE_REAL_CST (arg);
8773 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8776 arg = builtin_save_expr (arg);
8777 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8779 default:
8780 gcc_unreachable ();
8784 /* Fold a call to an unordered comparison function such as
8785 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8786 being called and ARGLIST is the argument list for the call.
8787 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8788 the opposite of the desired result. UNORDERED_CODE is used
8789 for modes that can hold NaNs and ORDERED_CODE is used for
8790 the rest. */
8792 static tree
8793 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8794 enum tree_code unordered_code,
8795 enum tree_code ordered_code)
8797 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8798 enum tree_code code;
8799 tree arg0, arg1;
8800 tree type0, type1;
8801 enum tree_code code0, code1;
8802 tree cmp_type = NULL_TREE;
8804 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8806 /* Check that we have exactly two arguments. */
8807 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8809 error ("too few arguments to function %qs",
8810 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8811 return error_mark_node;
8813 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8815 error ("too many arguments to function %qs",
8816 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8817 return error_mark_node;
8821 arg0 = TREE_VALUE (arglist);
8822 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8824 type0 = TREE_TYPE (arg0);
8825 type1 = TREE_TYPE (arg1);
8827 code0 = TREE_CODE (type0);
8828 code1 = TREE_CODE (type1);
8830 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8831 /* Choose the wider of two real types. */
8832 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8833 ? type0 : type1;
8834 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8835 cmp_type = type0;
8836 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8837 cmp_type = type1;
8838 else
8840 error ("non-floating-point argument to function %qs",
8841 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8842 return error_mark_node;
8845 arg0 = fold_convert (cmp_type, arg0);
8846 arg1 = fold_convert (cmp_type, arg1);
8848 if (unordered_code == UNORDERED_EXPR)
8850 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8851 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8852 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8855 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8856 : ordered_code;
8857 return fold_build1 (TRUTH_NOT_EXPR, type,
8858 fold_build2 (code, type, arg0, arg1));
8861 /* Used by constant folding to simplify calls to builtin functions. EXP is
8862 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8863 result of the function call is ignored. This function returns NULL_TREE
8864 if no simplification was possible. */
8866 static tree
8867 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8869 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8870 enum built_in_function fcode;
8872 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8873 return targetm.fold_builtin (fndecl, arglist, ignore);
8875 fcode = DECL_FUNCTION_CODE (fndecl);
8876 switch (fcode)
8878 case BUILT_IN_FPUTS:
8879 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8881 case BUILT_IN_FPUTS_UNLOCKED:
8882 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8884 case BUILT_IN_STRSTR:
8885 return fold_builtin_strstr (arglist, type);
8887 case BUILT_IN_STRCAT:
8888 return fold_builtin_strcat (arglist);
8890 case BUILT_IN_STRNCAT:
8891 return fold_builtin_strncat (arglist);
8893 case BUILT_IN_STRSPN:
8894 return fold_builtin_strspn (arglist);
8896 case BUILT_IN_STRCSPN:
8897 return fold_builtin_strcspn (arglist);
8899 case BUILT_IN_STRCHR:
8900 case BUILT_IN_INDEX:
8901 return fold_builtin_strchr (arglist, type);
8903 case BUILT_IN_STRRCHR:
8904 case BUILT_IN_RINDEX:
8905 return fold_builtin_strrchr (arglist, type);
8907 case BUILT_IN_STRCPY:
8908 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8910 case BUILT_IN_STRNCPY:
8911 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8913 case BUILT_IN_STRCMP:
8914 return fold_builtin_strcmp (arglist);
8916 case BUILT_IN_STRNCMP:
8917 return fold_builtin_strncmp (arglist);
8919 case BUILT_IN_STRPBRK:
8920 return fold_builtin_strpbrk (arglist, type);
8922 case BUILT_IN_BCMP:
8923 case BUILT_IN_MEMCMP:
8924 return fold_builtin_memcmp (arglist);
8926 case BUILT_IN_SPRINTF:
8927 return fold_builtin_sprintf (arglist, ignore);
8929 case BUILT_IN_CONSTANT_P:
8931 tree val;
8933 val = fold_builtin_constant_p (arglist);
8934 /* Gimplification will pull the CALL_EXPR for the builtin out of
8935 an if condition. When not optimizing, we'll not CSE it back.
8936 To avoid link error types of regressions, return false now. */
8937 if (!val && !optimize)
8938 val = integer_zero_node;
8940 return val;
8943 case BUILT_IN_EXPECT:
8944 return fold_builtin_expect (arglist);
8946 case BUILT_IN_CLASSIFY_TYPE:
8947 return fold_builtin_classify_type (arglist);
8949 case BUILT_IN_STRLEN:
8950 return fold_builtin_strlen (arglist);
8952 CASE_FLT_FN (BUILT_IN_FABS):
8953 return fold_builtin_fabs (arglist, type);
8955 case BUILT_IN_ABS:
8956 case BUILT_IN_LABS:
8957 case BUILT_IN_LLABS:
8958 case BUILT_IN_IMAXABS:
8959 return fold_builtin_abs (arglist, type);
8961 CASE_FLT_FN (BUILT_IN_CONJ):
8962 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8963 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8964 break;
8966 CASE_FLT_FN (BUILT_IN_CREAL):
8967 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8968 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8969 TREE_VALUE (arglist)));
8970 break;
8972 CASE_FLT_FN (BUILT_IN_CIMAG):
8973 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8974 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8975 TREE_VALUE (arglist)));
8976 break;
8978 CASE_FLT_FN (BUILT_IN_CABS):
8979 return fold_builtin_cabs (arglist, type, fndecl);
8981 CASE_FLT_FN (BUILT_IN_SQRT):
8982 return fold_builtin_sqrt (arglist, type);
8984 CASE_FLT_FN (BUILT_IN_CBRT):
8985 return fold_builtin_cbrt (arglist, type);
8987 CASE_FLT_FN (BUILT_IN_ASIN):
8988 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8989 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
8990 &dconstm1, &dconst1, true);
8991 break;
8993 CASE_FLT_FN (BUILT_IN_ACOS):
8994 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8995 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
8996 &dconstm1, &dconst1, true);
8997 break;
8999 CASE_FLT_FN (BUILT_IN_ATAN):
9000 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9001 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9002 NULL, NULL, 0);
9003 break;
9005 CASE_FLT_FN (BUILT_IN_ASINH):
9006 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9007 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9008 NULL, NULL, 0);
9009 break;
9011 CASE_FLT_FN (BUILT_IN_ACOSH):
9012 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9013 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9014 &dconst1, NULL, true);
9015 break;
9017 CASE_FLT_FN (BUILT_IN_ATANH):
9018 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9019 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9020 &dconstm1, &dconst1, false);
9021 break;
9023 CASE_FLT_FN (BUILT_IN_SIN):
9024 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9025 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9026 NULL, NULL, 0);
9027 break;
9029 CASE_FLT_FN (BUILT_IN_COS):
9030 return fold_builtin_cos (arglist, type, fndecl);
9032 CASE_FLT_FN (BUILT_IN_TAN):
9033 return fold_builtin_tan (arglist, type);
9035 CASE_FLT_FN (BUILT_IN_SINH):
9036 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9037 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9038 NULL, NULL, 0);
9039 break;
9041 CASE_FLT_FN (BUILT_IN_COSH):
9042 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9043 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_cosh,
9044 NULL, NULL, 0);
9045 break;
9047 CASE_FLT_FN (BUILT_IN_TANH):
9048 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9049 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9050 NULL, NULL, 0);
9051 break;
9053 CASE_FLT_FN (BUILT_IN_ERF):
9054 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9055 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9056 NULL, NULL, 0);
9057 break;
9059 CASE_FLT_FN (BUILT_IN_ERFC):
9060 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9061 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9062 NULL, NULL, 0);
9063 break;
9065 CASE_FLT_FN (BUILT_IN_EXP):
9066 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9068 CASE_FLT_FN (BUILT_IN_EXP2):
9069 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9071 CASE_FLT_FN (BUILT_IN_EXP10):
9072 CASE_FLT_FN (BUILT_IN_POW10):
9073 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9075 CASE_FLT_FN (BUILT_IN_EXPM1):
9076 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9077 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9078 NULL, NULL, 0);
9079 break;
9081 CASE_FLT_FN (BUILT_IN_LOG):
9082 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9084 CASE_FLT_FN (BUILT_IN_LOG2):
9085 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9087 CASE_FLT_FN (BUILT_IN_LOG10):
9088 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9090 CASE_FLT_FN (BUILT_IN_LOG1P):
9091 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9092 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9093 &dconstm1, NULL, false);
9094 break;
9096 CASE_FLT_FN (BUILT_IN_POW):
9097 return fold_builtin_pow (fndecl, arglist, type);
9099 CASE_FLT_FN (BUILT_IN_POWI):
9100 return fold_builtin_powi (fndecl, arglist, type);
9102 CASE_FLT_FN (BUILT_IN_INF):
9103 case BUILT_IN_INFD32:
9104 case BUILT_IN_INFD64:
9105 case BUILT_IN_INFD128:
9106 return fold_builtin_inf (type, true);
9108 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9109 return fold_builtin_inf (type, false);
9111 CASE_FLT_FN (BUILT_IN_NAN):
9112 case BUILT_IN_NAND32:
9113 case BUILT_IN_NAND64:
9114 case BUILT_IN_NAND128:
9115 return fold_builtin_nan (arglist, type, true);
9117 CASE_FLT_FN (BUILT_IN_NANS):
9118 return fold_builtin_nan (arglist, type, false);
9120 CASE_FLT_FN (BUILT_IN_FLOOR):
9121 return fold_builtin_floor (fndecl, arglist);
9123 CASE_FLT_FN (BUILT_IN_CEIL):
9124 return fold_builtin_ceil (fndecl, arglist);
9126 CASE_FLT_FN (BUILT_IN_TRUNC):
9127 return fold_builtin_trunc (fndecl, arglist);
9129 CASE_FLT_FN (BUILT_IN_ROUND):
9130 return fold_builtin_round (fndecl, arglist);
9132 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9133 CASE_FLT_FN (BUILT_IN_RINT):
9134 return fold_trunc_transparent_mathfn (fndecl, arglist);
9136 CASE_FLT_FN (BUILT_IN_LCEIL):
9137 CASE_FLT_FN (BUILT_IN_LLCEIL):
9138 CASE_FLT_FN (BUILT_IN_LFLOOR):
9139 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9140 CASE_FLT_FN (BUILT_IN_LROUND):
9141 CASE_FLT_FN (BUILT_IN_LLROUND):
9142 return fold_builtin_int_roundingfn (fndecl, arglist);
9144 CASE_FLT_FN (BUILT_IN_LRINT):
9145 CASE_FLT_FN (BUILT_IN_LLRINT):
9146 return fold_fixed_mathfn (fndecl, arglist);
9148 CASE_INT_FN (BUILT_IN_FFS):
9149 CASE_INT_FN (BUILT_IN_CLZ):
9150 CASE_INT_FN (BUILT_IN_CTZ):
9151 CASE_INT_FN (BUILT_IN_POPCOUNT):
9152 CASE_INT_FN (BUILT_IN_PARITY):
9153 return fold_builtin_bitop (fndecl, arglist);
9155 case BUILT_IN_MEMSET:
9156 return fold_builtin_memset (arglist, type, ignore);
9158 case BUILT_IN_MEMCPY:
9159 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9161 case BUILT_IN_MEMPCPY:
9162 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9164 case BUILT_IN_MEMMOVE:
9165 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9167 case BUILT_IN_BZERO:
9168 return fold_builtin_bzero (arglist, ignore);
9170 case BUILT_IN_BCOPY:
9171 return fold_builtin_bcopy (arglist, ignore);
9173 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9174 return fold_builtin_signbit (fndecl, arglist);
9176 case BUILT_IN_ISASCII:
9177 return fold_builtin_isascii (arglist);
9179 case BUILT_IN_TOASCII:
9180 return fold_builtin_toascii (arglist);
9182 case BUILT_IN_ISDIGIT:
9183 return fold_builtin_isdigit (arglist);
9185 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9186 return fold_builtin_copysign (fndecl, arglist, type);
9188 CASE_FLT_FN (BUILT_IN_FINITE):
9189 case BUILT_IN_FINITED32:
9190 case BUILT_IN_FINITED64:
9191 case BUILT_IN_FINITED128:
9192 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9194 CASE_FLT_FN (BUILT_IN_ISINF):
9195 case BUILT_IN_ISINFD32:
9196 case BUILT_IN_ISINFD64:
9197 case BUILT_IN_ISINFD128:
9198 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9200 CASE_FLT_FN (BUILT_IN_ISNAN):
9201 case BUILT_IN_ISNAND32:
9202 case BUILT_IN_ISNAND64:
9203 case BUILT_IN_ISNAND128:
9204 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9206 case BUILT_IN_ISGREATER:
9207 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9208 case BUILT_IN_ISGREATEREQUAL:
9209 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9210 case BUILT_IN_ISLESS:
9211 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9212 case BUILT_IN_ISLESSEQUAL:
9213 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9214 case BUILT_IN_ISLESSGREATER:
9215 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9216 case BUILT_IN_ISUNORDERED:
9217 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9218 NOP_EXPR);
9220 /* We do the folding for va_start in the expander. */
9221 case BUILT_IN_VA_START:
9222 break;
9224 case BUILT_IN_OBJECT_SIZE:
9225 return fold_builtin_object_size (arglist);
9226 case BUILT_IN_MEMCPY_CHK:
9227 case BUILT_IN_MEMPCPY_CHK:
9228 case BUILT_IN_MEMMOVE_CHK:
9229 case BUILT_IN_MEMSET_CHK:
9230 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9231 DECL_FUNCTION_CODE (fndecl));
9232 case BUILT_IN_STRCPY_CHK:
9233 case BUILT_IN_STPCPY_CHK:
9234 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9235 DECL_FUNCTION_CODE (fndecl));
9236 case BUILT_IN_STRNCPY_CHK:
9237 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9238 case BUILT_IN_STRCAT_CHK:
9239 return fold_builtin_strcat_chk (fndecl, arglist);
9240 case BUILT_IN_STRNCAT_CHK:
9241 return fold_builtin_strncat_chk (fndecl, arglist);
9242 case BUILT_IN_SPRINTF_CHK:
9243 case BUILT_IN_VSPRINTF_CHK:
9244 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9245 case BUILT_IN_SNPRINTF_CHK:
9246 case BUILT_IN_VSNPRINTF_CHK:
9247 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9248 DECL_FUNCTION_CODE (fndecl));
9250 case BUILT_IN_PRINTF:
9251 case BUILT_IN_PRINTF_UNLOCKED:
9252 case BUILT_IN_VPRINTF:
9253 case BUILT_IN_PRINTF_CHK:
9254 case BUILT_IN_VPRINTF_CHK:
9255 return fold_builtin_printf (fndecl, arglist, ignore,
9256 DECL_FUNCTION_CODE (fndecl));
9258 case BUILT_IN_FPRINTF:
9259 case BUILT_IN_FPRINTF_UNLOCKED:
9260 case BUILT_IN_VFPRINTF:
9261 case BUILT_IN_FPRINTF_CHK:
9262 case BUILT_IN_VFPRINTF_CHK:
9263 return fold_builtin_fprintf (fndecl, arglist, ignore,
9264 DECL_FUNCTION_CODE (fndecl));
9266 default:
9267 break;
9270 return 0;
9273 /* A wrapper function for builtin folding that prevents warnings for
9274 "statement without effect" and the like, caused by removing the
9275 call node earlier than the warning is generated. */
9277 tree
9278 fold_builtin (tree fndecl, tree arglist, bool ignore)
9280 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9281 if (exp && !ignore)
9283 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9284 TREE_NO_WARNING (exp) = 1;
9287 return exp;
9290 /* Conveniently construct a function call expression. */
9292 tree
9293 build_function_call_expr (tree fn, tree arglist)
9295 tree call_expr;
9297 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9298 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9299 call_expr, arglist, NULL_TREE);
9302 /* This function validates the types of a function call argument list
9303 represented as a tree chain of parameters against a specified list
9304 of tree_codes. If the last specifier is a 0, that represents an
9305 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9307 static int
9308 validate_arglist (tree arglist, ...)
9310 enum tree_code code;
9311 int res = 0;
9312 va_list ap;
9314 va_start (ap, arglist);
9318 code = va_arg (ap, enum tree_code);
9319 switch (code)
9321 case 0:
9322 /* This signifies an ellipses, any further arguments are all ok. */
9323 res = 1;
9324 goto end;
9325 case VOID_TYPE:
9326 /* This signifies an endlink, if no arguments remain, return
9327 true, otherwise return false. */
9328 res = arglist == 0;
9329 goto end;
9330 default:
9331 /* If no parameters remain or the parameter's code does not
9332 match the specified code, return false. Otherwise continue
9333 checking any remaining arguments. */
9334 if (arglist == 0)
9335 goto end;
9336 if (code == POINTER_TYPE)
9338 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9339 goto end;
9341 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9342 goto end;
9343 break;
9345 arglist = TREE_CHAIN (arglist);
9347 while (1);
9349 /* We need gotos here since we can only have one VA_CLOSE in a
9350 function. */
9351 end: ;
9352 va_end (ap);
9354 return res;
9357 /* Default target-specific builtin expander that does nothing. */
9360 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9361 rtx target ATTRIBUTE_UNUSED,
9362 rtx subtarget ATTRIBUTE_UNUSED,
9363 enum machine_mode mode ATTRIBUTE_UNUSED,
9364 int ignore ATTRIBUTE_UNUSED)
9366 return NULL_RTX;
9369 /* Returns true is EXP represents data that would potentially reside
9370 in a readonly section. */
9372 static bool
9373 readonly_data_expr (tree exp)
9375 STRIP_NOPS (exp);
9377 if (TREE_CODE (exp) != ADDR_EXPR)
9378 return false;
9380 exp = get_base_address (TREE_OPERAND (exp, 0));
9381 if (!exp)
9382 return false;
9384 /* Make sure we call decl_readonly_section only for trees it
9385 can handle (since it returns true for everything it doesn't
9386 understand). */
9387 if (TREE_CODE (exp) == STRING_CST
9388 || TREE_CODE (exp) == CONSTRUCTOR
9389 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9390 return decl_readonly_section (exp, 0);
9391 else
9392 return false;
9395 /* Simplify a call to the strstr builtin.
9397 Return 0 if no simplification was possible, otherwise return the
9398 simplified form of the call as a tree.
9400 The simplified form may be a constant or other expression which
9401 computes the same value, but in a more efficient manner (including
9402 calls to other builtin functions).
9404 The call may contain arguments which need to be evaluated, but
9405 which are not useful to determine the result of the call. In
9406 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9407 COMPOUND_EXPR will be an argument which must be evaluated.
9408 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9409 COMPOUND_EXPR in the chain will contain the tree for the simplified
9410 form of the builtin function call. */
9412 static tree
9413 fold_builtin_strstr (tree arglist, tree type)
9415 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9416 return 0;
9417 else
9419 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9420 tree fn;
9421 const char *p1, *p2;
9423 p2 = c_getstr (s2);
9424 if (p2 == NULL)
9425 return 0;
9427 p1 = c_getstr (s1);
9428 if (p1 != NULL)
9430 const char *r = strstr (p1, p2);
9431 tree tem;
9433 if (r == NULL)
9434 return build_int_cst (TREE_TYPE (s1), 0);
9436 /* Return an offset into the constant string argument. */
9437 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9438 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9439 return fold_convert (type, tem);
9442 /* The argument is const char *, and the result is char *, so we need
9443 a type conversion here to avoid a warning. */
9444 if (p2[0] == '\0')
9445 return fold_convert (type, s1);
9447 if (p2[1] != '\0')
9448 return 0;
9450 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9451 if (!fn)
9452 return 0;
9454 /* New argument list transforming strstr(s1, s2) to
9455 strchr(s1, s2[0]). */
9456 arglist = build_tree_list (NULL_TREE,
9457 build_int_cst (NULL_TREE, p2[0]));
9458 arglist = tree_cons (NULL_TREE, s1, arglist);
9459 return build_function_call_expr (fn, arglist);
9463 /* Simplify a call to the strchr builtin.
9465 Return 0 if no simplification was possible, otherwise return the
9466 simplified form of the call as a tree.
9468 The simplified form may be a constant or other expression which
9469 computes the same value, but in a more efficient manner (including
9470 calls to other builtin functions).
9472 The call may contain arguments which need to be evaluated, but
9473 which are not useful to determine the result of the call. In
9474 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9475 COMPOUND_EXPR will be an argument which must be evaluated.
9476 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9477 COMPOUND_EXPR in the chain will contain the tree for the simplified
9478 form of the builtin function call. */
9480 static tree
9481 fold_builtin_strchr (tree arglist, tree type)
9483 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9484 return 0;
9485 else
9487 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9488 const char *p1;
9490 if (TREE_CODE (s2) != INTEGER_CST)
9491 return 0;
9493 p1 = c_getstr (s1);
9494 if (p1 != NULL)
9496 char c;
9497 const char *r;
9498 tree tem;
9500 if (target_char_cast (s2, &c))
9501 return 0;
9503 r = strchr (p1, c);
9505 if (r == NULL)
9506 return build_int_cst (TREE_TYPE (s1), 0);
9508 /* Return an offset into the constant string argument. */
9509 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9510 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9511 return fold_convert (type, tem);
9513 return 0;
9517 /* Simplify a call to the strrchr builtin.
9519 Return 0 if no simplification was possible, otherwise return the
9520 simplified form of the call as a tree.
9522 The simplified form may be a constant or other expression which
9523 computes the same value, but in a more efficient manner (including
9524 calls to other builtin functions).
9526 The call may contain arguments which need to be evaluated, but
9527 which are not useful to determine the result of the call. In
9528 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9529 COMPOUND_EXPR will be an argument which must be evaluated.
9530 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9531 COMPOUND_EXPR in the chain will contain the tree for the simplified
9532 form of the builtin function call. */
9534 static tree
9535 fold_builtin_strrchr (tree arglist, tree type)
9537 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9538 return 0;
9539 else
9541 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9542 tree fn;
9543 const char *p1;
9545 if (TREE_CODE (s2) != INTEGER_CST)
9546 return 0;
9548 p1 = c_getstr (s1);
9549 if (p1 != NULL)
9551 char c;
9552 const char *r;
9553 tree tem;
9555 if (target_char_cast (s2, &c))
9556 return 0;
9558 r = strrchr (p1, c);
9560 if (r == NULL)
9561 return build_int_cst (TREE_TYPE (s1), 0);
9563 /* Return an offset into the constant string argument. */
9564 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9565 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9566 return fold_convert (type, tem);
9569 if (! integer_zerop (s2))
9570 return 0;
9572 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9573 if (!fn)
9574 return 0;
9576 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9577 return build_function_call_expr (fn, arglist);
9581 /* Simplify a call to the strpbrk builtin.
9583 Return 0 if no simplification was possible, otherwise return the
9584 simplified form of the call as a tree.
9586 The simplified form may be a constant or other expression which
9587 computes the same value, but in a more efficient manner (including
9588 calls to other builtin functions).
9590 The call may contain arguments which need to be evaluated, but
9591 which are not useful to determine the result of the call. In
9592 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9593 COMPOUND_EXPR will be an argument which must be evaluated.
9594 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9595 COMPOUND_EXPR in the chain will contain the tree for the simplified
9596 form of the builtin function call. */
9598 static tree
9599 fold_builtin_strpbrk (tree arglist, tree type)
9601 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9602 return 0;
9603 else
9605 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9606 tree fn;
9607 const char *p1, *p2;
9609 p2 = c_getstr (s2);
9610 if (p2 == NULL)
9611 return 0;
9613 p1 = c_getstr (s1);
9614 if (p1 != NULL)
9616 const char *r = strpbrk (p1, p2);
9617 tree tem;
9619 if (r == NULL)
9620 return build_int_cst (TREE_TYPE (s1), 0);
9622 /* Return an offset into the constant string argument. */
9623 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9624 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9625 return fold_convert (type, tem);
9628 if (p2[0] == '\0')
9629 /* strpbrk(x, "") == NULL.
9630 Evaluate and ignore s1 in case it had side-effects. */
9631 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9633 if (p2[1] != '\0')
9634 return 0; /* Really call strpbrk. */
9636 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9637 if (!fn)
9638 return 0;
9640 /* New argument list transforming strpbrk(s1, s2) to
9641 strchr(s1, s2[0]). */
9642 arglist = build_tree_list (NULL_TREE,
9643 build_int_cst (NULL_TREE, p2[0]));
9644 arglist = tree_cons (NULL_TREE, s1, arglist);
9645 return build_function_call_expr (fn, arglist);
9649 /* Simplify a call to the strcat builtin.
9651 Return 0 if no simplification was possible, otherwise return the
9652 simplified form of the call as a tree.
9654 The simplified form may be a constant or other expression which
9655 computes the same value, but in a more efficient manner (including
9656 calls to other builtin functions).
9658 The call may contain arguments which need to be evaluated, but
9659 which are not useful to determine the result of the call. In
9660 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9661 COMPOUND_EXPR will be an argument which must be evaluated.
9662 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9663 COMPOUND_EXPR in the chain will contain the tree for the simplified
9664 form of the builtin function call. */
9666 static tree
9667 fold_builtin_strcat (tree arglist)
9669 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9670 return 0;
9671 else
9673 tree dst = TREE_VALUE (arglist),
9674 src = TREE_VALUE (TREE_CHAIN (arglist));
9675 const char *p = c_getstr (src);
9677 /* If the string length is zero, return the dst parameter. */
9678 if (p && *p == '\0')
9679 return dst;
9681 return 0;
9685 /* Simplify a call to the strncat builtin.
9687 Return 0 if no simplification was possible, otherwise return the
9688 simplified form of the call as a tree.
9690 The simplified form may be a constant or other expression which
9691 computes the same value, but in a more efficient manner (including
9692 calls to other builtin functions).
9694 The call may contain arguments which need to be evaluated, but
9695 which are not useful to determine the result of the call. In
9696 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9697 COMPOUND_EXPR will be an argument which must be evaluated.
9698 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9699 COMPOUND_EXPR in the chain will contain the tree for the simplified
9700 form of the builtin function call. */
9702 static tree
9703 fold_builtin_strncat (tree arglist)
9705 if (!validate_arglist (arglist,
9706 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9707 return 0;
9708 else
9710 tree dst = TREE_VALUE (arglist);
9711 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9712 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9713 const char *p = c_getstr (src);
9715 /* If the requested length is zero, or the src parameter string
9716 length is zero, return the dst parameter. */
9717 if (integer_zerop (len) || (p && *p == '\0'))
9718 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9720 /* If the requested len is greater than or equal to the string
9721 length, call strcat. */
9722 if (TREE_CODE (len) == INTEGER_CST && p
9723 && compare_tree_int (len, strlen (p)) >= 0)
9725 tree newarglist
9726 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9727 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9729 /* If the replacement _DECL isn't initialized, don't do the
9730 transformation. */
9731 if (!fn)
9732 return 0;
9734 return build_function_call_expr (fn, newarglist);
9736 return 0;
9740 /* Simplify a call to the strspn builtin.
9742 Return 0 if no simplification was possible, otherwise return the
9743 simplified form of the call as a tree.
9745 The simplified form may be a constant or other expression which
9746 computes the same value, but in a more efficient manner (including
9747 calls to other builtin functions).
9749 The call may contain arguments which need to be evaluated, but
9750 which are not useful to determine the result of the call. In
9751 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9752 COMPOUND_EXPR will be an argument which must be evaluated.
9753 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9754 COMPOUND_EXPR in the chain will contain the tree for the simplified
9755 form of the builtin function call. */
9757 static tree
9758 fold_builtin_strspn (tree arglist)
9760 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9761 return 0;
9762 else
9764 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9765 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9767 /* If both arguments are constants, evaluate at compile-time. */
9768 if (p1 && p2)
9770 const size_t r = strspn (p1, p2);
9771 return size_int (r);
9774 /* If either argument is "", return 0. */
9775 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9776 /* Evaluate and ignore both arguments in case either one has
9777 side-effects. */
9778 return omit_two_operands (integer_type_node, integer_zero_node,
9779 s1, s2);
9780 return 0;
9784 /* Simplify a call to the strcspn builtin.
9786 Return 0 if no simplification was possible, otherwise return the
9787 simplified form of the call as a tree.
9789 The simplified form may be a constant or other expression which
9790 computes the same value, but in a more efficient manner (including
9791 calls to other builtin functions).
9793 The call may contain arguments which need to be evaluated, but
9794 which are not useful to determine the result of the call. In
9795 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9796 COMPOUND_EXPR will be an argument which must be evaluated.
9797 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9798 COMPOUND_EXPR in the chain will contain the tree for the simplified
9799 form of the builtin function call. */
9801 static tree
9802 fold_builtin_strcspn (tree arglist)
9804 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9805 return 0;
9806 else
9808 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9809 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9811 /* If both arguments are constants, evaluate at compile-time. */
9812 if (p1 && p2)
9814 const size_t r = strcspn (p1, p2);
9815 return size_int (r);
9818 /* If the first argument is "", return 0. */
9819 if (p1 && *p1 == '\0')
9821 /* Evaluate and ignore argument s2 in case it has
9822 side-effects. */
9823 return omit_one_operand (integer_type_node,
9824 integer_zero_node, s2);
9827 /* If the second argument is "", return __builtin_strlen(s1). */
9828 if (p2 && *p2 == '\0')
9830 tree newarglist = build_tree_list (NULL_TREE, s1),
9831 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9833 /* If the replacement _DECL isn't initialized, don't do the
9834 transformation. */
9835 if (!fn)
9836 return 0;
9838 return build_function_call_expr (fn, newarglist);
9840 return 0;
9844 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9845 by the builtin will be ignored. UNLOCKED is true is true if this
9846 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9847 the known length of the string. Return NULL_TREE if no simplification
9848 was possible. */
9850 tree
9851 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9853 tree fn;
9854 /* If we're using an unlocked function, assume the other unlocked
9855 functions exist explicitly. */
9856 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9857 : implicit_built_in_decls[BUILT_IN_FPUTC];
9858 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9859 : implicit_built_in_decls[BUILT_IN_FWRITE];
9861 /* If the return value is used, don't do the transformation. */
9862 if (!ignore)
9863 return 0;
9865 /* Verify the arguments in the original call. */
9866 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9867 return 0;
9869 if (! len)
9870 len = c_strlen (TREE_VALUE (arglist), 0);
9872 /* Get the length of the string passed to fputs. If the length
9873 can't be determined, punt. */
9874 if (!len
9875 || TREE_CODE (len) != INTEGER_CST)
9876 return 0;
9878 switch (compare_tree_int (len, 1))
9880 case -1: /* length is 0, delete the call entirely . */
9881 return omit_one_operand (integer_type_node, integer_zero_node,
9882 TREE_VALUE (TREE_CHAIN (arglist)));
9884 case 0: /* length is 1, call fputc. */
9886 const char *p = c_getstr (TREE_VALUE (arglist));
9888 if (p != NULL)
9890 /* New argument list transforming fputs(string, stream) to
9891 fputc(string[0], stream). */
9892 arglist = build_tree_list (NULL_TREE,
9893 TREE_VALUE (TREE_CHAIN (arglist)));
9894 arglist = tree_cons (NULL_TREE,
9895 build_int_cst (NULL_TREE, p[0]),
9896 arglist);
9897 fn = fn_fputc;
9898 break;
9901 /* FALLTHROUGH */
9902 case 1: /* length is greater than 1, call fwrite. */
9904 tree string_arg;
9906 /* If optimizing for size keep fputs. */
9907 if (optimize_size)
9908 return 0;
9909 string_arg = TREE_VALUE (arglist);
9910 /* New argument list transforming fputs(string, stream) to
9911 fwrite(string, 1, len, stream). */
9912 arglist = build_tree_list (NULL_TREE,
9913 TREE_VALUE (TREE_CHAIN (arglist)));
9914 arglist = tree_cons (NULL_TREE, len, arglist);
9915 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9916 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9917 fn = fn_fwrite;
9918 break;
9920 default:
9921 gcc_unreachable ();
9924 /* If the replacement _DECL isn't initialized, don't do the
9925 transformation. */
9926 if (!fn)
9927 return 0;
9929 /* These optimizations are only performed when the result is ignored,
9930 hence there's no need to cast the result to integer_type_node. */
9931 return build_function_call_expr (fn, arglist);
9934 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9935 produced. False otherwise. This is done so that we don't output the error
9936 or warning twice or three times. */
9937 bool
9938 fold_builtin_next_arg (tree arglist)
9940 tree fntype = TREE_TYPE (current_function_decl);
9942 if (TYPE_ARG_TYPES (fntype) == 0
9943 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9944 == void_type_node))
9946 error ("%<va_start%> used in function with fixed args");
9947 return true;
9949 else if (!arglist)
9951 /* Evidently an out of date version of <stdarg.h>; can't validate
9952 va_start's second argument, but can still work as intended. */
9953 warning (0, "%<__builtin_next_arg%> called without an argument");
9954 return true;
9956 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9957 when we checked the arguments and if needed issued a warning. */
9958 else if (!TREE_CHAIN (arglist)
9959 || !integer_zerop (TREE_VALUE (arglist))
9960 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9961 || TREE_CHAIN (TREE_CHAIN (arglist)))
9963 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9964 tree arg = TREE_VALUE (arglist);
9966 if (TREE_CHAIN (arglist))
9968 error ("%<va_start%> used with too many arguments");
9969 return true;
9972 /* Strip off all nops for the sake of the comparison. This
9973 is not quite the same as STRIP_NOPS. It does more.
9974 We must also strip off INDIRECT_EXPR for C++ reference
9975 parameters. */
9976 while (TREE_CODE (arg) == NOP_EXPR
9977 || TREE_CODE (arg) == CONVERT_EXPR
9978 || TREE_CODE (arg) == NON_LVALUE_EXPR
9979 || TREE_CODE (arg) == INDIRECT_REF)
9980 arg = TREE_OPERAND (arg, 0);
9981 if (arg != last_parm)
9983 /* FIXME: Sometimes with the tree optimizers we can get the
9984 not the last argument even though the user used the last
9985 argument. We just warn and set the arg to be the last
9986 argument so that we will get wrong-code because of
9987 it. */
9988 warning (0, "second parameter of %<va_start%> not last named argument");
9990 /* We want to verify the second parameter just once before the tree
9991 optimizers are run and then avoid keeping it in the tree,
9992 as otherwise we could warn even for correct code like:
9993 void foo (int i, ...)
9994 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9995 TREE_VALUE (arglist) = integer_zero_node;
9996 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9998 return false;
10002 /* Simplify a call to the sprintf builtin.
10004 Return 0 if no simplification was possible, otherwise return the
10005 simplified form of the call as a tree. If IGNORED is true, it means that
10006 the caller does not use the returned value of the function. */
10008 static tree
10009 fold_builtin_sprintf (tree arglist, int ignored)
10011 tree call, retval, dest, fmt;
10012 const char *fmt_str = NULL;
10014 /* Verify the required arguments in the original call. We deal with two
10015 types of sprintf() calls: 'sprintf (str, fmt)' and
10016 'sprintf (dest, "%s", orig)'. */
10017 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10018 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10019 VOID_TYPE))
10020 return NULL_TREE;
10022 /* Get the destination string and the format specifier. */
10023 dest = TREE_VALUE (arglist);
10024 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10026 /* Check whether the format is a literal string constant. */
10027 fmt_str = c_getstr (fmt);
10028 if (fmt_str == NULL)
10029 return NULL_TREE;
10031 call = NULL_TREE;
10032 retval = NULL_TREE;
10034 if (!init_target_chars())
10035 return 0;
10037 /* If the format doesn't contain % args or %%, use strcpy. */
10038 if (strchr (fmt_str, target_percent) == NULL)
10040 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10042 if (!fn)
10043 return NULL_TREE;
10045 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10046 'format' is known to contain no % formats. */
10047 arglist = build_tree_list (NULL_TREE, fmt);
10048 arglist = tree_cons (NULL_TREE, dest, arglist);
10049 call = build_function_call_expr (fn, arglist);
10050 if (!ignored)
10051 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10054 /* If the format is "%s", use strcpy if the result isn't used. */
10055 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10057 tree fn, orig;
10058 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10060 if (!fn)
10061 return NULL_TREE;
10063 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10064 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10065 arglist = build_tree_list (NULL_TREE, orig);
10066 arglist = tree_cons (NULL_TREE, dest, arglist);
10067 if (!ignored)
10069 retval = c_strlen (orig, 1);
10070 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10071 return NULL_TREE;
10073 call = build_function_call_expr (fn, arglist);
10076 if (call && retval)
10078 retval = fold_convert
10079 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10080 retval);
10081 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10083 else
10084 return call;
10087 /* Expand a call to __builtin_object_size. */
10090 expand_builtin_object_size (tree exp)
10092 tree ost;
10093 int object_size_type;
10094 tree fndecl = get_callee_fndecl (exp);
10095 tree arglist = TREE_OPERAND (exp, 1);
10096 location_t locus = EXPR_LOCATION (exp);
10098 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10100 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10101 &locus, fndecl);
10102 expand_builtin_trap ();
10103 return const0_rtx;
10106 ost = TREE_VALUE (TREE_CHAIN (arglist));
10107 STRIP_NOPS (ost);
10109 if (TREE_CODE (ost) != INTEGER_CST
10110 || tree_int_cst_sgn (ost) < 0
10111 || compare_tree_int (ost, 3) > 0)
10113 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10114 &locus, fndecl);
10115 expand_builtin_trap ();
10116 return const0_rtx;
10119 object_size_type = tree_low_cst (ost, 0);
10121 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10124 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10125 FCODE is the BUILT_IN_* to use.
10126 Return 0 if we failed; the caller should emit a normal call,
10127 otherwise try to get the result in TARGET, if convenient (and in
10128 mode MODE if that's convenient). */
10130 static rtx
10131 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10132 enum built_in_function fcode)
10134 tree arglist = TREE_OPERAND (exp, 1);
10135 tree dest, src, len, size;
10137 if (!validate_arglist (arglist,
10138 POINTER_TYPE,
10139 fcode == BUILT_IN_MEMSET_CHK
10140 ? INTEGER_TYPE : POINTER_TYPE,
10141 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10142 return 0;
10144 dest = TREE_VALUE (arglist);
10145 src = TREE_VALUE (TREE_CHAIN (arglist));
10146 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10147 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10149 if (! host_integerp (size, 1))
10150 return 0;
10152 if (host_integerp (len, 1) || integer_all_onesp (size))
10154 tree fn;
10156 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10158 location_t locus = EXPR_LOCATION (exp);
10159 warning (0, "%Hcall to %D will always overflow destination buffer",
10160 &locus, get_callee_fndecl (exp));
10161 return 0;
10164 arglist = build_tree_list (NULL_TREE, len);
10165 arglist = tree_cons (NULL_TREE, src, arglist);
10166 arglist = tree_cons (NULL_TREE, dest, arglist);
10168 fn = NULL_TREE;
10169 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10170 mem{cpy,pcpy,move,set} is available. */
10171 switch (fcode)
10173 case BUILT_IN_MEMCPY_CHK:
10174 fn = built_in_decls[BUILT_IN_MEMCPY];
10175 break;
10176 case BUILT_IN_MEMPCPY_CHK:
10177 fn = built_in_decls[BUILT_IN_MEMPCPY];
10178 break;
10179 case BUILT_IN_MEMMOVE_CHK:
10180 fn = built_in_decls[BUILT_IN_MEMMOVE];
10181 break;
10182 case BUILT_IN_MEMSET_CHK:
10183 fn = built_in_decls[BUILT_IN_MEMSET];
10184 break;
10185 default:
10186 break;
10189 if (! fn)
10190 return 0;
10192 fn = build_function_call_expr (fn, arglist);
10193 if (TREE_CODE (fn) == CALL_EXPR)
10194 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10195 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10197 else if (fcode == BUILT_IN_MEMSET_CHK)
10198 return 0;
10199 else
10201 unsigned int dest_align
10202 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10204 /* If DEST is not a pointer type, call the normal function. */
10205 if (dest_align == 0)
10206 return 0;
10208 /* If SRC and DEST are the same (and not volatile), do nothing. */
10209 if (operand_equal_p (src, dest, 0))
10211 tree expr;
10213 if (fcode != BUILT_IN_MEMPCPY_CHK)
10215 /* Evaluate and ignore LEN in case it has side-effects. */
10216 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10217 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10220 len = fold_convert (TREE_TYPE (dest), len);
10221 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10222 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10225 /* __memmove_chk special case. */
10226 if (fcode == BUILT_IN_MEMMOVE_CHK)
10228 unsigned int src_align
10229 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10231 if (src_align == 0)
10232 return 0;
10234 /* If src is categorized for a readonly section we can use
10235 normal __memcpy_chk. */
10236 if (readonly_data_expr (src))
10238 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10239 if (!fn)
10240 return 0;
10241 fn = build_function_call_expr (fn, arglist);
10242 if (TREE_CODE (fn) == CALL_EXPR)
10243 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10244 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10247 return 0;
10251 /* Emit warning if a buffer overflow is detected at compile time. */
10253 static void
10254 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10256 int arg_mask, is_strlen = 0;
10257 tree arglist = TREE_OPERAND (exp, 1), a;
10258 tree len, size;
10259 location_t locus;
10261 switch (fcode)
10263 case BUILT_IN_STRCPY_CHK:
10264 case BUILT_IN_STPCPY_CHK:
10265 /* For __strcat_chk the warning will be emitted only if overflowing
10266 by at least strlen (dest) + 1 bytes. */
10267 case BUILT_IN_STRCAT_CHK:
10268 arg_mask = 6;
10269 is_strlen = 1;
10270 break;
10271 case BUILT_IN_STRNCAT_CHK:
10272 /* For __strncat_chk the warning will be emitted only if overflowing
10273 by at least strlen (dest) + 1 bytes. */
10274 arg_mask = 12;
10275 break;
10276 case BUILT_IN_STRNCPY_CHK:
10277 arg_mask = 12;
10278 break;
10279 case BUILT_IN_SNPRINTF_CHK:
10280 case BUILT_IN_VSNPRINTF_CHK:
10281 arg_mask = 10;
10282 break;
10283 default:
10284 gcc_unreachable ();
10287 len = NULL_TREE;
10288 size = NULL_TREE;
10289 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10290 if (arg_mask & 1)
10292 if (len)
10293 size = a;
10294 else
10295 len = a;
10298 if (!len || !size)
10299 return;
10301 len = TREE_VALUE (len);
10302 size = TREE_VALUE (size);
10304 if (! host_integerp (size, 1) || integer_all_onesp (size))
10305 return;
10307 if (is_strlen)
10309 len = c_strlen (len, 1);
10310 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10311 return;
10313 else if (fcode == BUILT_IN_STRNCAT_CHK)
10315 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10316 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10317 return;
10318 src = c_strlen (src, 1);
10319 if (! src || ! host_integerp (src, 1))
10321 locus = EXPR_LOCATION (exp);
10322 warning (0, "%Hcall to %D might overflow destination buffer",
10323 &locus, get_callee_fndecl (exp));
10324 return;
10326 else if (tree_int_cst_lt (src, size))
10327 return;
10329 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10330 return;
10332 locus = EXPR_LOCATION (exp);
10333 warning (0, "%Hcall to %D will always overflow destination buffer",
10334 &locus, get_callee_fndecl (exp));
10337 /* Emit warning if a buffer overflow is detected at compile time
10338 in __sprintf_chk/__vsprintf_chk calls. */
10340 static void
10341 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10343 tree arglist = TREE_OPERAND (exp, 1);
10344 tree dest, size, len, fmt, flag;
10345 const char *fmt_str;
10347 /* Verify the required arguments in the original call. */
10348 if (! arglist)
10349 return;
10350 dest = TREE_VALUE (arglist);
10351 arglist = TREE_CHAIN (arglist);
10352 if (! arglist)
10353 return;
10354 flag = TREE_VALUE (arglist);
10355 arglist = TREE_CHAIN (arglist);
10356 if (! arglist)
10357 return;
10358 size = TREE_VALUE (arglist);
10359 arglist = TREE_CHAIN (arglist);
10360 if (! arglist)
10361 return;
10362 fmt = TREE_VALUE (arglist);
10363 arglist = TREE_CHAIN (arglist);
10365 if (! host_integerp (size, 1) || integer_all_onesp (size))
10366 return;
10368 /* Check whether the format is a literal string constant. */
10369 fmt_str = c_getstr (fmt);
10370 if (fmt_str == NULL)
10371 return;
10373 if (!init_target_chars())
10374 return;
10376 /* If the format doesn't contain % args or %%, we know its size. */
10377 if (strchr (fmt_str, target_percent) == 0)
10378 len = build_int_cstu (size_type_node, strlen (fmt_str));
10379 /* If the format is "%s" and first ... argument is a string literal,
10380 we know it too. */
10381 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10383 tree arg;
10385 if (! arglist)
10386 return;
10387 arg = TREE_VALUE (arglist);
10388 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10389 return;
10391 len = c_strlen (arg, 1);
10392 if (!len || ! host_integerp (len, 1))
10393 return;
10395 else
10396 return;
10398 if (! tree_int_cst_lt (len, size))
10400 location_t locus = EXPR_LOCATION (exp);
10401 warning (0, "%Hcall to %D will always overflow destination buffer",
10402 &locus, get_callee_fndecl (exp));
10406 /* Fold a call to __builtin_object_size, if possible. */
10408 tree
10409 fold_builtin_object_size (tree arglist)
10411 tree ptr, ost, ret = 0;
10412 int object_size_type;
10414 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10415 return 0;
10417 ptr = TREE_VALUE (arglist);
10418 ost = TREE_VALUE (TREE_CHAIN (arglist));
10419 STRIP_NOPS (ost);
10421 if (TREE_CODE (ost) != INTEGER_CST
10422 || tree_int_cst_sgn (ost) < 0
10423 || compare_tree_int (ost, 3) > 0)
10424 return 0;
10426 object_size_type = tree_low_cst (ost, 0);
10428 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10429 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10430 and (size_t) 0 for types 2 and 3. */
10431 if (TREE_SIDE_EFFECTS (ptr))
10432 return fold_convert (size_type_node,
10433 object_size_type < 2
10434 ? integer_minus_one_node : integer_zero_node);
10436 if (TREE_CODE (ptr) == ADDR_EXPR)
10437 ret = build_int_cstu (size_type_node,
10438 compute_builtin_object_size (ptr, object_size_type));
10440 else if (TREE_CODE (ptr) == SSA_NAME)
10442 unsigned HOST_WIDE_INT bytes;
10444 /* If object size is not known yet, delay folding until
10445 later. Maybe subsequent passes will help determining
10446 it. */
10447 bytes = compute_builtin_object_size (ptr, object_size_type);
10448 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10449 ? -1 : 0))
10450 ret = build_int_cstu (size_type_node, bytes);
10453 if (ret)
10455 ret = force_fit_type (ret, -1, false, false);
10456 if (TREE_CONSTANT_OVERFLOW (ret))
10457 ret = 0;
10460 return ret;
10463 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10464 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10465 code of the builtin. If MAXLEN is not NULL, it is maximum length
10466 passed as third argument. */
10468 tree
10469 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10470 enum built_in_function fcode)
10472 tree dest, src, len, size, fn;
10474 if (!validate_arglist (arglist,
10475 POINTER_TYPE,
10476 fcode == BUILT_IN_MEMSET_CHK
10477 ? INTEGER_TYPE : POINTER_TYPE,
10478 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10479 return 0;
10481 dest = TREE_VALUE (arglist);
10482 /* Actually val for __memset_chk, but it doesn't matter. */
10483 src = TREE_VALUE (TREE_CHAIN (arglist));
10484 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10485 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10487 /* If SRC and DEST are the same (and not volatile), return DEST
10488 (resp. DEST+LEN for __mempcpy_chk). */
10489 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10491 if (fcode != BUILT_IN_MEMPCPY_CHK)
10492 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10493 else
10495 tree temp = fold_convert (TREE_TYPE (dest), len);
10496 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10497 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10501 if (! host_integerp (size, 1))
10502 return 0;
10504 if (! integer_all_onesp (size))
10506 if (! host_integerp (len, 1))
10508 /* If LEN is not constant, try MAXLEN too.
10509 For MAXLEN only allow optimizing into non-_ocs function
10510 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10511 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10513 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10515 /* (void) __mempcpy_chk () can be optimized into
10516 (void) __memcpy_chk (). */
10517 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10518 if (!fn)
10519 return 0;
10521 return build_function_call_expr (fn, arglist);
10523 return 0;
10526 else
10527 maxlen = len;
10529 if (tree_int_cst_lt (size, maxlen))
10530 return 0;
10533 arglist = build_tree_list (NULL_TREE, len);
10534 arglist = tree_cons (NULL_TREE, src, arglist);
10535 arglist = tree_cons (NULL_TREE, dest, arglist);
10537 fn = NULL_TREE;
10538 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10539 mem{cpy,pcpy,move,set} is available. */
10540 switch (fcode)
10542 case BUILT_IN_MEMCPY_CHK:
10543 fn = built_in_decls[BUILT_IN_MEMCPY];
10544 break;
10545 case BUILT_IN_MEMPCPY_CHK:
10546 fn = built_in_decls[BUILT_IN_MEMPCPY];
10547 break;
10548 case BUILT_IN_MEMMOVE_CHK:
10549 fn = built_in_decls[BUILT_IN_MEMMOVE];
10550 break;
10551 case BUILT_IN_MEMSET_CHK:
10552 fn = built_in_decls[BUILT_IN_MEMSET];
10553 break;
10554 default:
10555 break;
10558 if (!fn)
10559 return 0;
10561 return build_function_call_expr (fn, arglist);
10564 /* Fold a call to the __st[rp]cpy_chk builtin.
10565 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10566 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10567 strings passed as second argument. */
10569 tree
10570 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10571 enum built_in_function fcode)
10573 tree dest, src, size, len, fn;
10575 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10576 VOID_TYPE))
10577 return 0;
10579 dest = TREE_VALUE (arglist);
10580 src = TREE_VALUE (TREE_CHAIN (arglist));
10581 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10583 /* If SRC and DEST are the same (and not volatile), return DEST. */
10584 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10585 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10587 if (! host_integerp (size, 1))
10588 return 0;
10590 if (! integer_all_onesp (size))
10592 len = c_strlen (src, 1);
10593 if (! len || ! host_integerp (len, 1))
10595 /* If LEN is not constant, try MAXLEN too.
10596 For MAXLEN only allow optimizing into non-_ocs function
10597 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10598 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10600 if (fcode == BUILT_IN_STPCPY_CHK)
10602 if (! ignore)
10603 return 0;
10605 /* If return value of __stpcpy_chk is ignored,
10606 optimize into __strcpy_chk. */
10607 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10608 if (!fn)
10609 return 0;
10611 return build_function_call_expr (fn, arglist);
10614 if (! len || TREE_SIDE_EFFECTS (len))
10615 return 0;
10617 /* If c_strlen returned something, but not a constant,
10618 transform __strcpy_chk into __memcpy_chk. */
10619 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10620 if (!fn)
10621 return 0;
10623 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10624 arglist = build_tree_list (NULL_TREE, size);
10625 arglist = tree_cons (NULL_TREE, len, arglist);
10626 arglist = tree_cons (NULL_TREE, src, arglist);
10627 arglist = tree_cons (NULL_TREE, dest, arglist);
10628 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10629 build_function_call_expr (fn, arglist));
10632 else
10633 maxlen = len;
10635 if (! tree_int_cst_lt (maxlen, size))
10636 return 0;
10639 arglist = build_tree_list (NULL_TREE, src);
10640 arglist = tree_cons (NULL_TREE, dest, arglist);
10642 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10643 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10644 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10645 if (!fn)
10646 return 0;
10648 return build_function_call_expr (fn, arglist);
10651 /* Fold a call to the __strncpy_chk builtin.
10652 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10654 tree
10655 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10657 tree dest, src, size, len, fn;
10659 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10660 INTEGER_TYPE, VOID_TYPE))
10661 return 0;
10663 dest = TREE_VALUE (arglist);
10664 src = TREE_VALUE (TREE_CHAIN (arglist));
10665 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10666 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10668 if (! host_integerp (size, 1))
10669 return 0;
10671 if (! integer_all_onesp (size))
10673 if (! host_integerp (len, 1))
10675 /* If LEN is not constant, try MAXLEN too.
10676 For MAXLEN only allow optimizing into non-_ocs function
10677 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10678 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10679 return 0;
10681 else
10682 maxlen = len;
10684 if (tree_int_cst_lt (size, maxlen))
10685 return 0;
10688 arglist = build_tree_list (NULL_TREE, len);
10689 arglist = tree_cons (NULL_TREE, src, arglist);
10690 arglist = tree_cons (NULL_TREE, dest, arglist);
10692 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10693 fn = built_in_decls[BUILT_IN_STRNCPY];
10694 if (!fn)
10695 return 0;
10697 return build_function_call_expr (fn, arglist);
10700 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10702 static tree
10703 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10705 tree dest, src, size, fn;
10706 const char *p;
10708 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10709 VOID_TYPE))
10710 return 0;
10712 dest = TREE_VALUE (arglist);
10713 src = TREE_VALUE (TREE_CHAIN (arglist));
10714 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10716 p = c_getstr (src);
10717 /* If the SRC parameter is "", return DEST. */
10718 if (p && *p == '\0')
10719 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10721 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10722 return 0;
10724 arglist = build_tree_list (NULL_TREE, src);
10725 arglist = tree_cons (NULL_TREE, dest, arglist);
10727 /* If __builtin_strcat_chk is used, assume strcat is available. */
10728 fn = built_in_decls[BUILT_IN_STRCAT];
10729 if (!fn)
10730 return 0;
10732 return build_function_call_expr (fn, arglist);
10735 /* Fold a call to the __strncat_chk builtin EXP. */
10737 static tree
10738 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10740 tree dest, src, size, len, fn;
10741 const char *p;
10743 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10744 INTEGER_TYPE, VOID_TYPE))
10745 return 0;
10747 dest = TREE_VALUE (arglist);
10748 src = TREE_VALUE (TREE_CHAIN (arglist));
10749 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10750 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10752 p = c_getstr (src);
10753 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10754 if (p && *p == '\0')
10755 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10756 else if (integer_zerop (len))
10757 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10759 if (! host_integerp (size, 1))
10760 return 0;
10762 if (! integer_all_onesp (size))
10764 tree src_len = c_strlen (src, 1);
10765 if (src_len
10766 && host_integerp (src_len, 1)
10767 && host_integerp (len, 1)
10768 && ! tree_int_cst_lt (len, src_len))
10770 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10771 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10772 if (!fn)
10773 return 0;
10775 arglist = build_tree_list (NULL_TREE, size);
10776 arglist = tree_cons (NULL_TREE, src, arglist);
10777 arglist = tree_cons (NULL_TREE, dest, arglist);
10778 return build_function_call_expr (fn, arglist);
10780 return 0;
10783 arglist = build_tree_list (NULL_TREE, len);
10784 arglist = tree_cons (NULL_TREE, src, arglist);
10785 arglist = tree_cons (NULL_TREE, dest, arglist);
10787 /* If __builtin_strncat_chk is used, assume strncat is available. */
10788 fn = built_in_decls[BUILT_IN_STRNCAT];
10789 if (!fn)
10790 return 0;
10792 return build_function_call_expr (fn, arglist);
10795 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10796 a normal call should be emitted rather than expanding the function
10797 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10799 static tree
10800 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10802 tree dest, size, len, fn, fmt, flag;
10803 const char *fmt_str;
10805 /* Verify the required arguments in the original call. */
10806 if (! arglist)
10807 return 0;
10808 dest = TREE_VALUE (arglist);
10809 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10810 return 0;
10811 arglist = TREE_CHAIN (arglist);
10812 if (! arglist)
10813 return 0;
10814 flag = TREE_VALUE (arglist);
10815 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10816 return 0;
10817 arglist = TREE_CHAIN (arglist);
10818 if (! arglist)
10819 return 0;
10820 size = TREE_VALUE (arglist);
10821 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10822 return 0;
10823 arglist = TREE_CHAIN (arglist);
10824 if (! arglist)
10825 return 0;
10826 fmt = TREE_VALUE (arglist);
10827 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10828 return 0;
10829 arglist = TREE_CHAIN (arglist);
10831 if (! host_integerp (size, 1))
10832 return 0;
10834 len = NULL_TREE;
10836 if (!init_target_chars())
10837 return 0;
10839 /* Check whether the format is a literal string constant. */
10840 fmt_str = c_getstr (fmt);
10841 if (fmt_str != NULL)
10843 /* If the format doesn't contain % args or %%, we know the size. */
10844 if (strchr (fmt_str, target_percent) == 0)
10846 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10847 len = build_int_cstu (size_type_node, strlen (fmt_str));
10849 /* If the format is "%s" and first ... argument is a string literal,
10850 we know the size too. */
10851 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10853 tree arg;
10855 if (arglist && !TREE_CHAIN (arglist))
10857 arg = TREE_VALUE (arglist);
10858 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10860 len = c_strlen (arg, 1);
10861 if (! len || ! host_integerp (len, 1))
10862 len = NULL_TREE;
10868 if (! integer_all_onesp (size))
10870 if (! len || ! tree_int_cst_lt (len, size))
10871 return 0;
10874 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10875 or if format doesn't contain % chars or is "%s". */
10876 if (! integer_zerop (flag))
10878 if (fmt_str == NULL)
10879 return 0;
10880 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10881 return 0;
10884 arglist = tree_cons (NULL_TREE, fmt, arglist);
10885 arglist = tree_cons (NULL_TREE, dest, arglist);
10887 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10888 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10889 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10890 if (!fn)
10891 return 0;
10893 return build_function_call_expr (fn, arglist);
10896 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10897 a normal call should be emitted rather than expanding the function
10898 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10899 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10900 passed as second argument. */
10902 tree
10903 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10904 enum built_in_function fcode)
10906 tree dest, size, len, fn, fmt, flag;
10907 const char *fmt_str;
10909 /* Verify the required arguments in the original call. */
10910 if (! arglist)
10911 return 0;
10912 dest = TREE_VALUE (arglist);
10913 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10914 return 0;
10915 arglist = TREE_CHAIN (arglist);
10916 if (! arglist)
10917 return 0;
10918 len = TREE_VALUE (arglist);
10919 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10920 return 0;
10921 arglist = TREE_CHAIN (arglist);
10922 if (! arglist)
10923 return 0;
10924 flag = TREE_VALUE (arglist);
10925 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10926 return 0;
10927 arglist = TREE_CHAIN (arglist);
10928 if (! arglist)
10929 return 0;
10930 size = TREE_VALUE (arglist);
10931 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10932 return 0;
10933 arglist = TREE_CHAIN (arglist);
10934 if (! arglist)
10935 return 0;
10936 fmt = TREE_VALUE (arglist);
10937 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10938 return 0;
10939 arglist = TREE_CHAIN (arglist);
10941 if (! host_integerp (size, 1))
10942 return 0;
10944 if (! integer_all_onesp (size))
10946 if (! host_integerp (len, 1))
10948 /* If LEN is not constant, try MAXLEN too.
10949 For MAXLEN only allow optimizing into non-_ocs function
10950 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10951 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10952 return 0;
10954 else
10955 maxlen = len;
10957 if (tree_int_cst_lt (size, maxlen))
10958 return 0;
10961 if (!init_target_chars())
10962 return 0;
10964 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10965 or if format doesn't contain % chars or is "%s". */
10966 if (! integer_zerop (flag))
10968 fmt_str = c_getstr (fmt);
10969 if (fmt_str == NULL)
10970 return 0;
10971 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10972 return 0;
10975 arglist = tree_cons (NULL_TREE, fmt, arglist);
10976 arglist = tree_cons (NULL_TREE, len, arglist);
10977 arglist = tree_cons (NULL_TREE, dest, arglist);
10979 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10980 available. */
10981 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10982 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10983 if (!fn)
10984 return 0;
10986 return build_function_call_expr (fn, arglist);
10989 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10991 Return 0 if no simplification was possible, otherwise return the
10992 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10993 code of the function to be simplified. */
10995 static tree
10996 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10997 enum built_in_function fcode)
10999 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11000 const char *fmt_str = NULL;
11002 /* If the return value is used, don't do the transformation. */
11003 if (! ignore)
11004 return 0;
11006 /* Verify the required arguments in the original call. */
11007 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11009 tree flag;
11011 if (! arglist)
11012 return 0;
11013 flag = TREE_VALUE (arglist);
11014 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11015 || TREE_SIDE_EFFECTS (flag))
11016 return 0;
11017 arglist = TREE_CHAIN (arglist);
11020 if (! arglist)
11021 return 0;
11022 fmt = TREE_VALUE (arglist);
11023 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11024 return 0;
11025 arglist = TREE_CHAIN (arglist);
11027 /* Check whether the format is a literal string constant. */
11028 fmt_str = c_getstr (fmt);
11029 if (fmt_str == NULL)
11030 return NULL_TREE;
11032 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11034 /* If we're using an unlocked function, assume the other
11035 unlocked functions exist explicitly. */
11036 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11037 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11039 else
11041 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11042 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11045 if (!init_target_chars())
11046 return 0;
11048 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11050 const char *str;
11052 if (strcmp (fmt_str, target_percent_s) == 0)
11054 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11055 return 0;
11057 if (! arglist
11058 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11059 || TREE_CHAIN (arglist))
11060 return 0;
11062 str = c_getstr (TREE_VALUE (arglist));
11063 if (str == NULL)
11064 return 0;
11066 else
11068 /* The format specifier doesn't contain any '%' characters. */
11069 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11070 && arglist)
11071 return 0;
11072 str = fmt_str;
11075 /* If the string was "", printf does nothing. */
11076 if (str[0] == '\0')
11077 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11079 /* If the string has length of 1, call putchar. */
11080 if (str[1] == '\0')
11082 /* Given printf("c"), (where c is any one character,)
11083 convert "c"[0] to an int and pass that to the replacement
11084 function. */
11085 arg = build_int_cst (NULL_TREE, str[0]);
11086 arglist = build_tree_list (NULL_TREE, arg);
11087 fn = fn_putchar;
11089 else
11091 /* If the string was "string\n", call puts("string"). */
11092 size_t len = strlen (str);
11093 if ((unsigned char)str[len - 1] == target_newline)
11095 /* Create a NUL-terminated string that's one char shorter
11096 than the original, stripping off the trailing '\n'. */
11097 char *newstr = alloca (len);
11098 memcpy (newstr, str, len - 1);
11099 newstr[len - 1] = 0;
11101 arg = build_string_literal (len, newstr);
11102 arglist = build_tree_list (NULL_TREE, arg);
11103 fn = fn_puts;
11105 else
11106 /* We'd like to arrange to call fputs(string,stdout) here,
11107 but we need stdout and don't have a way to get it yet. */
11108 return 0;
11112 /* The other optimizations can be done only on the non-va_list variants. */
11113 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11114 return 0;
11116 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11117 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11119 if (! arglist
11120 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11121 || TREE_CHAIN (arglist))
11122 return 0;
11123 fn = fn_puts;
11126 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11127 else if (strcmp (fmt_str, target_percent_c) == 0)
11129 if (! arglist
11130 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11131 || TREE_CHAIN (arglist))
11132 return 0;
11133 fn = fn_putchar;
11136 if (!fn)
11137 return 0;
11139 call = build_function_call_expr (fn, arglist);
11140 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11143 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11145 Return 0 if no simplification was possible, otherwise return the
11146 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11147 code of the function to be simplified. */
11149 static tree
11150 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11151 enum built_in_function fcode)
11153 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11154 const char *fmt_str = NULL;
11156 /* If the return value is used, don't do the transformation. */
11157 if (! ignore)
11158 return 0;
11160 /* Verify the required arguments in the original call. */
11161 if (! arglist)
11162 return 0;
11163 fp = TREE_VALUE (arglist);
11164 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11165 return 0;
11166 arglist = TREE_CHAIN (arglist);
11168 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11170 tree flag;
11172 if (! arglist)
11173 return 0;
11174 flag = TREE_VALUE (arglist);
11175 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11176 || TREE_SIDE_EFFECTS (flag))
11177 return 0;
11178 arglist = TREE_CHAIN (arglist);
11181 if (! arglist)
11182 return 0;
11183 fmt = TREE_VALUE (arglist);
11184 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11185 return 0;
11186 arglist = TREE_CHAIN (arglist);
11188 /* Check whether the format is a literal string constant. */
11189 fmt_str = c_getstr (fmt);
11190 if (fmt_str == NULL)
11191 return NULL_TREE;
11193 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11195 /* If we're using an unlocked function, assume the other
11196 unlocked functions exist explicitly. */
11197 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11198 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11200 else
11202 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11203 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11206 if (!init_target_chars())
11207 return 0;
11209 /* If the format doesn't contain % args or %%, use strcpy. */
11210 if (strchr (fmt_str, target_percent) == NULL)
11212 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11213 && arglist)
11214 return 0;
11216 /* If the format specifier was "", fprintf does nothing. */
11217 if (fmt_str[0] == '\0')
11219 /* If FP has side-effects, just wait until gimplification is
11220 done. */
11221 if (TREE_SIDE_EFFECTS (fp))
11222 return 0;
11224 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11227 /* When "string" doesn't contain %, replace all cases of
11228 fprintf (fp, string) with fputs (string, fp). The fputs
11229 builtin will take care of special cases like length == 1. */
11230 arglist = build_tree_list (NULL_TREE, fp);
11231 arglist = tree_cons (NULL_TREE, fmt, arglist);
11232 fn = fn_fputs;
11235 /* The other optimizations can be done only on the non-va_list variants. */
11236 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11237 return 0;
11239 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11240 else if (strcmp (fmt_str, target_percent_s) == 0)
11242 if (! arglist
11243 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11244 || TREE_CHAIN (arglist))
11245 return 0;
11246 arg = TREE_VALUE (arglist);
11247 arglist = build_tree_list (NULL_TREE, fp);
11248 arglist = tree_cons (NULL_TREE, arg, arglist);
11249 fn = fn_fputs;
11252 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11253 else if (strcmp (fmt_str, target_percent_c) == 0)
11255 if (! arglist
11256 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11257 || TREE_CHAIN (arglist))
11258 return 0;
11259 arg = TREE_VALUE (arglist);
11260 arglist = build_tree_list (NULL_TREE, fp);
11261 arglist = tree_cons (NULL_TREE, arg, arglist);
11262 fn = fn_fputc;
11265 if (!fn)
11266 return 0;
11268 call = build_function_call_expr (fn, arglist);
11269 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11272 /* Initialize format string characters in the target charset. */
11274 static bool
11275 init_target_chars (void)
11277 static bool init;
11278 if (!init)
11280 target_newline = lang_hooks.to_target_charset ('\n');
11281 target_percent = lang_hooks.to_target_charset ('%');
11282 target_c = lang_hooks.to_target_charset ('c');
11283 target_s = lang_hooks.to_target_charset ('s');
11284 if (target_newline == 0 || target_percent == 0 || target_c == 0
11285 || target_s == 0)
11286 return false;
11288 target_percent_c[0] = target_percent;
11289 target_percent_c[1] = target_c;
11290 target_percent_c[2] = '\0';
11292 target_percent_s[0] = target_percent;
11293 target_percent_s[1] = target_s;
11294 target_percent_s[2] = '\0';
11296 target_percent_s_newline[0] = target_percent;
11297 target_percent_s_newline[1] = target_s;
11298 target_percent_s_newline[2] = target_newline;
11299 target_percent_s_newline[3] = '\0';
11301 init = true;
11303 return true;
11306 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11307 FUNC on it and return the resulting value as a tree with type TYPE.
11308 If MIN and/or MAX are not NULL, then the supplied ARG must be
11309 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11310 acceptable values, otherwise they are not. The mpfr precision is
11311 set to the precision of TYPE. We assume that function FUNC returns
11312 zero if the result could be calculated exactly within the requested
11313 precision. */
11315 static tree
11316 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11317 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11318 bool inclusive)
11320 tree result = NULL_TREE;
11322 STRIP_NOPS (arg);
11324 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11326 REAL_VALUE_TYPE r = TREE_REAL_CST (arg);
11328 if (!real_isnan (&r) && !real_isinf (&r)
11329 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , &r, min))
11330 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , &r, max)))
11332 const enum machine_mode mode = TYPE_MODE (type);
11333 const int prec = REAL_MODE_FORMAT (mode)->p;
11334 int inexact;
11335 mpfr_t m;
11337 mpfr_init2 (m, prec);
11338 mpfr_from_real (m, &r);
11339 mpfr_clear_flags();
11340 inexact = func (m, m, GMP_RNDN);
11342 /* Proceed iff we get a normal number, i.e. not NaN or Inf
11343 and no overflow/underflow occurred. If -frounding-math,
11344 proceed iff the result of calling FUNC was exact. */
11345 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11346 && (!flag_rounding_math || !inexact))
11348 real_from_mpfr (&r, m);
11349 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR
11350 value, check for overflow/underflow. If the
11351 REAL_VALUE_TYPE is zero but the mpft_t is not, then
11352 we underflowed in the conversion. */
11353 if (!real_isnan (&r) && !real_isinf (&r)
11354 && (r.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11356 REAL_VALUE_TYPE rmode;
11357 real_convert (&rmode, mode, &r);
11358 /* Proceed iff the specified mode can hold the value. */
11359 if (real_identical (&rmode, &r))
11360 result = build_real (type, rmode);
11363 mpfr_clear (m);
11367 return result;