* config/m68k/m68k.md (bungt_rev): New pattern.
[official-gcc.git] / gcc / builtins.c
blob1f62dcaaf00b346e5aae7605d0c0fd56487ac25e
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_sin (tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_tan (tree);
156 static tree fold_builtin_atan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memory_op (tree, tree, bool, int);
164 static tree fold_builtin_strchr (tree, tree);
165 static tree fold_builtin_memcmp (tree);
166 static tree fold_builtin_strcmp (tree);
167 static tree fold_builtin_strncmp (tree);
168 static tree fold_builtin_signbit (tree, tree);
169 static tree fold_builtin_copysign (tree, tree, tree);
170 static tree fold_builtin_isascii (tree);
171 static tree fold_builtin_toascii (tree);
172 static tree fold_builtin_isdigit (tree);
173 static tree fold_builtin_fabs (tree, tree);
174 static tree fold_builtin_abs (tree, tree);
175 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
176 enum tree_code);
177 static tree fold_builtin_1 (tree, tree, bool);
179 static tree fold_builtin_strpbrk (tree, tree);
180 static tree fold_builtin_strstr (tree, tree);
181 static tree fold_builtin_strrchr (tree, tree);
182 static tree fold_builtin_strcat (tree);
183 static tree fold_builtin_strncat (tree);
184 static tree fold_builtin_strspn (tree);
185 static tree fold_builtin_strcspn (tree);
186 static tree fold_builtin_sprintf (tree, int);
188 static rtx expand_builtin_object_size (tree);
189 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
190 enum built_in_function);
191 static void maybe_emit_chk_warning (tree, enum built_in_function);
192 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
193 static tree fold_builtin_object_size (tree);
194 static tree fold_builtin_strcat_chk (tree, tree);
195 static tree fold_builtin_strncat_chk (tree, tree);
196 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
197 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
198 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
199 static bool init_target_chars (void);
201 static unsigned HOST_WIDE_INT target_newline;
202 static unsigned HOST_WIDE_INT target_percent;
203 static unsigned HOST_WIDE_INT target_c;
204 static unsigned HOST_WIDE_INT target_s;
205 static char target_percent_c[3];
206 static char target_percent_s[3];
207 static char target_percent_s_newline[4];
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 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
237 return 0;
239 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
240 align = MIN (align, max_align);
242 while (1)
244 switch (TREE_CODE (exp))
246 case NOP_EXPR:
247 case CONVERT_EXPR:
248 case NON_LVALUE_EXPR:
249 exp = TREE_OPERAND (exp, 0);
250 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
251 return align;
253 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
254 align = MIN (inner, max_align);
255 break;
257 case PLUS_EXPR:
258 /* If sum of pointer + int, restrict our maximum alignment to that
259 imposed by the integer. If not, we can't do any better than
260 ALIGN. */
261 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
262 return align;
264 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
265 & (max_align / BITS_PER_UNIT - 1))
266 != 0)
267 max_align >>= 1;
269 exp = TREE_OPERAND (exp, 0);
270 break;
272 case ADDR_EXPR:
273 /* See what we are pointing at and look at its alignment. */
274 exp = TREE_OPERAND (exp, 0);
275 inner = max_align;
276 if (handled_component_p (exp))
278 HOST_WIDE_INT bitsize, bitpos;
279 tree offset;
280 enum machine_mode mode;
281 int unsignedp, volatilep;
283 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
284 &mode, &unsignedp, &volatilep, true);
285 if (bitpos)
286 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
287 if (offset && TREE_CODE (offset) == PLUS_EXPR
288 && host_integerp (TREE_OPERAND (offset, 1), 1))
290 /* Any overflow in calculating offset_bits won't change
291 the alignment. */
292 unsigned offset_bits
293 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
294 * BITS_PER_UNIT);
296 if (offset_bits)
297 inner = MIN (inner, (offset_bits & -offset_bits));
298 offset = TREE_OPERAND (offset, 0);
300 if (offset && TREE_CODE (offset) == MULT_EXPR
301 && host_integerp (TREE_OPERAND (offset, 1), 1))
303 /* Any overflow in calculating offset_factor won't change
304 the alignment. */
305 unsigned offset_factor
306 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
307 * BITS_PER_UNIT);
309 if (offset_factor)
310 inner = MIN (inner, (offset_factor & -offset_factor));
312 else if (offset)
313 inner = MIN (inner, BITS_PER_UNIT);
315 if (TREE_CODE (exp) == FUNCTION_DECL)
316 align = FUNCTION_BOUNDARY;
317 else if (DECL_P (exp))
318 align = MIN (inner, DECL_ALIGN (exp));
319 #ifdef CONSTANT_ALIGNMENT
320 else if (CONSTANT_CLASS_P (exp))
321 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
322 #endif
323 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
324 || TREE_CODE (exp) == INDIRECT_REF)
325 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
326 else
327 align = MIN (align, inner);
328 return MIN (align, max_align);
330 default:
331 return align;
336 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
337 way, because it could contain a zero byte in the middle.
338 TREE_STRING_LENGTH is the size of the character array, not the string.
340 ONLY_VALUE should be nonzero if the result is not going to be emitted
341 into the instruction stream and zero if it is going to be expanded.
342 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
343 is returned, otherwise NULL, since
344 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
345 evaluate the side-effects.
347 The value returned is of type `ssizetype'.
349 Unfortunately, string_constant can't access the values of const char
350 arrays with initializers, so neither can we do so here. */
352 tree
353 c_strlen (tree src, int only_value)
355 tree offset_node;
356 HOST_WIDE_INT offset;
357 int max;
358 const char *ptr;
360 STRIP_NOPS (src);
361 if (TREE_CODE (src) == COND_EXPR
362 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
364 tree len1, len2;
366 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
367 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
368 if (tree_int_cst_equal (len1, len2))
369 return len1;
372 if (TREE_CODE (src) == COMPOUND_EXPR
373 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
374 return c_strlen (TREE_OPERAND (src, 1), only_value);
376 src = string_constant (src, &offset_node);
377 if (src == 0)
378 return 0;
380 max = TREE_STRING_LENGTH (src) - 1;
381 ptr = TREE_STRING_POINTER (src);
383 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
385 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
386 compute the offset to the following null if we don't know where to
387 start searching for it. */
388 int i;
390 for (i = 0; i < max; i++)
391 if (ptr[i] == 0)
392 return 0;
394 /* We don't know the starting offset, but we do know that the string
395 has no internal zero bytes. We can assume that the offset falls
396 within the bounds of the string; otherwise, the programmer deserves
397 what he gets. Subtract the offset from the length of the string,
398 and return that. This would perhaps not be valid if we were dealing
399 with named arrays in addition to literal string constants. */
401 return size_diffop (size_int (max), offset_node);
404 /* We have a known offset into the string. Start searching there for
405 a null character if we can represent it as a single HOST_WIDE_INT. */
406 if (offset_node == 0)
407 offset = 0;
408 else if (! host_integerp (offset_node, 0))
409 offset = -1;
410 else
411 offset = tree_low_cst (offset_node, 0);
413 /* If the offset is known to be out of bounds, warn, and call strlen at
414 runtime. */
415 if (offset < 0 || offset > max)
417 warning (0, "offset outside bounds of constant string");
418 return 0;
421 /* Use strlen to search for the first zero byte. Since any strings
422 constructed with build_string will have nulls appended, we win even
423 if we get handed something like (char[4])"abcd".
425 Since OFFSET is our starting index into the string, no further
426 calculation is needed. */
427 return ssize_int (strlen (ptr + offset));
430 /* Return a char pointer for a C string if it is a string constant
431 or sum of string constant and integer constant. */
433 static const char *
434 c_getstr (tree src)
436 tree offset_node;
438 src = string_constant (src, &offset_node);
439 if (src == 0)
440 return 0;
442 if (offset_node == 0)
443 return TREE_STRING_POINTER (src);
444 else if (!host_integerp (offset_node, 1)
445 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
446 return 0;
448 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
451 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
452 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
454 static rtx
455 c_readstr (const char *str, enum machine_mode mode)
457 HOST_WIDE_INT c[2];
458 HOST_WIDE_INT ch;
459 unsigned int i, j;
461 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
463 c[0] = 0;
464 c[1] = 0;
465 ch = 1;
466 for (i = 0; i < GET_MODE_SIZE (mode); i++)
468 j = i;
469 if (WORDS_BIG_ENDIAN)
470 j = GET_MODE_SIZE (mode) - i - 1;
471 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
472 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
473 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
474 j *= BITS_PER_UNIT;
475 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
477 if (ch)
478 ch = (unsigned char) str[i];
479 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
481 return immed_double_const (c[0], c[1], mode);
484 /* Cast a target constant CST to target CHAR and if that value fits into
485 host char type, return zero and put that value into variable pointed to by
486 P. */
488 static int
489 target_char_cast (tree cst, char *p)
491 unsigned HOST_WIDE_INT val, hostval;
493 if (!host_integerp (cst, 1)
494 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
495 return 1;
497 val = tree_low_cst (cst, 1);
498 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
499 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
501 hostval = val;
502 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
503 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
505 if (val != hostval)
506 return 1;
508 *p = hostval;
509 return 0;
512 /* Similar to save_expr, but assumes that arbitrary code is not executed
513 in between the multiple evaluations. In particular, we assume that a
514 non-addressable local variable will not be modified. */
516 static tree
517 builtin_save_expr (tree exp)
519 if (TREE_ADDRESSABLE (exp) == 0
520 && (TREE_CODE (exp) == PARM_DECL
521 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
522 return exp;
524 return save_expr (exp);
527 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
528 times to get the address of either a higher stack frame, or a return
529 address located within it (depending on FNDECL_CODE). */
531 static rtx
532 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
534 int i;
536 #ifdef INITIAL_FRAME_ADDRESS_RTX
537 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
538 #else
539 rtx tem;
541 /* For a zero count with __builtin_return_address, we don't care what
542 frame address we return, because target-specific definitions will
543 override us. Therefore frame pointer elimination is OK, and using
544 the soft frame pointer is OK.
546 For a non-zero count, or a zero count with __builtin_frame_address,
547 we require a stable offset from the current frame pointer to the
548 previous one, so we must use the hard frame pointer, and
549 we must disable frame pointer elimination. */
550 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
551 tem = frame_pointer_rtx;
552 else
554 tem = hard_frame_pointer_rtx;
556 /* Tell reload not to eliminate the frame pointer. */
557 current_function_accesses_prior_frames = 1;
559 #endif
561 /* Some machines need special handling before we can access
562 arbitrary frames. For example, on the sparc, we must first flush
563 all register windows to the stack. */
564 #ifdef SETUP_FRAME_ADDRESSES
565 if (count > 0)
566 SETUP_FRAME_ADDRESSES ();
567 #endif
569 /* On the sparc, the return address is not in the frame, it is in a
570 register. There is no way to access it off of the current frame
571 pointer, but it can be accessed off the previous frame pointer by
572 reading the value from the register window save area. */
573 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
574 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
575 count--;
576 #endif
578 /* Scan back COUNT frames to the specified frame. */
579 for (i = 0; i < count; i++)
581 /* Assume the dynamic chain pointer is in the word that the
582 frame address points to, unless otherwise specified. */
583 #ifdef DYNAMIC_CHAIN_ADDRESS
584 tem = DYNAMIC_CHAIN_ADDRESS (tem);
585 #endif
586 tem = memory_address (Pmode, tem);
587 tem = gen_frame_mem (Pmode, tem);
588 tem = copy_to_reg (tem);
591 /* For __builtin_frame_address, return what we've got. */
592 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
593 return tem;
595 /* For __builtin_return_address, Get the return address from that
596 frame. */
597 #ifdef RETURN_ADDR_RTX
598 tem = RETURN_ADDR_RTX (count, tem);
599 #else
600 tem = memory_address (Pmode,
601 plus_constant (tem, GET_MODE_SIZE (Pmode)));
602 tem = gen_frame_mem (Pmode, tem);
603 #endif
604 return tem;
607 /* Alias set used for setjmp buffer. */
608 static HOST_WIDE_INT setjmp_alias_set = -1;
610 /* Construct the leading half of a __builtin_setjmp call. Control will
611 return to RECEIVER_LABEL. This is used directly by sjlj exception
612 handling code. */
614 void
615 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
617 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
618 rtx stack_save;
619 rtx mem;
621 if (setjmp_alias_set == -1)
622 setjmp_alias_set = new_alias_set ();
624 buf_addr = convert_memory_address (Pmode, buf_addr);
626 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
628 /* We store the frame pointer and the address of receiver_label in
629 the buffer and use the rest of it for the stack save area, which
630 is machine-dependent. */
632 mem = gen_rtx_MEM (Pmode, buf_addr);
633 set_mem_alias_set (mem, setjmp_alias_set);
634 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
636 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
637 set_mem_alias_set (mem, setjmp_alias_set);
639 emit_move_insn (validize_mem (mem),
640 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
642 stack_save = gen_rtx_MEM (sa_mode,
643 plus_constant (buf_addr,
644 2 * GET_MODE_SIZE (Pmode)));
645 set_mem_alias_set (stack_save, setjmp_alias_set);
646 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
648 /* If there is further processing to do, do it. */
649 #ifdef HAVE_builtin_setjmp_setup
650 if (HAVE_builtin_setjmp_setup)
651 emit_insn (gen_builtin_setjmp_setup (buf_addr));
652 #endif
654 /* Tell optimize_save_area_alloca that extra work is going to
655 need to go on during alloca. */
656 current_function_calls_setjmp = 1;
658 /* Set this so all the registers get saved in our frame; we need to be
659 able to copy the saved values for any registers from frames we unwind. */
660 current_function_has_nonlocal_label = 1;
663 /* Construct the trailing part of a __builtin_setjmp call.
664 This is used directly by sjlj exception handling code. */
666 void
667 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
669 /* Clobber the FP when we get here, so we have to make sure it's
670 marked as used by this function. */
671 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
673 /* Mark the static chain as clobbered here so life information
674 doesn't get messed up for it. */
675 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
677 /* Now put in the code to restore the frame pointer, and argument
678 pointer, if needed. */
679 #ifdef HAVE_nonlocal_goto
680 if (! HAVE_nonlocal_goto)
681 #endif
682 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
684 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
685 if (fixed_regs[ARG_POINTER_REGNUM])
687 #ifdef ELIMINABLE_REGS
688 size_t i;
689 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
691 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
692 if (elim_regs[i].from == ARG_POINTER_REGNUM
693 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
694 break;
696 if (i == ARRAY_SIZE (elim_regs))
697 #endif
699 /* Now restore our arg pointer from the address at which it
700 was saved in our stack frame. */
701 emit_move_insn (virtual_incoming_args_rtx,
702 copy_to_reg (get_arg_pointer_save_area (cfun)));
705 #endif
707 #ifdef HAVE_builtin_setjmp_receiver
708 if (HAVE_builtin_setjmp_receiver)
709 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
710 else
711 #endif
712 #ifdef HAVE_nonlocal_goto_receiver
713 if (HAVE_nonlocal_goto_receiver)
714 emit_insn (gen_nonlocal_goto_receiver ());
715 else
716 #endif
717 { /* Nothing */ }
719 /* @@@ This is a kludge. Not all machine descriptions define a blockage
720 insn, but we must not allow the code we just generated to be reordered
721 by scheduling. Specifically, the update of the frame pointer must
722 happen immediately, not later. So emit an ASM_INPUT to act as blockage
723 insn. */
724 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
727 /* __builtin_setjmp is passed a pointer to an array of five words (not
728 all will be used on all machines). It operates similarly to the C
729 library function of the same name, but is more efficient. Much of
730 the code below (and for longjmp) is copied from the handling of
731 non-local gotos.
733 NOTE: This is intended for use by GNAT and the exception handling
734 scheme in the compiler and will only work in the method used by
735 them. */
737 static rtx
738 expand_builtin_setjmp (tree arglist, rtx target)
740 rtx buf_addr, next_lab, cont_lab;
742 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
743 return NULL_RTX;
745 if (target == 0 || !REG_P (target)
746 || REGNO (target) < FIRST_PSEUDO_REGISTER)
747 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
749 buf_addr = expand_normal (TREE_VALUE (arglist));
751 next_lab = gen_label_rtx ();
752 cont_lab = gen_label_rtx ();
754 expand_builtin_setjmp_setup (buf_addr, next_lab);
756 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
757 ensure that pending stack adjustments are flushed. */
758 emit_move_insn (target, const0_rtx);
759 emit_jump (cont_lab);
761 emit_label (next_lab);
763 expand_builtin_setjmp_receiver (next_lab);
765 /* Set TARGET to one. */
766 emit_move_insn (target, const1_rtx);
767 emit_label (cont_lab);
769 /* Tell flow about the strange goings on. Putting `next_lab' on
770 `nonlocal_goto_handler_labels' to indicates that function
771 calls may traverse the arc back to this label. */
773 current_function_has_nonlocal_label = 1;
774 nonlocal_goto_handler_labels
775 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
777 return target;
780 /* __builtin_longjmp is passed a pointer to an array of five words (not
781 all will be used on all machines). It operates similarly to the C
782 library function of the same name, but is more efficient. Much of
783 the code below is copied from the handling of non-local gotos.
785 NOTE: This is intended for use by GNAT and the exception handling
786 scheme in the compiler and will only work in the method used by
787 them. */
789 static void
790 expand_builtin_longjmp (rtx buf_addr, rtx value)
792 rtx fp, lab, stack, insn, last;
793 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
795 if (setjmp_alias_set == -1)
796 setjmp_alias_set = new_alias_set ();
798 buf_addr = convert_memory_address (Pmode, buf_addr);
800 buf_addr = force_reg (Pmode, buf_addr);
802 /* We used to store value in static_chain_rtx, but that fails if pointers
803 are smaller than integers. We instead require that the user must pass
804 a second argument of 1, because that is what builtin_setjmp will
805 return. This also makes EH slightly more efficient, since we are no
806 longer copying around a value that we don't care about. */
807 gcc_assert (value == const1_rtx);
809 last = get_last_insn ();
810 #ifdef HAVE_builtin_longjmp
811 if (HAVE_builtin_longjmp)
812 emit_insn (gen_builtin_longjmp (buf_addr));
813 else
814 #endif
816 fp = gen_rtx_MEM (Pmode, buf_addr);
817 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
818 GET_MODE_SIZE (Pmode)));
820 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
821 2 * GET_MODE_SIZE (Pmode)));
822 set_mem_alias_set (fp, setjmp_alias_set);
823 set_mem_alias_set (lab, setjmp_alias_set);
824 set_mem_alias_set (stack, setjmp_alias_set);
826 /* Pick up FP, label, and SP from the block and jump. This code is
827 from expand_goto in stmt.c; see there for detailed comments. */
828 #ifdef HAVE_nonlocal_goto
829 if (HAVE_nonlocal_goto)
830 /* We have to pass a value to the nonlocal_goto pattern that will
831 get copied into the static_chain pointer, but it does not matter
832 what that value is, because builtin_setjmp does not use it. */
833 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
834 else
835 #endif
837 lab = copy_to_reg (lab);
839 emit_insn (gen_rtx_CLOBBER (VOIDmode,
840 gen_rtx_MEM (BLKmode,
841 gen_rtx_SCRATCH (VOIDmode))));
842 emit_insn (gen_rtx_CLOBBER (VOIDmode,
843 gen_rtx_MEM (BLKmode,
844 hard_frame_pointer_rtx)));
846 emit_move_insn (hard_frame_pointer_rtx, fp);
847 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
849 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
850 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
851 emit_indirect_jump (lab);
855 /* Search backwards and mark the jump insn as a non-local goto.
856 Note that this precludes the use of __builtin_longjmp to a
857 __builtin_setjmp target in the same function. However, we've
858 already cautioned the user that these functions are for
859 internal exception handling use only. */
860 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
862 gcc_assert (insn != last);
864 if (JUMP_P (insn))
866 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
867 REG_NOTES (insn));
868 break;
870 else if (CALL_P (insn))
871 break;
875 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
876 and the address of the save area. */
878 static rtx
879 expand_builtin_nonlocal_goto (tree arglist)
881 tree t_label, t_save_area;
882 rtx r_label, r_save_area, r_fp, r_sp, insn;
884 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
885 return NULL_RTX;
887 t_label = TREE_VALUE (arglist);
888 arglist = TREE_CHAIN (arglist);
889 t_save_area = TREE_VALUE (arglist);
891 r_label = expand_normal (t_label);
892 r_label = convert_memory_address (Pmode, r_label);
893 r_save_area = expand_normal (t_save_area);
894 r_save_area = convert_memory_address (Pmode, r_save_area);
895 r_fp = gen_rtx_MEM (Pmode, r_save_area);
896 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
897 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
899 current_function_has_nonlocal_goto = 1;
901 #ifdef HAVE_nonlocal_goto
902 /* ??? We no longer need to pass the static chain value, afaik. */
903 if (HAVE_nonlocal_goto)
904 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
905 else
906 #endif
908 r_label = copy_to_reg (r_label);
910 emit_insn (gen_rtx_CLOBBER (VOIDmode,
911 gen_rtx_MEM (BLKmode,
912 gen_rtx_SCRATCH (VOIDmode))));
914 emit_insn (gen_rtx_CLOBBER (VOIDmode,
915 gen_rtx_MEM (BLKmode,
916 hard_frame_pointer_rtx)));
918 /* Restore frame pointer for containing function.
919 This sets the actual hard register used for the frame pointer
920 to the location of the function's incoming static chain info.
921 The non-local goto handler will then adjust it to contain the
922 proper value and reload the argument pointer, if needed. */
923 emit_move_insn (hard_frame_pointer_rtx, r_fp);
924 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
926 /* USE of hard_frame_pointer_rtx added for consistency;
927 not clear if really needed. */
928 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
929 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
930 emit_indirect_jump (r_label);
933 /* Search backwards to the jump insn and mark it as a
934 non-local goto. */
935 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
937 if (JUMP_P (insn))
939 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
940 const0_rtx, REG_NOTES (insn));
941 break;
943 else if (CALL_P (insn))
944 break;
947 return const0_rtx;
950 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
951 (not all will be used on all machines) that was passed to __builtin_setjmp.
952 It updates the stack pointer in that block to correspond to the current
953 stack pointer. */
955 static void
956 expand_builtin_update_setjmp_buf (rtx buf_addr)
958 enum machine_mode sa_mode = Pmode;
959 rtx stack_save;
962 #ifdef HAVE_save_stack_nonlocal
963 if (HAVE_save_stack_nonlocal)
964 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
965 #endif
966 #ifdef STACK_SAVEAREA_MODE
967 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
968 #endif
970 stack_save
971 = gen_rtx_MEM (sa_mode,
972 memory_address
973 (sa_mode,
974 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
976 #ifdef HAVE_setjmp
977 if (HAVE_setjmp)
978 emit_insn (gen_setjmp ());
979 #endif
981 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
984 /* Expand a call to __builtin_prefetch. For a target that does not support
985 data prefetch, evaluate the memory address argument in case it has side
986 effects. */
988 static void
989 expand_builtin_prefetch (tree arglist)
991 tree arg0, arg1, arg2;
992 rtx op0, op1, op2;
994 if (!validate_arglist (arglist, POINTER_TYPE, 0))
995 return;
997 arg0 = TREE_VALUE (arglist);
998 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
999 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1000 locality). */
1001 if (TREE_CHAIN (arglist))
1003 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1004 if (TREE_CHAIN (TREE_CHAIN (arglist)))
1005 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1006 else
1007 arg2 = build_int_cst (NULL_TREE, 3);
1009 else
1011 arg1 = integer_zero_node;
1012 arg2 = build_int_cst (NULL_TREE, 3);
1015 /* Argument 0 is an address. */
1016 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1018 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1019 if (TREE_CODE (arg1) != INTEGER_CST)
1021 error ("second argument to %<__builtin_prefetch%> must be a constant");
1022 arg1 = integer_zero_node;
1024 op1 = expand_normal (arg1);
1025 /* Argument 1 must be either zero or one. */
1026 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1028 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1029 " using zero");
1030 op1 = const0_rtx;
1033 /* Argument 2 (locality) must be a compile-time constant int. */
1034 if (TREE_CODE (arg2) != INTEGER_CST)
1036 error ("third argument to %<__builtin_prefetch%> must be a constant");
1037 arg2 = integer_zero_node;
1039 op2 = expand_normal (arg2);
1040 /* Argument 2 must be 0, 1, 2, or 3. */
1041 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1043 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1044 op2 = const0_rtx;
1047 #ifdef HAVE_prefetch
1048 if (HAVE_prefetch)
1050 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1051 (op0,
1052 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1053 || (GET_MODE (op0) != Pmode))
1055 op0 = convert_memory_address (Pmode, op0);
1056 op0 = force_reg (Pmode, op0);
1058 emit_insn (gen_prefetch (op0, op1, op2));
1060 #endif
1062 /* Don't do anything with direct references to volatile memory, but
1063 generate code to handle other side effects. */
1064 if (!MEM_P (op0) && side_effects_p (op0))
1065 emit_insn (op0);
1068 /* Get a MEM rtx for expression EXP which is the address of an operand
1069 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1070 the maximum length of the block of memory that might be accessed or
1071 NULL if unknown. */
1073 static rtx
1074 get_memory_rtx (tree exp, tree len)
1076 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1077 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1079 /* Get an expression we can use to find the attributes to assign to MEM.
1080 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1081 we can. First remove any nops. */
1082 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1083 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1084 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1085 exp = TREE_OPERAND (exp, 0);
1087 if (TREE_CODE (exp) == ADDR_EXPR)
1088 exp = TREE_OPERAND (exp, 0);
1089 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1090 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1091 else
1092 exp = NULL;
1094 /* Honor attributes derived from exp, except for the alias set
1095 (as builtin stringops may alias with anything) and the size
1096 (as stringops may access multiple array elements). */
1097 if (exp)
1099 set_mem_attributes (mem, exp, 0);
1101 /* Allow the string and memory builtins to overflow from one
1102 field into another, see http://gcc.gnu.org/PR23561.
1103 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1104 memory accessed by the string or memory builtin will fit
1105 within the field. */
1106 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1108 tree mem_expr = MEM_EXPR (mem);
1109 HOST_WIDE_INT offset = -1, length = -1;
1110 tree inner = exp;
1112 while (TREE_CODE (inner) == ARRAY_REF
1113 || TREE_CODE (inner) == NOP_EXPR
1114 || TREE_CODE (inner) == CONVERT_EXPR
1115 || TREE_CODE (inner) == NON_LVALUE_EXPR
1116 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1117 || TREE_CODE (inner) == SAVE_EXPR)
1118 inner = TREE_OPERAND (inner, 0);
1120 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1122 if (MEM_OFFSET (mem)
1123 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1124 offset = INTVAL (MEM_OFFSET (mem));
1126 if (offset >= 0 && len && host_integerp (len, 0))
1127 length = tree_low_cst (len, 0);
1129 while (TREE_CODE (inner) == COMPONENT_REF)
1131 tree field = TREE_OPERAND (inner, 1);
1132 gcc_assert (! DECL_BIT_FIELD (field));
1133 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1134 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1136 if (length >= 0
1137 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1138 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1140 HOST_WIDE_INT size
1141 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1142 /* If we can prove the memory starting at XEXP (mem, 0)
1143 and ending at XEXP (mem, 0) + LENGTH will fit into
1144 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1145 if (offset <= size
1146 && length <= size
1147 && offset + length <= size)
1148 break;
1151 if (offset >= 0
1152 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1153 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1154 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1155 / BITS_PER_UNIT;
1156 else
1158 offset = -1;
1159 length = -1;
1162 mem_expr = TREE_OPERAND (mem_expr, 0);
1163 inner = TREE_OPERAND (inner, 0);
1166 if (mem_expr == NULL)
1167 offset = -1;
1168 if (mem_expr != MEM_EXPR (mem))
1170 set_mem_expr (mem, mem_expr);
1171 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1174 set_mem_alias_set (mem, 0);
1175 set_mem_size (mem, NULL_RTX);
1178 return mem;
1181 /* Built-in functions to perform an untyped call and return. */
1183 /* For each register that may be used for calling a function, this
1184 gives a mode used to copy the register's value. VOIDmode indicates
1185 the register is not used for calling a function. If the machine
1186 has register windows, this gives only the outbound registers.
1187 INCOMING_REGNO gives the corresponding inbound register. */
1188 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1190 /* For each register that may be used for returning values, this gives
1191 a mode used to copy the register's value. VOIDmode indicates the
1192 register is not used for returning values. If the machine has
1193 register windows, this gives only the outbound registers.
1194 INCOMING_REGNO gives the corresponding inbound register. */
1195 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1197 /* For each register that may be used for calling a function, this
1198 gives the offset of that register into the block returned by
1199 __builtin_apply_args. 0 indicates that the register is not
1200 used for calling a function. */
1201 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1203 /* Return the size required for the block returned by __builtin_apply_args,
1204 and initialize apply_args_mode. */
1206 static int
1207 apply_args_size (void)
1209 static int size = -1;
1210 int align;
1211 unsigned int regno;
1212 enum machine_mode mode;
1214 /* The values computed by this function never change. */
1215 if (size < 0)
1217 /* The first value is the incoming arg-pointer. */
1218 size = GET_MODE_SIZE (Pmode);
1220 /* The second value is the structure value address unless this is
1221 passed as an "invisible" first argument. */
1222 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1223 size += GET_MODE_SIZE (Pmode);
1225 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1226 if (FUNCTION_ARG_REGNO_P (regno))
1228 mode = reg_raw_mode[regno];
1230 gcc_assert (mode != VOIDmode);
1232 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1233 if (size % align != 0)
1234 size = CEIL (size, align) * align;
1235 apply_args_reg_offset[regno] = size;
1236 size += GET_MODE_SIZE (mode);
1237 apply_args_mode[regno] = mode;
1239 else
1241 apply_args_mode[regno] = VOIDmode;
1242 apply_args_reg_offset[regno] = 0;
1245 return size;
1248 /* Return the size required for the block returned by __builtin_apply,
1249 and initialize apply_result_mode. */
1251 static int
1252 apply_result_size (void)
1254 static int size = -1;
1255 int align, regno;
1256 enum machine_mode mode;
1258 /* The values computed by this function never change. */
1259 if (size < 0)
1261 size = 0;
1263 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1264 if (FUNCTION_VALUE_REGNO_P (regno))
1266 mode = reg_raw_mode[regno];
1268 gcc_assert (mode != VOIDmode);
1270 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1271 if (size % align != 0)
1272 size = CEIL (size, align) * align;
1273 size += GET_MODE_SIZE (mode);
1274 apply_result_mode[regno] = mode;
1276 else
1277 apply_result_mode[regno] = VOIDmode;
1279 /* Allow targets that use untyped_call and untyped_return to override
1280 the size so that machine-specific information can be stored here. */
1281 #ifdef APPLY_RESULT_SIZE
1282 size = APPLY_RESULT_SIZE;
1283 #endif
1285 return size;
1288 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1289 /* Create a vector describing the result block RESULT. If SAVEP is true,
1290 the result block is used to save the values; otherwise it is used to
1291 restore the values. */
1293 static rtx
1294 result_vector (int savep, rtx result)
1296 int regno, size, align, nelts;
1297 enum machine_mode mode;
1298 rtx reg, mem;
1299 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1301 size = nelts = 0;
1302 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1303 if ((mode = apply_result_mode[regno]) != VOIDmode)
1305 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1306 if (size % align != 0)
1307 size = CEIL (size, align) * align;
1308 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1309 mem = adjust_address (result, mode, size);
1310 savevec[nelts++] = (savep
1311 ? gen_rtx_SET (VOIDmode, mem, reg)
1312 : gen_rtx_SET (VOIDmode, reg, mem));
1313 size += GET_MODE_SIZE (mode);
1315 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1317 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1319 /* Save the state required to perform an untyped call with the same
1320 arguments as were passed to the current function. */
1322 static rtx
1323 expand_builtin_apply_args_1 (void)
1325 rtx registers, tem;
1326 int size, align, regno;
1327 enum machine_mode mode;
1328 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1330 /* Create a block where the arg-pointer, structure value address,
1331 and argument registers can be saved. */
1332 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1334 /* Walk past the arg-pointer and structure value address. */
1335 size = GET_MODE_SIZE (Pmode);
1336 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1337 size += GET_MODE_SIZE (Pmode);
1339 /* Save each register used in calling a function to the block. */
1340 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1341 if ((mode = apply_args_mode[regno]) != VOIDmode)
1343 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1344 if (size % align != 0)
1345 size = CEIL (size, align) * align;
1347 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1349 emit_move_insn (adjust_address (registers, mode, size), tem);
1350 size += GET_MODE_SIZE (mode);
1353 /* Save the arg pointer to the block. */
1354 tem = copy_to_reg (virtual_incoming_args_rtx);
1355 #ifdef STACK_GROWS_DOWNWARD
1356 /* We need the pointer as the caller actually passed them to us, not
1357 as we might have pretended they were passed. Make sure it's a valid
1358 operand, as emit_move_insn isn't expected to handle a PLUS. */
1360 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1361 NULL_RTX);
1362 #endif
1363 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1365 size = GET_MODE_SIZE (Pmode);
1367 /* Save the structure value address unless this is passed as an
1368 "invisible" first argument. */
1369 if (struct_incoming_value)
1371 emit_move_insn (adjust_address (registers, Pmode, size),
1372 copy_to_reg (struct_incoming_value));
1373 size += GET_MODE_SIZE (Pmode);
1376 /* Return the address of the block. */
1377 return copy_addr_to_reg (XEXP (registers, 0));
1380 /* __builtin_apply_args returns block of memory allocated on
1381 the stack into which is stored the arg pointer, structure
1382 value address, static chain, and all the registers that might
1383 possibly be used in performing a function call. The code is
1384 moved to the start of the function so the incoming values are
1385 saved. */
1387 static rtx
1388 expand_builtin_apply_args (void)
1390 /* Don't do __builtin_apply_args more than once in a function.
1391 Save the result of the first call and reuse it. */
1392 if (apply_args_value != 0)
1393 return apply_args_value;
1395 /* When this function is called, it means that registers must be
1396 saved on entry to this function. So we migrate the
1397 call to the first insn of this function. */
1398 rtx temp;
1399 rtx seq;
1401 start_sequence ();
1402 temp = expand_builtin_apply_args_1 ();
1403 seq = get_insns ();
1404 end_sequence ();
1406 apply_args_value = temp;
1408 /* Put the insns after the NOTE that starts the function.
1409 If this is inside a start_sequence, make the outer-level insn
1410 chain current, so the code is placed at the start of the
1411 function. */
1412 push_topmost_sequence ();
1413 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1414 pop_topmost_sequence ();
1415 return temp;
1419 /* Perform an untyped call and save the state required to perform an
1420 untyped return of whatever value was returned by the given function. */
1422 static rtx
1423 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1425 int size, align, regno;
1426 enum machine_mode mode;
1427 rtx incoming_args, result, reg, dest, src, call_insn;
1428 rtx old_stack_level = 0;
1429 rtx call_fusage = 0;
1430 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1432 arguments = convert_memory_address (Pmode, arguments);
1434 /* Create a block where the return registers can be saved. */
1435 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1437 /* Fetch the arg pointer from the ARGUMENTS block. */
1438 incoming_args = gen_reg_rtx (Pmode);
1439 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1440 #ifndef STACK_GROWS_DOWNWARD
1441 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1442 incoming_args, 0, OPTAB_LIB_WIDEN);
1443 #endif
1445 /* Push a new argument block and copy the arguments. Do not allow
1446 the (potential) memcpy call below to interfere with our stack
1447 manipulations. */
1448 do_pending_stack_adjust ();
1449 NO_DEFER_POP;
1451 /* Save the stack with nonlocal if available. */
1452 #ifdef HAVE_save_stack_nonlocal
1453 if (HAVE_save_stack_nonlocal)
1454 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1455 else
1456 #endif
1457 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1459 /* Allocate a block of memory onto the stack and copy the memory
1460 arguments to the outgoing arguments address. */
1461 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1462 dest = virtual_outgoing_args_rtx;
1463 #ifndef STACK_GROWS_DOWNWARD
1464 if (GET_CODE (argsize) == CONST_INT)
1465 dest = plus_constant (dest, -INTVAL (argsize));
1466 else
1467 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1468 #endif
1469 dest = gen_rtx_MEM (BLKmode, dest);
1470 set_mem_align (dest, PARM_BOUNDARY);
1471 src = gen_rtx_MEM (BLKmode, incoming_args);
1472 set_mem_align (src, PARM_BOUNDARY);
1473 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1475 /* Refer to the argument block. */
1476 apply_args_size ();
1477 arguments = gen_rtx_MEM (BLKmode, arguments);
1478 set_mem_align (arguments, PARM_BOUNDARY);
1480 /* Walk past the arg-pointer and structure value address. */
1481 size = GET_MODE_SIZE (Pmode);
1482 if (struct_value)
1483 size += GET_MODE_SIZE (Pmode);
1485 /* Restore each of the registers previously saved. Make USE insns
1486 for each of these registers for use in making the call. */
1487 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1488 if ((mode = apply_args_mode[regno]) != VOIDmode)
1490 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1491 if (size % align != 0)
1492 size = CEIL (size, align) * align;
1493 reg = gen_rtx_REG (mode, regno);
1494 emit_move_insn (reg, adjust_address (arguments, mode, size));
1495 use_reg (&call_fusage, reg);
1496 size += GET_MODE_SIZE (mode);
1499 /* Restore the structure value address unless this is passed as an
1500 "invisible" first argument. */
1501 size = GET_MODE_SIZE (Pmode);
1502 if (struct_value)
1504 rtx value = gen_reg_rtx (Pmode);
1505 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1506 emit_move_insn (struct_value, value);
1507 if (REG_P (struct_value))
1508 use_reg (&call_fusage, struct_value);
1509 size += GET_MODE_SIZE (Pmode);
1512 /* All arguments and registers used for the call are set up by now! */
1513 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1515 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1516 and we don't want to load it into a register as an optimization,
1517 because prepare_call_address already did it if it should be done. */
1518 if (GET_CODE (function) != SYMBOL_REF)
1519 function = memory_address (FUNCTION_MODE, function);
1521 /* Generate the actual call instruction and save the return value. */
1522 #ifdef HAVE_untyped_call
1523 if (HAVE_untyped_call)
1524 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1525 result, result_vector (1, result)));
1526 else
1527 #endif
1528 #ifdef HAVE_call_value
1529 if (HAVE_call_value)
1531 rtx valreg = 0;
1533 /* Locate the unique return register. It is not possible to
1534 express a call that sets more than one return register using
1535 call_value; use untyped_call for that. In fact, untyped_call
1536 only needs to save the return registers in the given block. */
1537 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1538 if ((mode = apply_result_mode[regno]) != VOIDmode)
1540 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1542 valreg = gen_rtx_REG (mode, regno);
1545 emit_call_insn (GEN_CALL_VALUE (valreg,
1546 gen_rtx_MEM (FUNCTION_MODE, function),
1547 const0_rtx, NULL_RTX, const0_rtx));
1549 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1551 else
1552 #endif
1553 gcc_unreachable ();
1555 /* Find the CALL insn we just emitted, and attach the register usage
1556 information. */
1557 call_insn = last_call_insn ();
1558 add_function_usage_to (call_insn, call_fusage);
1560 /* Restore the stack. */
1561 #ifdef HAVE_save_stack_nonlocal
1562 if (HAVE_save_stack_nonlocal)
1563 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1564 else
1565 #endif
1566 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1568 OK_DEFER_POP;
1570 /* Return the address of the result block. */
1571 result = copy_addr_to_reg (XEXP (result, 0));
1572 return convert_memory_address (ptr_mode, result);
1575 /* Perform an untyped return. */
1577 static void
1578 expand_builtin_return (rtx result)
1580 int size, align, regno;
1581 enum machine_mode mode;
1582 rtx reg;
1583 rtx call_fusage = 0;
1585 result = convert_memory_address (Pmode, result);
1587 apply_result_size ();
1588 result = gen_rtx_MEM (BLKmode, result);
1590 #ifdef HAVE_untyped_return
1591 if (HAVE_untyped_return)
1593 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1594 emit_barrier ();
1595 return;
1597 #endif
1599 /* Restore the return value and note that each value is used. */
1600 size = 0;
1601 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1602 if ((mode = apply_result_mode[regno]) != VOIDmode)
1604 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1605 if (size % align != 0)
1606 size = CEIL (size, align) * align;
1607 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1608 emit_move_insn (reg, adjust_address (result, mode, size));
1610 push_to_sequence (call_fusage);
1611 emit_insn (gen_rtx_USE (VOIDmode, reg));
1612 call_fusage = get_insns ();
1613 end_sequence ();
1614 size += GET_MODE_SIZE (mode);
1617 /* Put the USE insns before the return. */
1618 emit_insn (call_fusage);
1620 /* Return whatever values was restored by jumping directly to the end
1621 of the function. */
1622 expand_naked_return ();
1625 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1627 static enum type_class
1628 type_to_class (tree type)
1630 switch (TREE_CODE (type))
1632 case VOID_TYPE: return void_type_class;
1633 case INTEGER_TYPE: return integer_type_class;
1634 case ENUMERAL_TYPE: return enumeral_type_class;
1635 case BOOLEAN_TYPE: return boolean_type_class;
1636 case POINTER_TYPE: return pointer_type_class;
1637 case REFERENCE_TYPE: return reference_type_class;
1638 case OFFSET_TYPE: return offset_type_class;
1639 case REAL_TYPE: return real_type_class;
1640 case COMPLEX_TYPE: return complex_type_class;
1641 case FUNCTION_TYPE: return function_type_class;
1642 case METHOD_TYPE: return method_type_class;
1643 case RECORD_TYPE: return record_type_class;
1644 case UNION_TYPE:
1645 case QUAL_UNION_TYPE: return union_type_class;
1646 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1647 ? string_type_class : array_type_class);
1648 case LANG_TYPE: return lang_type_class;
1649 default: return no_type_class;
1653 /* Expand a call to __builtin_classify_type with arguments found in
1654 ARGLIST. */
1656 static rtx
1657 expand_builtin_classify_type (tree arglist)
1659 if (arglist != 0)
1660 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1661 return GEN_INT (no_type_class);
1664 /* This helper macro, meant to be used in mathfn_built_in below,
1665 determines which among a set of three builtin math functions is
1666 appropriate for a given type mode. The `F' and `L' cases are
1667 automatically generated from the `double' case. */
1668 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1669 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1670 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1671 fcodel = BUILT_IN_MATHFN##L ; break;
1673 /* Return mathematic function equivalent to FN but operating directly
1674 on TYPE, if available. If we can't do the conversion, return zero. */
1675 tree
1676 mathfn_built_in (tree type, enum built_in_function fn)
1678 enum built_in_function fcode, fcodef, fcodel;
1680 switch (fn)
1682 CASE_MATHFN (BUILT_IN_ACOS)
1683 CASE_MATHFN (BUILT_IN_ACOSH)
1684 CASE_MATHFN (BUILT_IN_ASIN)
1685 CASE_MATHFN (BUILT_IN_ASINH)
1686 CASE_MATHFN (BUILT_IN_ATAN)
1687 CASE_MATHFN (BUILT_IN_ATAN2)
1688 CASE_MATHFN (BUILT_IN_ATANH)
1689 CASE_MATHFN (BUILT_IN_CBRT)
1690 CASE_MATHFN (BUILT_IN_CEIL)
1691 CASE_MATHFN (BUILT_IN_COPYSIGN)
1692 CASE_MATHFN (BUILT_IN_COS)
1693 CASE_MATHFN (BUILT_IN_COSH)
1694 CASE_MATHFN (BUILT_IN_DREM)
1695 CASE_MATHFN (BUILT_IN_ERF)
1696 CASE_MATHFN (BUILT_IN_ERFC)
1697 CASE_MATHFN (BUILT_IN_EXP)
1698 CASE_MATHFN (BUILT_IN_EXP10)
1699 CASE_MATHFN (BUILT_IN_EXP2)
1700 CASE_MATHFN (BUILT_IN_EXPM1)
1701 CASE_MATHFN (BUILT_IN_FABS)
1702 CASE_MATHFN (BUILT_IN_FDIM)
1703 CASE_MATHFN (BUILT_IN_FLOOR)
1704 CASE_MATHFN (BUILT_IN_FMA)
1705 CASE_MATHFN (BUILT_IN_FMAX)
1706 CASE_MATHFN (BUILT_IN_FMIN)
1707 CASE_MATHFN (BUILT_IN_FMOD)
1708 CASE_MATHFN (BUILT_IN_FREXP)
1709 CASE_MATHFN (BUILT_IN_GAMMA)
1710 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1711 CASE_MATHFN (BUILT_IN_HYPOT)
1712 CASE_MATHFN (BUILT_IN_ILOGB)
1713 CASE_MATHFN (BUILT_IN_INF)
1714 CASE_MATHFN (BUILT_IN_J0)
1715 CASE_MATHFN (BUILT_IN_J1)
1716 CASE_MATHFN (BUILT_IN_JN)
1717 CASE_MATHFN (BUILT_IN_LCEIL)
1718 CASE_MATHFN (BUILT_IN_LDEXP)
1719 CASE_MATHFN (BUILT_IN_LFLOOR)
1720 CASE_MATHFN (BUILT_IN_LGAMMA)
1721 CASE_MATHFN (BUILT_IN_LLCEIL)
1722 CASE_MATHFN (BUILT_IN_LLFLOOR)
1723 CASE_MATHFN (BUILT_IN_LLRINT)
1724 CASE_MATHFN (BUILT_IN_LLROUND)
1725 CASE_MATHFN (BUILT_IN_LOG)
1726 CASE_MATHFN (BUILT_IN_LOG10)
1727 CASE_MATHFN (BUILT_IN_LOG1P)
1728 CASE_MATHFN (BUILT_IN_LOG2)
1729 CASE_MATHFN (BUILT_IN_LOGB)
1730 CASE_MATHFN (BUILT_IN_LRINT)
1731 CASE_MATHFN (BUILT_IN_LROUND)
1732 CASE_MATHFN (BUILT_IN_MODF)
1733 CASE_MATHFN (BUILT_IN_NAN)
1734 CASE_MATHFN (BUILT_IN_NANS)
1735 CASE_MATHFN (BUILT_IN_NEARBYINT)
1736 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1737 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1738 CASE_MATHFN (BUILT_IN_POW)
1739 CASE_MATHFN (BUILT_IN_POWI)
1740 CASE_MATHFN (BUILT_IN_POW10)
1741 CASE_MATHFN (BUILT_IN_REMAINDER)
1742 CASE_MATHFN (BUILT_IN_REMQUO)
1743 CASE_MATHFN (BUILT_IN_RINT)
1744 CASE_MATHFN (BUILT_IN_ROUND)
1745 CASE_MATHFN (BUILT_IN_SCALB)
1746 CASE_MATHFN (BUILT_IN_SCALBLN)
1747 CASE_MATHFN (BUILT_IN_SCALBN)
1748 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1749 CASE_MATHFN (BUILT_IN_SIN)
1750 CASE_MATHFN (BUILT_IN_SINCOS)
1751 CASE_MATHFN (BUILT_IN_SINH)
1752 CASE_MATHFN (BUILT_IN_SQRT)
1753 CASE_MATHFN (BUILT_IN_TAN)
1754 CASE_MATHFN (BUILT_IN_TANH)
1755 CASE_MATHFN (BUILT_IN_TGAMMA)
1756 CASE_MATHFN (BUILT_IN_TRUNC)
1757 CASE_MATHFN (BUILT_IN_Y0)
1758 CASE_MATHFN (BUILT_IN_Y1)
1759 CASE_MATHFN (BUILT_IN_YN)
1761 default:
1762 return 0;
1765 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1766 return implicit_built_in_decls[fcode];
1767 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1768 return implicit_built_in_decls[fcodef];
1769 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1770 return implicit_built_in_decls[fcodel];
1771 else
1772 return 0;
1775 /* If errno must be maintained, expand the RTL to check if the result,
1776 TARGET, of a built-in function call, EXP, is NaN, and if so set
1777 errno to EDOM. */
1779 static void
1780 expand_errno_check (tree exp, rtx target)
1782 rtx lab = gen_label_rtx ();
1784 /* Test the result; if it is NaN, set errno=EDOM because
1785 the argument was not in the domain. */
1786 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1787 0, lab);
1789 #ifdef TARGET_EDOM
1790 /* If this built-in doesn't throw an exception, set errno directly. */
1791 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1793 #ifdef GEN_ERRNO_RTX
1794 rtx errno_rtx = GEN_ERRNO_RTX;
1795 #else
1796 rtx errno_rtx
1797 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1798 #endif
1799 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1800 emit_label (lab);
1801 return;
1803 #endif
1805 /* We can't set errno=EDOM directly; let the library call do it.
1806 Pop the arguments right away in case the call gets deleted. */
1807 NO_DEFER_POP;
1808 expand_call (exp, target, 0);
1809 OK_DEFER_POP;
1810 emit_label (lab);
1814 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1815 Return 0 if a normal call should be emitted rather than expanding the
1816 function in-line. EXP is the expression that is a call to the builtin
1817 function; if convenient, the result should be placed in TARGET.
1818 SUBTARGET may be used as the target for computing one of EXP's operands. */
1820 static rtx
1821 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1823 optab builtin_optab;
1824 rtx op0, insns, before_call;
1825 tree fndecl = get_callee_fndecl (exp);
1826 tree arglist = TREE_OPERAND (exp, 1);
1827 enum machine_mode mode;
1828 bool errno_set = false;
1829 tree arg, narg;
1831 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1832 return 0;
1834 arg = TREE_VALUE (arglist);
1836 switch (DECL_FUNCTION_CODE (fndecl))
1838 CASE_FLT_FN (BUILT_IN_SQRT):
1839 errno_set = ! tree_expr_nonnegative_p (arg);
1840 builtin_optab = sqrt_optab;
1841 break;
1842 CASE_FLT_FN (BUILT_IN_EXP):
1843 errno_set = true; builtin_optab = exp_optab; break;
1844 CASE_FLT_FN (BUILT_IN_EXP10):
1845 CASE_FLT_FN (BUILT_IN_POW10):
1846 errno_set = true; builtin_optab = exp10_optab; break;
1847 CASE_FLT_FN (BUILT_IN_EXP2):
1848 errno_set = true; builtin_optab = exp2_optab; break;
1849 CASE_FLT_FN (BUILT_IN_EXPM1):
1850 errno_set = true; builtin_optab = expm1_optab; break;
1851 CASE_FLT_FN (BUILT_IN_LOGB):
1852 errno_set = true; builtin_optab = logb_optab; break;
1853 CASE_FLT_FN (BUILT_IN_ILOGB):
1854 errno_set = true; builtin_optab = ilogb_optab; break;
1855 CASE_FLT_FN (BUILT_IN_LOG):
1856 errno_set = true; builtin_optab = log_optab; break;
1857 CASE_FLT_FN (BUILT_IN_LOG10):
1858 errno_set = true; builtin_optab = log10_optab; break;
1859 CASE_FLT_FN (BUILT_IN_LOG2):
1860 errno_set = true; builtin_optab = log2_optab; break;
1861 CASE_FLT_FN (BUILT_IN_LOG1P):
1862 errno_set = true; builtin_optab = log1p_optab; break;
1863 CASE_FLT_FN (BUILT_IN_ASIN):
1864 builtin_optab = asin_optab; break;
1865 CASE_FLT_FN (BUILT_IN_ACOS):
1866 builtin_optab = acos_optab; break;
1867 CASE_FLT_FN (BUILT_IN_TAN):
1868 builtin_optab = tan_optab; break;
1869 CASE_FLT_FN (BUILT_IN_ATAN):
1870 builtin_optab = atan_optab; break;
1871 CASE_FLT_FN (BUILT_IN_FLOOR):
1872 builtin_optab = floor_optab; break;
1873 CASE_FLT_FN (BUILT_IN_CEIL):
1874 builtin_optab = ceil_optab; break;
1875 CASE_FLT_FN (BUILT_IN_TRUNC):
1876 builtin_optab = btrunc_optab; break;
1877 CASE_FLT_FN (BUILT_IN_ROUND):
1878 builtin_optab = round_optab; break;
1879 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1880 builtin_optab = nearbyint_optab; break;
1881 CASE_FLT_FN (BUILT_IN_RINT):
1882 builtin_optab = rint_optab; break;
1883 CASE_FLT_FN (BUILT_IN_LRINT):
1884 CASE_FLT_FN (BUILT_IN_LLRINT):
1885 builtin_optab = lrint_optab; break;
1886 default:
1887 gcc_unreachable ();
1890 /* Make a suitable register to place result in. */
1891 mode = TYPE_MODE (TREE_TYPE (exp));
1893 if (! flag_errno_math || ! HONOR_NANS (mode))
1894 errno_set = false;
1896 /* Before working hard, check whether the instruction is available. */
1897 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1899 target = gen_reg_rtx (mode);
1901 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1902 need to expand the argument again. This way, we will not perform
1903 side-effects more the once. */
1904 narg = builtin_save_expr (arg);
1905 if (narg != arg)
1907 arg = narg;
1908 arglist = build_tree_list (NULL_TREE, arg);
1909 exp = build_function_call_expr (fndecl, arglist);
1912 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1914 start_sequence ();
1916 /* Compute into TARGET.
1917 Set TARGET to wherever the result comes back. */
1918 target = expand_unop (mode, builtin_optab, op0, target, 0);
1920 if (target != 0)
1922 if (errno_set)
1923 expand_errno_check (exp, target);
1925 /* Output the entire sequence. */
1926 insns = get_insns ();
1927 end_sequence ();
1928 emit_insn (insns);
1929 return target;
1932 /* If we were unable to expand via the builtin, stop the sequence
1933 (without outputting the insns) and call to the library function
1934 with the stabilized argument list. */
1935 end_sequence ();
1938 before_call = get_last_insn ();
1940 target = expand_call (exp, target, target == const0_rtx);
1942 /* If this is a sqrt operation and we don't care about errno, try to
1943 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1944 This allows the semantics of the libcall to be visible to the RTL
1945 optimizers. */
1946 if (builtin_optab == sqrt_optab && !errno_set)
1948 /* Search backwards through the insns emitted by expand_call looking
1949 for the instruction with the REG_RETVAL note. */
1950 rtx last = get_last_insn ();
1951 while (last != before_call)
1953 if (find_reg_note (last, REG_RETVAL, NULL))
1955 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1956 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1957 two elements, i.e. symbol_ref(sqrt) and the operand. */
1958 if (note
1959 && GET_CODE (note) == EXPR_LIST
1960 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1961 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1962 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1964 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1965 /* Check operand is a register with expected mode. */
1966 if (operand
1967 && REG_P (operand)
1968 && GET_MODE (operand) == mode)
1970 /* Replace the REG_EQUAL note with a SQRT rtx. */
1971 rtx equiv = gen_rtx_SQRT (mode, operand);
1972 set_unique_reg_note (last, REG_EQUAL, equiv);
1975 break;
1977 last = PREV_INSN (last);
1981 return target;
1984 /* Expand a call to the builtin binary math functions (pow and atan2).
1985 Return 0 if a normal call should be emitted rather than expanding the
1986 function in-line. EXP is the expression that is a call to the builtin
1987 function; if convenient, the result should be placed in TARGET.
1988 SUBTARGET may be used as the target for computing one of EXP's
1989 operands. */
1991 static rtx
1992 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1994 optab builtin_optab;
1995 rtx op0, op1, insns;
1996 int op1_type = REAL_TYPE;
1997 tree fndecl = get_callee_fndecl (exp);
1998 tree arglist = TREE_OPERAND (exp, 1);
1999 tree arg0, arg1, temp, narg;
2000 enum machine_mode mode;
2001 bool errno_set = true;
2002 bool stable = true;
2004 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2005 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2006 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2007 op1_type = INTEGER_TYPE;
2009 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2010 return 0;
2012 arg0 = TREE_VALUE (arglist);
2013 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2015 switch (DECL_FUNCTION_CODE (fndecl))
2017 CASE_FLT_FN (BUILT_IN_POW):
2018 builtin_optab = pow_optab; break;
2019 CASE_FLT_FN (BUILT_IN_ATAN2):
2020 builtin_optab = atan2_optab; break;
2021 CASE_FLT_FN (BUILT_IN_LDEXP):
2022 builtin_optab = ldexp_optab; break;
2023 CASE_FLT_FN (BUILT_IN_FMOD):
2024 builtin_optab = fmod_optab; break;
2025 CASE_FLT_FN (BUILT_IN_DREM):
2026 builtin_optab = drem_optab; break;
2027 default:
2028 gcc_unreachable ();
2031 /* Make a suitable register to place result in. */
2032 mode = TYPE_MODE (TREE_TYPE (exp));
2034 /* Before working hard, check whether the instruction is available. */
2035 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2036 return 0;
2038 target = gen_reg_rtx (mode);
2040 if (! flag_errno_math || ! HONOR_NANS (mode))
2041 errno_set = false;
2043 /* Always stabilize the argument list. */
2044 narg = builtin_save_expr (arg1);
2045 if (narg != arg1)
2047 arg1 = narg;
2048 temp = build_tree_list (NULL_TREE, narg);
2049 stable = false;
2051 else
2052 temp = TREE_CHAIN (arglist);
2054 narg = builtin_save_expr (arg0);
2055 if (narg != arg0)
2057 arg0 = narg;
2058 arglist = tree_cons (NULL_TREE, narg, temp);
2059 stable = false;
2061 else if (! stable)
2062 arglist = tree_cons (NULL_TREE, arg0, temp);
2064 if (! stable)
2065 exp = build_function_call_expr (fndecl, arglist);
2067 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2068 op1 = expand_normal (arg1);
2070 start_sequence ();
2072 /* Compute into TARGET.
2073 Set TARGET to wherever the result comes back. */
2074 target = expand_binop (mode, builtin_optab, op0, op1,
2075 target, 0, OPTAB_DIRECT);
2077 /* If we were unable to expand via the builtin, stop the sequence
2078 (without outputting the insns) and call to the library function
2079 with the stabilized argument list. */
2080 if (target == 0)
2082 end_sequence ();
2083 return expand_call (exp, target, target == const0_rtx);
2086 if (errno_set)
2087 expand_errno_check (exp, target);
2089 /* Output the entire sequence. */
2090 insns = get_insns ();
2091 end_sequence ();
2092 emit_insn (insns);
2094 return target;
2097 /* Expand a call to the builtin sin and cos math functions.
2098 Return 0 if a normal call should be emitted rather than expanding the
2099 function in-line. EXP is the expression that is a call to the builtin
2100 function; if convenient, the result should be placed in TARGET.
2101 SUBTARGET may be used as the target for computing one of EXP's
2102 operands. */
2104 static rtx
2105 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2107 optab builtin_optab;
2108 rtx op0, insns;
2109 tree fndecl = get_callee_fndecl (exp);
2110 tree arglist = TREE_OPERAND (exp, 1);
2111 enum machine_mode mode;
2112 tree arg, narg;
2114 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2115 return 0;
2117 arg = TREE_VALUE (arglist);
2119 switch (DECL_FUNCTION_CODE (fndecl))
2121 CASE_FLT_FN (BUILT_IN_SIN):
2122 CASE_FLT_FN (BUILT_IN_COS):
2123 builtin_optab = sincos_optab; break;
2124 default:
2125 gcc_unreachable ();
2128 /* Make a suitable register to place result in. */
2129 mode = TYPE_MODE (TREE_TYPE (exp));
2131 /* Check if sincos insn is available, otherwise fallback
2132 to sin or cos insn. */
2133 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2134 switch (DECL_FUNCTION_CODE (fndecl))
2136 CASE_FLT_FN (BUILT_IN_SIN):
2137 builtin_optab = sin_optab; break;
2138 CASE_FLT_FN (BUILT_IN_COS):
2139 builtin_optab = cos_optab; break;
2140 default:
2141 gcc_unreachable ();
2145 /* Before working hard, check whether the instruction is available. */
2146 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2148 target = gen_reg_rtx (mode);
2150 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2151 need to expand the argument again. This way, we will not perform
2152 side-effects more the once. */
2153 narg = save_expr (arg);
2154 if (narg != arg)
2156 arg = narg;
2157 arglist = build_tree_list (NULL_TREE, arg);
2158 exp = build_function_call_expr (fndecl, arglist);
2161 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2163 start_sequence ();
2165 /* Compute into TARGET.
2166 Set TARGET to wherever the result comes back. */
2167 if (builtin_optab == sincos_optab)
2169 int result;
2171 switch (DECL_FUNCTION_CODE (fndecl))
2173 CASE_FLT_FN (BUILT_IN_SIN):
2174 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2175 break;
2176 CASE_FLT_FN (BUILT_IN_COS):
2177 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2178 break;
2179 default:
2180 gcc_unreachable ();
2182 gcc_assert (result);
2184 else
2186 target = expand_unop (mode, builtin_optab, op0, target, 0);
2189 if (target != 0)
2191 /* Output the entire sequence. */
2192 insns = get_insns ();
2193 end_sequence ();
2194 emit_insn (insns);
2195 return target;
2198 /* If we were unable to expand via the builtin, stop the sequence
2199 (without outputting the insns) and call to the library function
2200 with the stabilized argument list. */
2201 end_sequence ();
2204 target = expand_call (exp, target, target == const0_rtx);
2206 return target;
2209 /* Expand a call to the builtin sincos math function.
2210 Return 0 if a normal call should be emitted rather than expanding the
2211 function in-line. EXP is the expression that is a call to the builtin
2212 function. */
2214 static rtx
2215 expand_builtin_sincos (tree exp)
2217 rtx op0, op1, op2, target1, target2;
2218 tree arglist = TREE_OPERAND (exp, 1);
2219 enum machine_mode mode;
2220 tree arg, sinp, cosp;
2221 int result;
2223 if (!validate_arglist (arglist, REAL_TYPE,
2224 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2225 return 0;
2227 arg = TREE_VALUE (arglist);
2228 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2229 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2231 /* Make a suitable register to place result in. */
2232 mode = TYPE_MODE (TREE_TYPE (arg));
2234 /* Check if sincos insn is available, otherwise emit the call. */
2235 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2236 return NULL_RTX;
2238 target1 = gen_reg_rtx (mode);
2239 target2 = gen_reg_rtx (mode);
2241 op0 = expand_normal (arg);
2242 op1 = expand_normal (build_fold_indirect_ref (sinp));
2243 op2 = expand_normal (build_fold_indirect_ref (cosp));
2245 /* Compute into target1 and target2.
2246 Set TARGET to wherever the result comes back. */
2247 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2248 gcc_assert (result);
2250 /* Move target1 and target2 to the memory locations indicated
2251 by op1 and op2. */
2252 emit_move_insn (op1, target1);
2253 emit_move_insn (op2, target2);
2255 return const0_rtx;
2258 /* Expand a call to one of the builtin rounding functions (lfloor).
2259 If expanding via optab fails, lower expression to (int)(floor(x)).
2260 EXP is the expression that is a call to the builtin function;
2261 if convenient, the result should be placed in TARGET. SUBTARGET may
2262 be used as the target for computing one of EXP's operands. */
2264 static rtx
2265 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2267 optab builtin_optab;
2268 rtx op0, insns, tmp;
2269 tree fndecl = get_callee_fndecl (exp);
2270 tree arglist = TREE_OPERAND (exp, 1);
2271 enum built_in_function fallback_fn;
2272 tree fallback_fndecl;
2273 enum machine_mode mode;
2274 tree arg, narg;
2276 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2277 gcc_unreachable ();
2279 arg = TREE_VALUE (arglist);
2281 switch (DECL_FUNCTION_CODE (fndecl))
2283 CASE_FLT_FN (BUILT_IN_LCEIL):
2284 CASE_FLT_FN (BUILT_IN_LLCEIL):
2285 builtin_optab = lceil_optab;
2286 fallback_fn = BUILT_IN_CEIL;
2287 break;
2289 CASE_FLT_FN (BUILT_IN_LFLOOR):
2290 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2291 builtin_optab = lfloor_optab;
2292 fallback_fn = BUILT_IN_FLOOR;
2293 break;
2295 default:
2296 gcc_unreachable ();
2299 /* Make a suitable register to place result in. */
2300 mode = TYPE_MODE (TREE_TYPE (exp));
2302 /* Before working hard, check whether the instruction is available. */
2303 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2305 target = gen_reg_rtx (mode);
2307 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2308 need to expand the argument again. This way, we will not perform
2309 side-effects more the once. */
2310 narg = builtin_save_expr (arg);
2311 if (narg != arg)
2313 arg = narg;
2314 arglist = build_tree_list (NULL_TREE, arg);
2315 exp = build_function_call_expr (fndecl, arglist);
2318 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2320 start_sequence ();
2322 /* Compute into TARGET.
2323 Set TARGET to wherever the result comes back. */
2324 target = expand_unop (mode, builtin_optab, op0, target, 0);
2326 if (target != 0)
2328 /* Output the entire sequence. */
2329 insns = get_insns ();
2330 end_sequence ();
2331 emit_insn (insns);
2332 return target;
2335 /* If we were unable to expand via the builtin, stop the sequence
2336 (without outputting the insns). */
2337 end_sequence ();
2340 /* Fall back to floating point rounding optab. */
2341 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2342 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2343 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2344 gcc_assert (fallback_fndecl != NULL_TREE);
2345 exp = build_function_call_expr (fallback_fndecl, arglist);
2347 tmp = expand_normal (exp);
2349 /* Truncate the result of floating point optab to integer
2350 via expand_fix (). */
2351 target = gen_reg_rtx (mode);
2352 expand_fix (target, tmp, 0);
2354 return target;
2357 /* To evaluate powi(x,n), the floating point value x raised to the
2358 constant integer exponent n, we use a hybrid algorithm that
2359 combines the "window method" with look-up tables. For an
2360 introduction to exponentiation algorithms and "addition chains",
2361 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2362 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2363 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2364 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2366 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2367 multiplications to inline before calling the system library's pow
2368 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2369 so this default never requires calling pow, powf or powl. */
2371 #ifndef POWI_MAX_MULTS
2372 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2373 #endif
2375 /* The size of the "optimal power tree" lookup table. All
2376 exponents less than this value are simply looked up in the
2377 powi_table below. This threshold is also used to size the
2378 cache of pseudo registers that hold intermediate results. */
2379 #define POWI_TABLE_SIZE 256
2381 /* The size, in bits of the window, used in the "window method"
2382 exponentiation algorithm. This is equivalent to a radix of
2383 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2384 #define POWI_WINDOW_SIZE 3
2386 /* The following table is an efficient representation of an
2387 "optimal power tree". For each value, i, the corresponding
2388 value, j, in the table states than an optimal evaluation
2389 sequence for calculating pow(x,i) can be found by evaluating
2390 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2391 100 integers is given in Knuth's "Seminumerical algorithms". */
2393 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2395 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2396 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2397 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2398 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2399 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2400 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2401 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2402 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2403 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2404 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2405 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2406 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2407 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2408 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2409 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2410 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2411 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2412 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2413 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2414 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2415 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2416 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2417 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2418 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2419 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2420 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2421 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2422 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2423 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2424 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2425 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2426 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2430 /* Return the number of multiplications required to calculate
2431 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2432 subroutine of powi_cost. CACHE is an array indicating
2433 which exponents have already been calculated. */
2435 static int
2436 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2438 /* If we've already calculated this exponent, then this evaluation
2439 doesn't require any additional multiplications. */
2440 if (cache[n])
2441 return 0;
2443 cache[n] = true;
2444 return powi_lookup_cost (n - powi_table[n], cache)
2445 + powi_lookup_cost (powi_table[n], cache) + 1;
2448 /* Return the number of multiplications required to calculate
2449 powi(x,n) for an arbitrary x, given the exponent N. This
2450 function needs to be kept in sync with expand_powi below. */
2452 static int
2453 powi_cost (HOST_WIDE_INT n)
2455 bool cache[POWI_TABLE_SIZE];
2456 unsigned HOST_WIDE_INT digit;
2457 unsigned HOST_WIDE_INT val;
2458 int result;
2460 if (n == 0)
2461 return 0;
2463 /* Ignore the reciprocal when calculating the cost. */
2464 val = (n < 0) ? -n : n;
2466 /* Initialize the exponent cache. */
2467 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2468 cache[1] = true;
2470 result = 0;
2472 while (val >= POWI_TABLE_SIZE)
2474 if (val & 1)
2476 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2477 result += powi_lookup_cost (digit, cache)
2478 + POWI_WINDOW_SIZE + 1;
2479 val >>= POWI_WINDOW_SIZE;
2481 else
2483 val >>= 1;
2484 result++;
2488 return result + powi_lookup_cost (val, cache);
2491 /* Recursive subroutine of expand_powi. This function takes the array,
2492 CACHE, of already calculated exponents and an exponent N and returns
2493 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2495 static rtx
2496 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2498 unsigned HOST_WIDE_INT digit;
2499 rtx target, result;
2500 rtx op0, op1;
2502 if (n < POWI_TABLE_SIZE)
2504 if (cache[n])
2505 return cache[n];
2507 target = gen_reg_rtx (mode);
2508 cache[n] = target;
2510 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2511 op1 = expand_powi_1 (mode, powi_table[n], cache);
2513 else if (n & 1)
2515 target = gen_reg_rtx (mode);
2516 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2517 op0 = expand_powi_1 (mode, n - digit, cache);
2518 op1 = expand_powi_1 (mode, digit, cache);
2520 else
2522 target = gen_reg_rtx (mode);
2523 op0 = expand_powi_1 (mode, n >> 1, cache);
2524 op1 = op0;
2527 result = expand_mult (mode, op0, op1, target, 0);
2528 if (result != target)
2529 emit_move_insn (target, result);
2530 return target;
2533 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2534 floating point operand in mode MODE, and N is the exponent. This
2535 function needs to be kept in sync with powi_cost above. */
2537 static rtx
2538 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2540 unsigned HOST_WIDE_INT val;
2541 rtx cache[POWI_TABLE_SIZE];
2542 rtx result;
2544 if (n == 0)
2545 return CONST1_RTX (mode);
2547 val = (n < 0) ? -n : n;
2549 memset (cache, 0, sizeof (cache));
2550 cache[1] = x;
2552 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2554 /* If the original exponent was negative, reciprocate the result. */
2555 if (n < 0)
2556 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2557 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2559 return result;
2562 /* Expand a call to the pow built-in mathematical function. Return 0 if
2563 a normal call should be emitted rather than expanding the function
2564 in-line. EXP is the expression that is a call to the builtin
2565 function; if convenient, the result should be placed in TARGET. */
2567 static rtx
2568 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2570 tree arglist = TREE_OPERAND (exp, 1);
2571 tree arg0, arg1;
2573 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2574 return 0;
2576 arg0 = TREE_VALUE (arglist);
2577 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2579 if (TREE_CODE (arg1) == REAL_CST
2580 && ! TREE_CONSTANT_OVERFLOW (arg1))
2582 REAL_VALUE_TYPE cint;
2583 REAL_VALUE_TYPE c;
2584 HOST_WIDE_INT n;
2586 c = TREE_REAL_CST (arg1);
2587 n = real_to_integer (&c);
2588 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2589 if (real_identical (&c, &cint))
2591 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2592 Otherwise, check the number of multiplications required.
2593 Note that pow never sets errno for an integer exponent. */
2594 if ((n >= -1 && n <= 2)
2595 || (flag_unsafe_math_optimizations
2596 && ! optimize_size
2597 && powi_cost (n) <= POWI_MAX_MULTS))
2599 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2600 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2601 op = force_reg (mode, op);
2602 return expand_powi (op, mode, n);
2607 if (! flag_unsafe_math_optimizations)
2608 return NULL_RTX;
2609 return expand_builtin_mathfn_2 (exp, target, subtarget);
2612 /* Expand a call to the powi built-in mathematical function. Return 0 if
2613 a normal call should be emitted rather than expanding the function
2614 in-line. EXP is the expression that is a call to the builtin
2615 function; if convenient, the result should be placed in TARGET. */
2617 static rtx
2618 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2620 tree arglist = TREE_OPERAND (exp, 1);
2621 tree arg0, arg1;
2622 rtx op0, op1;
2623 enum machine_mode mode;
2624 enum machine_mode mode2;
2626 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2627 return 0;
2629 arg0 = TREE_VALUE (arglist);
2630 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2631 mode = TYPE_MODE (TREE_TYPE (exp));
2633 /* Handle constant power. */
2635 if (TREE_CODE (arg1) == INTEGER_CST
2636 && ! TREE_CONSTANT_OVERFLOW (arg1))
2638 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2640 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2641 Otherwise, check the number of multiplications required. */
2642 if ((TREE_INT_CST_HIGH (arg1) == 0
2643 || TREE_INT_CST_HIGH (arg1) == -1)
2644 && ((n >= -1 && n <= 2)
2645 || (! optimize_size
2646 && powi_cost (n) <= POWI_MAX_MULTS)))
2648 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2649 op0 = force_reg (mode, op0);
2650 return expand_powi (op0, mode, n);
2654 /* Emit a libcall to libgcc. */
2656 /* Mode of the 2nd argument must match that of an int. */
2657 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2659 if (target == NULL_RTX)
2660 target = gen_reg_rtx (mode);
2662 op0 = expand_expr (arg0, subtarget, mode, 0);
2663 if (GET_MODE (op0) != mode)
2664 op0 = convert_to_mode (mode, op0, 0);
2665 op1 = expand_expr (arg1, 0, mode2, 0);
2666 if (GET_MODE (op1) != mode2)
2667 op1 = convert_to_mode (mode2, op1, 0);
2669 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2670 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2671 op0, mode, op1, mode2);
2673 return target;
2676 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2677 if we failed the caller should emit a normal call, otherwise
2678 try to get the result in TARGET, if convenient. */
2680 static rtx
2681 expand_builtin_strlen (tree arglist, rtx target,
2682 enum machine_mode target_mode)
2684 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2685 return 0;
2686 else
2688 rtx pat;
2689 tree len, src = TREE_VALUE (arglist);
2690 rtx result, src_reg, char_rtx, before_strlen;
2691 enum machine_mode insn_mode = target_mode, char_mode;
2692 enum insn_code icode = CODE_FOR_nothing;
2693 int align;
2695 /* If the length can be computed at compile-time, return it. */
2696 len = c_strlen (src, 0);
2697 if (len)
2698 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2700 /* If the length can be computed at compile-time and is constant
2701 integer, but there are side-effects in src, evaluate
2702 src for side-effects, then return len.
2703 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2704 can be optimized into: i++; x = 3; */
2705 len = c_strlen (src, 1);
2706 if (len && TREE_CODE (len) == INTEGER_CST)
2708 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2709 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2712 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2714 /* If SRC is not a pointer type, don't do this operation inline. */
2715 if (align == 0)
2716 return 0;
2718 /* Bail out if we can't compute strlen in the right mode. */
2719 while (insn_mode != VOIDmode)
2721 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2722 if (icode != CODE_FOR_nothing)
2723 break;
2725 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2727 if (insn_mode == VOIDmode)
2728 return 0;
2730 /* Make a place to write the result of the instruction. */
2731 result = target;
2732 if (! (result != 0
2733 && REG_P (result)
2734 && GET_MODE (result) == insn_mode
2735 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2736 result = gen_reg_rtx (insn_mode);
2738 /* Make a place to hold the source address. We will not expand
2739 the actual source until we are sure that the expansion will
2740 not fail -- there are trees that cannot be expanded twice. */
2741 src_reg = gen_reg_rtx (Pmode);
2743 /* Mark the beginning of the strlen sequence so we can emit the
2744 source operand later. */
2745 before_strlen = get_last_insn ();
2747 char_rtx = const0_rtx;
2748 char_mode = insn_data[(int) icode].operand[2].mode;
2749 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2750 char_mode))
2751 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2753 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2754 char_rtx, GEN_INT (align));
2755 if (! pat)
2756 return 0;
2757 emit_insn (pat);
2759 /* Now that we are assured of success, expand the source. */
2760 start_sequence ();
2761 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2762 if (pat != src_reg)
2763 emit_move_insn (src_reg, pat);
2764 pat = get_insns ();
2765 end_sequence ();
2767 if (before_strlen)
2768 emit_insn_after (pat, before_strlen);
2769 else
2770 emit_insn_before (pat, get_insns ());
2772 /* Return the value in the proper mode for this function. */
2773 if (GET_MODE (result) == target_mode)
2774 target = result;
2775 else if (target != 0)
2776 convert_move (target, result, 0);
2777 else
2778 target = convert_to_mode (target_mode, result, 0);
2780 return target;
2784 /* Expand a call to the strstr builtin. Return 0 if we failed the
2785 caller should emit a normal call, otherwise try to get the result
2786 in TARGET, if convenient (and in mode MODE if that's convenient). */
2788 static rtx
2789 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2791 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2793 tree result = fold_builtin_strstr (arglist, type);
2794 if (result)
2795 return expand_expr (result, target, mode, EXPAND_NORMAL);
2797 return 0;
2800 /* Expand a call to the strchr builtin. Return 0 if we failed the
2801 caller should emit a normal call, otherwise try to get the result
2802 in TARGET, if convenient (and in mode MODE if that's convenient). */
2804 static rtx
2805 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2807 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2809 tree result = fold_builtin_strchr (arglist, type);
2810 if (result)
2811 return expand_expr (result, target, mode, EXPAND_NORMAL);
2813 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2815 return 0;
2818 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2819 caller should emit a normal call, otherwise try to get the result
2820 in TARGET, if convenient (and in mode MODE if that's convenient). */
2822 static rtx
2823 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2825 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2827 tree result = fold_builtin_strrchr (arglist, type);
2828 if (result)
2829 return expand_expr (result, target, mode, EXPAND_NORMAL);
2831 return 0;
2834 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2835 caller should emit a normal call, otherwise try to get the result
2836 in TARGET, if convenient (and in mode MODE if that's convenient). */
2838 static rtx
2839 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2841 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2843 tree result = fold_builtin_strpbrk (arglist, type);
2844 if (result)
2845 return expand_expr (result, target, mode, EXPAND_NORMAL);
2847 return 0;
2850 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2851 bytes from constant string DATA + OFFSET and return it as target
2852 constant. */
2854 static rtx
2855 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2856 enum machine_mode mode)
2858 const char *str = (const char *) data;
2860 gcc_assert (offset >= 0
2861 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2862 <= strlen (str) + 1));
2864 return c_readstr (str + offset, mode);
2867 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2868 Return 0 if we failed, the caller should emit a normal call,
2869 otherwise try to get the result in TARGET, if convenient (and in
2870 mode MODE if that's convenient). */
2871 static rtx
2872 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2874 tree fndecl = get_callee_fndecl (exp);
2875 tree arglist = TREE_OPERAND (exp, 1);
2876 if (!validate_arglist (arglist,
2877 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2878 return 0;
2879 else
2881 tree dest = TREE_VALUE (arglist);
2882 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2883 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2884 const char *src_str;
2885 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2886 unsigned int dest_align
2887 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2888 rtx dest_mem, src_mem, dest_addr, len_rtx;
2889 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2890 false, /*endp=*/0);
2892 if (result)
2894 while (TREE_CODE (result) == COMPOUND_EXPR)
2896 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2897 EXPAND_NORMAL);
2898 result = TREE_OPERAND (result, 1);
2900 return expand_expr (result, target, mode, EXPAND_NORMAL);
2903 /* If DEST is not a pointer type, call the normal function. */
2904 if (dest_align == 0)
2905 return 0;
2907 /* If either SRC is not a pointer type, don't do this
2908 operation in-line. */
2909 if (src_align == 0)
2910 return 0;
2912 dest_mem = get_memory_rtx (dest, len);
2913 set_mem_align (dest_mem, dest_align);
2914 len_rtx = expand_normal (len);
2915 src_str = c_getstr (src);
2917 /* If SRC is a string constant and block move would be done
2918 by pieces, we can avoid loading the string from memory
2919 and only stored the computed constants. */
2920 if (src_str
2921 && GET_CODE (len_rtx) == CONST_INT
2922 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2923 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2924 (void *) src_str, dest_align))
2926 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2927 builtin_memcpy_read_str,
2928 (void *) src_str, dest_align, 0);
2929 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2930 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2931 return dest_mem;
2934 src_mem = get_memory_rtx (src, len);
2935 set_mem_align (src_mem, src_align);
2937 /* Copy word part most expediently. */
2938 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2939 CALL_EXPR_TAILCALL (exp)
2940 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2942 if (dest_addr == 0)
2944 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2945 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2947 return dest_addr;
2951 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2952 Return 0 if we failed; the caller should emit a normal call,
2953 otherwise try to get the result in TARGET, if convenient (and in
2954 mode MODE if that's convenient). If ENDP is 0 return the
2955 destination pointer, if ENDP is 1 return the end pointer ala
2956 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2957 stpcpy. */
2959 static rtx
2960 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2961 int endp)
2963 if (!validate_arglist (arglist,
2964 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2965 return 0;
2966 /* If return value is ignored, transform mempcpy into memcpy. */
2967 else if (target == const0_rtx)
2969 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2971 if (!fn)
2972 return 0;
2974 return expand_expr (build_function_call_expr (fn, arglist),
2975 target, mode, EXPAND_NORMAL);
2977 else
2979 tree dest = TREE_VALUE (arglist);
2980 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2981 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2982 const char *src_str;
2983 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2984 unsigned int dest_align
2985 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2986 rtx dest_mem, src_mem, len_rtx;
2987 tree result = fold_builtin_memory_op (arglist, type, false, endp);
2989 if (result)
2991 while (TREE_CODE (result) == COMPOUND_EXPR)
2993 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2994 EXPAND_NORMAL);
2995 result = TREE_OPERAND (result, 1);
2997 return expand_expr (result, target, mode, EXPAND_NORMAL);
3000 /* If either SRC or DEST is not a pointer type, don't do this
3001 operation in-line. */
3002 if (dest_align == 0 || src_align == 0)
3003 return 0;
3005 /* If LEN is not constant, call the normal function. */
3006 if (! host_integerp (len, 1))
3007 return 0;
3009 len_rtx = expand_normal (len);
3010 src_str = c_getstr (src);
3012 /* If SRC is a string constant and block move would be done
3013 by pieces, we can avoid loading the string from memory
3014 and only stored the computed constants. */
3015 if (src_str
3016 && GET_CODE (len_rtx) == CONST_INT
3017 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3018 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3019 (void *) src_str, dest_align))
3021 dest_mem = get_memory_rtx (dest, len);
3022 set_mem_align (dest_mem, dest_align);
3023 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3024 builtin_memcpy_read_str,
3025 (void *) src_str, dest_align, endp);
3026 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3027 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3028 return dest_mem;
3031 if (GET_CODE (len_rtx) == CONST_INT
3032 && can_move_by_pieces (INTVAL (len_rtx),
3033 MIN (dest_align, src_align)))
3035 dest_mem = get_memory_rtx (dest, len);
3036 set_mem_align (dest_mem, dest_align);
3037 src_mem = get_memory_rtx (src, len);
3038 set_mem_align (src_mem, src_align);
3039 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3040 MIN (dest_align, src_align), endp);
3041 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3042 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3043 return dest_mem;
3046 return 0;
3050 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3051 if we failed; the caller should emit a normal call. */
3053 static rtx
3054 expand_builtin_memmove (tree arglist, tree type, rtx target,
3055 enum machine_mode mode, tree orig_exp)
3057 if (!validate_arglist (arglist,
3058 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3059 return 0;
3060 else
3062 tree dest = TREE_VALUE (arglist);
3063 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3064 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3066 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3067 unsigned int dest_align
3068 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3069 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3071 if (result)
3073 while (TREE_CODE (result) == COMPOUND_EXPR)
3075 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3076 EXPAND_NORMAL);
3077 result = TREE_OPERAND (result, 1);
3079 return expand_expr (result, target, mode, EXPAND_NORMAL);
3082 /* If DEST is not a pointer type, call the normal function. */
3083 if (dest_align == 0)
3084 return 0;
3086 /* If either SRC is not a pointer type, don't do this
3087 operation in-line. */
3088 if (src_align == 0)
3089 return 0;
3091 /* If src is categorized for a readonly section we can use
3092 normal memcpy. */
3093 if (readonly_data_expr (src))
3095 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3096 if (!fn)
3097 return 0;
3098 fn = build_function_call_expr (fn, arglist);
3099 if (TREE_CODE (fn) == CALL_EXPR)
3100 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3101 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3104 /* If length is 1 and we can expand memcpy call inline,
3105 it is ok to use memcpy as well. */
3106 if (integer_onep (len))
3108 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3109 /*endp=*/0);
3110 if (ret)
3111 return ret;
3114 /* Otherwise, call the normal function. */
3115 return 0;
3119 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3120 if we failed the caller should emit a normal call. */
3122 static rtx
3123 expand_builtin_bcopy (tree exp)
3125 tree arglist = TREE_OPERAND (exp, 1);
3126 tree type = TREE_TYPE (exp);
3127 tree src, dest, size, newarglist;
3129 if (!validate_arglist (arglist,
3130 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3131 return NULL_RTX;
3133 src = TREE_VALUE (arglist);
3134 dest = TREE_VALUE (TREE_CHAIN (arglist));
3135 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3137 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3138 memmove(ptr y, ptr x, size_t z). This is done this way
3139 so that if it isn't expanded inline, we fallback to
3140 calling bcopy instead of memmove. */
3142 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3143 newarglist = tree_cons (NULL_TREE, src, newarglist);
3144 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3146 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3149 #ifndef HAVE_movstr
3150 # define HAVE_movstr 0
3151 # define CODE_FOR_movstr CODE_FOR_nothing
3152 #endif
3154 /* Expand into a movstr instruction, if one is available. Return 0 if
3155 we failed, the caller should emit a normal call, otherwise try to
3156 get the result in TARGET, if convenient. If ENDP is 0 return the
3157 destination pointer, if ENDP is 1 return the end pointer ala
3158 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3159 stpcpy. */
3161 static rtx
3162 expand_movstr (tree dest, tree src, rtx target, int endp)
3164 rtx end;
3165 rtx dest_mem;
3166 rtx src_mem;
3167 rtx insn;
3168 const struct insn_data * data;
3170 if (!HAVE_movstr)
3171 return 0;
3173 dest_mem = get_memory_rtx (dest, NULL);
3174 src_mem = get_memory_rtx (src, NULL);
3175 if (!endp)
3177 target = force_reg (Pmode, XEXP (dest_mem, 0));
3178 dest_mem = replace_equiv_address (dest_mem, target);
3179 end = gen_reg_rtx (Pmode);
3181 else
3183 if (target == 0 || target == const0_rtx)
3185 end = gen_reg_rtx (Pmode);
3186 if (target == 0)
3187 target = end;
3189 else
3190 end = target;
3193 data = insn_data + CODE_FOR_movstr;
3195 if (data->operand[0].mode != VOIDmode)
3196 end = gen_lowpart (data->operand[0].mode, end);
3198 insn = data->genfun (end, dest_mem, src_mem);
3200 gcc_assert (insn);
3202 emit_insn (insn);
3204 /* movstr is supposed to set end to the address of the NUL
3205 terminator. If the caller requested a mempcpy-like return value,
3206 adjust it. */
3207 if (endp == 1 && target != const0_rtx)
3209 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3210 emit_move_insn (target, force_operand (tem, NULL_RTX));
3213 return target;
3216 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3217 if we failed the caller should emit a normal call, otherwise try to get
3218 the result in TARGET, if convenient (and in mode MODE if that's
3219 convenient). */
3221 static rtx
3222 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3224 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3226 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3227 if (result)
3229 while (TREE_CODE (result) == COMPOUND_EXPR)
3231 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3232 EXPAND_NORMAL);
3233 result = TREE_OPERAND (result, 1);
3235 return expand_expr (result, target, mode, EXPAND_NORMAL);
3238 return expand_movstr (TREE_VALUE (arglist),
3239 TREE_VALUE (TREE_CHAIN (arglist)),
3240 target, /*endp=*/0);
3242 return 0;
3245 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3246 Return 0 if we failed the caller should emit a normal call,
3247 otherwise try to get the result in TARGET, if convenient (and in
3248 mode MODE if that's convenient). */
3250 static rtx
3251 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3253 tree arglist = TREE_OPERAND (exp, 1);
3254 /* If return value is ignored, transform stpcpy into strcpy. */
3255 if (target == const0_rtx)
3257 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3258 if (!fn)
3259 return 0;
3261 return expand_expr (build_function_call_expr (fn, arglist),
3262 target, mode, EXPAND_NORMAL);
3265 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3266 return 0;
3267 else
3269 tree dst, src, len, lenp1;
3270 tree narglist;
3271 rtx ret;
3273 /* Ensure we get an actual string whose length can be evaluated at
3274 compile-time, not an expression containing a string. This is
3275 because the latter will potentially produce pessimized code
3276 when used to produce the return value. */
3277 src = TREE_VALUE (TREE_CHAIN (arglist));
3278 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3279 return expand_movstr (TREE_VALUE (arglist),
3280 TREE_VALUE (TREE_CHAIN (arglist)),
3281 target, /*endp=*/2);
3283 dst = TREE_VALUE (arglist);
3284 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3285 narglist = build_tree_list (NULL_TREE, lenp1);
3286 narglist = tree_cons (NULL_TREE, src, narglist);
3287 narglist = tree_cons (NULL_TREE, dst, narglist);
3288 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3289 target, mode, /*endp=*/2);
3291 if (ret)
3292 return ret;
3294 if (TREE_CODE (len) == INTEGER_CST)
3296 rtx len_rtx = expand_normal (len);
3298 if (GET_CODE (len_rtx) == CONST_INT)
3300 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3301 arglist, target, mode);
3303 if (ret)
3305 if (! target)
3307 if (mode != VOIDmode)
3308 target = gen_reg_rtx (mode);
3309 else
3310 target = gen_reg_rtx (GET_MODE (ret));
3312 if (GET_MODE (target) != GET_MODE (ret))
3313 ret = gen_lowpart (GET_MODE (target), ret);
3315 ret = plus_constant (ret, INTVAL (len_rtx));
3316 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3317 gcc_assert (ret);
3319 return target;
3324 return expand_movstr (TREE_VALUE (arglist),
3325 TREE_VALUE (TREE_CHAIN (arglist)),
3326 target, /*endp=*/2);
3330 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3331 bytes from constant string DATA + OFFSET and return it as target
3332 constant. */
3334 static rtx
3335 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3336 enum machine_mode mode)
3338 const char *str = (const char *) data;
3340 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3341 return const0_rtx;
3343 return c_readstr (str + offset, mode);
3346 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3347 if we failed the caller should emit a normal call. */
3349 static rtx
3350 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3352 tree fndecl = get_callee_fndecl (exp);
3353 tree arglist = TREE_OPERAND (exp, 1);
3354 if (validate_arglist (arglist,
3355 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3357 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3358 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3359 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3361 if (result)
3363 while (TREE_CODE (result) == COMPOUND_EXPR)
3365 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3366 EXPAND_NORMAL);
3367 result = TREE_OPERAND (result, 1);
3369 return expand_expr (result, target, mode, EXPAND_NORMAL);
3372 /* We must be passed a constant len and src parameter. */
3373 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3374 return 0;
3376 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3378 /* We're required to pad with trailing zeros if the requested
3379 len is greater than strlen(s2)+1. In that case try to
3380 use store_by_pieces, if it fails, punt. */
3381 if (tree_int_cst_lt (slen, len))
3383 tree dest = TREE_VALUE (arglist);
3384 unsigned int dest_align
3385 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3386 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3387 rtx dest_mem;
3389 if (!p || dest_align == 0 || !host_integerp (len, 1)
3390 || !can_store_by_pieces (tree_low_cst (len, 1),
3391 builtin_strncpy_read_str,
3392 (void *) p, dest_align))
3393 return 0;
3395 dest_mem = get_memory_rtx (dest, len);
3396 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3397 builtin_strncpy_read_str,
3398 (void *) p, dest_align, 0);
3399 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3400 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3401 return dest_mem;
3404 return 0;
3407 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3408 bytes from constant string DATA + OFFSET and return it as target
3409 constant. */
3411 static rtx
3412 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3413 enum machine_mode mode)
3415 const char *c = (const char *) data;
3416 char *p = alloca (GET_MODE_SIZE (mode));
3418 memset (p, *c, GET_MODE_SIZE (mode));
3420 return c_readstr (p, mode);
3423 /* Callback routine for store_by_pieces. Return the RTL of a register
3424 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3425 char value given in the RTL register data. For example, if mode is
3426 4 bytes wide, return the RTL for 0x01010101*data. */
3428 static rtx
3429 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3430 enum machine_mode mode)
3432 rtx target, coeff;
3433 size_t size;
3434 char *p;
3436 size = GET_MODE_SIZE (mode);
3437 if (size == 1)
3438 return (rtx) data;
3440 p = alloca (size);
3441 memset (p, 1, size);
3442 coeff = c_readstr (p, mode);
3444 target = convert_to_mode (mode, (rtx) data, 1);
3445 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3446 return force_reg (mode, target);
3449 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3450 if we failed the caller should emit a normal call, otherwise try to get
3451 the result in TARGET, if convenient (and in mode MODE if that's
3452 convenient). */
3454 static rtx
3455 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3456 tree orig_exp)
3458 if (!validate_arglist (arglist,
3459 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3460 return 0;
3461 else
3463 tree dest = TREE_VALUE (arglist);
3464 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3465 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3466 tree fndecl, fn;
3467 enum built_in_function fcode;
3468 char c;
3469 unsigned int dest_align;
3470 rtx dest_mem, dest_addr, len_rtx;
3472 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3474 /* If DEST is not a pointer type, don't do this
3475 operation in-line. */
3476 if (dest_align == 0)
3477 return 0;
3479 /* If the LEN parameter is zero, return DEST. */
3480 if (integer_zerop (len))
3482 /* Evaluate and ignore VAL in case it has side-effects. */
3483 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3484 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3487 /* Stabilize the arguments in case we fail. */
3488 dest = builtin_save_expr (dest);
3489 val = builtin_save_expr (val);
3490 len = builtin_save_expr (len);
3492 len_rtx = expand_normal (len);
3493 dest_mem = get_memory_rtx (dest, len);
3495 if (TREE_CODE (val) != INTEGER_CST)
3497 rtx val_rtx;
3499 val_rtx = expand_normal (val);
3500 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3501 val_rtx, 0);
3503 /* Assume that we can memset by pieces if we can store the
3504 * the coefficients by pieces (in the required modes).
3505 * We can't pass builtin_memset_gen_str as that emits RTL. */
3506 c = 1;
3507 if (host_integerp (len, 1)
3508 && !(optimize_size && tree_low_cst (len, 1) > 1)
3509 && can_store_by_pieces (tree_low_cst (len, 1),
3510 builtin_memset_read_str, &c, dest_align))
3512 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3513 val_rtx);
3514 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3515 builtin_memset_gen_str, val_rtx, dest_align, 0);
3517 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3518 dest_align))
3519 goto do_libcall;
3521 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3522 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3523 return dest_mem;
3526 if (target_char_cast (val, &c))
3527 goto do_libcall;
3529 if (c)
3531 if (host_integerp (len, 1)
3532 && !(optimize_size && tree_low_cst (len, 1) > 1)
3533 && can_store_by_pieces (tree_low_cst (len, 1),
3534 builtin_memset_read_str, &c, dest_align))
3535 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3536 builtin_memset_read_str, &c, dest_align, 0);
3537 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3538 dest_align))
3539 goto do_libcall;
3541 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3542 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3543 return dest_mem;
3546 set_mem_align (dest_mem, dest_align);
3547 dest_addr = clear_storage (dest_mem, len_rtx,
3548 CALL_EXPR_TAILCALL (orig_exp)
3549 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3551 if (dest_addr == 0)
3553 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3554 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3557 return dest_addr;
3559 do_libcall:
3560 fndecl = get_callee_fndecl (orig_exp);
3561 fcode = DECL_FUNCTION_CODE (fndecl);
3562 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3563 arglist = build_tree_list (NULL_TREE, len);
3564 if (fcode == BUILT_IN_MEMSET)
3565 arglist = tree_cons (NULL_TREE, val, arglist);
3566 arglist = tree_cons (NULL_TREE, dest, arglist);
3567 fn = build_function_call_expr (fndecl, arglist);
3568 if (TREE_CODE (fn) == CALL_EXPR)
3569 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3570 return expand_call (fn, target, target == const0_rtx);
3574 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3575 if we failed the caller should emit a normal call. */
3577 static rtx
3578 expand_builtin_bzero (tree exp)
3580 tree arglist = TREE_OPERAND (exp, 1);
3581 tree dest, size, newarglist;
3583 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3584 return NULL_RTX;
3586 dest = TREE_VALUE (arglist);
3587 size = TREE_VALUE (TREE_CHAIN (arglist));
3589 /* New argument list transforming bzero(ptr x, int y) to
3590 memset(ptr x, int 0, size_t y). This is done this way
3591 so that if it isn't expanded inline, we fallback to
3592 calling bzero instead of memset. */
3594 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3595 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3596 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3598 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3601 /* Expand expression EXP, which is a call to the memcmp built-in function.
3602 ARGLIST is the argument list for this call. Return 0 if we failed and the
3603 caller should emit a normal call, otherwise try to get the result in
3604 TARGET, if convenient (and in mode MODE, if that's convenient). */
3606 static rtx
3607 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3608 enum machine_mode mode)
3610 if (!validate_arglist (arglist,
3611 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3612 return 0;
3613 else
3615 tree result = fold_builtin_memcmp (arglist);
3616 if (result)
3617 return expand_expr (result, target, mode, EXPAND_NORMAL);
3620 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3622 tree arg1 = TREE_VALUE (arglist);
3623 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3624 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3625 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3626 rtx result;
3627 rtx insn;
3629 int arg1_align
3630 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3631 int arg2_align
3632 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3633 enum machine_mode insn_mode;
3635 #ifdef HAVE_cmpmemsi
3636 if (HAVE_cmpmemsi)
3637 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3638 else
3639 #endif
3640 #ifdef HAVE_cmpstrnsi
3641 if (HAVE_cmpstrnsi)
3642 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3643 else
3644 #endif
3645 return 0;
3647 /* If we don't have POINTER_TYPE, call the function. */
3648 if (arg1_align == 0 || arg2_align == 0)
3649 return 0;
3651 /* Make a place to write the result of the instruction. */
3652 result = target;
3653 if (! (result != 0
3654 && REG_P (result) && GET_MODE (result) == insn_mode
3655 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3656 result = gen_reg_rtx (insn_mode);
3658 arg1_rtx = get_memory_rtx (arg1, len);
3659 arg2_rtx = get_memory_rtx (arg2, len);
3660 arg3_rtx = expand_normal (len);
3662 /* Set MEM_SIZE as appropriate. */
3663 if (GET_CODE (arg3_rtx) == CONST_INT)
3665 set_mem_size (arg1_rtx, arg3_rtx);
3666 set_mem_size (arg2_rtx, arg3_rtx);
3669 #ifdef HAVE_cmpmemsi
3670 if (HAVE_cmpmemsi)
3671 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3672 GEN_INT (MIN (arg1_align, arg2_align)));
3673 else
3674 #endif
3675 #ifdef HAVE_cmpstrnsi
3676 if (HAVE_cmpstrnsi)
3677 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3678 GEN_INT (MIN (arg1_align, arg2_align)));
3679 else
3680 #endif
3681 gcc_unreachable ();
3683 if (insn)
3684 emit_insn (insn);
3685 else
3686 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3687 TYPE_MODE (integer_type_node), 3,
3688 XEXP (arg1_rtx, 0), Pmode,
3689 XEXP (arg2_rtx, 0), Pmode,
3690 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3691 TYPE_UNSIGNED (sizetype)),
3692 TYPE_MODE (sizetype));
3694 /* Return the value in the proper mode for this function. */
3695 mode = TYPE_MODE (TREE_TYPE (exp));
3696 if (GET_MODE (result) == mode)
3697 return result;
3698 else if (target != 0)
3700 convert_move (target, result, 0);
3701 return target;
3703 else
3704 return convert_to_mode (mode, result, 0);
3706 #endif
3708 return 0;
3711 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3712 if we failed the caller should emit a normal call, otherwise try to get
3713 the result in TARGET, if convenient. */
3715 static rtx
3716 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3718 tree arglist = TREE_OPERAND (exp, 1);
3720 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3721 return 0;
3722 else
3724 tree result = fold_builtin_strcmp (arglist);
3725 if (result)
3726 return expand_expr (result, target, mode, EXPAND_NORMAL);
3729 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3730 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3731 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3733 rtx arg1_rtx, arg2_rtx;
3734 rtx result, insn = NULL_RTX;
3735 tree fndecl, fn;
3737 tree arg1 = TREE_VALUE (arglist);
3738 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3739 int arg1_align
3740 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3741 int arg2_align
3742 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3744 /* If we don't have POINTER_TYPE, call the function. */
3745 if (arg1_align == 0 || arg2_align == 0)
3746 return 0;
3748 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3749 arg1 = builtin_save_expr (arg1);
3750 arg2 = builtin_save_expr (arg2);
3752 arg1_rtx = get_memory_rtx (arg1, NULL);
3753 arg2_rtx = get_memory_rtx (arg2, NULL);
3755 #ifdef HAVE_cmpstrsi
3756 /* Try to call cmpstrsi. */
3757 if (HAVE_cmpstrsi)
3759 enum machine_mode insn_mode
3760 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3762 /* Make a place to write the result of the instruction. */
3763 result = target;
3764 if (! (result != 0
3765 && REG_P (result) && GET_MODE (result) == insn_mode
3766 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3767 result = gen_reg_rtx (insn_mode);
3769 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3770 GEN_INT (MIN (arg1_align, arg2_align)));
3772 #endif
3773 #ifdef HAVE_cmpstrnsi
3774 /* Try to determine at least one length and call cmpstrnsi. */
3775 if (!insn && HAVE_cmpstrnsi)
3777 tree len;
3778 rtx arg3_rtx;
3780 enum machine_mode insn_mode
3781 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3782 tree len1 = c_strlen (arg1, 1);
3783 tree len2 = c_strlen (arg2, 1);
3785 if (len1)
3786 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3787 if (len2)
3788 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3790 /* If we don't have a constant length for the first, use the length
3791 of the second, if we know it. We don't require a constant for
3792 this case; some cost analysis could be done if both are available
3793 but neither is constant. For now, assume they're equally cheap,
3794 unless one has side effects. If both strings have constant lengths,
3795 use the smaller. */
3797 if (!len1)
3798 len = len2;
3799 else if (!len2)
3800 len = len1;
3801 else if (TREE_SIDE_EFFECTS (len1))
3802 len = len2;
3803 else if (TREE_SIDE_EFFECTS (len2))
3804 len = len1;
3805 else if (TREE_CODE (len1) != INTEGER_CST)
3806 len = len2;
3807 else if (TREE_CODE (len2) != INTEGER_CST)
3808 len = len1;
3809 else if (tree_int_cst_lt (len1, len2))
3810 len = len1;
3811 else
3812 len = len2;
3814 /* If both arguments have side effects, we cannot optimize. */
3815 if (!len || TREE_SIDE_EFFECTS (len))
3816 goto do_libcall;
3818 arg3_rtx = expand_normal (len);
3820 /* Make a place to write the result of the instruction. */
3821 result = target;
3822 if (! (result != 0
3823 && REG_P (result) && GET_MODE (result) == insn_mode
3824 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3825 result = gen_reg_rtx (insn_mode);
3827 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3828 GEN_INT (MIN (arg1_align, arg2_align)));
3830 #endif
3832 if (insn)
3834 emit_insn (insn);
3836 /* Return the value in the proper mode for this function. */
3837 mode = TYPE_MODE (TREE_TYPE (exp));
3838 if (GET_MODE (result) == mode)
3839 return result;
3840 if (target == 0)
3841 return convert_to_mode (mode, result, 0);
3842 convert_move (target, result, 0);
3843 return target;
3846 /* Expand the library call ourselves using a stabilized argument
3847 list to avoid re-evaluating the function's arguments twice. */
3848 #ifdef HAVE_cmpstrnsi
3849 do_libcall:
3850 #endif
3851 arglist = build_tree_list (NULL_TREE, arg2);
3852 arglist = tree_cons (NULL_TREE, arg1, arglist);
3853 fndecl = get_callee_fndecl (exp);
3854 fn = build_function_call_expr (fndecl, arglist);
3855 if (TREE_CODE (fn) == CALL_EXPR)
3856 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3857 return expand_call (fn, target, target == const0_rtx);
3859 #endif
3860 return 0;
3863 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3864 if we failed the caller should emit a normal call, otherwise try to get
3865 the result in TARGET, if convenient. */
3867 static rtx
3868 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3870 tree arglist = TREE_OPERAND (exp, 1);
3872 if (!validate_arglist (arglist,
3873 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3874 return 0;
3875 else
3877 tree result = fold_builtin_strncmp (arglist);
3878 if (result)
3879 return expand_expr (result, target, mode, EXPAND_NORMAL);
3882 /* If c_strlen can determine an expression for one of the string
3883 lengths, and it doesn't have side effects, then emit cmpstrnsi
3884 using length MIN(strlen(string)+1, arg3). */
3885 #ifdef HAVE_cmpstrnsi
3886 if (HAVE_cmpstrnsi)
3888 tree arg1 = TREE_VALUE (arglist);
3889 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3890 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3891 tree len, len1, len2;
3892 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3893 rtx result, insn;
3894 tree fndecl, fn;
3896 int arg1_align
3897 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3898 int arg2_align
3899 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3900 enum machine_mode insn_mode
3901 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3903 len1 = c_strlen (arg1, 1);
3904 len2 = c_strlen (arg2, 1);
3906 if (len1)
3907 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3908 if (len2)
3909 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3911 /* If we don't have a constant length for the first, use the length
3912 of the second, if we know it. We don't require a constant for
3913 this case; some cost analysis could be done if both are available
3914 but neither is constant. For now, assume they're equally cheap,
3915 unless one has side effects. If both strings have constant lengths,
3916 use the smaller. */
3918 if (!len1)
3919 len = len2;
3920 else if (!len2)
3921 len = len1;
3922 else if (TREE_SIDE_EFFECTS (len1))
3923 len = len2;
3924 else if (TREE_SIDE_EFFECTS (len2))
3925 len = len1;
3926 else if (TREE_CODE (len1) != INTEGER_CST)
3927 len = len2;
3928 else if (TREE_CODE (len2) != INTEGER_CST)
3929 len = len1;
3930 else if (tree_int_cst_lt (len1, len2))
3931 len = len1;
3932 else
3933 len = len2;
3935 /* If both arguments have side effects, we cannot optimize. */
3936 if (!len || TREE_SIDE_EFFECTS (len))
3937 return 0;
3939 /* The actual new length parameter is MIN(len,arg3). */
3940 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3941 fold_convert (TREE_TYPE (len), arg3));
3943 /* If we don't have POINTER_TYPE, call the function. */
3944 if (arg1_align == 0 || arg2_align == 0)
3945 return 0;
3947 /* Make a place to write the result of the instruction. */
3948 result = target;
3949 if (! (result != 0
3950 && REG_P (result) && GET_MODE (result) == insn_mode
3951 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3952 result = gen_reg_rtx (insn_mode);
3954 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3955 arg1 = builtin_save_expr (arg1);
3956 arg2 = builtin_save_expr (arg2);
3957 len = builtin_save_expr (len);
3959 arg1_rtx = get_memory_rtx (arg1, len);
3960 arg2_rtx = get_memory_rtx (arg2, len);
3961 arg3_rtx = expand_normal (len);
3962 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3963 GEN_INT (MIN (arg1_align, arg2_align)));
3964 if (insn)
3966 emit_insn (insn);
3968 /* Return the value in the proper mode for this function. */
3969 mode = TYPE_MODE (TREE_TYPE (exp));
3970 if (GET_MODE (result) == mode)
3971 return result;
3972 if (target == 0)
3973 return convert_to_mode (mode, result, 0);
3974 convert_move (target, result, 0);
3975 return target;
3978 /* Expand the library call ourselves using a stabilized argument
3979 list to avoid re-evaluating the function's arguments twice. */
3980 arglist = build_tree_list (NULL_TREE, len);
3981 arglist = tree_cons (NULL_TREE, arg2, arglist);
3982 arglist = tree_cons (NULL_TREE, arg1, arglist);
3983 fndecl = get_callee_fndecl (exp);
3984 fn = build_function_call_expr (fndecl, arglist);
3985 if (TREE_CODE (fn) == CALL_EXPR)
3986 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3987 return expand_call (fn, target, target == const0_rtx);
3989 #endif
3990 return 0;
3993 /* Expand expression EXP, which is a call to the strcat builtin.
3994 Return 0 if we failed the caller should emit a normal call,
3995 otherwise try to get the result in TARGET, if convenient. */
3997 static rtx
3998 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4000 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4001 return 0;
4002 else
4004 tree dst = TREE_VALUE (arglist),
4005 src = TREE_VALUE (TREE_CHAIN (arglist));
4006 const char *p = c_getstr (src);
4008 /* If the string length is zero, return the dst parameter. */
4009 if (p && *p == '\0')
4010 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4012 if (!optimize_size)
4014 /* See if we can store by pieces into (dst + strlen(dst)). */
4015 tree newsrc, newdst,
4016 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4017 rtx insns;
4019 /* Stabilize the argument list. */
4020 newsrc = builtin_save_expr (src);
4021 if (newsrc != src)
4022 arglist = build_tree_list (NULL_TREE, newsrc);
4023 else
4024 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4026 dst = builtin_save_expr (dst);
4028 start_sequence ();
4030 /* Create strlen (dst). */
4031 newdst =
4032 build_function_call_expr (strlen_fn,
4033 build_tree_list (NULL_TREE, dst));
4034 /* Create (dst + (cast) strlen (dst)). */
4035 newdst = fold_convert (TREE_TYPE (dst), newdst);
4036 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4038 newdst = builtin_save_expr (newdst);
4039 arglist = tree_cons (NULL_TREE, newdst, arglist);
4041 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4043 end_sequence (); /* Stop sequence. */
4044 return 0;
4047 /* Output the entire sequence. */
4048 insns = get_insns ();
4049 end_sequence ();
4050 emit_insn (insns);
4052 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4055 return 0;
4059 /* Expand expression EXP, which is a call to the strncat builtin.
4060 Return 0 if we failed the caller should emit a normal call,
4061 otherwise try to get the result in TARGET, if convenient. */
4063 static rtx
4064 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4066 if (validate_arglist (arglist,
4067 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4069 tree result = fold_builtin_strncat (arglist);
4070 if (result)
4071 return expand_expr (result, target, mode, EXPAND_NORMAL);
4073 return 0;
4076 /* Expand expression EXP, which is a call to the strspn builtin.
4077 Return 0 if we failed the caller should emit a normal call,
4078 otherwise try to get the result in TARGET, if convenient. */
4080 static rtx
4081 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4083 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4085 tree result = fold_builtin_strspn (arglist);
4086 if (result)
4087 return expand_expr (result, target, mode, EXPAND_NORMAL);
4089 return 0;
4092 /* Expand expression EXP, which is a call to the strcspn builtin.
4093 Return 0 if we failed the caller should emit a normal call,
4094 otherwise try to get the result in TARGET, if convenient. */
4096 static rtx
4097 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4099 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4101 tree result = fold_builtin_strcspn (arglist);
4102 if (result)
4103 return expand_expr (result, target, mode, EXPAND_NORMAL);
4105 return 0;
4108 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4109 if that's convenient. */
4112 expand_builtin_saveregs (void)
4114 rtx val, seq;
4116 /* Don't do __builtin_saveregs more than once in a function.
4117 Save the result of the first call and reuse it. */
4118 if (saveregs_value != 0)
4119 return saveregs_value;
4121 /* When this function is called, it means that registers must be
4122 saved on entry to this function. So we migrate the call to the
4123 first insn of this function. */
4125 start_sequence ();
4127 /* Do whatever the machine needs done in this case. */
4128 val = targetm.calls.expand_builtin_saveregs ();
4130 seq = get_insns ();
4131 end_sequence ();
4133 saveregs_value = val;
4135 /* Put the insns after the NOTE that starts the function. If this
4136 is inside a start_sequence, make the outer-level insn chain current, so
4137 the code is placed at the start of the function. */
4138 push_topmost_sequence ();
4139 emit_insn_after (seq, entry_of_function ());
4140 pop_topmost_sequence ();
4142 return val;
4145 /* __builtin_args_info (N) returns word N of the arg space info
4146 for the current function. The number and meanings of words
4147 is controlled by the definition of CUMULATIVE_ARGS. */
4149 static rtx
4150 expand_builtin_args_info (tree arglist)
4152 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4153 int *word_ptr = (int *) &current_function_args_info;
4155 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4157 if (arglist != 0)
4159 if (!host_integerp (TREE_VALUE (arglist), 0))
4160 error ("argument of %<__builtin_args_info%> must be constant");
4161 else
4163 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4165 if (wordnum < 0 || wordnum >= nwords)
4166 error ("argument of %<__builtin_args_info%> out of range");
4167 else
4168 return GEN_INT (word_ptr[wordnum]);
4171 else
4172 error ("missing argument in %<__builtin_args_info%>");
4174 return const0_rtx;
4177 /* Expand a call to __builtin_next_arg. */
4179 static rtx
4180 expand_builtin_next_arg (void)
4182 /* Checking arguments is already done in fold_builtin_next_arg
4183 that must be called before this function. */
4184 return expand_binop (Pmode, add_optab,
4185 current_function_internal_arg_pointer,
4186 current_function_arg_offset_rtx,
4187 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4190 /* Make it easier for the backends by protecting the valist argument
4191 from multiple evaluations. */
4193 static tree
4194 stabilize_va_list (tree valist, int needs_lvalue)
4196 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4198 if (TREE_SIDE_EFFECTS (valist))
4199 valist = save_expr (valist);
4201 /* For this case, the backends will be expecting a pointer to
4202 TREE_TYPE (va_list_type_node), but it's possible we've
4203 actually been given an array (an actual va_list_type_node).
4204 So fix it. */
4205 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4207 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4208 valist = build_fold_addr_expr_with_type (valist, p1);
4211 else
4213 tree pt;
4215 if (! needs_lvalue)
4217 if (! TREE_SIDE_EFFECTS (valist))
4218 return valist;
4220 pt = build_pointer_type (va_list_type_node);
4221 valist = fold_build1 (ADDR_EXPR, pt, valist);
4222 TREE_SIDE_EFFECTS (valist) = 1;
4225 if (TREE_SIDE_EFFECTS (valist))
4226 valist = save_expr (valist);
4227 valist = build_fold_indirect_ref (valist);
4230 return valist;
4233 /* The "standard" definition of va_list is void*. */
4235 tree
4236 std_build_builtin_va_list (void)
4238 return ptr_type_node;
4241 /* The "standard" implementation of va_start: just assign `nextarg' to
4242 the variable. */
4244 void
4245 std_expand_builtin_va_start (tree valist, rtx nextarg)
4247 tree t;
4249 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4250 make_tree (ptr_type_node, nextarg));
4251 TREE_SIDE_EFFECTS (t) = 1;
4253 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4256 /* Expand ARGLIST, from a call to __builtin_va_start. */
4258 static rtx
4259 expand_builtin_va_start (tree arglist)
4261 rtx nextarg;
4262 tree chain, valist;
4264 chain = TREE_CHAIN (arglist);
4266 if (!chain)
4268 error ("too few arguments to function %<va_start%>");
4269 return const0_rtx;
4272 if (fold_builtin_next_arg (chain))
4273 return const0_rtx;
4275 nextarg = expand_builtin_next_arg ();
4276 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4278 #ifdef EXPAND_BUILTIN_VA_START
4279 EXPAND_BUILTIN_VA_START (valist, nextarg);
4280 #else
4281 std_expand_builtin_va_start (valist, nextarg);
4282 #endif
4284 return const0_rtx;
4287 /* The "standard" implementation of va_arg: read the value from the
4288 current (padded) address and increment by the (padded) size. */
4290 tree
4291 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4293 tree addr, t, type_size, rounded_size, valist_tmp;
4294 unsigned HOST_WIDE_INT align, boundary;
4295 bool indirect;
4297 #ifdef ARGS_GROW_DOWNWARD
4298 /* All of the alignment and movement below is for args-grow-up machines.
4299 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4300 implement their own specialized gimplify_va_arg_expr routines. */
4301 gcc_unreachable ();
4302 #endif
4304 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4305 if (indirect)
4306 type = build_pointer_type (type);
4308 align = PARM_BOUNDARY / BITS_PER_UNIT;
4309 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4311 /* Hoist the valist value into a temporary for the moment. */
4312 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4314 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4315 requires greater alignment, we must perform dynamic alignment. */
4316 if (boundary > align
4317 && !integer_zerop (TYPE_SIZE (type)))
4319 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4320 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4321 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4322 gimplify_and_add (t, pre_p);
4324 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4325 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4326 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4327 gimplify_and_add (t, pre_p);
4329 else
4330 boundary = align;
4332 /* If the actual alignment is less than the alignment of the type,
4333 adjust the type accordingly so that we don't assume strict alignment
4334 when deferencing the pointer. */
4335 boundary *= BITS_PER_UNIT;
4336 if (boundary < TYPE_ALIGN (type))
4338 type = build_variant_type_copy (type);
4339 TYPE_ALIGN (type) = boundary;
4342 /* Compute the rounded size of the type. */
4343 type_size = size_in_bytes (type);
4344 rounded_size = round_up (type_size, align);
4346 /* Reduce rounded_size so it's sharable with the postqueue. */
4347 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4349 /* Get AP. */
4350 addr = valist_tmp;
4351 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4353 /* Small args are padded downward. */
4354 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4355 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4356 size_binop (MINUS_EXPR, rounded_size, type_size));
4357 t = fold_convert (TREE_TYPE (addr), t);
4358 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4361 /* Compute new value for AP. */
4362 t = fold_convert (TREE_TYPE (valist), rounded_size);
4363 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4364 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4365 gimplify_and_add (t, pre_p);
4367 addr = fold_convert (build_pointer_type (type), addr);
4369 if (indirect)
4370 addr = build_va_arg_indirect_ref (addr);
4372 return build_va_arg_indirect_ref (addr);
4375 /* Build an indirect-ref expression over the given TREE, which represents a
4376 piece of a va_arg() expansion. */
4377 tree
4378 build_va_arg_indirect_ref (tree addr)
4380 addr = build_fold_indirect_ref (addr);
4382 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4383 mf_mark (addr);
4385 return addr;
4388 /* Return a dummy expression of type TYPE in order to keep going after an
4389 error. */
4391 static tree
4392 dummy_object (tree type)
4394 tree t = build_int_cst (build_pointer_type (type), 0);
4395 return build1 (INDIRECT_REF, type, t);
4398 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4399 builtin function, but a very special sort of operator. */
4401 enum gimplify_status
4402 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4404 tree promoted_type, want_va_type, have_va_type;
4405 tree valist = TREE_OPERAND (*expr_p, 0);
4406 tree type = TREE_TYPE (*expr_p);
4407 tree t;
4409 /* Verify that valist is of the proper type. */
4410 want_va_type = va_list_type_node;
4411 have_va_type = TREE_TYPE (valist);
4413 if (have_va_type == error_mark_node)
4414 return GS_ERROR;
4416 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4418 /* If va_list is an array type, the argument may have decayed
4419 to a pointer type, e.g. by being passed to another function.
4420 In that case, unwrap both types so that we can compare the
4421 underlying records. */
4422 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4423 || POINTER_TYPE_P (have_va_type))
4425 want_va_type = TREE_TYPE (want_va_type);
4426 have_va_type = TREE_TYPE (have_va_type);
4430 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4432 error ("first argument to %<va_arg%> not of type %<va_list%>");
4433 return GS_ERROR;
4436 /* Generate a diagnostic for requesting data of a type that cannot
4437 be passed through `...' due to type promotion at the call site. */
4438 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4439 != type)
4441 static bool gave_help;
4443 /* Unfortunately, this is merely undefined, rather than a constraint
4444 violation, so we cannot make this an error. If this call is never
4445 executed, the program is still strictly conforming. */
4446 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4447 type, promoted_type);
4448 if (! gave_help)
4450 gave_help = true;
4451 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4452 promoted_type, type);
4455 /* We can, however, treat "undefined" any way we please.
4456 Call abort to encourage the user to fix the program. */
4457 inform ("if this code is reached, the program will abort");
4458 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4459 NULL);
4460 append_to_statement_list (t, pre_p);
4462 /* This is dead code, but go ahead and finish so that the
4463 mode of the result comes out right. */
4464 *expr_p = dummy_object (type);
4465 return GS_ALL_DONE;
4467 else
4469 /* Make it easier for the backends by protecting the valist argument
4470 from multiple evaluations. */
4471 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4473 /* For this case, the backends will be expecting a pointer to
4474 TREE_TYPE (va_list_type_node), but it's possible we've
4475 actually been given an array (an actual va_list_type_node).
4476 So fix it. */
4477 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4479 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4480 valist = build_fold_addr_expr_with_type (valist, p1);
4482 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4484 else
4485 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4487 if (!targetm.gimplify_va_arg_expr)
4488 /* FIXME:Once most targets are converted we should merely
4489 assert this is non-null. */
4490 return GS_ALL_DONE;
4492 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4493 return GS_OK;
4497 /* Expand ARGLIST, from a call to __builtin_va_end. */
4499 static rtx
4500 expand_builtin_va_end (tree arglist)
4502 tree valist = TREE_VALUE (arglist);
4504 /* Evaluate for side effects, if needed. I hate macros that don't
4505 do that. */
4506 if (TREE_SIDE_EFFECTS (valist))
4507 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4509 return const0_rtx;
4512 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4513 builtin rather than just as an assignment in stdarg.h because of the
4514 nastiness of array-type va_list types. */
4516 static rtx
4517 expand_builtin_va_copy (tree arglist)
4519 tree dst, src, t;
4521 dst = TREE_VALUE (arglist);
4522 src = TREE_VALUE (TREE_CHAIN (arglist));
4524 dst = stabilize_va_list (dst, 1);
4525 src = stabilize_va_list (src, 0);
4527 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4529 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4530 TREE_SIDE_EFFECTS (t) = 1;
4531 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4533 else
4535 rtx dstb, srcb, size;
4537 /* Evaluate to pointers. */
4538 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4539 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4540 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4541 VOIDmode, EXPAND_NORMAL);
4543 dstb = convert_memory_address (Pmode, dstb);
4544 srcb = convert_memory_address (Pmode, srcb);
4546 /* "Dereference" to BLKmode memories. */
4547 dstb = gen_rtx_MEM (BLKmode, dstb);
4548 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4549 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4550 srcb = gen_rtx_MEM (BLKmode, srcb);
4551 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4552 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4554 /* Copy. */
4555 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4558 return const0_rtx;
4561 /* Expand a call to one of the builtin functions __builtin_frame_address or
4562 __builtin_return_address. */
4564 static rtx
4565 expand_builtin_frame_address (tree fndecl, tree arglist)
4567 /* The argument must be a nonnegative integer constant.
4568 It counts the number of frames to scan up the stack.
4569 The value is the return address saved in that frame. */
4570 if (arglist == 0)
4571 /* Warning about missing arg was already issued. */
4572 return const0_rtx;
4573 else if (! host_integerp (TREE_VALUE (arglist), 1))
4575 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4576 error ("invalid argument to %<__builtin_frame_address%>");
4577 else
4578 error ("invalid argument to %<__builtin_return_address%>");
4579 return const0_rtx;
4581 else
4583 rtx tem
4584 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4585 tree_low_cst (TREE_VALUE (arglist), 1));
4587 /* Some ports cannot access arbitrary stack frames. */
4588 if (tem == NULL)
4590 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4591 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4592 else
4593 warning (0, "unsupported argument to %<__builtin_return_address%>");
4594 return const0_rtx;
4597 /* For __builtin_frame_address, return what we've got. */
4598 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4599 return tem;
4601 if (!REG_P (tem)
4602 && ! CONSTANT_P (tem))
4603 tem = copy_to_mode_reg (Pmode, tem);
4604 return tem;
4608 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4609 we failed and the caller should emit a normal call, otherwise try to get
4610 the result in TARGET, if convenient. */
4612 static rtx
4613 expand_builtin_alloca (tree arglist, rtx target)
4615 rtx op0;
4616 rtx result;
4618 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4619 should always expand to function calls. These can be intercepted
4620 in libmudflap. */
4621 if (flag_mudflap)
4622 return 0;
4624 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4625 return 0;
4627 /* Compute the argument. */
4628 op0 = expand_normal (TREE_VALUE (arglist));
4630 /* Allocate the desired space. */
4631 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4632 result = convert_memory_address (ptr_mode, result);
4634 return result;
4637 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4638 Return 0 if a normal call should be emitted rather than expanding the
4639 function in-line. If convenient, the result should be placed in TARGET.
4640 SUBTARGET may be used as the target for computing one of EXP's operands. */
4642 static rtx
4643 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4644 rtx subtarget, optab op_optab)
4646 rtx op0;
4647 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4648 return 0;
4650 /* Compute the argument. */
4651 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4652 /* Compute op, into TARGET if possible.
4653 Set TARGET to wherever the result comes back. */
4654 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4655 op_optab, op0, target, 1);
4656 gcc_assert (target);
4658 return convert_to_mode (target_mode, target, 0);
4661 /* If the string passed to fputs is a constant and is one character
4662 long, we attempt to transform this call into __builtin_fputc(). */
4664 static rtx
4665 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4667 /* Verify the arguments in the original call. */
4668 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4670 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4671 unlocked, NULL_TREE);
4672 if (result)
4673 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4675 return 0;
4678 /* Expand a call to __builtin_expect. We return our argument and emit a
4679 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4680 a non-jump context. */
4682 static rtx
4683 expand_builtin_expect (tree arglist, rtx target)
4685 tree exp, c;
4686 rtx note, rtx_c;
4688 if (arglist == NULL_TREE
4689 || TREE_CHAIN (arglist) == NULL_TREE)
4690 return const0_rtx;
4691 exp = TREE_VALUE (arglist);
4692 c = TREE_VALUE (TREE_CHAIN (arglist));
4694 if (TREE_CODE (c) != INTEGER_CST)
4696 error ("second argument to %<__builtin_expect%> must be a constant");
4697 c = integer_zero_node;
4700 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4702 /* Don't bother with expected value notes for integral constants. */
4703 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4705 /* We do need to force this into a register so that we can be
4706 moderately sure to be able to correctly interpret the branch
4707 condition later. */
4708 target = force_reg (GET_MODE (target), target);
4710 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4712 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4713 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4716 return target;
4719 /* Like expand_builtin_expect, except do this in a jump context. This is
4720 called from do_jump if the conditional is a __builtin_expect. Return either
4721 a list of insns to emit the jump or NULL if we cannot optimize
4722 __builtin_expect. We need to optimize this at jump time so that machines
4723 like the PowerPC don't turn the test into a SCC operation, and then jump
4724 based on the test being 0/1. */
4727 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4729 tree arglist = TREE_OPERAND (exp, 1);
4730 tree arg0 = TREE_VALUE (arglist);
4731 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4732 rtx ret = NULL_RTX;
4734 /* Only handle __builtin_expect (test, 0) and
4735 __builtin_expect (test, 1). */
4736 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4737 && (integer_zerop (arg1) || integer_onep (arg1)))
4739 rtx insn, drop_through_label, temp;
4741 /* Expand the jump insns. */
4742 start_sequence ();
4743 do_jump (arg0, if_false_label, if_true_label);
4744 ret = get_insns ();
4746 drop_through_label = get_last_insn ();
4747 if (drop_through_label && NOTE_P (drop_through_label))
4748 drop_through_label = prev_nonnote_insn (drop_through_label);
4749 if (drop_through_label && !LABEL_P (drop_through_label))
4750 drop_through_label = NULL_RTX;
4751 end_sequence ();
4753 if (! if_true_label)
4754 if_true_label = drop_through_label;
4755 if (! if_false_label)
4756 if_false_label = drop_through_label;
4758 /* Go through and add the expect's to each of the conditional jumps. */
4759 insn = ret;
4760 while (insn != NULL_RTX)
4762 rtx next = NEXT_INSN (insn);
4764 if (JUMP_P (insn) && any_condjump_p (insn))
4766 rtx ifelse = SET_SRC (pc_set (insn));
4767 rtx then_dest = XEXP (ifelse, 1);
4768 rtx else_dest = XEXP (ifelse, 2);
4769 int taken = -1;
4771 /* First check if we recognize any of the labels. */
4772 if (GET_CODE (then_dest) == LABEL_REF
4773 && XEXP (then_dest, 0) == if_true_label)
4774 taken = 1;
4775 else if (GET_CODE (then_dest) == LABEL_REF
4776 && XEXP (then_dest, 0) == if_false_label)
4777 taken = 0;
4778 else if (GET_CODE (else_dest) == LABEL_REF
4779 && XEXP (else_dest, 0) == if_false_label)
4780 taken = 1;
4781 else if (GET_CODE (else_dest) == LABEL_REF
4782 && XEXP (else_dest, 0) == if_true_label)
4783 taken = 0;
4784 /* Otherwise check where we drop through. */
4785 else if (else_dest == pc_rtx)
4787 if (next && NOTE_P (next))
4788 next = next_nonnote_insn (next);
4790 if (next && JUMP_P (next)
4791 && any_uncondjump_p (next))
4792 temp = XEXP (SET_SRC (pc_set (next)), 0);
4793 else
4794 temp = next;
4796 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4797 else that can't possibly match either target label. */
4798 if (temp == if_false_label)
4799 taken = 1;
4800 else if (temp == if_true_label)
4801 taken = 0;
4803 else if (then_dest == pc_rtx)
4805 if (next && NOTE_P (next))
4806 next = next_nonnote_insn (next);
4808 if (next && JUMP_P (next)
4809 && any_uncondjump_p (next))
4810 temp = XEXP (SET_SRC (pc_set (next)), 0);
4811 else
4812 temp = next;
4814 if (temp == if_false_label)
4815 taken = 0;
4816 else if (temp == if_true_label)
4817 taken = 1;
4820 if (taken != -1)
4822 /* If the test is expected to fail, reverse the
4823 probabilities. */
4824 if (integer_zerop (arg1))
4825 taken = 1 - taken;
4826 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4830 insn = next;
4834 return ret;
4837 void
4838 expand_builtin_trap (void)
4840 #ifdef HAVE_trap
4841 if (HAVE_trap)
4842 emit_insn (gen_trap ());
4843 else
4844 #endif
4845 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4846 emit_barrier ();
4849 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4850 Return 0 if a normal call should be emitted rather than expanding
4851 the function inline. If convenient, the result should be placed
4852 in TARGET. SUBTARGET may be used as the target for computing
4853 the operand. */
4855 static rtx
4856 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4858 enum machine_mode mode;
4859 tree arg;
4860 rtx op0;
4862 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4863 return 0;
4865 arg = TREE_VALUE (arglist);
4866 mode = TYPE_MODE (TREE_TYPE (arg));
4867 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4868 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4871 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4872 Return NULL is a normal call should be emitted rather than expanding the
4873 function inline. If convenient, the result should be placed in TARGET.
4874 SUBTARGET may be used as the target for computing the operand. */
4876 static rtx
4877 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4879 rtx op0, op1;
4880 tree arg;
4882 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4883 return 0;
4885 arg = TREE_VALUE (arglist);
4886 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4888 arg = TREE_VALUE (TREE_CHAIN (arglist));
4889 op1 = expand_normal (arg);
4891 return expand_copysign (op0, op1, target);
4894 /* Create a new constant string literal and return a char* pointer to it.
4895 The STRING_CST value is the LEN characters at STR. */
4896 tree
4897 build_string_literal (int len, const char *str)
4899 tree t, elem, index, type;
4901 t = build_string (len, str);
4902 elem = build_type_variant (char_type_node, 1, 0);
4903 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4904 type = build_array_type (elem, index);
4905 TREE_TYPE (t) = type;
4906 TREE_CONSTANT (t) = 1;
4907 TREE_INVARIANT (t) = 1;
4908 TREE_READONLY (t) = 1;
4909 TREE_STATIC (t) = 1;
4911 type = build_pointer_type (type);
4912 t = build1 (ADDR_EXPR, type, t);
4914 type = build_pointer_type (elem);
4915 t = build1 (NOP_EXPR, type, t);
4916 return t;
4919 /* Expand EXP, a call to printf or printf_unlocked.
4920 Return 0 if a normal call should be emitted rather than transforming
4921 the function inline. If convenient, the result should be placed in
4922 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4923 call. */
4924 static rtx
4925 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4926 bool unlocked)
4928 tree arglist = TREE_OPERAND (exp, 1);
4929 /* If we're using an unlocked function, assume the other unlocked
4930 functions exist explicitly. */
4931 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4932 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4933 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4934 : implicit_built_in_decls[BUILT_IN_PUTS];
4935 const char *fmt_str;
4936 tree fn, fmt, arg;
4938 /* If the return value is used, don't do the transformation. */
4939 if (target != const0_rtx)
4940 return 0;
4942 /* Verify the required arguments in the original call. */
4943 if (! arglist)
4944 return 0;
4945 fmt = TREE_VALUE (arglist);
4946 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4947 return 0;
4948 arglist = TREE_CHAIN (arglist);
4950 /* Check whether the format is a literal string constant. */
4951 fmt_str = c_getstr (fmt);
4952 if (fmt_str == NULL)
4953 return 0;
4955 if (!init_target_chars())
4956 return 0;
4958 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4959 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4961 if (! arglist
4962 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4963 || TREE_CHAIN (arglist))
4964 return 0;
4965 fn = fn_puts;
4967 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4968 else if (strcmp (fmt_str, target_percent_c) == 0)
4970 if (! arglist
4971 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4972 || TREE_CHAIN (arglist))
4973 return 0;
4974 fn = fn_putchar;
4976 else
4978 /* We can't handle anything else with % args or %% ... yet. */
4979 if (strchr (fmt_str, target_percent))
4980 return 0;
4982 if (arglist)
4983 return 0;
4985 /* If the format specifier was "", printf does nothing. */
4986 if (fmt_str[0] == '\0')
4987 return const0_rtx;
4988 /* If the format specifier has length of 1, call putchar. */
4989 if (fmt_str[1] == '\0')
4991 /* Given printf("c"), (where c is any one character,)
4992 convert "c"[0] to an int and pass that to the replacement
4993 function. */
4994 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4995 arglist = build_tree_list (NULL_TREE, arg);
4996 fn = fn_putchar;
4998 else
5000 /* If the format specifier was "string\n", call puts("string"). */
5001 size_t len = strlen (fmt_str);
5002 if ((unsigned char)fmt_str[len - 1] == target_newline)
5004 /* Create a NUL-terminated string that's one char shorter
5005 than the original, stripping off the trailing '\n'. */
5006 char *newstr = alloca (len);
5007 memcpy (newstr, fmt_str, len - 1);
5008 newstr[len - 1] = 0;
5010 arg = build_string_literal (len, newstr);
5011 arglist = build_tree_list (NULL_TREE, arg);
5012 fn = fn_puts;
5014 else
5015 /* We'd like to arrange to call fputs(string,stdout) here,
5016 but we need stdout and don't have a way to get it yet. */
5017 return 0;
5021 if (!fn)
5022 return 0;
5023 fn = build_function_call_expr (fn, arglist);
5024 if (TREE_CODE (fn) == CALL_EXPR)
5025 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5026 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5029 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5030 Return 0 if a normal call should be emitted rather than transforming
5031 the function inline. If convenient, the result should be placed in
5032 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5033 call. */
5034 static rtx
5035 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5036 bool unlocked)
5038 tree arglist = TREE_OPERAND (exp, 1);
5039 /* If we're using an unlocked function, assume the other unlocked
5040 functions exist explicitly. */
5041 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5042 : implicit_built_in_decls[BUILT_IN_FPUTC];
5043 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5044 : implicit_built_in_decls[BUILT_IN_FPUTS];
5045 const char *fmt_str;
5046 tree fn, fmt, fp, arg;
5048 /* If the return value is used, don't do the transformation. */
5049 if (target != const0_rtx)
5050 return 0;
5052 /* Verify the required arguments in the original call. */
5053 if (! arglist)
5054 return 0;
5055 fp = TREE_VALUE (arglist);
5056 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5057 return 0;
5058 arglist = TREE_CHAIN (arglist);
5059 if (! arglist)
5060 return 0;
5061 fmt = TREE_VALUE (arglist);
5062 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5063 return 0;
5064 arglist = TREE_CHAIN (arglist);
5066 /* Check whether the format is a literal string constant. */
5067 fmt_str = c_getstr (fmt);
5068 if (fmt_str == NULL)
5069 return 0;
5071 if (!init_target_chars())
5072 return 0;
5074 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5075 if (strcmp (fmt_str, target_percent_s) == 0)
5077 if (! arglist
5078 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5079 || TREE_CHAIN (arglist))
5080 return 0;
5081 arg = TREE_VALUE (arglist);
5082 arglist = build_tree_list (NULL_TREE, fp);
5083 arglist = tree_cons (NULL_TREE, arg, arglist);
5084 fn = fn_fputs;
5086 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5087 else if (strcmp (fmt_str, target_percent_c) == 0)
5089 if (! arglist
5090 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5091 || TREE_CHAIN (arglist))
5092 return 0;
5093 arg = TREE_VALUE (arglist);
5094 arglist = build_tree_list (NULL_TREE, fp);
5095 arglist = tree_cons (NULL_TREE, arg, arglist);
5096 fn = fn_fputc;
5098 else
5100 /* We can't handle anything else with % args or %% ... yet. */
5101 if (strchr (fmt_str, target_percent))
5102 return 0;
5104 if (arglist)
5105 return 0;
5107 /* If the format specifier was "", fprintf does nothing. */
5108 if (fmt_str[0] == '\0')
5110 /* Evaluate and ignore FILE* argument for side-effects. */
5111 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5112 return const0_rtx;
5115 /* When "string" doesn't contain %, replace all cases of
5116 fprintf(stream,string) with fputs(string,stream). The fputs
5117 builtin will take care of special cases like length == 1. */
5118 arglist = build_tree_list (NULL_TREE, fp);
5119 arglist = tree_cons (NULL_TREE, fmt, arglist);
5120 fn = fn_fputs;
5123 if (!fn)
5124 return 0;
5125 fn = build_function_call_expr (fn, arglist);
5126 if (TREE_CODE (fn) == CALL_EXPR)
5127 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5128 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5131 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5132 a normal call should be emitted rather than expanding the function
5133 inline. If convenient, the result should be placed in TARGET with
5134 mode MODE. */
5136 static rtx
5137 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5139 tree orig_arglist, dest, fmt;
5140 const char *fmt_str;
5142 orig_arglist = arglist;
5144 /* Verify the required arguments in the original call. */
5145 if (! arglist)
5146 return 0;
5147 dest = TREE_VALUE (arglist);
5148 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5149 return 0;
5150 arglist = TREE_CHAIN (arglist);
5151 if (! arglist)
5152 return 0;
5153 fmt = TREE_VALUE (arglist);
5154 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5155 return 0;
5156 arglist = TREE_CHAIN (arglist);
5158 /* Check whether the format is a literal string constant. */
5159 fmt_str = c_getstr (fmt);
5160 if (fmt_str == NULL)
5161 return 0;
5163 if (!init_target_chars())
5164 return 0;
5166 /* If the format doesn't contain % args or %%, use strcpy. */
5167 if (strchr (fmt_str, target_percent) == 0)
5169 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5170 tree exp;
5172 if (arglist || ! fn)
5173 return 0;
5174 expand_expr (build_function_call_expr (fn, orig_arglist),
5175 const0_rtx, VOIDmode, EXPAND_NORMAL);
5176 if (target == const0_rtx)
5177 return const0_rtx;
5178 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5179 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5181 /* If the format is "%s", use strcpy if the result isn't used. */
5182 else if (strcmp (fmt_str, target_percent_s) == 0)
5184 tree fn, arg, len;
5185 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5187 if (! fn)
5188 return 0;
5190 if (! arglist || TREE_CHAIN (arglist))
5191 return 0;
5192 arg = TREE_VALUE (arglist);
5193 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5194 return 0;
5196 if (target != const0_rtx)
5198 len = c_strlen (arg, 1);
5199 if (! len || TREE_CODE (len) != INTEGER_CST)
5200 return 0;
5202 else
5203 len = NULL_TREE;
5205 arglist = build_tree_list (NULL_TREE, arg);
5206 arglist = tree_cons (NULL_TREE, dest, arglist);
5207 expand_expr (build_function_call_expr (fn, arglist),
5208 const0_rtx, VOIDmode, EXPAND_NORMAL);
5210 if (target == const0_rtx)
5211 return const0_rtx;
5212 return expand_expr (len, target, mode, EXPAND_NORMAL);
5215 return 0;
5218 /* Expand a call to either the entry or exit function profiler. */
5220 static rtx
5221 expand_builtin_profile_func (bool exitp)
5223 rtx this, which;
5225 this = DECL_RTL (current_function_decl);
5226 gcc_assert (MEM_P (this));
5227 this = XEXP (this, 0);
5229 if (exitp)
5230 which = profile_function_exit_libfunc;
5231 else
5232 which = profile_function_entry_libfunc;
5234 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5235 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5237 Pmode);
5239 return const0_rtx;
5242 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5244 static rtx
5245 round_trampoline_addr (rtx tramp)
5247 rtx temp, addend, mask;
5249 /* If we don't need too much alignment, we'll have been guaranteed
5250 proper alignment by get_trampoline_type. */
5251 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5252 return tramp;
5254 /* Round address up to desired boundary. */
5255 temp = gen_reg_rtx (Pmode);
5256 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5257 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5259 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5260 temp, 0, OPTAB_LIB_WIDEN);
5261 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5262 temp, 0, OPTAB_LIB_WIDEN);
5264 return tramp;
5267 static rtx
5268 expand_builtin_init_trampoline (tree arglist)
5270 tree t_tramp, t_func, t_chain;
5271 rtx r_tramp, r_func, r_chain;
5272 #ifdef TRAMPOLINE_TEMPLATE
5273 rtx blktramp;
5274 #endif
5276 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5277 POINTER_TYPE, VOID_TYPE))
5278 return NULL_RTX;
5280 t_tramp = TREE_VALUE (arglist);
5281 arglist = TREE_CHAIN (arglist);
5282 t_func = TREE_VALUE (arglist);
5283 arglist = TREE_CHAIN (arglist);
5284 t_chain = TREE_VALUE (arglist);
5286 r_tramp = expand_normal (t_tramp);
5287 r_func = expand_normal (t_func);
5288 r_chain = expand_normal (t_chain);
5290 /* Generate insns to initialize the trampoline. */
5291 r_tramp = round_trampoline_addr (r_tramp);
5292 #ifdef TRAMPOLINE_TEMPLATE
5293 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5294 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5295 emit_block_move (blktramp, assemble_trampoline_template (),
5296 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5297 #endif
5298 trampolines_created = 1;
5299 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5301 return const0_rtx;
5304 static rtx
5305 expand_builtin_adjust_trampoline (tree arglist)
5307 rtx tramp;
5309 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5310 return NULL_RTX;
5312 tramp = expand_normal (TREE_VALUE (arglist));
5313 tramp = round_trampoline_addr (tramp);
5314 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5315 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5316 #endif
5318 return tramp;
5321 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5322 Return NULL_RTX if a normal call should be emitted rather than expanding
5323 the function in-line. EXP is the expression that is a call to the builtin
5324 function; if convenient, the result should be placed in TARGET. */
5326 static rtx
5327 expand_builtin_signbit (tree exp, rtx target)
5329 const struct real_format *fmt;
5330 enum machine_mode fmode, imode, rmode;
5331 HOST_WIDE_INT hi, lo;
5332 tree arg, arglist;
5333 int word, bitpos;
5334 rtx temp;
5336 arglist = TREE_OPERAND (exp, 1);
5337 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5338 return 0;
5340 arg = TREE_VALUE (arglist);
5341 fmode = TYPE_MODE (TREE_TYPE (arg));
5342 rmode = TYPE_MODE (TREE_TYPE (exp));
5343 fmt = REAL_MODE_FORMAT (fmode);
5345 /* For floating point formats without a sign bit, implement signbit
5346 as "ARG < 0.0". */
5347 bitpos = fmt->signbit_ro;
5348 if (bitpos < 0)
5350 /* But we can't do this if the format supports signed zero. */
5351 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5352 return 0;
5354 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5355 build_real (TREE_TYPE (arg), dconst0));
5356 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5359 temp = expand_normal (arg);
5360 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5362 imode = int_mode_for_mode (fmode);
5363 if (imode == BLKmode)
5364 return 0;
5365 temp = gen_lowpart (imode, temp);
5367 else
5369 imode = word_mode;
5370 /* Handle targets with different FP word orders. */
5371 if (FLOAT_WORDS_BIG_ENDIAN)
5372 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5373 else
5374 word = bitpos / BITS_PER_WORD;
5375 temp = operand_subword_force (temp, word, fmode);
5376 bitpos = bitpos % BITS_PER_WORD;
5379 /* Force the intermediate word_mode (or narrower) result into a
5380 register. This avoids attempting to create paradoxical SUBREGs
5381 of floating point modes below. */
5382 temp = force_reg (imode, temp);
5384 /* If the bitpos is within the "result mode" lowpart, the operation
5385 can be implement with a single bitwise AND. Otherwise, we need
5386 a right shift and an AND. */
5388 if (bitpos < GET_MODE_BITSIZE (rmode))
5390 if (bitpos < HOST_BITS_PER_WIDE_INT)
5392 hi = 0;
5393 lo = (HOST_WIDE_INT) 1 << bitpos;
5395 else
5397 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5398 lo = 0;
5401 if (imode != rmode)
5402 temp = gen_lowpart (rmode, temp);
5403 temp = expand_binop (rmode, and_optab, temp,
5404 immed_double_const (lo, hi, rmode),
5405 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5407 else
5409 /* Perform a logical right shift to place the signbit in the least
5410 significant bit, then truncate the result to the desired mode
5411 and mask just this bit. */
5412 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5413 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5414 temp = gen_lowpart (rmode, temp);
5415 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5416 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5419 return temp;
5422 /* Expand fork or exec calls. TARGET is the desired target of the
5423 call. ARGLIST is the list of arguments of the call. FN is the
5424 identificator of the actual function. IGNORE is nonzero if the
5425 value is to be ignored. */
5427 static rtx
5428 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5430 tree id, decl;
5431 tree call;
5433 /* If we are not profiling, just call the function. */
5434 if (!profile_arc_flag)
5435 return NULL_RTX;
5437 /* Otherwise call the wrapper. This should be equivalent for the rest of
5438 compiler, so the code does not diverge, and the wrapper may run the
5439 code necessary for keeping the profiling sane. */
5441 switch (DECL_FUNCTION_CODE (fn))
5443 case BUILT_IN_FORK:
5444 id = get_identifier ("__gcov_fork");
5445 break;
5447 case BUILT_IN_EXECL:
5448 id = get_identifier ("__gcov_execl");
5449 break;
5451 case BUILT_IN_EXECV:
5452 id = get_identifier ("__gcov_execv");
5453 break;
5455 case BUILT_IN_EXECLP:
5456 id = get_identifier ("__gcov_execlp");
5457 break;
5459 case BUILT_IN_EXECLE:
5460 id = get_identifier ("__gcov_execle");
5461 break;
5463 case BUILT_IN_EXECVP:
5464 id = get_identifier ("__gcov_execvp");
5465 break;
5467 case BUILT_IN_EXECVE:
5468 id = get_identifier ("__gcov_execve");
5469 break;
5471 default:
5472 gcc_unreachable ();
5475 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5476 DECL_EXTERNAL (decl) = 1;
5477 TREE_PUBLIC (decl) = 1;
5478 DECL_ARTIFICIAL (decl) = 1;
5479 TREE_NOTHROW (decl) = 1;
5480 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5481 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5482 call = build_function_call_expr (decl, arglist);
5484 return expand_call (call, target, ignore);
5488 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5489 the pointer in these functions is void*, the tree optimizers may remove
5490 casts. The mode computed in expand_builtin isn't reliable either, due
5491 to __sync_bool_compare_and_swap.
5493 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5494 group of builtins. This gives us log2 of the mode size. */
5496 static inline enum machine_mode
5497 get_builtin_sync_mode (int fcode_diff)
5499 /* The size is not negotiable, so ask not to get BLKmode in return
5500 if the target indicates that a smaller size would be better. */
5501 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5504 /* Expand the memory expression LOC and return the appropriate memory operand
5505 for the builtin_sync operations. */
5507 static rtx
5508 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5510 rtx addr, mem;
5512 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5514 /* Note that we explicitly do not want any alias information for this
5515 memory, so that we kill all other live memories. Otherwise we don't
5516 satisfy the full barrier semantics of the intrinsic. */
5517 mem = validize_mem (gen_rtx_MEM (mode, addr));
5519 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5520 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5521 MEM_VOLATILE_P (mem) = 1;
5523 return mem;
5526 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5527 ARGLIST is the operands list to the function. CODE is the rtx code
5528 that corresponds to the arithmetic or logical operation from the name;
5529 an exception here is that NOT actually means NAND. TARGET is an optional
5530 place for us to store the results; AFTER is true if this is the
5531 fetch_and_xxx form. IGNORE is true if we don't actually care about
5532 the result of the operation at all. */
5534 static rtx
5535 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5536 enum rtx_code code, bool after,
5537 rtx target, bool ignore)
5539 rtx val, mem;
5541 /* Expand the operands. */
5542 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5544 arglist = TREE_CHAIN (arglist);
5545 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5547 if (ignore)
5548 return expand_sync_operation (mem, val, code);
5549 else
5550 return expand_sync_fetch_operation (mem, val, code, after, target);
5553 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5554 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5555 true if this is the boolean form. TARGET is a place for us to store the
5556 results; this is NOT optional if IS_BOOL is true. */
5558 static rtx
5559 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5560 bool is_bool, rtx target)
5562 rtx old_val, new_val, mem;
5564 /* Expand the operands. */
5565 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5567 arglist = TREE_CHAIN (arglist);
5568 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5570 arglist = TREE_CHAIN (arglist);
5571 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
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);
5597 return expand_sync_lock_test_and_set (mem, val, target);
5600 /* Expand the __sync_synchronize intrinsic. */
5602 static void
5603 expand_builtin_synchronize (void)
5605 tree x;
5607 #ifdef HAVE_memory_barrier
5608 if (HAVE_memory_barrier)
5610 emit_insn (gen_memory_barrier ());
5611 return;
5613 #endif
5615 /* If no explicit memory barrier instruction is available, create an
5616 empty asm stmt with a memory clobber. */
5617 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5618 tree_cons (NULL, build_string (6, "memory"), NULL));
5619 ASM_VOLATILE_P (x) = 1;
5620 expand_asm_expr (x);
5623 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5624 to the function. */
5626 static void
5627 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5629 enum insn_code icode;
5630 rtx mem, insn;
5631 rtx val = const0_rtx;
5633 /* Expand the operands. */
5634 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5636 /* If there is an explicit operation in the md file, use it. */
5637 icode = sync_lock_release[mode];
5638 if (icode != CODE_FOR_nothing)
5640 if (!insn_data[icode].operand[1].predicate (val, mode))
5641 val = force_reg (mode, val);
5643 insn = GEN_FCN (icode) (mem, val);
5644 if (insn)
5646 emit_insn (insn);
5647 return;
5651 /* Otherwise we can implement this operation by emitting a barrier
5652 followed by a store of zero. */
5653 expand_builtin_synchronize ();
5654 emit_move_insn (mem, val);
5657 /* Expand an expression EXP that calls a built-in function,
5658 with result going to TARGET if that's convenient
5659 (and in mode MODE if that's convenient).
5660 SUBTARGET may be used as the target for computing one of EXP's operands.
5661 IGNORE is nonzero if the value is to be ignored. */
5664 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5665 int ignore)
5667 tree fndecl = get_callee_fndecl (exp);
5668 tree arglist = TREE_OPERAND (exp, 1);
5669 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5670 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5672 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5673 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5675 /* When not optimizing, generate calls to library functions for a certain
5676 set of builtins. */
5677 if (!optimize
5678 && !called_as_built_in (fndecl)
5679 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5680 && fcode != BUILT_IN_ALLOCA)
5681 return expand_call (exp, target, ignore);
5683 /* The built-in function expanders test for target == const0_rtx
5684 to determine whether the function's result will be ignored. */
5685 if (ignore)
5686 target = const0_rtx;
5688 /* If the result of a pure or const built-in function is ignored, and
5689 none of its arguments are volatile, we can avoid expanding the
5690 built-in call and just evaluate the arguments for side-effects. */
5691 if (target == const0_rtx
5692 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5694 bool volatilep = false;
5695 tree arg;
5697 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5698 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5700 volatilep = true;
5701 break;
5704 if (! volatilep)
5706 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5707 expand_expr (TREE_VALUE (arg), const0_rtx,
5708 VOIDmode, EXPAND_NORMAL);
5709 return const0_rtx;
5713 switch (fcode)
5715 CASE_FLT_FN (BUILT_IN_FABS):
5716 target = expand_builtin_fabs (arglist, target, subtarget);
5717 if (target)
5718 return target;
5719 break;
5721 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5722 target = expand_builtin_copysign (arglist, target, subtarget);
5723 if (target)
5724 return target;
5725 break;
5727 /* Just do a normal library call if we were unable to fold
5728 the values. */
5729 CASE_FLT_FN (BUILT_IN_CABS):
5730 break;
5732 CASE_FLT_FN (BUILT_IN_EXP):
5733 CASE_FLT_FN (BUILT_IN_EXP10):
5734 CASE_FLT_FN (BUILT_IN_POW10):
5735 CASE_FLT_FN (BUILT_IN_EXP2):
5736 CASE_FLT_FN (BUILT_IN_EXPM1):
5737 CASE_FLT_FN (BUILT_IN_LOGB):
5738 CASE_FLT_FN (BUILT_IN_ILOGB):
5739 CASE_FLT_FN (BUILT_IN_LOG):
5740 CASE_FLT_FN (BUILT_IN_LOG10):
5741 CASE_FLT_FN (BUILT_IN_LOG2):
5742 CASE_FLT_FN (BUILT_IN_LOG1P):
5743 CASE_FLT_FN (BUILT_IN_TAN):
5744 CASE_FLT_FN (BUILT_IN_ASIN):
5745 CASE_FLT_FN (BUILT_IN_ACOS):
5746 CASE_FLT_FN (BUILT_IN_ATAN):
5747 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5748 because of possible accuracy problems. */
5749 if (! flag_unsafe_math_optimizations)
5750 break;
5751 CASE_FLT_FN (BUILT_IN_SQRT):
5752 CASE_FLT_FN (BUILT_IN_FLOOR):
5753 CASE_FLT_FN (BUILT_IN_CEIL):
5754 CASE_FLT_FN (BUILT_IN_TRUNC):
5755 CASE_FLT_FN (BUILT_IN_ROUND):
5756 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5757 CASE_FLT_FN (BUILT_IN_RINT):
5758 CASE_FLT_FN (BUILT_IN_LRINT):
5759 CASE_FLT_FN (BUILT_IN_LLRINT):
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_POW):
5775 target = expand_builtin_pow (exp, target, subtarget);
5776 if (target)
5777 return target;
5778 break;
5780 CASE_FLT_FN (BUILT_IN_POWI):
5781 target = expand_builtin_powi (exp, target, subtarget);
5782 if (target)
5783 return target;
5784 break;
5786 CASE_FLT_FN (BUILT_IN_ATAN2):
5787 CASE_FLT_FN (BUILT_IN_LDEXP):
5788 CASE_FLT_FN (BUILT_IN_FMOD):
5789 CASE_FLT_FN (BUILT_IN_DREM):
5790 if (! flag_unsafe_math_optimizations)
5791 break;
5792 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5793 if (target)
5794 return target;
5795 break;
5797 CASE_FLT_FN (BUILT_IN_SIN):
5798 CASE_FLT_FN (BUILT_IN_COS):
5799 if (! flag_unsafe_math_optimizations)
5800 break;
5801 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5802 if (target)
5803 return target;
5804 break;
5806 CASE_FLT_FN (BUILT_IN_SINCOS):
5807 if (! flag_unsafe_math_optimizations)
5808 break;
5809 target = expand_builtin_sincos (exp);
5810 if (target)
5811 return target;
5812 break;
5814 case BUILT_IN_APPLY_ARGS:
5815 return expand_builtin_apply_args ();
5817 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5818 FUNCTION with a copy of the parameters described by
5819 ARGUMENTS, and ARGSIZE. It returns a block of memory
5820 allocated on the stack into which is stored all the registers
5821 that might possibly be used for returning the result of a
5822 function. ARGUMENTS is the value returned by
5823 __builtin_apply_args. ARGSIZE is the number of bytes of
5824 arguments that must be copied. ??? How should this value be
5825 computed? We'll also need a safe worst case value for varargs
5826 functions. */
5827 case BUILT_IN_APPLY:
5828 if (!validate_arglist (arglist, POINTER_TYPE,
5829 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5830 && !validate_arglist (arglist, REFERENCE_TYPE,
5831 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5832 return const0_rtx;
5833 else
5835 int i;
5836 tree t;
5837 rtx ops[3];
5839 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5840 ops[i] = expand_normal (TREE_VALUE (t));
5842 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5845 /* __builtin_return (RESULT) causes the function to return the
5846 value described by RESULT. RESULT is address of the block of
5847 memory returned by __builtin_apply. */
5848 case BUILT_IN_RETURN:
5849 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5850 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5851 return const0_rtx;
5853 case BUILT_IN_SAVEREGS:
5854 return expand_builtin_saveregs ();
5856 case BUILT_IN_ARGS_INFO:
5857 return expand_builtin_args_info (arglist);
5859 /* Return the address of the first anonymous stack arg. */
5860 case BUILT_IN_NEXT_ARG:
5861 if (fold_builtin_next_arg (arglist))
5862 return const0_rtx;
5863 return expand_builtin_next_arg ();
5865 case BUILT_IN_CLASSIFY_TYPE:
5866 return expand_builtin_classify_type (arglist);
5868 case BUILT_IN_CONSTANT_P:
5869 return const0_rtx;
5871 case BUILT_IN_FRAME_ADDRESS:
5872 case BUILT_IN_RETURN_ADDRESS:
5873 return expand_builtin_frame_address (fndecl, arglist);
5875 /* Returns the address of the area where the structure is returned.
5876 0 otherwise. */
5877 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5878 if (arglist != 0
5879 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5880 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5881 return const0_rtx;
5882 else
5883 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5885 case BUILT_IN_ALLOCA:
5886 target = expand_builtin_alloca (arglist, target);
5887 if (target)
5888 return target;
5889 break;
5891 case BUILT_IN_STACK_SAVE:
5892 return expand_stack_save ();
5894 case BUILT_IN_STACK_RESTORE:
5895 expand_stack_restore (TREE_VALUE (arglist));
5896 return const0_rtx;
5898 CASE_INT_FN (BUILT_IN_FFS):
5899 case BUILT_IN_FFSIMAX:
5900 target = expand_builtin_unop (target_mode, arglist, target,
5901 subtarget, ffs_optab);
5902 if (target)
5903 return target;
5904 break;
5906 CASE_INT_FN (BUILT_IN_CLZ):
5907 case BUILT_IN_CLZIMAX:
5908 target = expand_builtin_unop (target_mode, arglist, target,
5909 subtarget, clz_optab);
5910 if (target)
5911 return target;
5912 break;
5914 CASE_INT_FN (BUILT_IN_CTZ):
5915 case BUILT_IN_CTZIMAX:
5916 target = expand_builtin_unop (target_mode, arglist, target,
5917 subtarget, ctz_optab);
5918 if (target)
5919 return target;
5920 break;
5922 CASE_INT_FN (BUILT_IN_POPCOUNT):
5923 case BUILT_IN_POPCOUNTIMAX:
5924 target = expand_builtin_unop (target_mode, arglist, target,
5925 subtarget, popcount_optab);
5926 if (target)
5927 return target;
5928 break;
5930 CASE_INT_FN (BUILT_IN_PARITY):
5931 case BUILT_IN_PARITYIMAX:
5932 target = expand_builtin_unop (target_mode, arglist, target,
5933 subtarget, parity_optab);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_STRLEN:
5939 target = expand_builtin_strlen (arglist, target, target_mode);
5940 if (target)
5941 return target;
5942 break;
5944 case BUILT_IN_STRCPY:
5945 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5946 if (target)
5947 return target;
5948 break;
5950 case BUILT_IN_STRNCPY:
5951 target = expand_builtin_strncpy (exp, target, mode);
5952 if (target)
5953 return target;
5954 break;
5956 case BUILT_IN_STPCPY:
5957 target = expand_builtin_stpcpy (exp, target, mode);
5958 if (target)
5959 return target;
5960 break;
5962 case BUILT_IN_STRCAT:
5963 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5964 if (target)
5965 return target;
5966 break;
5968 case BUILT_IN_STRNCAT:
5969 target = expand_builtin_strncat (arglist, target, mode);
5970 if (target)
5971 return target;
5972 break;
5974 case BUILT_IN_STRSPN:
5975 target = expand_builtin_strspn (arglist, target, mode);
5976 if (target)
5977 return target;
5978 break;
5980 case BUILT_IN_STRCSPN:
5981 target = expand_builtin_strcspn (arglist, target, mode);
5982 if (target)
5983 return target;
5984 break;
5986 case BUILT_IN_STRSTR:
5987 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5988 if (target)
5989 return target;
5990 break;
5992 case BUILT_IN_STRPBRK:
5993 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5994 if (target)
5995 return target;
5996 break;
5998 case BUILT_IN_INDEX:
5999 case BUILT_IN_STRCHR:
6000 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6001 if (target)
6002 return target;
6003 break;
6005 case BUILT_IN_RINDEX:
6006 case BUILT_IN_STRRCHR:
6007 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6008 if (target)
6009 return target;
6010 break;
6012 case BUILT_IN_MEMCPY:
6013 target = expand_builtin_memcpy (exp, target, mode);
6014 if (target)
6015 return target;
6016 break;
6018 case BUILT_IN_MEMPCPY:
6019 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6020 if (target)
6021 return target;
6022 break;
6024 case BUILT_IN_MEMMOVE:
6025 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6026 mode, exp);
6027 if (target)
6028 return target;
6029 break;
6031 case BUILT_IN_BCOPY:
6032 target = expand_builtin_bcopy (exp);
6033 if (target)
6034 return target;
6035 break;
6037 case BUILT_IN_MEMSET:
6038 target = expand_builtin_memset (arglist, target, mode, exp);
6039 if (target)
6040 return target;
6041 break;
6043 case BUILT_IN_BZERO:
6044 target = expand_builtin_bzero (exp);
6045 if (target)
6046 return target;
6047 break;
6049 case BUILT_IN_STRCMP:
6050 target = expand_builtin_strcmp (exp, target, mode);
6051 if (target)
6052 return target;
6053 break;
6055 case BUILT_IN_STRNCMP:
6056 target = expand_builtin_strncmp (exp, target, mode);
6057 if (target)
6058 return target;
6059 break;
6061 case BUILT_IN_BCMP:
6062 case BUILT_IN_MEMCMP:
6063 target = expand_builtin_memcmp (exp, arglist, target, mode);
6064 if (target)
6065 return target;
6066 break;
6068 case BUILT_IN_SETJMP:
6069 target = expand_builtin_setjmp (arglist, target);
6070 if (target)
6071 return target;
6072 break;
6074 /* __builtin_longjmp is passed a pointer to an array of five words.
6075 It's similar to the C library longjmp function but works with
6076 __builtin_setjmp above. */
6077 case BUILT_IN_LONGJMP:
6078 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6079 break;
6080 else
6082 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6083 VOIDmode, EXPAND_NORMAL);
6084 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6086 if (value != const1_rtx)
6088 error ("%<__builtin_longjmp%> second argument must be 1");
6089 return const0_rtx;
6092 expand_builtin_longjmp (buf_addr, value);
6093 return const0_rtx;
6096 case BUILT_IN_NONLOCAL_GOTO:
6097 target = expand_builtin_nonlocal_goto (arglist);
6098 if (target)
6099 return target;
6100 break;
6102 /* This updates the setjmp buffer that is its argument with the value
6103 of the current stack pointer. */
6104 case BUILT_IN_UPDATE_SETJMP_BUF:
6105 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6107 rtx buf_addr
6108 = expand_normal (TREE_VALUE (arglist));
6110 expand_builtin_update_setjmp_buf (buf_addr);
6111 return const0_rtx;
6113 break;
6115 case BUILT_IN_TRAP:
6116 expand_builtin_trap ();
6117 return const0_rtx;
6119 case BUILT_IN_PRINTF:
6120 target = expand_builtin_printf (exp, target, mode, false);
6121 if (target)
6122 return target;
6123 break;
6125 case BUILT_IN_PRINTF_UNLOCKED:
6126 target = expand_builtin_printf (exp, target, mode, true);
6127 if (target)
6128 return target;
6129 break;
6131 case BUILT_IN_FPUTS:
6132 target = expand_builtin_fputs (arglist, target, false);
6133 if (target)
6134 return target;
6135 break;
6136 case BUILT_IN_FPUTS_UNLOCKED:
6137 target = expand_builtin_fputs (arglist, target, true);
6138 if (target)
6139 return target;
6140 break;
6142 case BUILT_IN_FPRINTF:
6143 target = expand_builtin_fprintf (exp, target, mode, false);
6144 if (target)
6145 return target;
6146 break;
6148 case BUILT_IN_FPRINTF_UNLOCKED:
6149 target = expand_builtin_fprintf (exp, target, mode, true);
6150 if (target)
6151 return target;
6152 break;
6154 case BUILT_IN_SPRINTF:
6155 target = expand_builtin_sprintf (arglist, target, mode);
6156 if (target)
6157 return target;
6158 break;
6160 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6161 target = expand_builtin_signbit (exp, target);
6162 if (target)
6163 return target;
6164 break;
6166 /* Various hooks for the DWARF 2 __throw routine. */
6167 case BUILT_IN_UNWIND_INIT:
6168 expand_builtin_unwind_init ();
6169 return const0_rtx;
6170 case BUILT_IN_DWARF_CFA:
6171 return virtual_cfa_rtx;
6172 #ifdef DWARF2_UNWIND_INFO
6173 case BUILT_IN_DWARF_SP_COLUMN:
6174 return expand_builtin_dwarf_sp_column ();
6175 case BUILT_IN_INIT_DWARF_REG_SIZES:
6176 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6177 return const0_rtx;
6178 #endif
6179 case BUILT_IN_FROB_RETURN_ADDR:
6180 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6181 case BUILT_IN_EXTRACT_RETURN_ADDR:
6182 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6183 case BUILT_IN_EH_RETURN:
6184 expand_builtin_eh_return (TREE_VALUE (arglist),
6185 TREE_VALUE (TREE_CHAIN (arglist)));
6186 return const0_rtx;
6187 #ifdef EH_RETURN_DATA_REGNO
6188 case BUILT_IN_EH_RETURN_DATA_REGNO:
6189 return expand_builtin_eh_return_data_regno (arglist);
6190 #endif
6191 case BUILT_IN_EXTEND_POINTER:
6192 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6194 case BUILT_IN_VA_START:
6195 case BUILT_IN_STDARG_START:
6196 return expand_builtin_va_start (arglist);
6197 case BUILT_IN_VA_END:
6198 return expand_builtin_va_end (arglist);
6199 case BUILT_IN_VA_COPY:
6200 return expand_builtin_va_copy (arglist);
6201 case BUILT_IN_EXPECT:
6202 return expand_builtin_expect (arglist, target);
6203 case BUILT_IN_PREFETCH:
6204 expand_builtin_prefetch (arglist);
6205 return const0_rtx;
6207 case BUILT_IN_PROFILE_FUNC_ENTER:
6208 return expand_builtin_profile_func (false);
6209 case BUILT_IN_PROFILE_FUNC_EXIT:
6210 return expand_builtin_profile_func (true);
6212 case BUILT_IN_INIT_TRAMPOLINE:
6213 return expand_builtin_init_trampoline (arglist);
6214 case BUILT_IN_ADJUST_TRAMPOLINE:
6215 return expand_builtin_adjust_trampoline (arglist);
6217 case BUILT_IN_FORK:
6218 case BUILT_IN_EXECL:
6219 case BUILT_IN_EXECV:
6220 case BUILT_IN_EXECLP:
6221 case BUILT_IN_EXECLE:
6222 case BUILT_IN_EXECVP:
6223 case BUILT_IN_EXECVE:
6224 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6225 if (target)
6226 return target;
6227 break;
6229 case BUILT_IN_FETCH_AND_ADD_1:
6230 case BUILT_IN_FETCH_AND_ADD_2:
6231 case BUILT_IN_FETCH_AND_ADD_4:
6232 case BUILT_IN_FETCH_AND_ADD_8:
6233 case BUILT_IN_FETCH_AND_ADD_16:
6234 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6235 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6236 false, target, ignore);
6237 if (target)
6238 return target;
6239 break;
6241 case BUILT_IN_FETCH_AND_SUB_1:
6242 case BUILT_IN_FETCH_AND_SUB_2:
6243 case BUILT_IN_FETCH_AND_SUB_4:
6244 case BUILT_IN_FETCH_AND_SUB_8:
6245 case BUILT_IN_FETCH_AND_SUB_16:
6246 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6247 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6248 false, target, ignore);
6249 if (target)
6250 return target;
6251 break;
6253 case BUILT_IN_FETCH_AND_OR_1:
6254 case BUILT_IN_FETCH_AND_OR_2:
6255 case BUILT_IN_FETCH_AND_OR_4:
6256 case BUILT_IN_FETCH_AND_OR_8:
6257 case BUILT_IN_FETCH_AND_OR_16:
6258 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6259 target = expand_builtin_sync_operation (mode, arglist, IOR,
6260 false, target, ignore);
6261 if (target)
6262 return target;
6263 break;
6265 case BUILT_IN_FETCH_AND_AND_1:
6266 case BUILT_IN_FETCH_AND_AND_2:
6267 case BUILT_IN_FETCH_AND_AND_4:
6268 case BUILT_IN_FETCH_AND_AND_8:
6269 case BUILT_IN_FETCH_AND_AND_16:
6270 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6271 target = expand_builtin_sync_operation (mode, arglist, AND,
6272 false, target, ignore);
6273 if (target)
6274 return target;
6275 break;
6277 case BUILT_IN_FETCH_AND_XOR_1:
6278 case BUILT_IN_FETCH_AND_XOR_2:
6279 case BUILT_IN_FETCH_AND_XOR_4:
6280 case BUILT_IN_FETCH_AND_XOR_8:
6281 case BUILT_IN_FETCH_AND_XOR_16:
6282 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6283 target = expand_builtin_sync_operation (mode, arglist, XOR,
6284 false, target, ignore);
6285 if (target)
6286 return target;
6287 break;
6289 case BUILT_IN_FETCH_AND_NAND_1:
6290 case BUILT_IN_FETCH_AND_NAND_2:
6291 case BUILT_IN_FETCH_AND_NAND_4:
6292 case BUILT_IN_FETCH_AND_NAND_8:
6293 case BUILT_IN_FETCH_AND_NAND_16:
6294 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6295 target = expand_builtin_sync_operation (mode, arglist, NOT,
6296 false, target, ignore);
6297 if (target)
6298 return target;
6299 break;
6301 case BUILT_IN_ADD_AND_FETCH_1:
6302 case BUILT_IN_ADD_AND_FETCH_2:
6303 case BUILT_IN_ADD_AND_FETCH_4:
6304 case BUILT_IN_ADD_AND_FETCH_8:
6305 case BUILT_IN_ADD_AND_FETCH_16:
6306 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6307 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6308 true, target, ignore);
6309 if (target)
6310 return target;
6311 break;
6313 case BUILT_IN_SUB_AND_FETCH_1:
6314 case BUILT_IN_SUB_AND_FETCH_2:
6315 case BUILT_IN_SUB_AND_FETCH_4:
6316 case BUILT_IN_SUB_AND_FETCH_8:
6317 case BUILT_IN_SUB_AND_FETCH_16:
6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6319 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6320 true, target, ignore);
6321 if (target)
6322 return target;
6323 break;
6325 case BUILT_IN_OR_AND_FETCH_1:
6326 case BUILT_IN_OR_AND_FETCH_2:
6327 case BUILT_IN_OR_AND_FETCH_4:
6328 case BUILT_IN_OR_AND_FETCH_8:
6329 case BUILT_IN_OR_AND_FETCH_16:
6330 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6331 target = expand_builtin_sync_operation (mode, arglist, IOR,
6332 true, target, ignore);
6333 if (target)
6334 return target;
6335 break;
6337 case BUILT_IN_AND_AND_FETCH_1:
6338 case BUILT_IN_AND_AND_FETCH_2:
6339 case BUILT_IN_AND_AND_FETCH_4:
6340 case BUILT_IN_AND_AND_FETCH_8:
6341 case BUILT_IN_AND_AND_FETCH_16:
6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6343 target = expand_builtin_sync_operation (mode, arglist, AND,
6344 true, target, ignore);
6345 if (target)
6346 return target;
6347 break;
6349 case BUILT_IN_XOR_AND_FETCH_1:
6350 case BUILT_IN_XOR_AND_FETCH_2:
6351 case BUILT_IN_XOR_AND_FETCH_4:
6352 case BUILT_IN_XOR_AND_FETCH_8:
6353 case BUILT_IN_XOR_AND_FETCH_16:
6354 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6355 target = expand_builtin_sync_operation (mode, arglist, XOR,
6356 true, target, ignore);
6357 if (target)
6358 return target;
6359 break;
6361 case BUILT_IN_NAND_AND_FETCH_1:
6362 case BUILT_IN_NAND_AND_FETCH_2:
6363 case BUILT_IN_NAND_AND_FETCH_4:
6364 case BUILT_IN_NAND_AND_FETCH_8:
6365 case BUILT_IN_NAND_AND_FETCH_16:
6366 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6367 target = expand_builtin_sync_operation (mode, arglist, NOT,
6368 true, target, ignore);
6369 if (target)
6370 return target;
6371 break;
6373 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6374 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6375 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6376 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6377 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6378 if (mode == VOIDmode)
6379 mode = TYPE_MODE (boolean_type_node);
6380 if (!target || !register_operand (target, mode))
6381 target = gen_reg_rtx (mode);
6383 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6384 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6385 if (target)
6386 return target;
6387 break;
6389 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6390 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6391 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6392 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6393 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6394 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6395 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6396 if (target)
6397 return target;
6398 break;
6400 case BUILT_IN_LOCK_TEST_AND_SET_1:
6401 case BUILT_IN_LOCK_TEST_AND_SET_2:
6402 case BUILT_IN_LOCK_TEST_AND_SET_4:
6403 case BUILT_IN_LOCK_TEST_AND_SET_8:
6404 case BUILT_IN_LOCK_TEST_AND_SET_16:
6405 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6406 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6407 if (target)
6408 return target;
6409 break;
6411 case BUILT_IN_LOCK_RELEASE_1:
6412 case BUILT_IN_LOCK_RELEASE_2:
6413 case BUILT_IN_LOCK_RELEASE_4:
6414 case BUILT_IN_LOCK_RELEASE_8:
6415 case BUILT_IN_LOCK_RELEASE_16:
6416 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6417 expand_builtin_lock_release (mode, arglist);
6418 return const0_rtx;
6420 case BUILT_IN_SYNCHRONIZE:
6421 expand_builtin_synchronize ();
6422 return const0_rtx;
6424 case BUILT_IN_OBJECT_SIZE:
6425 return expand_builtin_object_size (exp);
6427 case BUILT_IN_MEMCPY_CHK:
6428 case BUILT_IN_MEMPCPY_CHK:
6429 case BUILT_IN_MEMMOVE_CHK:
6430 case BUILT_IN_MEMSET_CHK:
6431 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6432 if (target)
6433 return target;
6434 break;
6436 case BUILT_IN_STRCPY_CHK:
6437 case BUILT_IN_STPCPY_CHK:
6438 case BUILT_IN_STRNCPY_CHK:
6439 case BUILT_IN_STRCAT_CHK:
6440 case BUILT_IN_SNPRINTF_CHK:
6441 case BUILT_IN_VSNPRINTF_CHK:
6442 maybe_emit_chk_warning (exp, fcode);
6443 break;
6445 case BUILT_IN_SPRINTF_CHK:
6446 case BUILT_IN_VSPRINTF_CHK:
6447 maybe_emit_sprintf_chk_warning (exp, fcode);
6448 break;
6450 default: /* just do library call, if unknown builtin */
6451 break;
6454 /* The switch statement above can drop through to cause the function
6455 to be called normally. */
6456 return expand_call (exp, target, ignore);
6459 /* Determine whether a tree node represents a call to a built-in
6460 function. If the tree T is a call to a built-in function with
6461 the right number of arguments of the appropriate types, return
6462 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6463 Otherwise the return value is END_BUILTINS. */
6465 enum built_in_function
6466 builtin_mathfn_code (tree t)
6468 tree fndecl, arglist, parmlist;
6469 tree argtype, parmtype;
6471 if (TREE_CODE (t) != CALL_EXPR
6472 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6473 return END_BUILTINS;
6475 fndecl = get_callee_fndecl (t);
6476 if (fndecl == NULL_TREE
6477 || TREE_CODE (fndecl) != FUNCTION_DECL
6478 || ! DECL_BUILT_IN (fndecl)
6479 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6480 return END_BUILTINS;
6482 arglist = TREE_OPERAND (t, 1);
6483 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6484 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6486 /* If a function doesn't take a variable number of arguments,
6487 the last element in the list will have type `void'. */
6488 parmtype = TREE_VALUE (parmlist);
6489 if (VOID_TYPE_P (parmtype))
6491 if (arglist)
6492 return END_BUILTINS;
6493 return DECL_FUNCTION_CODE (fndecl);
6496 if (! arglist)
6497 return END_BUILTINS;
6499 argtype = TREE_TYPE (TREE_VALUE (arglist));
6501 if (SCALAR_FLOAT_TYPE_P (parmtype))
6503 if (! SCALAR_FLOAT_TYPE_P (argtype))
6504 return END_BUILTINS;
6506 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6508 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6509 return END_BUILTINS;
6511 else if (POINTER_TYPE_P (parmtype))
6513 if (! POINTER_TYPE_P (argtype))
6514 return END_BUILTINS;
6516 else if (INTEGRAL_TYPE_P (parmtype))
6518 if (! INTEGRAL_TYPE_P (argtype))
6519 return END_BUILTINS;
6521 else
6522 return END_BUILTINS;
6524 arglist = TREE_CHAIN (arglist);
6527 /* Variable-length argument list. */
6528 return DECL_FUNCTION_CODE (fndecl);
6531 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6532 constant. ARGLIST is the argument list of the call. */
6534 static tree
6535 fold_builtin_constant_p (tree arglist)
6537 if (arglist == 0)
6538 return 0;
6540 arglist = TREE_VALUE (arglist);
6542 /* We return 1 for a numeric type that's known to be a constant
6543 value at compile-time or for an aggregate type that's a
6544 literal constant. */
6545 STRIP_NOPS (arglist);
6547 /* If we know this is a constant, emit the constant of one. */
6548 if (CONSTANT_CLASS_P (arglist)
6549 || (TREE_CODE (arglist) == CONSTRUCTOR
6550 && TREE_CONSTANT (arglist)))
6551 return integer_one_node;
6552 if (TREE_CODE (arglist) == ADDR_EXPR)
6554 tree op = TREE_OPERAND (arglist, 0);
6555 if (TREE_CODE (op) == STRING_CST
6556 || (TREE_CODE (op) == ARRAY_REF
6557 && integer_zerop (TREE_OPERAND (op, 1))
6558 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6559 return integer_one_node;
6562 /* If this expression has side effects, show we don't know it to be a
6563 constant. Likewise if it's a pointer or aggregate type since in
6564 those case we only want literals, since those are only optimized
6565 when generating RTL, not later.
6566 And finally, if we are compiling an initializer, not code, we
6567 need to return a definite result now; there's not going to be any
6568 more optimization done. */
6569 if (TREE_SIDE_EFFECTS (arglist)
6570 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6571 || POINTER_TYPE_P (TREE_TYPE (arglist))
6572 || cfun == 0
6573 || folding_initializer)
6574 return integer_zero_node;
6576 return 0;
6579 /* Fold a call to __builtin_expect, if we expect that a comparison against
6580 the argument will fold to a constant. In practice, this means a true
6581 constant or the address of a non-weak symbol. ARGLIST is the argument
6582 list of the call. */
6584 static tree
6585 fold_builtin_expect (tree arglist)
6587 tree arg, inner;
6589 if (arglist == 0)
6590 return 0;
6592 arg = TREE_VALUE (arglist);
6594 /* If the argument isn't invariant, then there's nothing we can do. */
6595 if (!TREE_INVARIANT (arg))
6596 return 0;
6598 /* If we're looking at an address of a weak decl, then do not fold. */
6599 inner = arg;
6600 STRIP_NOPS (inner);
6601 if (TREE_CODE (inner) == ADDR_EXPR)
6605 inner = TREE_OPERAND (inner, 0);
6607 while (TREE_CODE (inner) == COMPONENT_REF
6608 || TREE_CODE (inner) == ARRAY_REF);
6609 if (DECL_P (inner) && DECL_WEAK (inner))
6610 return 0;
6613 /* Otherwise, ARG already has the proper type for the return value. */
6614 return arg;
6617 /* Fold a call to __builtin_classify_type. */
6619 static tree
6620 fold_builtin_classify_type (tree arglist)
6622 if (arglist == 0)
6623 return build_int_cst (NULL_TREE, no_type_class);
6625 return build_int_cst (NULL_TREE,
6626 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6629 /* Fold a call to __builtin_strlen. */
6631 static tree
6632 fold_builtin_strlen (tree arglist)
6634 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6635 return NULL_TREE;
6636 else
6638 tree len = c_strlen (TREE_VALUE (arglist), 0);
6640 if (len)
6642 /* Convert from the internal "sizetype" type to "size_t". */
6643 if (size_type_node)
6644 len = fold_convert (size_type_node, len);
6645 return len;
6648 return NULL_TREE;
6652 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6654 static tree
6655 fold_builtin_inf (tree type, int warn)
6657 REAL_VALUE_TYPE real;
6659 /* __builtin_inff is intended to be usable to define INFINITY on all
6660 targets. If an infinity is not available, INFINITY expands "to a
6661 positive constant of type float that overflows at translation
6662 time", footnote "In this case, using INFINITY will violate the
6663 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6664 Thus we pedwarn to ensure this constraint violation is
6665 diagnosed. */
6666 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6667 pedwarn ("target format does not support infinity");
6669 real_inf (&real);
6670 return build_real (type, real);
6673 /* Fold a call to __builtin_nan or __builtin_nans. */
6675 static tree
6676 fold_builtin_nan (tree arglist, tree type, int quiet)
6678 REAL_VALUE_TYPE real;
6679 const char *str;
6681 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6682 return 0;
6683 str = c_getstr (TREE_VALUE (arglist));
6684 if (!str)
6685 return 0;
6687 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6688 return 0;
6690 return build_real (type, real);
6693 /* Return true if the floating point expression T has an integer value.
6694 We also allow +Inf, -Inf and NaN to be considered integer values. */
6696 static bool
6697 integer_valued_real_p (tree t)
6699 switch (TREE_CODE (t))
6701 case FLOAT_EXPR:
6702 return true;
6704 case ABS_EXPR:
6705 case SAVE_EXPR:
6706 case NON_LVALUE_EXPR:
6707 return integer_valued_real_p (TREE_OPERAND (t, 0));
6709 case COMPOUND_EXPR:
6710 case MODIFY_EXPR:
6711 case BIND_EXPR:
6712 return integer_valued_real_p (TREE_OPERAND (t, 1));
6714 case PLUS_EXPR:
6715 case MINUS_EXPR:
6716 case MULT_EXPR:
6717 case MIN_EXPR:
6718 case MAX_EXPR:
6719 return integer_valued_real_p (TREE_OPERAND (t, 0))
6720 && integer_valued_real_p (TREE_OPERAND (t, 1));
6722 case COND_EXPR:
6723 return integer_valued_real_p (TREE_OPERAND (t, 1))
6724 && integer_valued_real_p (TREE_OPERAND (t, 2));
6726 case REAL_CST:
6727 if (! TREE_CONSTANT_OVERFLOW (t))
6729 REAL_VALUE_TYPE c, cint;
6731 c = TREE_REAL_CST (t);
6732 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6733 return real_identical (&c, &cint);
6735 break;
6737 case NOP_EXPR:
6739 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6740 if (TREE_CODE (type) == INTEGER_TYPE)
6741 return true;
6742 if (TREE_CODE (type) == REAL_TYPE)
6743 return integer_valued_real_p (TREE_OPERAND (t, 0));
6744 break;
6747 case CALL_EXPR:
6748 switch (builtin_mathfn_code (t))
6750 CASE_FLT_FN (BUILT_IN_CEIL):
6751 CASE_FLT_FN (BUILT_IN_FLOOR):
6752 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6753 CASE_FLT_FN (BUILT_IN_RINT):
6754 CASE_FLT_FN (BUILT_IN_ROUND):
6755 CASE_FLT_FN (BUILT_IN_TRUNC):
6756 return true;
6758 default:
6759 break;
6761 break;
6763 default:
6764 break;
6766 return false;
6769 /* EXP is assumed to be builtin call where truncation can be propagated
6770 across (for instance floor((double)f) == (double)floorf (f).
6771 Do the transformation. */
6773 static tree
6774 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6776 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6777 tree arg;
6779 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6780 return 0;
6782 arg = TREE_VALUE (arglist);
6783 /* Integer rounding functions are idempotent. */
6784 if (fcode == builtin_mathfn_code (arg))
6785 return arg;
6787 /* If argument is already integer valued, and we don't need to worry
6788 about setting errno, there's no need to perform rounding. */
6789 if (! flag_errno_math && integer_valued_real_p (arg))
6790 return arg;
6792 if (optimize)
6794 tree arg0 = strip_float_extensions (arg);
6795 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6796 tree newtype = TREE_TYPE (arg0);
6797 tree decl;
6799 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6800 && (decl = mathfn_built_in (newtype, fcode)))
6802 arglist =
6803 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6804 return fold_convert (ftype,
6805 build_function_call_expr (decl, arglist));
6808 return 0;
6811 /* EXP is assumed to be builtin call which can narrow the FP type of
6812 the argument, for instance lround((double)f) -> lroundf (f). */
6814 static tree
6815 fold_fixed_mathfn (tree fndecl, tree arglist)
6817 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6818 tree arg;
6820 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6821 return 0;
6823 arg = TREE_VALUE (arglist);
6825 /* If argument is already integer valued, and we don't need to worry
6826 about setting errno, there's no need to perform rounding. */
6827 if (! flag_errno_math && integer_valued_real_p (arg))
6828 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6830 if (optimize)
6832 tree ftype = TREE_TYPE (arg);
6833 tree arg0 = strip_float_extensions (arg);
6834 tree newtype = TREE_TYPE (arg0);
6835 tree decl;
6837 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6838 && (decl = mathfn_built_in (newtype, fcode)))
6840 arglist =
6841 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6842 return build_function_call_expr (decl, arglist);
6846 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6847 sizeof (long long) == sizeof (long). */
6848 if (TYPE_PRECISION (long_long_integer_type_node)
6849 == TYPE_PRECISION (long_integer_type_node))
6851 tree newfn = NULL_TREE;
6852 switch (fcode)
6854 CASE_FLT_FN (BUILT_IN_LLCEIL):
6855 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6856 break;
6858 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6859 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6860 break;
6862 CASE_FLT_FN (BUILT_IN_LLROUND):
6863 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6864 break;
6866 CASE_FLT_FN (BUILT_IN_LLRINT):
6867 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6868 break;
6870 default:
6871 break;
6874 if (newfn)
6876 tree newcall = build_function_call_expr (newfn, arglist);
6877 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6881 return 0;
6884 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6885 is the argument list, TYPE is the return type and FNDECL is the
6886 original function DECL. Return NULL_TREE if no if no simplification
6887 can be made. */
6889 static tree
6890 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6892 tree arg;
6894 if (!arglist || TREE_CHAIN (arglist))
6895 return NULL_TREE;
6897 arg = TREE_VALUE (arglist);
6898 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6899 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6900 return NULL_TREE;
6902 /* Evaluate cabs of a constant at compile-time. */
6903 if (flag_unsafe_math_optimizations
6904 && TREE_CODE (arg) == COMPLEX_CST
6905 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6906 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6907 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6908 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6910 REAL_VALUE_TYPE r, i;
6912 r = TREE_REAL_CST (TREE_REALPART (arg));
6913 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6915 real_arithmetic (&r, MULT_EXPR, &r, &r);
6916 real_arithmetic (&i, MULT_EXPR, &i, &i);
6917 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6918 if (real_sqrt (&r, TYPE_MODE (type), &r)
6919 || ! flag_trapping_math)
6920 return build_real (type, r);
6923 /* If either part is zero, cabs is fabs of the other. */
6924 if (TREE_CODE (arg) == COMPLEX_EXPR
6925 && real_zerop (TREE_OPERAND (arg, 0)))
6926 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6927 if (TREE_CODE (arg) == COMPLEX_EXPR
6928 && real_zerop (TREE_OPERAND (arg, 1)))
6929 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6931 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6932 if (TREE_CODE (arg) == NEGATE_EXPR
6933 || TREE_CODE (arg) == CONJ_EXPR)
6935 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6936 return build_function_call_expr (fndecl, arglist);
6939 /* Don't do this when optimizing for size. */
6940 if (flag_unsafe_math_optimizations
6941 && optimize && !optimize_size)
6943 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6945 if (sqrtfn != NULL_TREE)
6947 tree rpart, ipart, result, arglist;
6949 arg = builtin_save_expr (arg);
6951 rpart = fold_build1 (REALPART_EXPR, type, arg);
6952 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6954 rpart = builtin_save_expr (rpart);
6955 ipart = builtin_save_expr (ipart);
6957 result = fold_build2 (PLUS_EXPR, type,
6958 fold_build2 (MULT_EXPR, type,
6959 rpart, rpart),
6960 fold_build2 (MULT_EXPR, type,
6961 ipart, ipart));
6963 arglist = build_tree_list (NULL_TREE, result);
6964 return build_function_call_expr (sqrtfn, arglist);
6968 return NULL_TREE;
6971 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6972 NULL_TREE if no simplification can be made. */
6974 static tree
6975 fold_builtin_sqrt (tree arglist, tree type)
6978 enum built_in_function fcode;
6979 tree arg = TREE_VALUE (arglist);
6981 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6982 return NULL_TREE;
6984 /* Optimize sqrt of constant value. */
6985 if (TREE_CODE (arg) == REAL_CST
6986 && ! TREE_CONSTANT_OVERFLOW (arg))
6988 REAL_VALUE_TYPE r, x;
6990 x = TREE_REAL_CST (arg);
6991 if (real_sqrt (&r, TYPE_MODE (type), &x)
6992 || (!flag_trapping_math && !flag_errno_math))
6993 return build_real (type, r);
6996 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6997 fcode = builtin_mathfn_code (arg);
6998 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7000 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7001 arg = fold_build2 (MULT_EXPR, type,
7002 TREE_VALUE (TREE_OPERAND (arg, 1)),
7003 build_real (type, dconsthalf));
7004 arglist = build_tree_list (NULL_TREE, arg);
7005 return build_function_call_expr (expfn, arglist);
7008 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7009 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7011 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7013 if (powfn)
7015 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7016 tree tree_root;
7017 /* The inner root was either sqrt or cbrt. */
7018 REAL_VALUE_TYPE dconstroot =
7019 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7021 /* Adjust for the outer root. */
7022 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7023 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7024 tree_root = build_real (type, dconstroot);
7025 arglist = tree_cons (NULL_TREE, arg0,
7026 build_tree_list (NULL_TREE, tree_root));
7027 return build_function_call_expr (powfn, arglist);
7031 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7032 if (flag_unsafe_math_optimizations
7033 && (fcode == BUILT_IN_POW
7034 || fcode == BUILT_IN_POWF
7035 || fcode == BUILT_IN_POWL))
7037 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7038 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7039 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7040 tree narg1;
7041 if (!tree_expr_nonnegative_p (arg0))
7042 arg0 = build1 (ABS_EXPR, type, arg0);
7043 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7044 build_real (type, dconsthalf));
7045 arglist = tree_cons (NULL_TREE, arg0,
7046 build_tree_list (NULL_TREE, narg1));
7047 return build_function_call_expr (powfn, arglist);
7050 return NULL_TREE;
7053 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7054 NULL_TREE if no simplification can be made. */
7055 static tree
7056 fold_builtin_cbrt (tree arglist, tree type)
7058 tree arg = TREE_VALUE (arglist);
7059 const enum built_in_function fcode = builtin_mathfn_code (arg);
7061 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7062 return NULL_TREE;
7064 /* Optimize cbrt of constant value. */
7065 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7066 return arg;
7068 if (flag_unsafe_math_optimizations)
7070 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7071 if (BUILTIN_EXPONENT_P (fcode))
7073 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7074 const REAL_VALUE_TYPE third_trunc =
7075 real_value_truncate (TYPE_MODE (type), dconstthird);
7076 arg = fold_build2 (MULT_EXPR, type,
7077 TREE_VALUE (TREE_OPERAND (arg, 1)),
7078 build_real (type, third_trunc));
7079 arglist = build_tree_list (NULL_TREE, arg);
7080 return build_function_call_expr (expfn, arglist);
7083 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7084 if (BUILTIN_SQRT_P (fcode))
7086 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7088 if (powfn)
7090 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7091 tree tree_root;
7092 REAL_VALUE_TYPE dconstroot = dconstthird;
7094 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7095 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7096 tree_root = build_real (type, dconstroot);
7097 arglist = tree_cons (NULL_TREE, arg0,
7098 build_tree_list (NULL_TREE, tree_root));
7099 return build_function_call_expr (powfn, arglist);
7103 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7104 if (BUILTIN_CBRT_P (fcode))
7106 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7107 if (tree_expr_nonnegative_p (arg0))
7109 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7111 if (powfn)
7113 tree tree_root;
7114 REAL_VALUE_TYPE dconstroot;
7116 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7117 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7118 tree_root = build_real (type, dconstroot);
7119 arglist = tree_cons (NULL_TREE, arg0,
7120 build_tree_list (NULL_TREE, tree_root));
7121 return build_function_call_expr (powfn, arglist);
7126 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7127 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7128 || fcode == BUILT_IN_POWL)
7130 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7131 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7132 if (tree_expr_nonnegative_p (arg00))
7134 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7135 const REAL_VALUE_TYPE dconstroot
7136 = real_value_truncate (TYPE_MODE (type), dconstthird);
7137 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7138 build_real (type, dconstroot));
7139 arglist = tree_cons (NULL_TREE, arg00,
7140 build_tree_list (NULL_TREE, narg01));
7141 return build_function_call_expr (powfn, arglist);
7145 return NULL_TREE;
7148 /* Fold function call to builtin sin, sinf, or sinl. Return
7149 NULL_TREE if no simplification can be made. */
7150 static tree
7151 fold_builtin_sin (tree arglist)
7153 tree arg = TREE_VALUE (arglist);
7155 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7156 return NULL_TREE;
7158 /* Optimize sin (0.0) = 0.0. */
7159 if (real_zerop (arg))
7160 return arg;
7162 return NULL_TREE;
7165 /* Fold function call to builtin cos, cosf, or cosl. Return
7166 NULL_TREE if no simplification can be made. */
7167 static tree
7168 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7170 tree arg = TREE_VALUE (arglist);
7172 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7173 return NULL_TREE;
7175 /* Optimize cos (0.0) = 1.0. */
7176 if (real_zerop (arg))
7177 return build_real (type, dconst1);
7179 /* Optimize cos(-x) into cos (x). */
7180 if (TREE_CODE (arg) == NEGATE_EXPR)
7182 tree args = build_tree_list (NULL_TREE,
7183 TREE_OPERAND (arg, 0));
7184 return build_function_call_expr (fndecl, args);
7187 return NULL_TREE;
7190 /* Fold function call to builtin tan, tanf, or tanl. Return
7191 NULL_TREE if no simplification can be made. */
7192 static tree
7193 fold_builtin_tan (tree arglist)
7195 enum built_in_function fcode;
7196 tree arg = TREE_VALUE (arglist);
7198 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7199 return NULL_TREE;
7201 /* Optimize tan(0.0) = 0.0. */
7202 if (real_zerop (arg))
7203 return arg;
7205 /* Optimize tan(atan(x)) = x. */
7206 fcode = builtin_mathfn_code (arg);
7207 if (flag_unsafe_math_optimizations
7208 && (fcode == BUILT_IN_ATAN
7209 || fcode == BUILT_IN_ATANF
7210 || fcode == BUILT_IN_ATANL))
7211 return TREE_VALUE (TREE_OPERAND (arg, 1));
7213 return NULL_TREE;
7216 /* Fold function call to builtin atan, atanf, or atanl. Return
7217 NULL_TREE if no simplification can be made. */
7219 static tree
7220 fold_builtin_atan (tree arglist, tree type)
7223 tree arg = TREE_VALUE (arglist);
7225 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7226 return NULL_TREE;
7228 /* Optimize atan(0.0) = 0.0. */
7229 if (real_zerop (arg))
7230 return arg;
7232 /* Optimize atan(1.0) = pi/4. */
7233 if (real_onep (arg))
7235 REAL_VALUE_TYPE cst;
7237 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7238 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7239 return build_real (type, cst);
7242 return NULL_TREE;
7245 /* Fold function call to builtin trunc, truncf or truncl. Return
7246 NULL_TREE if no simplification can be made. */
7248 static tree
7249 fold_builtin_trunc (tree fndecl, tree arglist)
7251 tree arg;
7253 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7254 return 0;
7256 /* Optimize trunc of constant value. */
7257 arg = TREE_VALUE (arglist);
7258 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7260 REAL_VALUE_TYPE r, x;
7261 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7263 x = TREE_REAL_CST (arg);
7264 real_trunc (&r, TYPE_MODE (type), &x);
7265 return build_real (type, r);
7268 return fold_trunc_transparent_mathfn (fndecl, arglist);
7271 /* Fold function call to builtin floor, floorf or floorl. Return
7272 NULL_TREE if no simplification can be made. */
7274 static tree
7275 fold_builtin_floor (tree fndecl, tree arglist)
7277 tree arg;
7279 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7280 return 0;
7282 /* Optimize floor of constant value. */
7283 arg = TREE_VALUE (arglist);
7284 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7286 REAL_VALUE_TYPE x;
7288 x = TREE_REAL_CST (arg);
7289 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7291 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7292 REAL_VALUE_TYPE r;
7294 real_floor (&r, TYPE_MODE (type), &x);
7295 return build_real (type, r);
7299 return fold_trunc_transparent_mathfn (fndecl, arglist);
7302 /* Fold function call to builtin ceil, ceilf or ceill. Return
7303 NULL_TREE if no simplification can be made. */
7305 static tree
7306 fold_builtin_ceil (tree fndecl, tree arglist)
7308 tree arg;
7310 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7311 return 0;
7313 /* Optimize ceil of constant value. */
7314 arg = TREE_VALUE (arglist);
7315 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7317 REAL_VALUE_TYPE x;
7319 x = TREE_REAL_CST (arg);
7320 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7322 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7323 REAL_VALUE_TYPE r;
7325 real_ceil (&r, TYPE_MODE (type), &x);
7326 return build_real (type, r);
7330 return fold_trunc_transparent_mathfn (fndecl, arglist);
7333 /* Fold function call to builtin round, roundf or roundl. Return
7334 NULL_TREE if no simplification can be made. */
7336 static tree
7337 fold_builtin_round (tree fndecl, tree arglist)
7339 tree arg;
7341 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7342 return 0;
7344 /* Optimize round of constant value. */
7345 arg = TREE_VALUE (arglist);
7346 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7348 REAL_VALUE_TYPE x;
7350 x = TREE_REAL_CST (arg);
7351 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7353 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7354 REAL_VALUE_TYPE r;
7356 real_round (&r, TYPE_MODE (type), &x);
7357 return build_real (type, r);
7361 return fold_trunc_transparent_mathfn (fndecl, arglist);
7364 /* Fold function call to builtin lround, lroundf or lroundl (or the
7365 corresponding long long versions) and other rounding functions.
7366 Return NULL_TREE if no simplification can be made. */
7368 static tree
7369 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7371 tree arg;
7373 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7374 return 0;
7376 /* Optimize lround of constant value. */
7377 arg = TREE_VALUE (arglist);
7378 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7380 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7382 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7384 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7385 tree ftype = TREE_TYPE (arg), result;
7386 HOST_WIDE_INT hi, lo;
7387 REAL_VALUE_TYPE r;
7389 switch (DECL_FUNCTION_CODE (fndecl))
7391 CASE_FLT_FN (BUILT_IN_LFLOOR):
7392 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7393 real_floor (&r, TYPE_MODE (ftype), &x);
7394 break;
7396 CASE_FLT_FN (BUILT_IN_LCEIL):
7397 CASE_FLT_FN (BUILT_IN_LLCEIL):
7398 real_ceil (&r, TYPE_MODE (ftype), &x);
7399 break;
7401 CASE_FLT_FN (BUILT_IN_LROUND):
7402 CASE_FLT_FN (BUILT_IN_LLROUND):
7403 real_round (&r, TYPE_MODE (ftype), &x);
7404 break;
7406 default:
7407 gcc_unreachable ();
7410 REAL_VALUE_TO_INT (&lo, &hi, r);
7411 result = build_int_cst_wide (NULL_TREE, lo, hi);
7412 if (int_fits_type_p (result, itype))
7413 return fold_convert (itype, result);
7417 return fold_fixed_mathfn (fndecl, arglist);
7420 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7421 and their long and long long variants (i.e. ffsl and ffsll).
7422 Return NULL_TREE if no simplification can be made. */
7424 static tree
7425 fold_builtin_bitop (tree fndecl, tree arglist)
7427 tree arg;
7429 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7430 return NULL_TREE;
7432 /* Optimize for constant argument. */
7433 arg = TREE_VALUE (arglist);
7434 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7436 HOST_WIDE_INT hi, width, result;
7437 unsigned HOST_WIDE_INT lo;
7438 tree type;
7440 type = TREE_TYPE (arg);
7441 width = TYPE_PRECISION (type);
7442 lo = TREE_INT_CST_LOW (arg);
7444 /* Clear all the bits that are beyond the type's precision. */
7445 if (width > HOST_BITS_PER_WIDE_INT)
7447 hi = TREE_INT_CST_HIGH (arg);
7448 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7449 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7451 else
7453 hi = 0;
7454 if (width < HOST_BITS_PER_WIDE_INT)
7455 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7458 switch (DECL_FUNCTION_CODE (fndecl))
7460 CASE_INT_FN (BUILT_IN_FFS):
7461 if (lo != 0)
7462 result = exact_log2 (lo & -lo) + 1;
7463 else if (hi != 0)
7464 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7465 else
7466 result = 0;
7467 break;
7469 CASE_INT_FN (BUILT_IN_CLZ):
7470 if (hi != 0)
7471 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7472 else if (lo != 0)
7473 result = width - floor_log2 (lo) - 1;
7474 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7475 result = width;
7476 break;
7478 CASE_INT_FN (BUILT_IN_CTZ):
7479 if (lo != 0)
7480 result = exact_log2 (lo & -lo);
7481 else if (hi != 0)
7482 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7483 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7484 result = width;
7485 break;
7487 CASE_INT_FN (BUILT_IN_POPCOUNT):
7488 result = 0;
7489 while (lo)
7490 result++, lo &= lo - 1;
7491 while (hi)
7492 result++, hi &= hi - 1;
7493 break;
7495 CASE_INT_FN (BUILT_IN_PARITY):
7496 result = 0;
7497 while (lo)
7498 result++, lo &= lo - 1;
7499 while (hi)
7500 result++, hi &= hi - 1;
7501 result &= 1;
7502 break;
7504 default:
7505 gcc_unreachable ();
7508 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7511 return NULL_TREE;
7514 /* Return true if EXPR is the real constant contained in VALUE. */
7516 static bool
7517 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7519 STRIP_NOPS (expr);
7521 return ((TREE_CODE (expr) == REAL_CST
7522 && ! TREE_CONSTANT_OVERFLOW (expr)
7523 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7524 || (TREE_CODE (expr) == COMPLEX_CST
7525 && real_dconstp (TREE_REALPART (expr), value)
7526 && real_zerop (TREE_IMAGPART (expr))));
7529 /* A subroutine of fold_builtin to fold the various logarithmic
7530 functions. EXP is the CALL_EXPR of a call to a builtin logN
7531 function. VALUE is the base of the logN function. */
7533 static tree
7534 fold_builtin_logarithm (tree fndecl, tree arglist,
7535 const REAL_VALUE_TYPE *value)
7537 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7539 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7540 tree arg = TREE_VALUE (arglist);
7541 const enum built_in_function fcode = builtin_mathfn_code (arg);
7543 /* Optimize logN(1.0) = 0.0. */
7544 if (real_onep (arg))
7545 return build_real (type, dconst0);
7547 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7548 exactly, then only do this if flag_unsafe_math_optimizations. */
7549 if (exact_real_truncate (TYPE_MODE (type), value)
7550 || flag_unsafe_math_optimizations)
7552 const REAL_VALUE_TYPE value_truncate =
7553 real_value_truncate (TYPE_MODE (type), *value);
7554 if (real_dconstp (arg, &value_truncate))
7555 return build_real (type, dconst1);
7558 /* Special case, optimize logN(expN(x)) = x. */
7559 if (flag_unsafe_math_optimizations
7560 && ((value == &dconste
7561 && (fcode == BUILT_IN_EXP
7562 || fcode == BUILT_IN_EXPF
7563 || fcode == BUILT_IN_EXPL))
7564 || (value == &dconst2
7565 && (fcode == BUILT_IN_EXP2
7566 || fcode == BUILT_IN_EXP2F
7567 || fcode == BUILT_IN_EXP2L))
7568 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7569 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7571 /* Optimize logN(func()) for various exponential functions. We
7572 want to determine the value "x" and the power "exponent" in
7573 order to transform logN(x**exponent) into exponent*logN(x). */
7574 if (flag_unsafe_math_optimizations)
7576 tree exponent = 0, x = 0;
7578 switch (fcode)
7580 CASE_FLT_FN (BUILT_IN_EXP):
7581 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7582 x = build_real (type,
7583 real_value_truncate (TYPE_MODE (type), dconste));
7584 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7585 break;
7586 CASE_FLT_FN (BUILT_IN_EXP2):
7587 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7588 x = build_real (type, dconst2);
7589 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7590 break;
7591 CASE_FLT_FN (BUILT_IN_EXP10):
7592 CASE_FLT_FN (BUILT_IN_POW10):
7593 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7594 x = build_real (type, dconst10);
7595 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7596 break;
7597 CASE_FLT_FN (BUILT_IN_SQRT):
7598 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7599 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7600 exponent = build_real (type, dconsthalf);
7601 break;
7602 CASE_FLT_FN (BUILT_IN_CBRT):
7603 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7604 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7605 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7606 dconstthird));
7607 break;
7608 CASE_FLT_FN (BUILT_IN_POW):
7609 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7610 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7611 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7612 break;
7613 default:
7614 break;
7617 /* Now perform the optimization. */
7618 if (x && exponent)
7620 tree logfn;
7621 arglist = build_tree_list (NULL_TREE, x);
7622 logfn = build_function_call_expr (fndecl, arglist);
7623 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7628 return 0;
7631 /* Fold a builtin function call to pow, powf, or powl. Return
7632 NULL_TREE if no simplification can be made. */
7633 static tree
7634 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7636 tree arg0 = TREE_VALUE (arglist);
7637 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7639 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7640 return NULL_TREE;
7642 /* Optimize pow(1.0,y) = 1.0. */
7643 if (real_onep (arg0))
7644 return omit_one_operand (type, build_real (type, dconst1), arg1);
7646 if (TREE_CODE (arg1) == REAL_CST
7647 && ! TREE_CONSTANT_OVERFLOW (arg1))
7649 REAL_VALUE_TYPE cint;
7650 REAL_VALUE_TYPE c;
7651 HOST_WIDE_INT n;
7653 c = TREE_REAL_CST (arg1);
7655 /* Optimize pow(x,0.0) = 1.0. */
7656 if (REAL_VALUES_EQUAL (c, dconst0))
7657 return omit_one_operand (type, build_real (type, dconst1),
7658 arg0);
7660 /* Optimize pow(x,1.0) = x. */
7661 if (REAL_VALUES_EQUAL (c, dconst1))
7662 return arg0;
7664 /* Optimize pow(x,-1.0) = 1.0/x. */
7665 if (REAL_VALUES_EQUAL (c, dconstm1))
7666 return fold_build2 (RDIV_EXPR, type,
7667 build_real (type, dconst1), arg0);
7669 /* Optimize pow(x,0.5) = sqrt(x). */
7670 if (flag_unsafe_math_optimizations
7671 && REAL_VALUES_EQUAL (c, dconsthalf))
7673 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7675 if (sqrtfn != NULL_TREE)
7677 tree arglist = build_tree_list (NULL_TREE, arg0);
7678 return build_function_call_expr (sqrtfn, arglist);
7682 /* Check for an integer exponent. */
7683 n = real_to_integer (&c);
7684 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7685 if (real_identical (&c, &cint))
7687 /* Attempt to evaluate pow at compile-time. */
7688 if (TREE_CODE (arg0) == REAL_CST
7689 && ! TREE_CONSTANT_OVERFLOW (arg0))
7691 REAL_VALUE_TYPE x;
7692 bool inexact;
7694 x = TREE_REAL_CST (arg0);
7695 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7696 if (flag_unsafe_math_optimizations || !inexact)
7697 return build_real (type, x);
7700 /* Strip sign ops from even integer powers. */
7701 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7703 tree narg0 = fold_strip_sign_ops (arg0);
7704 if (narg0)
7706 arglist = build_tree_list (NULL_TREE, arg1);
7707 arglist = tree_cons (NULL_TREE, narg0, arglist);
7708 return build_function_call_expr (fndecl, arglist);
7714 if (flag_unsafe_math_optimizations)
7716 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7718 /* Optimize pow(expN(x),y) = expN(x*y). */
7719 if (BUILTIN_EXPONENT_P (fcode))
7721 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7722 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7723 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7724 arglist = build_tree_list (NULL_TREE, arg);
7725 return build_function_call_expr (expfn, arglist);
7728 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7729 if (BUILTIN_SQRT_P (fcode))
7731 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7732 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7733 build_real (type, dconsthalf));
7735 arglist = tree_cons (NULL_TREE, narg0,
7736 build_tree_list (NULL_TREE, narg1));
7737 return build_function_call_expr (fndecl, arglist);
7740 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7741 if (BUILTIN_CBRT_P (fcode))
7743 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7744 if (tree_expr_nonnegative_p (arg))
7746 const REAL_VALUE_TYPE dconstroot
7747 = real_value_truncate (TYPE_MODE (type), dconstthird);
7748 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7749 build_real (type, dconstroot));
7750 arglist = tree_cons (NULL_TREE, arg,
7751 build_tree_list (NULL_TREE, narg1));
7752 return build_function_call_expr (fndecl, arglist);
7756 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7757 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7758 || fcode == BUILT_IN_POWL)
7760 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7761 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7762 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7763 arglist = tree_cons (NULL_TREE, arg00,
7764 build_tree_list (NULL_TREE, narg1));
7765 return build_function_call_expr (fndecl, arglist);
7769 return NULL_TREE;
7772 /* Fold a builtin function call to powi, powif, or powil. Return
7773 NULL_TREE if no simplification can be made. */
7774 static tree
7775 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7777 tree arg0 = TREE_VALUE (arglist);
7778 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7780 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7781 return NULL_TREE;
7783 /* Optimize pow(1.0,y) = 1.0. */
7784 if (real_onep (arg0))
7785 return omit_one_operand (type, build_real (type, dconst1), arg1);
7787 if (host_integerp (arg1, 0))
7789 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7791 /* Evaluate powi at compile-time. */
7792 if (TREE_CODE (arg0) == REAL_CST
7793 && ! TREE_CONSTANT_OVERFLOW (arg0))
7795 REAL_VALUE_TYPE x;
7796 x = TREE_REAL_CST (arg0);
7797 real_powi (&x, TYPE_MODE (type), &x, c);
7798 return build_real (type, x);
7801 /* Optimize pow(x,0) = 1.0. */
7802 if (c == 0)
7803 return omit_one_operand (type, build_real (type, dconst1),
7804 arg0);
7806 /* Optimize pow(x,1) = x. */
7807 if (c == 1)
7808 return arg0;
7810 /* Optimize pow(x,-1) = 1.0/x. */
7811 if (c == -1)
7812 return fold_build2 (RDIV_EXPR, type,
7813 build_real (type, dconst1), arg0);
7816 return NULL_TREE;
7819 /* A subroutine of fold_builtin to fold the various exponent
7820 functions. EXP is the CALL_EXPR of a call to a builtin function.
7821 VALUE is the value which will be raised to a power. */
7823 static tree
7824 fold_builtin_exponent (tree fndecl, tree arglist,
7825 const REAL_VALUE_TYPE *value)
7827 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7829 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7830 tree arg = TREE_VALUE (arglist);
7832 /* Optimize exp*(0.0) = 1.0. */
7833 if (real_zerop (arg))
7834 return build_real (type, dconst1);
7836 /* Optimize expN(1.0) = N. */
7837 if (real_onep (arg))
7839 REAL_VALUE_TYPE cst;
7841 real_convert (&cst, TYPE_MODE (type), value);
7842 return build_real (type, cst);
7845 /* Attempt to evaluate expN(integer) at compile-time. */
7846 if (flag_unsafe_math_optimizations
7847 && TREE_CODE (arg) == REAL_CST
7848 && ! TREE_CONSTANT_OVERFLOW (arg))
7850 REAL_VALUE_TYPE cint;
7851 REAL_VALUE_TYPE c;
7852 HOST_WIDE_INT n;
7854 c = TREE_REAL_CST (arg);
7855 n = real_to_integer (&c);
7856 real_from_integer (&cint, VOIDmode, n,
7857 n < 0 ? -1 : 0, 0);
7858 if (real_identical (&c, &cint))
7860 REAL_VALUE_TYPE x;
7862 real_powi (&x, TYPE_MODE (type), value, n);
7863 return build_real (type, x);
7867 /* Optimize expN(logN(x)) = x. */
7868 if (flag_unsafe_math_optimizations)
7870 const enum built_in_function fcode = builtin_mathfn_code (arg);
7872 if ((value == &dconste
7873 && (fcode == BUILT_IN_LOG
7874 || fcode == BUILT_IN_LOGF
7875 || fcode == BUILT_IN_LOGL))
7876 || (value == &dconst2
7877 && (fcode == BUILT_IN_LOG2
7878 || fcode == BUILT_IN_LOG2F
7879 || fcode == BUILT_IN_LOG2L))
7880 || (value == &dconst10
7881 && (fcode == BUILT_IN_LOG10
7882 || fcode == BUILT_IN_LOG10F
7883 || fcode == BUILT_IN_LOG10L)))
7884 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7888 return 0;
7891 /* Fold function call to builtin memset. Return
7892 NULL_TREE if no simplification can be made. */
7894 static tree
7895 fold_builtin_memset (tree arglist, tree type, bool ignore)
7897 tree dest, c, len, var, ret;
7898 unsigned HOST_WIDE_INT length, cval;
7900 if (!validate_arglist (arglist,
7901 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
7902 return 0;
7904 dest = TREE_VALUE (arglist);
7905 c = TREE_VALUE (TREE_CHAIN (arglist));
7906 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7908 if (! host_integerp (len, 1))
7909 return 0;
7911 /* If the LEN parameter is zero, return DEST. */
7912 if (integer_zerop (len))
7913 return omit_one_operand (type, dest, c);
7915 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
7916 return 0;
7918 var = dest;
7919 STRIP_NOPS (var);
7920 if (TREE_CODE (var) != ADDR_EXPR)
7921 return 0;
7923 var = TREE_OPERAND (var, 0);
7924 if (TREE_THIS_VOLATILE (var))
7925 return 0;
7927 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
7928 && !POINTER_TYPE_P (TREE_TYPE (var)))
7929 return 0;
7931 length = tree_low_cst (len, 1);
7932 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
7933 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
7934 < (int) length)
7935 return 0;
7937 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
7938 return 0;
7940 if (integer_zerop (c))
7941 cval = 0;
7942 else
7944 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
7945 return 0;
7947 cval = tree_low_cst (c, 1);
7948 cval &= 0xff;
7949 cval |= cval << 8;
7950 cval |= cval << 16;
7951 cval |= (cval << 31) << 1;
7954 ret = build_int_cst_type (TREE_TYPE (var), cval);
7955 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
7956 if (ignore)
7957 return ret;
7959 return omit_one_operand (type, dest, ret);
7962 /* Fold function call to builtin memset. Return
7963 NULL_TREE if no simplification can be made. */
7965 static tree
7966 fold_builtin_bzero (tree arglist, bool ignore)
7968 tree dest, size, newarglist;
7970 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7971 return 0;
7973 if (!ignore)
7974 return 0;
7976 dest = TREE_VALUE (arglist);
7977 size = TREE_VALUE (TREE_CHAIN (arglist));
7979 /* New argument list transforming bzero(ptr x, int y) to
7980 memset(ptr x, int 0, size_t y). This is done this way
7981 so that if it isn't expanded inline, we fallback to
7982 calling bzero instead of memset. */
7984 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
7985 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
7986 newarglist = tree_cons (NULL_TREE, dest, newarglist);
7987 return fold_builtin_memset (newarglist, void_type_node, ignore);
7990 /* Fold function call to builtin mem{{,p}cpy,move}. Return
7991 NULL_TREE if no simplification can be made.
7992 If ENDP is 0, return DEST (like memcpy).
7993 If ENDP is 1, return DEST+LEN (like mempcpy).
7994 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
7995 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
7996 (memmove). */
7998 static tree
7999 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8001 tree dest, src, len, destvar, srcvar, expr;
8002 unsigned HOST_WIDE_INT length;
8004 if (! validate_arglist (arglist,
8005 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8006 return 0;
8008 dest = TREE_VALUE (arglist);
8009 src = TREE_VALUE (TREE_CHAIN (arglist));
8010 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8012 /* If the LEN parameter is zero, return DEST. */
8013 if (integer_zerop (len))
8014 return omit_one_operand (type, dest, src);
8016 /* If SRC and DEST are the same (and not volatile), return
8017 DEST{,+LEN,+LEN-1}. */
8018 if (operand_equal_p (src, dest, 0))
8019 expr = len;
8020 else
8022 if (! host_integerp (len, 1))
8023 return 0;
8025 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8026 return 0;
8028 destvar = dest;
8029 STRIP_NOPS (destvar);
8030 if (TREE_CODE (destvar) != ADDR_EXPR)
8031 return 0;
8033 destvar = TREE_OPERAND (destvar, 0);
8034 if (TREE_THIS_VOLATILE (destvar))
8035 return 0;
8037 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8038 && !POINTER_TYPE_P (TREE_TYPE (destvar))
8039 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8040 return 0;
8042 srcvar = src;
8043 STRIP_NOPS (srcvar);
8044 if (TREE_CODE (srcvar) != ADDR_EXPR)
8045 return 0;
8047 srcvar = TREE_OPERAND (srcvar, 0);
8048 if (TREE_THIS_VOLATILE (srcvar))
8049 return 0;
8051 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8052 && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8053 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8054 return 0;
8056 length = tree_low_cst (len, 1);
8057 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8058 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8059 < (int) length
8060 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8061 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8062 < (int) length)
8063 return 0;
8065 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8066 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8067 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8068 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8069 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8070 else
8071 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8072 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8075 if (ignore)
8076 return expr;
8078 if (endp == 0 || endp == 3)
8079 return omit_one_operand (type, dest, expr);
8081 if (expr == len)
8082 expr = 0;
8084 if (endp == 2)
8085 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8086 ssize_int (1));
8088 len = fold_convert (TREE_TYPE (dest), len);
8089 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8090 dest = fold_convert (type, dest);
8091 if (expr)
8092 dest = omit_one_operand (type, dest, expr);
8093 return dest;
8096 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8097 simplification can be made. */
8099 static tree
8100 fold_builtin_bcopy (tree arglist, bool ignore)
8102 tree src, dest, size, newarglist;
8104 if (!validate_arglist (arglist,
8105 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8106 return 0;
8108 if (! ignore)
8109 return 0;
8111 src = TREE_VALUE (arglist);
8112 dest = TREE_VALUE (TREE_CHAIN (arglist));
8113 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8115 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8116 memmove(ptr y, ptr x, size_t z). This is done this way
8117 so that if it isn't expanded inline, we fallback to
8118 calling bcopy instead of memmove. */
8120 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8121 newarglist = tree_cons (NULL_TREE, src, newarglist);
8122 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8124 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8127 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8128 the length of the string to be copied. Return NULL_TREE if no
8129 simplification can be made. */
8131 tree
8132 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8134 tree dest, src, fn;
8136 if (!validate_arglist (arglist,
8137 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8138 return 0;
8140 dest = TREE_VALUE (arglist);
8141 src = TREE_VALUE (TREE_CHAIN (arglist));
8143 /* If SRC and DEST are the same (and not volatile), return DEST. */
8144 if (operand_equal_p (src, dest, 0))
8145 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8147 if (optimize_size)
8148 return 0;
8150 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8151 if (!fn)
8152 return 0;
8154 if (!len)
8156 len = c_strlen (src, 1);
8157 if (! len || TREE_SIDE_EFFECTS (len))
8158 return 0;
8161 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8162 arglist = build_tree_list (NULL_TREE, len);
8163 arglist = tree_cons (NULL_TREE, src, arglist);
8164 arglist = tree_cons (NULL_TREE, dest, arglist);
8165 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8166 build_function_call_expr (fn, arglist));
8169 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8170 the length of the source string. Return NULL_TREE if no simplification
8171 can be made. */
8173 tree
8174 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8176 tree dest, src, len, fn;
8178 if (!validate_arglist (arglist,
8179 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8180 return 0;
8182 dest = TREE_VALUE (arglist);
8183 src = TREE_VALUE (TREE_CHAIN (arglist));
8184 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8186 /* If the LEN parameter is zero, return DEST. */
8187 if (integer_zerop (len))
8188 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8190 /* We can't compare slen with len as constants below if len is not a
8191 constant. */
8192 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8193 return 0;
8195 if (!slen)
8196 slen = c_strlen (src, 1);
8198 /* Now, we must be passed a constant src ptr parameter. */
8199 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8200 return 0;
8202 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8204 /* We do not support simplification of this case, though we do
8205 support it when expanding trees into RTL. */
8206 /* FIXME: generate a call to __builtin_memset. */
8207 if (tree_int_cst_lt (slen, len))
8208 return 0;
8210 /* OK transform into builtin memcpy. */
8211 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8212 if (!fn)
8213 return 0;
8214 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8215 build_function_call_expr (fn, arglist));
8218 /* Fold function call to builtin memcmp. Return
8219 NULL_TREE if no simplification can be made. */
8221 static tree
8222 fold_builtin_memcmp (tree arglist)
8224 tree arg1, arg2, len;
8225 const char *p1, *p2;
8227 if (!validate_arglist (arglist,
8228 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8229 return 0;
8231 arg1 = TREE_VALUE (arglist);
8232 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8233 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8235 /* If the LEN parameter is zero, return zero. */
8236 if (integer_zerop (len))
8237 return omit_two_operands (integer_type_node, integer_zero_node,
8238 arg1, arg2);
8240 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8241 if (operand_equal_p (arg1, arg2, 0))
8242 return omit_one_operand (integer_type_node, integer_zero_node, len);
8244 p1 = c_getstr (arg1);
8245 p2 = c_getstr (arg2);
8247 /* If all arguments are constant, and the value of len is not greater
8248 than the lengths of arg1 and arg2, evaluate at compile-time. */
8249 if (host_integerp (len, 1) && p1 && p2
8250 && compare_tree_int (len, strlen (p1) + 1) <= 0
8251 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8253 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8255 if (r > 0)
8256 return integer_one_node;
8257 else if (r < 0)
8258 return integer_minus_one_node;
8259 else
8260 return integer_zero_node;
8263 /* If len parameter is one, return an expression corresponding to
8264 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8265 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8267 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8268 tree cst_uchar_ptr_node
8269 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8271 tree ind1 = fold_convert (integer_type_node,
8272 build1 (INDIRECT_REF, cst_uchar_node,
8273 fold_convert (cst_uchar_ptr_node,
8274 arg1)));
8275 tree ind2 = fold_convert (integer_type_node,
8276 build1 (INDIRECT_REF, cst_uchar_node,
8277 fold_convert (cst_uchar_ptr_node,
8278 arg2)));
8279 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8282 return 0;
8285 /* Fold function call to builtin strcmp. Return
8286 NULL_TREE if no simplification can be made. */
8288 static tree
8289 fold_builtin_strcmp (tree arglist)
8291 tree arg1, arg2;
8292 const char *p1, *p2;
8294 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8295 return 0;
8297 arg1 = TREE_VALUE (arglist);
8298 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8300 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8301 if (operand_equal_p (arg1, arg2, 0))
8302 return integer_zero_node;
8304 p1 = c_getstr (arg1);
8305 p2 = c_getstr (arg2);
8307 if (p1 && p2)
8309 const int i = strcmp (p1, p2);
8310 if (i < 0)
8311 return integer_minus_one_node;
8312 else if (i > 0)
8313 return integer_one_node;
8314 else
8315 return integer_zero_node;
8318 /* If the second arg is "", return *(const unsigned char*)arg1. */
8319 if (p2 && *p2 == '\0')
8321 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8322 tree cst_uchar_ptr_node
8323 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8325 return fold_convert (integer_type_node,
8326 build1 (INDIRECT_REF, cst_uchar_node,
8327 fold_convert (cst_uchar_ptr_node,
8328 arg1)));
8331 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8332 if (p1 && *p1 == '\0')
8334 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8335 tree cst_uchar_ptr_node
8336 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8338 tree temp = fold_convert (integer_type_node,
8339 build1 (INDIRECT_REF, cst_uchar_node,
8340 fold_convert (cst_uchar_ptr_node,
8341 arg2)));
8342 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8345 return 0;
8348 /* Fold function call to builtin strncmp. Return
8349 NULL_TREE if no simplification can be made. */
8351 static tree
8352 fold_builtin_strncmp (tree arglist)
8354 tree arg1, arg2, len;
8355 const char *p1, *p2;
8357 if (!validate_arglist (arglist,
8358 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8359 return 0;
8361 arg1 = TREE_VALUE (arglist);
8362 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8363 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8365 /* If the LEN parameter is zero, return zero. */
8366 if (integer_zerop (len))
8367 return omit_two_operands (integer_type_node, integer_zero_node,
8368 arg1, arg2);
8370 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8371 if (operand_equal_p (arg1, arg2, 0))
8372 return omit_one_operand (integer_type_node, integer_zero_node, len);
8374 p1 = c_getstr (arg1);
8375 p2 = c_getstr (arg2);
8377 if (host_integerp (len, 1) && p1 && p2)
8379 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8380 if (i > 0)
8381 return integer_one_node;
8382 else if (i < 0)
8383 return integer_minus_one_node;
8384 else
8385 return integer_zero_node;
8388 /* If the second arg is "", and the length is greater than zero,
8389 return *(const unsigned char*)arg1. */
8390 if (p2 && *p2 == '\0'
8391 && TREE_CODE (len) == INTEGER_CST
8392 && tree_int_cst_sgn (len) == 1)
8394 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8395 tree cst_uchar_ptr_node
8396 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8398 return fold_convert (integer_type_node,
8399 build1 (INDIRECT_REF, cst_uchar_node,
8400 fold_convert (cst_uchar_ptr_node,
8401 arg1)));
8404 /* If the first arg is "", and the length is greater than zero,
8405 return -*(const unsigned char*)arg2. */
8406 if (p1 && *p1 == '\0'
8407 && TREE_CODE (len) == INTEGER_CST
8408 && tree_int_cst_sgn (len) == 1)
8410 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8411 tree cst_uchar_ptr_node
8412 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8414 tree temp = fold_convert (integer_type_node,
8415 build1 (INDIRECT_REF, cst_uchar_node,
8416 fold_convert (cst_uchar_ptr_node,
8417 arg2)));
8418 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8421 /* If len parameter is one, return an expression corresponding to
8422 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8423 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8425 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8426 tree cst_uchar_ptr_node
8427 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8429 tree ind1 = fold_convert (integer_type_node,
8430 build1 (INDIRECT_REF, cst_uchar_node,
8431 fold_convert (cst_uchar_ptr_node,
8432 arg1)));
8433 tree ind2 = fold_convert (integer_type_node,
8434 build1 (INDIRECT_REF, cst_uchar_node,
8435 fold_convert (cst_uchar_ptr_node,
8436 arg2)));
8437 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8440 return 0;
8443 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8444 NULL_TREE if no simplification can be made. */
8446 static tree
8447 fold_builtin_signbit (tree fndecl, tree arglist)
8449 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8450 tree arg, temp;
8452 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8453 return NULL_TREE;
8455 arg = TREE_VALUE (arglist);
8457 /* If ARG is a compile-time constant, determine the result. */
8458 if (TREE_CODE (arg) == REAL_CST
8459 && !TREE_CONSTANT_OVERFLOW (arg))
8461 REAL_VALUE_TYPE c;
8463 c = TREE_REAL_CST (arg);
8464 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8465 return fold_convert (type, temp);
8468 /* If ARG is non-negative, the result is always zero. */
8469 if (tree_expr_nonnegative_p (arg))
8470 return omit_one_operand (type, integer_zero_node, arg);
8472 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8473 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8474 return fold_build2 (LT_EXPR, type, arg,
8475 build_real (TREE_TYPE (arg), dconst0));
8477 return NULL_TREE;
8480 /* Fold function call to builtin copysign, copysignf or copysignl.
8481 Return NULL_TREE if no simplification can be made. */
8483 static tree
8484 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8486 tree arg1, arg2, tem;
8488 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8489 return NULL_TREE;
8491 arg1 = TREE_VALUE (arglist);
8492 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8494 /* copysign(X,X) is X. */
8495 if (operand_equal_p (arg1, arg2, 0))
8496 return fold_convert (type, arg1);
8498 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8499 if (TREE_CODE (arg1) == REAL_CST
8500 && TREE_CODE (arg2) == REAL_CST
8501 && !TREE_CONSTANT_OVERFLOW (arg1)
8502 && !TREE_CONSTANT_OVERFLOW (arg2))
8504 REAL_VALUE_TYPE c1, c2;
8506 c1 = TREE_REAL_CST (arg1);
8507 c2 = TREE_REAL_CST (arg2);
8508 /* c1.sign := c2.sign. */
8509 real_copysign (&c1, &c2);
8510 return build_real (type, c1);
8513 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8514 Remember to evaluate Y for side-effects. */
8515 if (tree_expr_nonnegative_p (arg2))
8516 return omit_one_operand (type,
8517 fold_build1 (ABS_EXPR, type, arg1),
8518 arg2);
8520 /* Strip sign changing operations for the first argument. */
8521 tem = fold_strip_sign_ops (arg1);
8522 if (tem)
8524 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8525 return build_function_call_expr (fndecl, arglist);
8528 return NULL_TREE;
8531 /* Fold a call to builtin isascii. */
8533 static tree
8534 fold_builtin_isascii (tree arglist)
8536 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8537 return 0;
8538 else
8540 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8541 tree arg = TREE_VALUE (arglist);
8543 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8544 build_int_cst (NULL_TREE,
8545 ~ (unsigned HOST_WIDE_INT) 0x7f));
8546 arg = fold_build2 (EQ_EXPR, integer_type_node,
8547 arg, integer_zero_node);
8549 if (in_gimple_form && !TREE_CONSTANT (arg))
8550 return NULL_TREE;
8551 else
8552 return arg;
8556 /* Fold a call to builtin toascii. */
8558 static tree
8559 fold_builtin_toascii (tree arglist)
8561 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8562 return 0;
8563 else
8565 /* Transform toascii(c) -> (c & 0x7f). */
8566 tree arg = TREE_VALUE (arglist);
8568 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8569 build_int_cst (NULL_TREE, 0x7f));
8573 /* Fold a call to builtin isdigit. */
8575 static tree
8576 fold_builtin_isdigit (tree arglist)
8578 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8579 return 0;
8580 else
8582 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8583 /* According to the C standard, isdigit is unaffected by locale.
8584 However, it definitely is affected by the target character set. */
8585 tree arg;
8586 unsigned HOST_WIDE_INT target_digit0
8587 = lang_hooks.to_target_charset ('0');
8589 if (target_digit0 == 0)
8590 return NULL_TREE;
8592 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8593 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8594 build_int_cst (unsigned_type_node, target_digit0));
8595 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8596 build_int_cst (unsigned_type_node, 9));
8597 if (in_gimple_form && !TREE_CONSTANT (arg))
8598 return NULL_TREE;
8599 else
8600 return arg;
8604 /* Fold a call to fabs, fabsf or fabsl. */
8606 static tree
8607 fold_builtin_fabs (tree arglist, tree type)
8609 tree arg;
8611 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8612 return 0;
8614 arg = TREE_VALUE (arglist);
8615 arg = fold_convert (type, arg);
8616 if (TREE_CODE (arg) == REAL_CST)
8617 return fold_abs_const (arg, type);
8618 return fold_build1 (ABS_EXPR, type, arg);
8621 /* Fold a call to abs, labs, llabs or imaxabs. */
8623 static tree
8624 fold_builtin_abs (tree arglist, tree type)
8626 tree arg;
8628 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8629 return 0;
8631 arg = TREE_VALUE (arglist);
8632 arg = fold_convert (type, arg);
8633 if (TREE_CODE (arg) == INTEGER_CST)
8634 return fold_abs_const (arg, type);
8635 return fold_build1 (ABS_EXPR, type, arg);
8638 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8639 EXP is the CALL_EXPR for the call. */
8641 static tree
8642 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8644 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8645 tree arg;
8646 REAL_VALUE_TYPE r;
8648 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8650 /* Check that we have exactly one argument. */
8651 if (arglist == 0)
8653 error ("too few arguments to function %qs",
8654 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8655 return error_mark_node;
8657 else if (TREE_CHAIN (arglist) != 0)
8659 error ("too many arguments to function %qs",
8660 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8661 return error_mark_node;
8663 else
8665 error ("non-floating-point argument to function %qs",
8666 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8667 return error_mark_node;
8671 arg = TREE_VALUE (arglist);
8672 switch (builtin_index)
8674 case BUILT_IN_ISINF:
8675 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8676 return omit_one_operand (type, integer_zero_node, arg);
8678 if (TREE_CODE (arg) == REAL_CST)
8680 r = TREE_REAL_CST (arg);
8681 if (real_isinf (&r))
8682 return real_compare (GT_EXPR, &r, &dconst0)
8683 ? integer_one_node : integer_minus_one_node;
8684 else
8685 return integer_zero_node;
8688 return NULL_TREE;
8690 case BUILT_IN_FINITE:
8691 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8692 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8693 return omit_one_operand (type, integer_zero_node, arg);
8695 if (TREE_CODE (arg) == REAL_CST)
8697 r = TREE_REAL_CST (arg);
8698 return real_isinf (&r) || real_isnan (&r)
8699 ? integer_zero_node : integer_one_node;
8702 return NULL_TREE;
8704 case BUILT_IN_ISNAN:
8705 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8706 return omit_one_operand (type, integer_zero_node, arg);
8708 if (TREE_CODE (arg) == REAL_CST)
8710 r = TREE_REAL_CST (arg);
8711 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8714 arg = builtin_save_expr (arg);
8715 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8717 default:
8718 gcc_unreachable ();
8722 /* Fold a call to an unordered comparison function such as
8723 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8724 being called and ARGLIST is the argument list for the call.
8725 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8726 the opposite of the desired result. UNORDERED_CODE is used
8727 for modes that can hold NaNs and ORDERED_CODE is used for
8728 the rest. */
8730 static tree
8731 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8732 enum tree_code unordered_code,
8733 enum tree_code ordered_code)
8735 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8736 enum tree_code code;
8737 tree arg0, arg1;
8738 tree type0, type1;
8739 enum tree_code code0, code1;
8740 tree cmp_type = NULL_TREE;
8742 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8744 /* Check that we have exactly two arguments. */
8745 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8747 error ("too few arguments to function %qs",
8748 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8749 return error_mark_node;
8751 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8753 error ("too many arguments to function %qs",
8754 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8755 return error_mark_node;
8759 arg0 = TREE_VALUE (arglist);
8760 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8762 type0 = TREE_TYPE (arg0);
8763 type1 = TREE_TYPE (arg1);
8765 code0 = TREE_CODE (type0);
8766 code1 = TREE_CODE (type1);
8768 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8769 /* Choose the wider of two real types. */
8770 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8771 ? type0 : type1;
8772 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8773 cmp_type = type0;
8774 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8775 cmp_type = type1;
8776 else
8778 error ("non-floating-point argument to function %qs",
8779 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8780 return error_mark_node;
8783 arg0 = fold_convert (cmp_type, arg0);
8784 arg1 = fold_convert (cmp_type, arg1);
8786 if (unordered_code == UNORDERED_EXPR)
8788 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8789 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8790 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8793 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8794 : ordered_code;
8795 return fold_build1 (TRUTH_NOT_EXPR, type,
8796 fold_build2 (code, type, arg0, arg1));
8799 /* Used by constant folding to simplify calls to builtin functions. EXP is
8800 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8801 result of the function call is ignored. This function returns NULL_TREE
8802 if no simplification was possible. */
8804 static tree
8805 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8807 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8808 enum built_in_function fcode;
8810 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8811 return targetm.fold_builtin (fndecl, arglist, ignore);
8813 fcode = DECL_FUNCTION_CODE (fndecl);
8814 switch (fcode)
8816 case BUILT_IN_FPUTS:
8817 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8819 case BUILT_IN_FPUTS_UNLOCKED:
8820 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8822 case BUILT_IN_STRSTR:
8823 return fold_builtin_strstr (arglist, type);
8825 case BUILT_IN_STRCAT:
8826 return fold_builtin_strcat (arglist);
8828 case BUILT_IN_STRNCAT:
8829 return fold_builtin_strncat (arglist);
8831 case BUILT_IN_STRSPN:
8832 return fold_builtin_strspn (arglist);
8834 case BUILT_IN_STRCSPN:
8835 return fold_builtin_strcspn (arglist);
8837 case BUILT_IN_STRCHR:
8838 case BUILT_IN_INDEX:
8839 return fold_builtin_strchr (arglist, type);
8841 case BUILT_IN_STRRCHR:
8842 case BUILT_IN_RINDEX:
8843 return fold_builtin_strrchr (arglist, type);
8845 case BUILT_IN_STRCPY:
8846 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8848 case BUILT_IN_STRNCPY:
8849 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8851 case BUILT_IN_STRCMP:
8852 return fold_builtin_strcmp (arglist);
8854 case BUILT_IN_STRNCMP:
8855 return fold_builtin_strncmp (arglist);
8857 case BUILT_IN_STRPBRK:
8858 return fold_builtin_strpbrk (arglist, type);
8860 case BUILT_IN_BCMP:
8861 case BUILT_IN_MEMCMP:
8862 return fold_builtin_memcmp (arglist);
8864 case BUILT_IN_SPRINTF:
8865 return fold_builtin_sprintf (arglist, ignore);
8867 case BUILT_IN_CONSTANT_P:
8869 tree val;
8871 val = fold_builtin_constant_p (arglist);
8872 /* Gimplification will pull the CALL_EXPR for the builtin out of
8873 an if condition. When not optimizing, we'll not CSE it back.
8874 To avoid link error types of regressions, return false now. */
8875 if (!val && !optimize)
8876 val = integer_zero_node;
8878 return val;
8881 case BUILT_IN_EXPECT:
8882 return fold_builtin_expect (arglist);
8884 case BUILT_IN_CLASSIFY_TYPE:
8885 return fold_builtin_classify_type (arglist);
8887 case BUILT_IN_STRLEN:
8888 return fold_builtin_strlen (arglist);
8890 CASE_FLT_FN (BUILT_IN_FABS):
8891 return fold_builtin_fabs (arglist, type);
8893 case BUILT_IN_ABS:
8894 case BUILT_IN_LABS:
8895 case BUILT_IN_LLABS:
8896 case BUILT_IN_IMAXABS:
8897 return fold_builtin_abs (arglist, type);
8899 CASE_FLT_FN (BUILT_IN_CONJ):
8900 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8901 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8902 break;
8904 CASE_FLT_FN (BUILT_IN_CREAL):
8905 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8906 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8907 TREE_VALUE (arglist)));
8908 break;
8910 CASE_FLT_FN (BUILT_IN_CIMAG):
8911 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8912 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8913 TREE_VALUE (arglist)));
8914 break;
8916 CASE_FLT_FN (BUILT_IN_CABS):
8917 return fold_builtin_cabs (arglist, type, fndecl);
8919 CASE_FLT_FN (BUILT_IN_SQRT):
8920 return fold_builtin_sqrt (arglist, type);
8922 CASE_FLT_FN (BUILT_IN_CBRT):
8923 return fold_builtin_cbrt (arglist, type);
8925 CASE_FLT_FN (BUILT_IN_SIN):
8926 return fold_builtin_sin (arglist);
8928 CASE_FLT_FN (BUILT_IN_COS):
8929 return fold_builtin_cos (arglist, type, fndecl);
8931 CASE_FLT_FN (BUILT_IN_EXP):
8932 return fold_builtin_exponent (fndecl, arglist, &dconste);
8934 CASE_FLT_FN (BUILT_IN_EXP2):
8935 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8937 CASE_FLT_FN (BUILT_IN_EXP10):
8938 CASE_FLT_FN (BUILT_IN_POW10):
8939 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8941 CASE_FLT_FN (BUILT_IN_LOG):
8942 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8944 CASE_FLT_FN (BUILT_IN_LOG2):
8945 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8947 CASE_FLT_FN (BUILT_IN_LOG10):
8948 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8950 CASE_FLT_FN (BUILT_IN_TAN):
8951 return fold_builtin_tan (arglist);
8953 CASE_FLT_FN (BUILT_IN_ATAN):
8954 return fold_builtin_atan (arglist, type);
8956 CASE_FLT_FN (BUILT_IN_POW):
8957 return fold_builtin_pow (fndecl, arglist, type);
8959 CASE_FLT_FN (BUILT_IN_POWI):
8960 return fold_builtin_powi (fndecl, arglist, type);
8962 CASE_FLT_FN (BUILT_IN_INF):
8963 case BUILT_IN_INFD32:
8964 case BUILT_IN_INFD64:
8965 case BUILT_IN_INFD128:
8966 return fold_builtin_inf (type, true);
8968 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8969 return fold_builtin_inf (type, false);
8971 CASE_FLT_FN (BUILT_IN_NAN):
8972 case BUILT_IN_NAND32:
8973 case BUILT_IN_NAND64:
8974 case BUILT_IN_NAND128:
8975 return fold_builtin_nan (arglist, type, true);
8977 CASE_FLT_FN (BUILT_IN_NANS):
8978 return fold_builtin_nan (arglist, type, false);
8980 CASE_FLT_FN (BUILT_IN_FLOOR):
8981 return fold_builtin_floor (fndecl, arglist);
8983 CASE_FLT_FN (BUILT_IN_CEIL):
8984 return fold_builtin_ceil (fndecl, arglist);
8986 CASE_FLT_FN (BUILT_IN_TRUNC):
8987 return fold_builtin_trunc (fndecl, arglist);
8989 CASE_FLT_FN (BUILT_IN_ROUND):
8990 return fold_builtin_round (fndecl, arglist);
8992 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8993 CASE_FLT_FN (BUILT_IN_RINT):
8994 return fold_trunc_transparent_mathfn (fndecl, arglist);
8996 CASE_FLT_FN (BUILT_IN_LCEIL):
8997 CASE_FLT_FN (BUILT_IN_LLCEIL):
8998 CASE_FLT_FN (BUILT_IN_LFLOOR):
8999 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9000 CASE_FLT_FN (BUILT_IN_LROUND):
9001 CASE_FLT_FN (BUILT_IN_LLROUND):
9002 return fold_builtin_int_roundingfn (fndecl, arglist);
9004 CASE_FLT_FN (BUILT_IN_LRINT):
9005 CASE_FLT_FN (BUILT_IN_LLRINT):
9006 return fold_fixed_mathfn (fndecl, arglist);
9008 CASE_INT_FN (BUILT_IN_FFS):
9009 CASE_INT_FN (BUILT_IN_CLZ):
9010 CASE_INT_FN (BUILT_IN_CTZ):
9011 CASE_INT_FN (BUILT_IN_POPCOUNT):
9012 CASE_INT_FN (BUILT_IN_PARITY):
9013 return fold_builtin_bitop (fndecl, arglist);
9015 case BUILT_IN_MEMSET:
9016 return fold_builtin_memset (arglist, type, ignore);
9018 case BUILT_IN_MEMCPY:
9019 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9021 case BUILT_IN_MEMPCPY:
9022 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9024 case BUILT_IN_MEMMOVE:
9025 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9027 case BUILT_IN_BZERO:
9028 return fold_builtin_bzero (arglist, ignore);
9030 case BUILT_IN_BCOPY:
9031 return fold_builtin_bcopy (arglist, ignore);
9033 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9034 return fold_builtin_signbit (fndecl, arglist);
9036 case BUILT_IN_ISASCII:
9037 return fold_builtin_isascii (arglist);
9039 case BUILT_IN_TOASCII:
9040 return fold_builtin_toascii (arglist);
9042 case BUILT_IN_ISDIGIT:
9043 return fold_builtin_isdigit (arglist);
9045 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9046 return fold_builtin_copysign (fndecl, arglist, type);
9048 CASE_FLT_FN (BUILT_IN_FINITE):
9049 case BUILT_IN_FINITED32:
9050 case BUILT_IN_FINITED64:
9051 case BUILT_IN_FINITED128:
9052 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9054 CASE_FLT_FN (BUILT_IN_ISINF):
9055 case BUILT_IN_ISINFD32:
9056 case BUILT_IN_ISINFD64:
9057 case BUILT_IN_ISINFD128:
9058 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9060 CASE_FLT_FN (BUILT_IN_ISNAN):
9061 case BUILT_IN_ISNAND32:
9062 case BUILT_IN_ISNAND64:
9063 case BUILT_IN_ISNAND128:
9064 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9066 case BUILT_IN_ISGREATER:
9067 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9068 case BUILT_IN_ISGREATEREQUAL:
9069 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9070 case BUILT_IN_ISLESS:
9071 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9072 case BUILT_IN_ISLESSEQUAL:
9073 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9074 case BUILT_IN_ISLESSGREATER:
9075 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9076 case BUILT_IN_ISUNORDERED:
9077 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9078 NOP_EXPR);
9080 /* We do the folding for va_start in the expander. */
9081 case BUILT_IN_VA_START:
9082 break;
9084 case BUILT_IN_OBJECT_SIZE:
9085 return fold_builtin_object_size (arglist);
9086 case BUILT_IN_MEMCPY_CHK:
9087 case BUILT_IN_MEMPCPY_CHK:
9088 case BUILT_IN_MEMMOVE_CHK:
9089 case BUILT_IN_MEMSET_CHK:
9090 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9091 DECL_FUNCTION_CODE (fndecl));
9092 case BUILT_IN_STRCPY_CHK:
9093 case BUILT_IN_STPCPY_CHK:
9094 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9095 DECL_FUNCTION_CODE (fndecl));
9096 case BUILT_IN_STRNCPY_CHK:
9097 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9098 case BUILT_IN_STRCAT_CHK:
9099 return fold_builtin_strcat_chk (fndecl, arglist);
9100 case BUILT_IN_STRNCAT_CHK:
9101 return fold_builtin_strncat_chk (fndecl, arglist);
9102 case BUILT_IN_SPRINTF_CHK:
9103 case BUILT_IN_VSPRINTF_CHK:
9104 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9105 case BUILT_IN_SNPRINTF_CHK:
9106 case BUILT_IN_VSNPRINTF_CHK:
9107 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9108 DECL_FUNCTION_CODE (fndecl));
9110 case BUILT_IN_PRINTF:
9111 case BUILT_IN_PRINTF_UNLOCKED:
9112 case BUILT_IN_VPRINTF:
9113 case BUILT_IN_PRINTF_CHK:
9114 case BUILT_IN_VPRINTF_CHK:
9115 return fold_builtin_printf (fndecl, arglist, ignore,
9116 DECL_FUNCTION_CODE (fndecl));
9118 case BUILT_IN_FPRINTF:
9119 case BUILT_IN_FPRINTF_UNLOCKED:
9120 case BUILT_IN_VFPRINTF:
9121 case BUILT_IN_FPRINTF_CHK:
9122 case BUILT_IN_VFPRINTF_CHK:
9123 return fold_builtin_fprintf (fndecl, arglist, ignore,
9124 DECL_FUNCTION_CODE (fndecl));
9126 default:
9127 break;
9130 return 0;
9133 /* A wrapper function for builtin folding that prevents warnings for
9134 "statement without effect" and the like, caused by removing the
9135 call node earlier than the warning is generated. */
9137 tree
9138 fold_builtin (tree fndecl, tree arglist, bool ignore)
9140 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9141 if (exp)
9143 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9144 TREE_NO_WARNING (exp) = 1;
9147 return exp;
9150 /* Conveniently construct a function call expression. */
9152 tree
9153 build_function_call_expr (tree fn, tree arglist)
9155 tree call_expr;
9157 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9158 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9159 call_expr, arglist, NULL_TREE);
9162 /* This function validates the types of a function call argument list
9163 represented as a tree chain of parameters against a specified list
9164 of tree_codes. If the last specifier is a 0, that represents an
9165 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9167 static int
9168 validate_arglist (tree arglist, ...)
9170 enum tree_code code;
9171 int res = 0;
9172 va_list ap;
9174 va_start (ap, arglist);
9178 code = va_arg (ap, enum tree_code);
9179 switch (code)
9181 case 0:
9182 /* This signifies an ellipses, any further arguments are all ok. */
9183 res = 1;
9184 goto end;
9185 case VOID_TYPE:
9186 /* This signifies an endlink, if no arguments remain, return
9187 true, otherwise return false. */
9188 res = arglist == 0;
9189 goto end;
9190 default:
9191 /* If no parameters remain or the parameter's code does not
9192 match the specified code, return false. Otherwise continue
9193 checking any remaining arguments. */
9194 if (arglist == 0)
9195 goto end;
9196 if (code == POINTER_TYPE)
9198 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9199 goto end;
9201 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9202 goto end;
9203 break;
9205 arglist = TREE_CHAIN (arglist);
9207 while (1);
9209 /* We need gotos here since we can only have one VA_CLOSE in a
9210 function. */
9211 end: ;
9212 va_end (ap);
9214 return res;
9217 /* Default target-specific builtin expander that does nothing. */
9220 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9221 rtx target ATTRIBUTE_UNUSED,
9222 rtx subtarget ATTRIBUTE_UNUSED,
9223 enum machine_mode mode ATTRIBUTE_UNUSED,
9224 int ignore ATTRIBUTE_UNUSED)
9226 return NULL_RTX;
9229 /* Returns true is EXP represents data that would potentially reside
9230 in a readonly section. */
9232 static bool
9233 readonly_data_expr (tree exp)
9235 STRIP_NOPS (exp);
9237 if (TREE_CODE (exp) != ADDR_EXPR)
9238 return false;
9240 exp = get_base_address (TREE_OPERAND (exp, 0));
9241 if (!exp)
9242 return false;
9244 /* Make sure we call decl_readonly_section only for trees it
9245 can handle (since it returns true for everything it doesn't
9246 understand). */
9247 if (TREE_CODE (exp) == STRING_CST
9248 || TREE_CODE (exp) == CONSTRUCTOR
9249 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9250 return decl_readonly_section (exp, 0);
9251 else
9252 return false;
9255 /* Simplify a call to the strstr builtin.
9257 Return 0 if no simplification was possible, otherwise return the
9258 simplified form of the call as a tree.
9260 The simplified form may be a constant or other expression which
9261 computes the same value, but in a more efficient manner (including
9262 calls to other builtin functions).
9264 The call may contain arguments which need to be evaluated, but
9265 which are not useful to determine the result of the call. In
9266 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9267 COMPOUND_EXPR will be an argument which must be evaluated.
9268 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9269 COMPOUND_EXPR in the chain will contain the tree for the simplified
9270 form of the builtin function call. */
9272 static tree
9273 fold_builtin_strstr (tree arglist, tree type)
9275 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9276 return 0;
9277 else
9279 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9280 tree fn;
9281 const char *p1, *p2;
9283 p2 = c_getstr (s2);
9284 if (p2 == NULL)
9285 return 0;
9287 p1 = c_getstr (s1);
9288 if (p1 != NULL)
9290 const char *r = strstr (p1, p2);
9291 tree tem;
9293 if (r == NULL)
9294 return build_int_cst (TREE_TYPE (s1), 0);
9296 /* Return an offset into the constant string argument. */
9297 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9298 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9299 return fold_convert (type, tem);
9302 /* The argument is const char *, and the result is char *, so we need
9303 a type conversion here to avoid a warning. */
9304 if (p2[0] == '\0')
9305 return fold_convert (type, s1);
9307 if (p2[1] != '\0')
9308 return 0;
9310 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9311 if (!fn)
9312 return 0;
9314 /* New argument list transforming strstr(s1, s2) to
9315 strchr(s1, s2[0]). */
9316 arglist = build_tree_list (NULL_TREE,
9317 build_int_cst (NULL_TREE, p2[0]));
9318 arglist = tree_cons (NULL_TREE, s1, arglist);
9319 return build_function_call_expr (fn, arglist);
9323 /* Simplify a call to the strchr builtin.
9325 Return 0 if no simplification was possible, otherwise return the
9326 simplified form of the call as a tree.
9328 The simplified form may be a constant or other expression which
9329 computes the same value, but in a more efficient manner (including
9330 calls to other builtin functions).
9332 The call may contain arguments which need to be evaluated, but
9333 which are not useful to determine the result of the call. In
9334 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9335 COMPOUND_EXPR will be an argument which must be evaluated.
9336 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9337 COMPOUND_EXPR in the chain will contain the tree for the simplified
9338 form of the builtin function call. */
9340 static tree
9341 fold_builtin_strchr (tree arglist, tree type)
9343 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9344 return 0;
9345 else
9347 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9348 const char *p1;
9350 if (TREE_CODE (s2) != INTEGER_CST)
9351 return 0;
9353 p1 = c_getstr (s1);
9354 if (p1 != NULL)
9356 char c;
9357 const char *r;
9358 tree tem;
9360 if (target_char_cast (s2, &c))
9361 return 0;
9363 r = strchr (p1, c);
9365 if (r == NULL)
9366 return build_int_cst (TREE_TYPE (s1), 0);
9368 /* Return an offset into the constant string argument. */
9369 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9370 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9371 return fold_convert (type, tem);
9373 return 0;
9377 /* Simplify a call to the strrchr builtin.
9379 Return 0 if no simplification was possible, otherwise return the
9380 simplified form of the call as a tree.
9382 The simplified form may be a constant or other expression which
9383 computes the same value, but in a more efficient manner (including
9384 calls to other builtin functions).
9386 The call may contain arguments which need to be evaluated, but
9387 which are not useful to determine the result of the call. In
9388 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9389 COMPOUND_EXPR will be an argument which must be evaluated.
9390 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9391 COMPOUND_EXPR in the chain will contain the tree for the simplified
9392 form of the builtin function call. */
9394 static tree
9395 fold_builtin_strrchr (tree arglist, tree type)
9397 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9398 return 0;
9399 else
9401 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9402 tree fn;
9403 const char *p1;
9405 if (TREE_CODE (s2) != INTEGER_CST)
9406 return 0;
9408 p1 = c_getstr (s1);
9409 if (p1 != NULL)
9411 char c;
9412 const char *r;
9413 tree tem;
9415 if (target_char_cast (s2, &c))
9416 return 0;
9418 r = strrchr (p1, c);
9420 if (r == NULL)
9421 return build_int_cst (TREE_TYPE (s1), 0);
9423 /* Return an offset into the constant string argument. */
9424 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9425 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9426 return fold_convert (type, tem);
9429 if (! integer_zerop (s2))
9430 return 0;
9432 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9433 if (!fn)
9434 return 0;
9436 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9437 return build_function_call_expr (fn, arglist);
9441 /* Simplify a call to the strpbrk builtin.
9443 Return 0 if no simplification was possible, otherwise return the
9444 simplified form of the call as a tree.
9446 The simplified form may be a constant or other expression which
9447 computes the same value, but in a more efficient manner (including
9448 calls to other builtin functions).
9450 The call may contain arguments which need to be evaluated, but
9451 which are not useful to determine the result of the call. In
9452 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9453 COMPOUND_EXPR will be an argument which must be evaluated.
9454 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9455 COMPOUND_EXPR in the chain will contain the tree for the simplified
9456 form of the builtin function call. */
9458 static tree
9459 fold_builtin_strpbrk (tree arglist, tree type)
9461 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9462 return 0;
9463 else
9465 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9466 tree fn;
9467 const char *p1, *p2;
9469 p2 = c_getstr (s2);
9470 if (p2 == NULL)
9471 return 0;
9473 p1 = c_getstr (s1);
9474 if (p1 != NULL)
9476 const char *r = strpbrk (p1, p2);
9477 tree tem;
9479 if (r == NULL)
9480 return build_int_cst (TREE_TYPE (s1), 0);
9482 /* Return an offset into the constant string argument. */
9483 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9484 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9485 return fold_convert (type, tem);
9488 if (p2[0] == '\0')
9489 /* strpbrk(x, "") == NULL.
9490 Evaluate and ignore s1 in case it had side-effects. */
9491 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9493 if (p2[1] != '\0')
9494 return 0; /* Really call strpbrk. */
9496 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9497 if (!fn)
9498 return 0;
9500 /* New argument list transforming strpbrk(s1, s2) to
9501 strchr(s1, s2[0]). */
9502 arglist = build_tree_list (NULL_TREE,
9503 build_int_cst (NULL_TREE, p2[0]));
9504 arglist = tree_cons (NULL_TREE, s1, arglist);
9505 return build_function_call_expr (fn, arglist);
9509 /* Simplify a call to the strcat builtin.
9511 Return 0 if no simplification was possible, otherwise return the
9512 simplified form of the call as a tree.
9514 The simplified form may be a constant or other expression which
9515 computes the same value, but in a more efficient manner (including
9516 calls to other builtin functions).
9518 The call may contain arguments which need to be evaluated, but
9519 which are not useful to determine the result of the call. In
9520 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9521 COMPOUND_EXPR will be an argument which must be evaluated.
9522 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9523 COMPOUND_EXPR in the chain will contain the tree for the simplified
9524 form of the builtin function call. */
9526 static tree
9527 fold_builtin_strcat (tree arglist)
9529 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9530 return 0;
9531 else
9533 tree dst = TREE_VALUE (arglist),
9534 src = TREE_VALUE (TREE_CHAIN (arglist));
9535 const char *p = c_getstr (src);
9537 /* If the string length is zero, return the dst parameter. */
9538 if (p && *p == '\0')
9539 return dst;
9541 return 0;
9545 /* Simplify a call to the strncat builtin.
9547 Return 0 if no simplification was possible, otherwise return the
9548 simplified form of the call as a tree.
9550 The simplified form may be a constant or other expression which
9551 computes the same value, but in a more efficient manner (including
9552 calls to other builtin functions).
9554 The call may contain arguments which need to be evaluated, but
9555 which are not useful to determine the result of the call. In
9556 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9557 COMPOUND_EXPR will be an argument which must be evaluated.
9558 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9559 COMPOUND_EXPR in the chain will contain the tree for the simplified
9560 form of the builtin function call. */
9562 static tree
9563 fold_builtin_strncat (tree arglist)
9565 if (!validate_arglist (arglist,
9566 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9567 return 0;
9568 else
9570 tree dst = TREE_VALUE (arglist);
9571 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9572 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9573 const char *p = c_getstr (src);
9575 /* If the requested length is zero, or the src parameter string
9576 length is zero, return the dst parameter. */
9577 if (integer_zerop (len) || (p && *p == '\0'))
9578 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9580 /* If the requested len is greater than or equal to the string
9581 length, call strcat. */
9582 if (TREE_CODE (len) == INTEGER_CST && p
9583 && compare_tree_int (len, strlen (p)) >= 0)
9585 tree newarglist
9586 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9587 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9589 /* If the replacement _DECL isn't initialized, don't do the
9590 transformation. */
9591 if (!fn)
9592 return 0;
9594 return build_function_call_expr (fn, newarglist);
9596 return 0;
9600 /* Simplify a call to the strspn builtin.
9602 Return 0 if no simplification was possible, otherwise return the
9603 simplified form of the call as a tree.
9605 The simplified form may be a constant or other expression which
9606 computes the same value, but in a more efficient manner (including
9607 calls to other builtin functions).
9609 The call may contain arguments which need to be evaluated, but
9610 which are not useful to determine the result of the call. In
9611 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9612 COMPOUND_EXPR will be an argument which must be evaluated.
9613 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9614 COMPOUND_EXPR in the chain will contain the tree for the simplified
9615 form of the builtin function call. */
9617 static tree
9618 fold_builtin_strspn (tree arglist)
9620 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9621 return 0;
9622 else
9624 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9625 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9627 /* If both arguments are constants, evaluate at compile-time. */
9628 if (p1 && p2)
9630 const size_t r = strspn (p1, p2);
9631 return size_int (r);
9634 /* If either argument is "", return 0. */
9635 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9636 /* Evaluate and ignore both arguments in case either one has
9637 side-effects. */
9638 return omit_two_operands (integer_type_node, integer_zero_node,
9639 s1, s2);
9640 return 0;
9644 /* Simplify a call to the strcspn builtin.
9646 Return 0 if no simplification was possible, otherwise return the
9647 simplified form of the call as a tree.
9649 The simplified form may be a constant or other expression which
9650 computes the same value, but in a more efficient manner (including
9651 calls to other builtin functions).
9653 The call may contain arguments which need to be evaluated, but
9654 which are not useful to determine the result of the call. In
9655 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9656 COMPOUND_EXPR will be an argument which must be evaluated.
9657 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9658 COMPOUND_EXPR in the chain will contain the tree for the simplified
9659 form of the builtin function call. */
9661 static tree
9662 fold_builtin_strcspn (tree arglist)
9664 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9665 return 0;
9666 else
9668 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9669 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9671 /* If both arguments are constants, evaluate at compile-time. */
9672 if (p1 && p2)
9674 const size_t r = strcspn (p1, p2);
9675 return size_int (r);
9678 /* If the first argument is "", return 0. */
9679 if (p1 && *p1 == '\0')
9681 /* Evaluate and ignore argument s2 in case it has
9682 side-effects. */
9683 return omit_one_operand (integer_type_node,
9684 integer_zero_node, s2);
9687 /* If the second argument is "", return __builtin_strlen(s1). */
9688 if (p2 && *p2 == '\0')
9690 tree newarglist = build_tree_list (NULL_TREE, s1),
9691 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9693 /* If the replacement _DECL isn't initialized, don't do the
9694 transformation. */
9695 if (!fn)
9696 return 0;
9698 return build_function_call_expr (fn, newarglist);
9700 return 0;
9704 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9705 by the builtin will be ignored. UNLOCKED is true is true if this
9706 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9707 the known length of the string. Return NULL_TREE if no simplification
9708 was possible. */
9710 tree
9711 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9713 tree fn;
9714 /* If we're using an unlocked function, assume the other unlocked
9715 functions exist explicitly. */
9716 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9717 : implicit_built_in_decls[BUILT_IN_FPUTC];
9718 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9719 : implicit_built_in_decls[BUILT_IN_FWRITE];
9721 /* If the return value is used, don't do the transformation. */
9722 if (!ignore)
9723 return 0;
9725 /* Verify the arguments in the original call. */
9726 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9727 return 0;
9729 if (! len)
9730 len = c_strlen (TREE_VALUE (arglist), 0);
9732 /* Get the length of the string passed to fputs. If the length
9733 can't be determined, punt. */
9734 if (!len
9735 || TREE_CODE (len) != INTEGER_CST)
9736 return 0;
9738 switch (compare_tree_int (len, 1))
9740 case -1: /* length is 0, delete the call entirely . */
9741 return omit_one_operand (integer_type_node, integer_zero_node,
9742 TREE_VALUE (TREE_CHAIN (arglist)));
9744 case 0: /* length is 1, call fputc. */
9746 const char *p = c_getstr (TREE_VALUE (arglist));
9748 if (p != NULL)
9750 /* New argument list transforming fputs(string, stream) to
9751 fputc(string[0], stream). */
9752 arglist = build_tree_list (NULL_TREE,
9753 TREE_VALUE (TREE_CHAIN (arglist)));
9754 arglist = tree_cons (NULL_TREE,
9755 build_int_cst (NULL_TREE, p[0]),
9756 arglist);
9757 fn = fn_fputc;
9758 break;
9761 /* FALLTHROUGH */
9762 case 1: /* length is greater than 1, call fwrite. */
9764 tree string_arg;
9766 /* If optimizing for size keep fputs. */
9767 if (optimize_size)
9768 return 0;
9769 string_arg = TREE_VALUE (arglist);
9770 /* New argument list transforming fputs(string, stream) to
9771 fwrite(string, 1, len, stream). */
9772 arglist = build_tree_list (NULL_TREE,
9773 TREE_VALUE (TREE_CHAIN (arglist)));
9774 arglist = tree_cons (NULL_TREE, len, arglist);
9775 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9776 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9777 fn = fn_fwrite;
9778 break;
9780 default:
9781 gcc_unreachable ();
9784 /* If the replacement _DECL isn't initialized, don't do the
9785 transformation. */
9786 if (!fn)
9787 return 0;
9789 /* These optimizations are only performed when the result is ignored,
9790 hence there's no need to cast the result to integer_type_node. */
9791 return build_function_call_expr (fn, arglist);
9794 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9795 produced. False otherwise. This is done so that we don't output the error
9796 or warning twice or three times. */
9797 bool
9798 fold_builtin_next_arg (tree arglist)
9800 tree fntype = TREE_TYPE (current_function_decl);
9802 if (TYPE_ARG_TYPES (fntype) == 0
9803 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9804 == void_type_node))
9806 error ("%<va_start%> used in function with fixed args");
9807 return true;
9809 else if (!arglist)
9811 /* Evidently an out of date version of <stdarg.h>; can't validate
9812 va_start's second argument, but can still work as intended. */
9813 warning (0, "%<__builtin_next_arg%> called without an argument");
9814 return true;
9816 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9817 when we checked the arguments and if needed issued a warning. */
9818 else if (!TREE_CHAIN (arglist)
9819 || !integer_zerop (TREE_VALUE (arglist))
9820 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9821 || TREE_CHAIN (TREE_CHAIN (arglist)))
9823 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9824 tree arg = TREE_VALUE (arglist);
9826 if (TREE_CHAIN (arglist))
9828 error ("%<va_start%> used with too many arguments");
9829 return true;
9832 /* Strip off all nops for the sake of the comparison. This
9833 is not quite the same as STRIP_NOPS. It does more.
9834 We must also strip off INDIRECT_EXPR for C++ reference
9835 parameters. */
9836 while (TREE_CODE (arg) == NOP_EXPR
9837 || TREE_CODE (arg) == CONVERT_EXPR
9838 || TREE_CODE (arg) == NON_LVALUE_EXPR
9839 || TREE_CODE (arg) == INDIRECT_REF)
9840 arg = TREE_OPERAND (arg, 0);
9841 if (arg != last_parm)
9843 /* FIXME: Sometimes with the tree optimizers we can get the
9844 not the last argument even though the user used the last
9845 argument. We just warn and set the arg to be the last
9846 argument so that we will get wrong-code because of
9847 it. */
9848 warning (0, "second parameter of %<va_start%> not last named argument");
9850 /* We want to verify the second parameter just once before the tree
9851 optimizers are run and then avoid keeping it in the tree,
9852 as otherwise we could warn even for correct code like:
9853 void foo (int i, ...)
9854 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9855 TREE_VALUE (arglist) = integer_zero_node;
9856 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9858 return false;
9862 /* Simplify a call to the sprintf builtin.
9864 Return 0 if no simplification was possible, otherwise return the
9865 simplified form of the call as a tree. If IGNORED is true, it means that
9866 the caller does not use the returned value of the function. */
9868 static tree
9869 fold_builtin_sprintf (tree arglist, int ignored)
9871 tree call, retval, dest, fmt;
9872 const char *fmt_str = NULL;
9874 /* Verify the required arguments in the original call. We deal with two
9875 types of sprintf() calls: 'sprintf (str, fmt)' and
9876 'sprintf (dest, "%s", orig)'. */
9877 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9878 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9879 VOID_TYPE))
9880 return NULL_TREE;
9882 /* Get the destination string and the format specifier. */
9883 dest = TREE_VALUE (arglist);
9884 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9886 /* Check whether the format is a literal string constant. */
9887 fmt_str = c_getstr (fmt);
9888 if (fmt_str == NULL)
9889 return NULL_TREE;
9891 call = NULL_TREE;
9892 retval = NULL_TREE;
9894 if (!init_target_chars())
9895 return 0;
9897 /* If the format doesn't contain % args or %%, use strcpy. */
9898 if (strchr (fmt_str, target_percent) == NULL)
9900 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9902 if (!fn)
9903 return NULL_TREE;
9905 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9906 'format' is known to contain no % formats. */
9907 arglist = build_tree_list (NULL_TREE, fmt);
9908 arglist = tree_cons (NULL_TREE, dest, arglist);
9909 call = build_function_call_expr (fn, arglist);
9910 if (!ignored)
9911 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9914 /* If the format is "%s", use strcpy if the result isn't used. */
9915 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9917 tree fn, orig;
9918 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9920 if (!fn)
9921 return NULL_TREE;
9923 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9924 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9925 arglist = build_tree_list (NULL_TREE, orig);
9926 arglist = tree_cons (NULL_TREE, dest, arglist);
9927 if (!ignored)
9929 retval = c_strlen (orig, 1);
9930 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9931 return NULL_TREE;
9933 call = build_function_call_expr (fn, arglist);
9936 if (call && retval)
9938 retval = fold_convert
9939 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9940 retval);
9941 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9943 else
9944 return call;
9947 /* Expand a call to __builtin_object_size. */
9950 expand_builtin_object_size (tree exp)
9952 tree ost;
9953 int object_size_type;
9954 tree fndecl = get_callee_fndecl (exp);
9955 tree arglist = TREE_OPERAND (exp, 1);
9956 location_t locus = EXPR_LOCATION (exp);
9958 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9960 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9961 &locus, fndecl);
9962 expand_builtin_trap ();
9963 return const0_rtx;
9966 ost = TREE_VALUE (TREE_CHAIN (arglist));
9967 STRIP_NOPS (ost);
9969 if (TREE_CODE (ost) != INTEGER_CST
9970 || tree_int_cst_sgn (ost) < 0
9971 || compare_tree_int (ost, 3) > 0)
9973 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9974 &locus, fndecl);
9975 expand_builtin_trap ();
9976 return const0_rtx;
9979 object_size_type = tree_low_cst (ost, 0);
9981 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9984 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9985 FCODE is the BUILT_IN_* to use.
9986 Return 0 if we failed; the caller should emit a normal call,
9987 otherwise try to get the result in TARGET, if convenient (and in
9988 mode MODE if that's convenient). */
9990 static rtx
9991 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9992 enum built_in_function fcode)
9994 tree arglist = TREE_OPERAND (exp, 1);
9995 tree dest, src, len, size;
9997 if (!validate_arglist (arglist,
9998 POINTER_TYPE,
9999 fcode == BUILT_IN_MEMSET_CHK
10000 ? INTEGER_TYPE : POINTER_TYPE,
10001 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10002 return 0;
10004 dest = TREE_VALUE (arglist);
10005 src = TREE_VALUE (TREE_CHAIN (arglist));
10006 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10007 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10009 if (! host_integerp (size, 1))
10010 return 0;
10012 if (host_integerp (len, 1) || integer_all_onesp (size))
10014 tree fn;
10016 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10018 location_t locus = EXPR_LOCATION (exp);
10019 warning (0, "%Hcall to %D will always overflow destination buffer",
10020 &locus, get_callee_fndecl (exp));
10021 return 0;
10024 arglist = build_tree_list (NULL_TREE, len);
10025 arglist = tree_cons (NULL_TREE, src, arglist);
10026 arglist = tree_cons (NULL_TREE, dest, arglist);
10028 fn = NULL_TREE;
10029 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10030 mem{cpy,pcpy,move,set} is available. */
10031 switch (fcode)
10033 case BUILT_IN_MEMCPY_CHK:
10034 fn = built_in_decls[BUILT_IN_MEMCPY];
10035 break;
10036 case BUILT_IN_MEMPCPY_CHK:
10037 fn = built_in_decls[BUILT_IN_MEMPCPY];
10038 break;
10039 case BUILT_IN_MEMMOVE_CHK:
10040 fn = built_in_decls[BUILT_IN_MEMMOVE];
10041 break;
10042 case BUILT_IN_MEMSET_CHK:
10043 fn = built_in_decls[BUILT_IN_MEMSET];
10044 break;
10045 default:
10046 break;
10049 if (! fn)
10050 return 0;
10052 fn = build_function_call_expr (fn, arglist);
10053 if (TREE_CODE (fn) == CALL_EXPR)
10054 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10055 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10057 else if (fcode == BUILT_IN_MEMSET_CHK)
10058 return 0;
10059 else
10061 unsigned int dest_align
10062 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10064 /* If DEST is not a pointer type, call the normal function. */
10065 if (dest_align == 0)
10066 return 0;
10068 /* If SRC and DEST are the same (and not volatile), do nothing. */
10069 if (operand_equal_p (src, dest, 0))
10071 tree expr;
10073 if (fcode != BUILT_IN_MEMPCPY_CHK)
10075 /* Evaluate and ignore LEN in case it has side-effects. */
10076 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10077 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10080 len = fold_convert (TREE_TYPE (dest), len);
10081 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10082 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10085 /* __memmove_chk special case. */
10086 if (fcode == BUILT_IN_MEMMOVE_CHK)
10088 unsigned int src_align
10089 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10091 if (src_align == 0)
10092 return 0;
10094 /* If src is categorized for a readonly section we can use
10095 normal __memcpy_chk. */
10096 if (readonly_data_expr (src))
10098 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10099 if (!fn)
10100 return 0;
10101 fn = build_function_call_expr (fn, arglist);
10102 if (TREE_CODE (fn) == CALL_EXPR)
10103 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10104 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10107 return 0;
10111 /* Emit warning if a buffer overflow is detected at compile time. */
10113 static void
10114 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10116 int arg_mask, is_strlen = 0;
10117 tree arglist = TREE_OPERAND (exp, 1), a;
10118 tree len, size;
10119 location_t locus;
10121 switch (fcode)
10123 case BUILT_IN_STRCPY_CHK:
10124 case BUILT_IN_STPCPY_CHK:
10125 /* For __strcat_chk the warning will be emitted only if overflowing
10126 by at least strlen (dest) + 1 bytes. */
10127 case BUILT_IN_STRCAT_CHK:
10128 arg_mask = 6;
10129 is_strlen = 1;
10130 break;
10131 case BUILT_IN_STRNCPY_CHK:
10132 arg_mask = 12;
10133 break;
10134 case BUILT_IN_SNPRINTF_CHK:
10135 case BUILT_IN_VSNPRINTF_CHK:
10136 arg_mask = 10;
10137 break;
10138 default:
10139 gcc_unreachable ();
10142 len = NULL_TREE;
10143 size = NULL_TREE;
10144 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10145 if (arg_mask & 1)
10147 if (len)
10148 size = a;
10149 else
10150 len = a;
10153 if (!len || !size)
10154 return;
10156 len = TREE_VALUE (len);
10157 size = TREE_VALUE (size);
10159 if (! host_integerp (size, 1) || integer_all_onesp (size))
10160 return;
10162 if (is_strlen)
10164 len = c_strlen (len, 1);
10165 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10166 return;
10168 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10169 return;
10171 locus = EXPR_LOCATION (exp);
10172 warning (0, "%Hcall to %D will always overflow destination buffer",
10173 &locus, get_callee_fndecl (exp));
10176 /* Emit warning if a buffer overflow is detected at compile time
10177 in __sprintf_chk/__vsprintf_chk calls. */
10179 static void
10180 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10182 tree arglist = TREE_OPERAND (exp, 1);
10183 tree dest, size, len, fmt, flag;
10184 const char *fmt_str;
10186 /* Verify the required arguments in the original call. */
10187 if (! arglist)
10188 return;
10189 dest = TREE_VALUE (arglist);
10190 arglist = TREE_CHAIN (arglist);
10191 if (! arglist)
10192 return;
10193 flag = TREE_VALUE (arglist);
10194 arglist = TREE_CHAIN (arglist);
10195 if (! arglist)
10196 return;
10197 size = TREE_VALUE (arglist);
10198 arglist = TREE_CHAIN (arglist);
10199 if (! arglist)
10200 return;
10201 fmt = TREE_VALUE (arglist);
10202 arglist = TREE_CHAIN (arglist);
10204 if (! host_integerp (size, 1) || integer_all_onesp (size))
10205 return;
10207 /* Check whether the format is a literal string constant. */
10208 fmt_str = c_getstr (fmt);
10209 if (fmt_str == NULL)
10210 return;
10212 if (!init_target_chars())
10213 return;
10215 /* If the format doesn't contain % args or %%, we know its size. */
10216 if (strchr (fmt_str, target_percent) == 0)
10217 len = build_int_cstu (size_type_node, strlen (fmt_str));
10218 /* If the format is "%s" and first ... argument is a string literal,
10219 we know it too. */
10220 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10222 tree arg;
10224 if (! arglist)
10225 return;
10226 arg = TREE_VALUE (arglist);
10227 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10228 return;
10230 len = c_strlen (arg, 1);
10231 if (!len || ! host_integerp (len, 1))
10232 return;
10234 else
10235 return;
10237 if (! tree_int_cst_lt (len, size))
10239 location_t locus = EXPR_LOCATION (exp);
10240 warning (0, "%Hcall to %D will always overflow destination buffer",
10241 &locus, get_callee_fndecl (exp));
10245 /* Fold a call to __builtin_object_size, if possible. */
10247 tree
10248 fold_builtin_object_size (tree arglist)
10250 tree ptr, ost, ret = 0;
10251 int object_size_type;
10253 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10254 return 0;
10256 ptr = TREE_VALUE (arglist);
10257 ost = TREE_VALUE (TREE_CHAIN (arglist));
10258 STRIP_NOPS (ost);
10260 if (TREE_CODE (ost) != INTEGER_CST
10261 || tree_int_cst_sgn (ost) < 0
10262 || compare_tree_int (ost, 3) > 0)
10263 return 0;
10265 object_size_type = tree_low_cst (ost, 0);
10267 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10268 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10269 and (size_t) 0 for types 2 and 3. */
10270 if (TREE_SIDE_EFFECTS (ptr))
10271 return fold_convert (size_type_node,
10272 object_size_type < 2
10273 ? integer_minus_one_node : integer_zero_node);
10275 if (TREE_CODE (ptr) == ADDR_EXPR)
10276 ret = build_int_cstu (size_type_node,
10277 compute_builtin_object_size (ptr, object_size_type));
10279 else if (TREE_CODE (ptr) == SSA_NAME)
10281 unsigned HOST_WIDE_INT bytes;
10283 /* If object size is not known yet, delay folding until
10284 later. Maybe subsequent passes will help determining
10285 it. */
10286 bytes = compute_builtin_object_size (ptr, object_size_type);
10287 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10288 ? -1 : 0))
10289 ret = build_int_cstu (size_type_node, bytes);
10292 if (ret)
10294 ret = force_fit_type (ret, -1, false, false);
10295 if (TREE_CONSTANT_OVERFLOW (ret))
10296 ret = 0;
10299 return ret;
10302 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10303 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10304 code of the builtin. If MAXLEN is not NULL, it is maximum length
10305 passed as third argument. */
10307 tree
10308 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10309 enum built_in_function fcode)
10311 tree dest, src, len, size, fn;
10313 if (!validate_arglist (arglist,
10314 POINTER_TYPE,
10315 fcode == BUILT_IN_MEMSET_CHK
10316 ? INTEGER_TYPE : POINTER_TYPE,
10317 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10318 return 0;
10320 dest = TREE_VALUE (arglist);
10321 /* Actually val for __memset_chk, but it doesn't matter. */
10322 src = TREE_VALUE (TREE_CHAIN (arglist));
10323 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10324 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10326 /* If SRC and DEST are the same (and not volatile), return DEST
10327 (resp. DEST+LEN for __mempcpy_chk). */
10328 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10330 if (fcode != BUILT_IN_MEMPCPY_CHK)
10331 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10332 else
10334 tree temp = fold_convert (TREE_TYPE (dest), len);
10335 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10336 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10340 if (! host_integerp (size, 1))
10341 return 0;
10343 if (! integer_all_onesp (size))
10345 if (! host_integerp (len, 1))
10347 /* If LEN is not constant, try MAXLEN too.
10348 For MAXLEN only allow optimizing into non-_ocs function
10349 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10350 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10352 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10354 /* (void) __mempcpy_chk () can be optimized into
10355 (void) __memcpy_chk (). */
10356 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10357 if (!fn)
10358 return 0;
10360 return build_function_call_expr (fn, arglist);
10362 return 0;
10365 else
10366 maxlen = len;
10368 if (tree_int_cst_lt (size, maxlen))
10369 return 0;
10372 arglist = build_tree_list (NULL_TREE, len);
10373 arglist = tree_cons (NULL_TREE, src, arglist);
10374 arglist = tree_cons (NULL_TREE, dest, arglist);
10376 fn = NULL_TREE;
10377 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10378 mem{cpy,pcpy,move,set} is available. */
10379 switch (fcode)
10381 case BUILT_IN_MEMCPY_CHK:
10382 fn = built_in_decls[BUILT_IN_MEMCPY];
10383 break;
10384 case BUILT_IN_MEMPCPY_CHK:
10385 fn = built_in_decls[BUILT_IN_MEMPCPY];
10386 break;
10387 case BUILT_IN_MEMMOVE_CHK:
10388 fn = built_in_decls[BUILT_IN_MEMMOVE];
10389 break;
10390 case BUILT_IN_MEMSET_CHK:
10391 fn = built_in_decls[BUILT_IN_MEMSET];
10392 break;
10393 default:
10394 break;
10397 if (!fn)
10398 return 0;
10400 return build_function_call_expr (fn, arglist);
10403 /* Fold a call to the __st[rp]cpy_chk builtin.
10404 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10405 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10406 strings passed as second argument. */
10408 tree
10409 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10410 enum built_in_function fcode)
10412 tree dest, src, size, len, fn;
10414 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10415 VOID_TYPE))
10416 return 0;
10418 dest = TREE_VALUE (arglist);
10419 src = TREE_VALUE (TREE_CHAIN (arglist));
10420 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10422 /* If SRC and DEST are the same (and not volatile), return DEST. */
10423 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10424 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10426 if (! host_integerp (size, 1))
10427 return 0;
10429 if (! integer_all_onesp (size))
10431 len = c_strlen (src, 1);
10432 if (! len || ! host_integerp (len, 1))
10434 /* If LEN is not constant, try MAXLEN too.
10435 For MAXLEN only allow optimizing into non-_ocs function
10436 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10437 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10439 if (fcode == BUILT_IN_STPCPY_CHK)
10441 if (! ignore)
10442 return 0;
10444 /* If return value of __stpcpy_chk is ignored,
10445 optimize into __strcpy_chk. */
10446 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10447 if (!fn)
10448 return 0;
10450 return build_function_call_expr (fn, arglist);
10453 if (! len || TREE_SIDE_EFFECTS (len))
10454 return 0;
10456 /* If c_strlen returned something, but not a constant,
10457 transform __strcpy_chk into __memcpy_chk. */
10458 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10459 if (!fn)
10460 return 0;
10462 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10463 arglist = build_tree_list (NULL_TREE, size);
10464 arglist = tree_cons (NULL_TREE, len, arglist);
10465 arglist = tree_cons (NULL_TREE, src, arglist);
10466 arglist = tree_cons (NULL_TREE, dest, arglist);
10467 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10468 build_function_call_expr (fn, arglist));
10471 else
10472 maxlen = len;
10474 if (! tree_int_cst_lt (maxlen, size))
10475 return 0;
10478 arglist = build_tree_list (NULL_TREE, src);
10479 arglist = tree_cons (NULL_TREE, dest, arglist);
10481 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10482 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10483 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10484 if (!fn)
10485 return 0;
10487 return build_function_call_expr (fn, arglist);
10490 /* Fold a call to the __strncpy_chk builtin.
10491 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10493 tree
10494 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10496 tree dest, src, size, len, fn;
10498 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10499 INTEGER_TYPE, VOID_TYPE))
10500 return 0;
10502 dest = TREE_VALUE (arglist);
10503 src = TREE_VALUE (TREE_CHAIN (arglist));
10504 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10505 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10507 if (! host_integerp (size, 1))
10508 return 0;
10510 if (! integer_all_onesp (size))
10512 if (! host_integerp (len, 1))
10514 /* If LEN is not constant, try MAXLEN too.
10515 For MAXLEN only allow optimizing into non-_ocs function
10516 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10517 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10518 return 0;
10520 else
10521 maxlen = len;
10523 if (tree_int_cst_lt (size, maxlen))
10524 return 0;
10527 arglist = build_tree_list (NULL_TREE, len);
10528 arglist = tree_cons (NULL_TREE, src, arglist);
10529 arglist = tree_cons (NULL_TREE, dest, arglist);
10531 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10532 fn = built_in_decls[BUILT_IN_STRNCPY];
10533 if (!fn)
10534 return 0;
10536 return build_function_call_expr (fn, arglist);
10539 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10541 static tree
10542 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10544 tree dest, src, size, fn;
10545 const char *p;
10547 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10548 VOID_TYPE))
10549 return 0;
10551 dest = TREE_VALUE (arglist);
10552 src = TREE_VALUE (TREE_CHAIN (arglist));
10553 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10555 p = c_getstr (src);
10556 /* If the SRC parameter is "", return DEST. */
10557 if (p && *p == '\0')
10558 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10560 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10561 return 0;
10563 arglist = build_tree_list (NULL_TREE, src);
10564 arglist = tree_cons (NULL_TREE, dest, arglist);
10566 /* If __builtin_strcat_chk is used, assume strcat is available. */
10567 fn = built_in_decls[BUILT_IN_STRCAT];
10568 if (!fn)
10569 return 0;
10571 return build_function_call_expr (fn, arglist);
10574 /* Fold a call to the __strncat_chk builtin EXP. */
10576 static tree
10577 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10579 tree dest, src, size, len, fn;
10580 const char *p;
10582 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10583 INTEGER_TYPE, VOID_TYPE))
10584 return 0;
10586 dest = TREE_VALUE (arglist);
10587 src = TREE_VALUE (TREE_CHAIN (arglist));
10588 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10589 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10591 p = c_getstr (src);
10592 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10593 if (p && *p == '\0')
10594 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10595 else if (integer_zerop (len))
10596 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10598 if (! host_integerp (size, 1))
10599 return 0;
10601 if (! integer_all_onesp (size))
10603 tree src_len = c_strlen (src, 1);
10604 if (src_len
10605 && host_integerp (src_len, 1)
10606 && host_integerp (len, 1)
10607 && ! tree_int_cst_lt (len, src_len))
10609 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10610 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10611 if (!fn)
10612 return 0;
10614 arglist = build_tree_list (NULL_TREE, size);
10615 arglist = tree_cons (NULL_TREE, src, arglist);
10616 arglist = tree_cons (NULL_TREE, dest, arglist);
10617 return build_function_call_expr (fn, arglist);
10619 return 0;
10622 arglist = build_tree_list (NULL_TREE, len);
10623 arglist = tree_cons (NULL_TREE, src, arglist);
10624 arglist = tree_cons (NULL_TREE, dest, arglist);
10626 /* If __builtin_strncat_chk is used, assume strncat is available. */
10627 fn = built_in_decls[BUILT_IN_STRNCAT];
10628 if (!fn)
10629 return 0;
10631 return build_function_call_expr (fn, arglist);
10634 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10635 a normal call should be emitted rather than expanding the function
10636 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10638 static tree
10639 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10641 tree dest, size, len, fn, fmt, flag;
10642 const char *fmt_str;
10644 /* Verify the required arguments in the original call. */
10645 if (! arglist)
10646 return 0;
10647 dest = TREE_VALUE (arglist);
10648 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10649 return 0;
10650 arglist = TREE_CHAIN (arglist);
10651 if (! arglist)
10652 return 0;
10653 flag = TREE_VALUE (arglist);
10654 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10655 return 0;
10656 arglist = TREE_CHAIN (arglist);
10657 if (! arglist)
10658 return 0;
10659 size = TREE_VALUE (arglist);
10660 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10661 return 0;
10662 arglist = TREE_CHAIN (arglist);
10663 if (! arglist)
10664 return 0;
10665 fmt = TREE_VALUE (arglist);
10666 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10667 return 0;
10668 arglist = TREE_CHAIN (arglist);
10670 if (! host_integerp (size, 1))
10671 return 0;
10673 len = NULL_TREE;
10675 if (!init_target_chars())
10676 return 0;
10678 /* Check whether the format is a literal string constant. */
10679 fmt_str = c_getstr (fmt);
10680 if (fmt_str != NULL)
10682 /* If the format doesn't contain % args or %%, we know the size. */
10683 if (strchr (fmt_str, target_percent) == 0)
10685 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10686 len = build_int_cstu (size_type_node, strlen (fmt_str));
10688 /* If the format is "%s" and first ... argument is a string literal,
10689 we know the size too. */
10690 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10692 tree arg;
10694 if (arglist && !TREE_CHAIN (arglist))
10696 arg = TREE_VALUE (arglist);
10697 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10699 len = c_strlen (arg, 1);
10700 if (! len || ! host_integerp (len, 1))
10701 len = NULL_TREE;
10707 if (! integer_all_onesp (size))
10709 if (! len || ! tree_int_cst_lt (len, size))
10710 return 0;
10713 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10714 or if format doesn't contain % chars or is "%s". */
10715 if (! integer_zerop (flag))
10717 if (fmt_str == NULL)
10718 return 0;
10719 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10720 return 0;
10723 arglist = tree_cons (NULL_TREE, fmt, arglist);
10724 arglist = tree_cons (NULL_TREE, dest, arglist);
10726 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10727 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10728 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10729 if (!fn)
10730 return 0;
10732 return build_function_call_expr (fn, arglist);
10735 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10736 a normal call should be emitted rather than expanding the function
10737 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10738 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10739 passed as second argument. */
10741 tree
10742 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10743 enum built_in_function fcode)
10745 tree dest, size, len, fn, fmt, flag;
10746 const char *fmt_str;
10748 /* Verify the required arguments in the original call. */
10749 if (! arglist)
10750 return 0;
10751 dest = TREE_VALUE (arglist);
10752 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10753 return 0;
10754 arglist = TREE_CHAIN (arglist);
10755 if (! arglist)
10756 return 0;
10757 len = TREE_VALUE (arglist);
10758 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10759 return 0;
10760 arglist = TREE_CHAIN (arglist);
10761 if (! arglist)
10762 return 0;
10763 flag = TREE_VALUE (arglist);
10764 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10765 return 0;
10766 arglist = TREE_CHAIN (arglist);
10767 if (! arglist)
10768 return 0;
10769 size = TREE_VALUE (arglist);
10770 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10771 return 0;
10772 arglist = TREE_CHAIN (arglist);
10773 if (! arglist)
10774 return 0;
10775 fmt = TREE_VALUE (arglist);
10776 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10777 return 0;
10778 arglist = TREE_CHAIN (arglist);
10780 if (! host_integerp (size, 1))
10781 return 0;
10783 if (! integer_all_onesp (size))
10785 if (! host_integerp (len, 1))
10787 /* If LEN is not constant, try MAXLEN too.
10788 For MAXLEN only allow optimizing into non-_ocs function
10789 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10790 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10791 return 0;
10793 else
10794 maxlen = len;
10796 if (tree_int_cst_lt (size, maxlen))
10797 return 0;
10800 if (!init_target_chars())
10801 return 0;
10803 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10804 or if format doesn't contain % chars or is "%s". */
10805 if (! integer_zerop (flag))
10807 fmt_str = c_getstr (fmt);
10808 if (fmt_str == NULL)
10809 return 0;
10810 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10811 return 0;
10814 arglist = tree_cons (NULL_TREE, fmt, arglist);
10815 arglist = tree_cons (NULL_TREE, len, arglist);
10816 arglist = tree_cons (NULL_TREE, dest, arglist);
10818 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10819 available. */
10820 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10821 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10822 if (!fn)
10823 return 0;
10825 return build_function_call_expr (fn, arglist);
10828 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10830 Return 0 if no simplification was possible, otherwise return the
10831 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10832 code of the function to be simplified. */
10834 static tree
10835 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10836 enum built_in_function fcode)
10838 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10839 const char *fmt_str = NULL;
10841 /* If the return value is used, don't do the transformation. */
10842 if (! ignore)
10843 return 0;
10845 /* Verify the required arguments in the original call. */
10846 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10848 tree flag;
10850 if (! arglist)
10851 return 0;
10852 flag = TREE_VALUE (arglist);
10853 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10854 || TREE_SIDE_EFFECTS (flag))
10855 return 0;
10856 arglist = TREE_CHAIN (arglist);
10859 if (! arglist)
10860 return 0;
10861 fmt = TREE_VALUE (arglist);
10862 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10863 return 0;
10864 arglist = TREE_CHAIN (arglist);
10866 /* Check whether the format is a literal string constant. */
10867 fmt_str = c_getstr (fmt);
10868 if (fmt_str == NULL)
10869 return NULL_TREE;
10871 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10873 /* If we're using an unlocked function, assume the other
10874 unlocked functions exist explicitly. */
10875 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10876 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10878 else
10880 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10881 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10884 if (!init_target_chars())
10885 return 0;
10887 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10889 const char *str;
10891 if (strcmp (fmt_str, target_percent_s) == 0)
10893 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10894 return 0;
10896 if (! arglist
10897 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10898 || TREE_CHAIN (arglist))
10899 return 0;
10901 str = c_getstr (TREE_VALUE (arglist));
10902 if (str == NULL)
10903 return 0;
10905 else
10907 /* The format specifier doesn't contain any '%' characters. */
10908 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10909 && arglist)
10910 return 0;
10911 str = fmt_str;
10914 /* If the string was "", printf does nothing. */
10915 if (str[0] == '\0')
10916 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10918 /* If the string has length of 1, call putchar. */
10919 if (str[1] == '\0')
10921 /* Given printf("c"), (where c is any one character,)
10922 convert "c"[0] to an int and pass that to the replacement
10923 function. */
10924 arg = build_int_cst (NULL_TREE, str[0]);
10925 arglist = build_tree_list (NULL_TREE, arg);
10926 fn = fn_putchar;
10928 else
10930 /* If the string was "string\n", call puts("string"). */
10931 size_t len = strlen (str);
10932 if ((unsigned char)str[len - 1] == target_newline)
10934 /* Create a NUL-terminated string that's one char shorter
10935 than the original, stripping off the trailing '\n'. */
10936 char *newstr = alloca (len);
10937 memcpy (newstr, str, len - 1);
10938 newstr[len - 1] = 0;
10940 arg = build_string_literal (len, newstr);
10941 arglist = build_tree_list (NULL_TREE, arg);
10942 fn = fn_puts;
10944 else
10945 /* We'd like to arrange to call fputs(string,stdout) here,
10946 but we need stdout and don't have a way to get it yet. */
10947 return 0;
10951 /* The other optimizations can be done only on the non-va_list variants. */
10952 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10953 return 0;
10955 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10956 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10958 if (! arglist
10959 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10960 || TREE_CHAIN (arglist))
10961 return 0;
10962 fn = fn_puts;
10965 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10966 else if (strcmp (fmt_str, target_percent_c) == 0)
10968 if (! arglist
10969 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10970 || TREE_CHAIN (arglist))
10971 return 0;
10972 fn = fn_putchar;
10975 if (!fn)
10976 return 0;
10978 call = build_function_call_expr (fn, arglist);
10979 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10982 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10984 Return 0 if no simplification was possible, otherwise return the
10985 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10986 code of the function to be simplified. */
10988 static tree
10989 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10990 enum built_in_function fcode)
10992 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10993 const char *fmt_str = NULL;
10995 /* If the return value is used, don't do the transformation. */
10996 if (! ignore)
10997 return 0;
10999 /* Verify the required arguments in the original call. */
11000 if (! arglist)
11001 return 0;
11002 fp = TREE_VALUE (arglist);
11003 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11004 return 0;
11005 arglist = TREE_CHAIN (arglist);
11007 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_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_FPRINTF_UNLOCKED)
11034 /* If we're using an unlocked function, assume the other
11035 unlocked functions exist explicitly. */
11036 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11037 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11039 else
11041 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11042 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11045 if (!init_target_chars())
11046 return 0;
11048 /* If the format doesn't contain % args or %%, use strcpy. */
11049 if (strchr (fmt_str, target_percent) == NULL)
11051 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11052 && arglist)
11053 return 0;
11055 /* If the format specifier was "", fprintf does nothing. */
11056 if (fmt_str[0] == '\0')
11058 /* If FP has side-effects, just wait until gimplification is
11059 done. */
11060 if (TREE_SIDE_EFFECTS (fp))
11061 return 0;
11063 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11066 /* When "string" doesn't contain %, replace all cases of
11067 fprintf (fp, string) with fputs (string, fp). The fputs
11068 builtin will take care of special cases like length == 1. */
11069 arglist = build_tree_list (NULL_TREE, fp);
11070 arglist = tree_cons (NULL_TREE, fmt, arglist);
11071 fn = fn_fputs;
11074 /* The other optimizations can be done only on the non-va_list variants. */
11075 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11076 return 0;
11078 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11079 else if (strcmp (fmt_str, target_percent_s) == 0)
11081 if (! arglist
11082 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11083 || TREE_CHAIN (arglist))
11084 return 0;
11085 arg = TREE_VALUE (arglist);
11086 arglist = build_tree_list (NULL_TREE, fp);
11087 arglist = tree_cons (NULL_TREE, arg, arglist);
11088 fn = fn_fputs;
11091 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11092 else if (strcmp (fmt_str, target_percent_c) == 0)
11094 if (! arglist
11095 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11096 || TREE_CHAIN (arglist))
11097 return 0;
11098 arg = TREE_VALUE (arglist);
11099 arglist = build_tree_list (NULL_TREE, fp);
11100 arglist = tree_cons (NULL_TREE, arg, arglist);
11101 fn = fn_fputc;
11104 if (!fn)
11105 return 0;
11107 call = build_function_call_expr (fn, arglist);
11108 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11111 /* Initialize format string characters in the target charset. */
11113 static bool
11114 init_target_chars (void)
11116 static bool init;
11117 if (!init)
11119 target_newline = lang_hooks.to_target_charset ('\n');
11120 target_percent = lang_hooks.to_target_charset ('%');
11121 target_c = lang_hooks.to_target_charset ('c');
11122 target_s = lang_hooks.to_target_charset ('s');
11123 if (target_newline == 0 || target_percent == 0 || target_c == 0
11124 || target_s == 0)
11125 return false;
11127 target_percent_c[0] = target_percent;
11128 target_percent_c[1] = target_c;
11129 target_percent_c[2] = '\0';
11131 target_percent_s[0] = target_percent;
11132 target_percent_s[1] = target_s;
11133 target_percent_s[2] = '\0';
11135 target_percent_s_newline[0] = target_percent;
11136 target_percent_s_newline[1] = target_s;
11137 target_percent_s_newline[2] = target_newline;
11138 target_percent_s_newline[3] = '\0';
11140 init = true;
11142 return true;