Revert emutls patch.
[official-gcc.git] / gcc / builtins.c
blob29974622ea19c24bd767bdef352661927e8cda4c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static void expand_builtin_update_setjmp_buf (rtx);
85 static void expand_builtin_prefetch (tree);
86 static rtx expand_builtin_apply_args (void);
87 static rtx expand_builtin_apply_args_1 (void);
88 static rtx expand_builtin_apply (rtx, rtx, rtx);
89 static void expand_builtin_return (rtx);
90 static enum type_class type_to_class (tree);
91 static rtx expand_builtin_classify_type (tree);
92 static void expand_errno_check (tree, rtx);
93 static rtx expand_builtin_mathfn (tree, rtx, rtx);
94 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
96 static rtx expand_builtin_sincos (tree);
97 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
98 static rtx expand_builtin_args_info (tree);
99 static rtx expand_builtin_next_arg (void);
100 static rtx expand_builtin_va_start (tree);
101 static rtx expand_builtin_va_end (tree);
102 static rtx expand_builtin_va_copy (tree);
103 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
113 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
114 static rtx expand_builtin_bcopy (tree);
115 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
116 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_strlen (tree);
140 static tree fold_builtin_inf (tree, int);
141 static tree fold_builtin_nan (tree, tree, int);
142 static int validate_arglist (tree, ...);
143 static bool integer_valued_real_p (tree);
144 static tree fold_trunc_transparent_mathfn (tree, tree);
145 static bool readonly_data_expr (tree);
146 static rtx expand_builtin_fabs (tree, rtx, rtx);
147 static rtx expand_builtin_signbit (tree, rtx);
148 static tree fold_builtin_sqrt (tree, tree);
149 static tree fold_builtin_cbrt (tree, tree);
150 static tree fold_builtin_pow (tree, tree, tree);
151 static tree fold_builtin_powi (tree, tree, tree);
152 static tree fold_builtin_sin (tree);
153 static tree fold_builtin_cos (tree, tree, tree);
154 static tree fold_builtin_tan (tree);
155 static tree fold_builtin_atan (tree, tree);
156 static tree fold_builtin_trunc (tree, tree);
157 static tree fold_builtin_floor (tree, tree);
158 static tree fold_builtin_ceil (tree, tree);
159 static tree fold_builtin_round (tree, tree);
160 static tree fold_builtin_int_roundingfn (tree, tree);
161 static tree fold_builtin_bitop (tree, tree);
162 static tree fold_builtin_memory_op (tree, tree, bool, int);
163 static tree fold_builtin_strchr (tree, tree);
164 static tree fold_builtin_memcmp (tree);
165 static tree fold_builtin_strcmp (tree);
166 static tree fold_builtin_strncmp (tree);
167 static tree fold_builtin_signbit (tree, tree);
168 static tree fold_builtin_copysign (tree, tree, tree);
169 static tree fold_builtin_isascii (tree);
170 static tree fold_builtin_toascii (tree);
171 static tree fold_builtin_isdigit (tree);
172 static tree fold_builtin_fabs (tree, tree);
173 static tree fold_builtin_abs (tree, tree);
174 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
175 enum tree_code);
176 static tree fold_builtin_1 (tree, tree, bool);
178 static tree fold_builtin_strpbrk (tree, tree);
179 static tree fold_builtin_strstr (tree, tree);
180 static tree fold_builtin_strrchr (tree, tree);
181 static tree fold_builtin_strcat (tree);
182 static tree fold_builtin_strncat (tree);
183 static tree fold_builtin_strspn (tree);
184 static tree fold_builtin_strcspn (tree);
185 static tree fold_builtin_sprintf (tree, int);
187 static rtx expand_builtin_object_size (tree);
188 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
189 enum built_in_function);
190 static void maybe_emit_chk_warning (tree, enum built_in_function);
191 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
192 static tree fold_builtin_object_size (tree);
193 static tree fold_builtin_strcat_chk (tree, tree);
194 static tree fold_builtin_strncat_chk (tree, tree);
195 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
196 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
197 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
198 static bool init_target_chars (void);
200 static unsigned HOST_WIDE_INT target_newline;
201 static unsigned HOST_WIDE_INT target_percent;
202 static unsigned HOST_WIDE_INT target_c;
203 static unsigned HOST_WIDE_INT target_s;
204 static char target_percent_c[3];
205 static char target_percent_s[3];
206 static char target_percent_s_newline[4];
208 /* Return true if NODE should be considered for inline expansion regardless
209 of the optimization level. This means whenever a function is invoked with
210 its "internal" name, which normally contains the prefix "__builtin". */
212 static bool called_as_built_in (tree node)
214 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
215 if (strncmp (name, "__builtin_", 10) == 0)
216 return true;
217 if (strncmp (name, "__sync_", 7) == 0)
218 return true;
219 return false;
222 /* Return the alignment in bits of EXP, a pointer valued expression.
223 But don't return more than MAX_ALIGN no matter what.
224 The alignment returned is, by default, the alignment of the thing that
225 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
227 Otherwise, look at the expression to see if we can do better, i.e., if the
228 expression is actually pointing at an object whose alignment is tighter. */
230 static int
231 get_pointer_alignment (tree exp, unsigned int max_align)
233 unsigned int align, inner;
235 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
236 return 0;
238 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
239 align = MIN (align, max_align);
241 while (1)
243 switch (TREE_CODE (exp))
245 case NOP_EXPR:
246 case CONVERT_EXPR:
247 case NON_LVALUE_EXPR:
248 exp = TREE_OPERAND (exp, 0);
249 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
250 return align;
252 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
253 align = MIN (inner, max_align);
254 break;
256 case PLUS_EXPR:
257 /* If sum of pointer + int, restrict our maximum alignment to that
258 imposed by the integer. If not, we can't do any better than
259 ALIGN. */
260 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
261 return align;
263 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
264 & (max_align / BITS_PER_UNIT - 1))
265 != 0)
266 max_align >>= 1;
268 exp = TREE_OPERAND (exp, 0);
269 break;
271 case ADDR_EXPR:
272 /* See what we are pointing at and look at its alignment. */
273 exp = TREE_OPERAND (exp, 0);
274 inner = max_align;
275 if (handled_component_p (exp))
277 HOST_WIDE_INT bitsize, bitpos;
278 tree offset;
279 enum machine_mode mode;
280 int unsignedp, volatilep;
282 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
283 &mode, &unsignedp, &volatilep, true);
284 if (bitpos)
285 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
286 if (offset && TREE_CODE (offset) == PLUS_EXPR
287 && host_integerp (TREE_OPERAND (offset, 1), 1))
289 /* Any overflow in calculating offset_bits won't change
290 the alignment. */
291 unsigned offset_bits
292 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
293 * BITS_PER_UNIT);
295 if (offset_bits)
296 inner = MIN (inner, (offset_bits & -offset_bits));
297 offset = TREE_OPERAND (offset, 0);
299 if (offset && TREE_CODE (offset) == MULT_EXPR
300 && host_integerp (TREE_OPERAND (offset, 1), 1))
302 /* Any overflow in calculating offset_factor won't change
303 the alignment. */
304 unsigned offset_factor
305 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
306 * BITS_PER_UNIT);
308 if (offset_factor)
309 inner = MIN (inner, (offset_factor & -offset_factor));
311 else if (offset)
312 inner = MIN (inner, BITS_PER_UNIT);
314 if (TREE_CODE (exp) == FUNCTION_DECL)
315 align = FUNCTION_BOUNDARY;
316 else if (DECL_P (exp))
317 align = MIN (inner, DECL_ALIGN (exp));
318 #ifdef CONSTANT_ALIGNMENT
319 else if (CONSTANT_CLASS_P (exp))
320 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
321 #endif
322 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
323 || TREE_CODE (exp) == INDIRECT_REF)
324 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
325 else
326 align = MIN (align, inner);
327 return MIN (align, max_align);
329 default:
330 return align;
335 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
336 way, because it could contain a zero byte in the middle.
337 TREE_STRING_LENGTH is the size of the character array, not the string.
339 ONLY_VALUE should be nonzero if the result is not going to be emitted
340 into the instruction stream and zero if it is going to be expanded.
341 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
342 is returned, otherwise NULL, since
343 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
344 evaluate the side-effects.
346 The value returned is of type `ssizetype'.
348 Unfortunately, string_constant can't access the values of const char
349 arrays with initializers, so neither can we do so here. */
351 tree
352 c_strlen (tree src, int only_value)
354 tree offset_node;
355 HOST_WIDE_INT offset;
356 int max;
357 const char *ptr;
359 STRIP_NOPS (src);
360 if (TREE_CODE (src) == COND_EXPR
361 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
363 tree len1, len2;
365 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
366 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
367 if (tree_int_cst_equal (len1, len2))
368 return len1;
371 if (TREE_CODE (src) == COMPOUND_EXPR
372 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
373 return c_strlen (TREE_OPERAND (src, 1), only_value);
375 src = string_constant (src, &offset_node);
376 if (src == 0)
377 return 0;
379 max = TREE_STRING_LENGTH (src) - 1;
380 ptr = TREE_STRING_POINTER (src);
382 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
384 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
385 compute the offset to the following null if we don't know where to
386 start searching for it. */
387 int i;
389 for (i = 0; i < max; i++)
390 if (ptr[i] == 0)
391 return 0;
393 /* We don't know the starting offset, but we do know that the string
394 has no internal zero bytes. We can assume that the offset falls
395 within the bounds of the string; otherwise, the programmer deserves
396 what he gets. Subtract the offset from the length of the string,
397 and return that. This would perhaps not be valid if we were dealing
398 with named arrays in addition to literal string constants. */
400 return size_diffop (size_int (max), offset_node);
403 /* We have a known offset into the string. Start searching there for
404 a null character if we can represent it as a single HOST_WIDE_INT. */
405 if (offset_node == 0)
406 offset = 0;
407 else if (! host_integerp (offset_node, 0))
408 offset = -1;
409 else
410 offset = tree_low_cst (offset_node, 0);
412 /* If the offset is known to be out of bounds, warn, and call strlen at
413 runtime. */
414 if (offset < 0 || offset > max)
416 warning (0, "offset outside bounds of constant string");
417 return 0;
420 /* Use strlen to search for the first zero byte. Since any strings
421 constructed with build_string will have nulls appended, we win even
422 if we get handed something like (char[4])"abcd".
424 Since OFFSET is our starting index into the string, no further
425 calculation is needed. */
426 return ssize_int (strlen (ptr + offset));
429 /* Return a char pointer for a C string if it is a string constant
430 or sum of string constant and integer constant. */
432 static const char *
433 c_getstr (tree src)
435 tree offset_node;
437 src = string_constant (src, &offset_node);
438 if (src == 0)
439 return 0;
441 if (offset_node == 0)
442 return TREE_STRING_POINTER (src);
443 else if (!host_integerp (offset_node, 1)
444 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
445 return 0;
447 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
450 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
451 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
453 static rtx
454 c_readstr (const char *str, enum machine_mode mode)
456 HOST_WIDE_INT c[2];
457 HOST_WIDE_INT ch;
458 unsigned int i, j;
460 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
462 c[0] = 0;
463 c[1] = 0;
464 ch = 1;
465 for (i = 0; i < GET_MODE_SIZE (mode); i++)
467 j = i;
468 if (WORDS_BIG_ENDIAN)
469 j = GET_MODE_SIZE (mode) - i - 1;
470 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
471 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
472 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
473 j *= BITS_PER_UNIT;
474 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
476 if (ch)
477 ch = (unsigned char) str[i];
478 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
480 return immed_double_const (c[0], c[1], mode);
483 /* Cast a target constant CST to target CHAR and if that value fits into
484 host char type, return zero and put that value into variable pointed to by
485 P. */
487 static int
488 target_char_cast (tree cst, char *p)
490 unsigned HOST_WIDE_INT val, hostval;
492 if (!host_integerp (cst, 1)
493 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
494 return 1;
496 val = tree_low_cst (cst, 1);
497 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
498 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
500 hostval = val;
501 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
502 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
504 if (val != hostval)
505 return 1;
507 *p = hostval;
508 return 0;
511 /* Similar to save_expr, but assumes that arbitrary code is not executed
512 in between the multiple evaluations. In particular, we assume that a
513 non-addressable local variable will not be modified. */
515 static tree
516 builtin_save_expr (tree exp)
518 if (TREE_ADDRESSABLE (exp) == 0
519 && (TREE_CODE (exp) == PARM_DECL
520 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
521 return exp;
523 return save_expr (exp);
526 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
527 times to get the address of either a higher stack frame, or a return
528 address located within it (depending on FNDECL_CODE). */
530 static rtx
531 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
533 int i;
535 #ifdef INITIAL_FRAME_ADDRESS_RTX
536 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
537 #else
538 rtx tem;
540 /* For a zero count with __builtin_return_address, we don't care what
541 frame address we return, because target-specific definitions will
542 override us. Therefore frame pointer elimination is OK, and using
543 the soft frame pointer is OK.
545 For a non-zero count, or a zero count with __builtin_frame_address,
546 we require a stable offset from the current frame pointer to the
547 previous one, so we must use the hard frame pointer, and
548 we must disable frame pointer elimination. */
549 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
550 tem = frame_pointer_rtx;
551 else
553 tem = hard_frame_pointer_rtx;
555 /* Tell reload not to eliminate the frame pointer. */
556 current_function_accesses_prior_frames = 1;
558 #endif
560 /* Some machines need special handling before we can access
561 arbitrary frames. For example, on the SPARC, we must first flush
562 all register windows to the stack. */
563 #ifdef SETUP_FRAME_ADDRESSES
564 if (count > 0)
565 SETUP_FRAME_ADDRESSES ();
566 #endif
568 /* On the SPARC, the return address is not in the frame, it is in a
569 register. There is no way to access it off of the current frame
570 pointer, but it can be accessed off the previous frame pointer by
571 reading the value from the register window save area. */
572 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
573 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
574 count--;
575 #endif
577 /* Scan back COUNT frames to the specified frame. */
578 for (i = 0; i < count; i++)
580 /* Assume the dynamic chain pointer is in the word that the
581 frame address points to, unless otherwise specified. */
582 #ifdef DYNAMIC_CHAIN_ADDRESS
583 tem = DYNAMIC_CHAIN_ADDRESS (tem);
584 #endif
585 tem = memory_address (Pmode, tem);
586 tem = gen_frame_mem (Pmode, tem);
587 tem = copy_to_reg (tem);
590 /* For __builtin_frame_address, return what we've got. But, on
591 the SPARC for example, we may have to add a bias. */
592 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
593 #ifdef FRAME_ADDR_RTX
594 return FRAME_ADDR_RTX (tem);
595 #else
596 return tem;
597 #endif
599 /* For __builtin_return_address, get the return address from that frame. */
600 #ifdef RETURN_ADDR_RTX
601 tem = RETURN_ADDR_RTX (count, tem);
602 #else
603 tem = memory_address (Pmode,
604 plus_constant (tem, GET_MODE_SIZE (Pmode)));
605 tem = gen_frame_mem (Pmode, tem);
606 #endif
607 return tem;
610 /* Alias set used for setjmp buffer. */
611 static HOST_WIDE_INT setjmp_alias_set = -1;
613 /* Construct the leading half of a __builtin_setjmp call. Control will
614 return to RECEIVER_LABEL. This is also called directly by the SJLJ
615 exception handling code. */
617 void
618 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
620 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
621 rtx stack_save;
622 rtx mem;
624 if (setjmp_alias_set == -1)
625 setjmp_alias_set = new_alias_set ();
627 buf_addr = convert_memory_address (Pmode, buf_addr);
629 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
631 /* We store the frame pointer and the address of receiver_label in
632 the buffer and use the rest of it for the stack save area, which
633 is machine-dependent. */
635 mem = gen_rtx_MEM (Pmode, buf_addr);
636 set_mem_alias_set (mem, setjmp_alias_set);
637 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
639 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
640 set_mem_alias_set (mem, setjmp_alias_set);
642 emit_move_insn (validize_mem (mem),
643 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
645 stack_save = gen_rtx_MEM (sa_mode,
646 plus_constant (buf_addr,
647 2 * GET_MODE_SIZE (Pmode)));
648 set_mem_alias_set (stack_save, setjmp_alias_set);
649 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
651 /* If there is further processing to do, do it. */
652 #ifdef HAVE_builtin_setjmp_setup
653 if (HAVE_builtin_setjmp_setup)
654 emit_insn (gen_builtin_setjmp_setup (buf_addr));
655 #endif
657 /* Tell optimize_save_area_alloca that extra work is going to
658 need to go on during alloca. */
659 current_function_calls_setjmp = 1;
661 /* Set this so all the registers get saved in our frame; we need to be
662 able to copy the saved values for any registers from frames we unwind. */
663 current_function_has_nonlocal_label = 1;
666 /* Construct the trailing part of a __builtin_setjmp call. This is
667 also called directly by the SJLJ exception handling code. */
669 void
670 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
672 /* Clobber the FP when we get here, so we have to make sure it's
673 marked as used by this function. */
674 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
676 /* Mark the static chain as clobbered here so life information
677 doesn't get messed up for it. */
678 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
680 /* Now put in the code to restore the frame pointer, and argument
681 pointer, if needed. */
682 #ifdef HAVE_nonlocal_goto
683 if (! HAVE_nonlocal_goto)
684 #endif
686 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
687 /* This might change the hard frame pointer in ways that aren't
688 apparent to early optimization passes, so force a clobber. */
689 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
692 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
693 if (fixed_regs[ARG_POINTER_REGNUM])
695 #ifdef ELIMINABLE_REGS
696 size_t i;
697 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
699 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
700 if (elim_regs[i].from == ARG_POINTER_REGNUM
701 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
702 break;
704 if (i == ARRAY_SIZE (elim_regs))
705 #endif
707 /* Now restore our arg pointer from the address at which it
708 was saved in our stack frame. */
709 emit_move_insn (virtual_incoming_args_rtx,
710 copy_to_reg (get_arg_pointer_save_area (cfun)));
713 #endif
715 #ifdef HAVE_builtin_setjmp_receiver
716 if (HAVE_builtin_setjmp_receiver)
717 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
718 else
719 #endif
720 #ifdef HAVE_nonlocal_goto_receiver
721 if (HAVE_nonlocal_goto_receiver)
722 emit_insn (gen_nonlocal_goto_receiver ());
723 else
724 #endif
725 { /* Nothing */ }
727 /* @@@ This is a kludge. Not all machine descriptions define a blockage
728 insn, but we must not allow the code we just generated to be reordered
729 by scheduling. Specifically, the update of the frame pointer must
730 happen immediately, not later. So emit an ASM_INPUT to act as blockage
731 insn. */
732 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
735 /* __builtin_longjmp is passed a pointer to an array of five words (not
736 all will be used on all machines). It operates similarly to the C
737 library function of the same name, but is more efficient. Much of
738 the code below is copied from the handling of non-local gotos. */
740 static void
741 expand_builtin_longjmp (rtx buf_addr, rtx value)
743 rtx fp, lab, stack, insn, last;
744 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
746 if (setjmp_alias_set == -1)
747 setjmp_alias_set = new_alias_set ();
749 buf_addr = convert_memory_address (Pmode, buf_addr);
751 buf_addr = force_reg (Pmode, buf_addr);
753 /* We used to store value in static_chain_rtx, but that fails if pointers
754 are smaller than integers. We instead require that the user must pass
755 a second argument of 1, because that is what builtin_setjmp will
756 return. This also makes EH slightly more efficient, since we are no
757 longer copying around a value that we don't care about. */
758 gcc_assert (value == const1_rtx);
760 last = get_last_insn ();
761 #ifdef HAVE_builtin_longjmp
762 if (HAVE_builtin_longjmp)
763 emit_insn (gen_builtin_longjmp (buf_addr));
764 else
765 #endif
767 fp = gen_rtx_MEM (Pmode, buf_addr);
768 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
769 GET_MODE_SIZE (Pmode)));
771 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
772 2 * GET_MODE_SIZE (Pmode)));
773 set_mem_alias_set (fp, setjmp_alias_set);
774 set_mem_alias_set (lab, setjmp_alias_set);
775 set_mem_alias_set (stack, setjmp_alias_set);
777 /* Pick up FP, label, and SP from the block and jump. This code is
778 from expand_goto in stmt.c; see there for detailed comments. */
779 #ifdef HAVE_nonlocal_goto
780 if (HAVE_nonlocal_goto)
781 /* We have to pass a value to the nonlocal_goto pattern that will
782 get copied into the static_chain pointer, but it does not matter
783 what that value is, because builtin_setjmp does not use it. */
784 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
785 else
786 #endif
788 lab = copy_to_reg (lab);
790 emit_insn (gen_rtx_CLOBBER (VOIDmode,
791 gen_rtx_MEM (BLKmode,
792 gen_rtx_SCRATCH (VOIDmode))));
793 emit_insn (gen_rtx_CLOBBER (VOIDmode,
794 gen_rtx_MEM (BLKmode,
795 hard_frame_pointer_rtx)));
797 emit_move_insn (hard_frame_pointer_rtx, fp);
798 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
800 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
801 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
802 emit_indirect_jump (lab);
806 /* Search backwards and mark the jump insn as a non-local goto.
807 Note that this precludes the use of __builtin_longjmp to a
808 __builtin_setjmp target in the same function. However, we've
809 already cautioned the user that these functions are for
810 internal exception handling use only. */
811 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
813 gcc_assert (insn != last);
815 if (JUMP_P (insn))
817 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
818 REG_NOTES (insn));
819 break;
821 else if (CALL_P (insn))
822 break;
826 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
827 and the address of the save area. */
829 static rtx
830 expand_builtin_nonlocal_goto (tree arglist)
832 tree t_label, t_save_area;
833 rtx r_label, r_save_area, r_fp, r_sp, insn;
835 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
836 return NULL_RTX;
838 t_label = TREE_VALUE (arglist);
839 arglist = TREE_CHAIN (arglist);
840 t_save_area = TREE_VALUE (arglist);
842 r_label = expand_normal (t_label);
843 r_label = convert_memory_address (Pmode, r_label);
844 r_save_area = expand_normal (t_save_area);
845 r_save_area = convert_memory_address (Pmode, r_save_area);
846 r_fp = gen_rtx_MEM (Pmode, r_save_area);
847 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
848 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
850 current_function_has_nonlocal_goto = 1;
852 #ifdef HAVE_nonlocal_goto
853 /* ??? We no longer need to pass the static chain value, afaik. */
854 if (HAVE_nonlocal_goto)
855 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
856 else
857 #endif
859 r_label = copy_to_reg (r_label);
861 emit_insn (gen_rtx_CLOBBER (VOIDmode,
862 gen_rtx_MEM (BLKmode,
863 gen_rtx_SCRATCH (VOIDmode))));
865 emit_insn (gen_rtx_CLOBBER (VOIDmode,
866 gen_rtx_MEM (BLKmode,
867 hard_frame_pointer_rtx)));
869 /* Restore frame pointer for containing function.
870 This sets the actual hard register used for the frame pointer
871 to the location of the function's incoming static chain info.
872 The non-local goto handler will then adjust it to contain the
873 proper value and reload the argument pointer, if needed. */
874 emit_move_insn (hard_frame_pointer_rtx, r_fp);
875 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
877 /* USE of hard_frame_pointer_rtx added for consistency;
878 not clear if really needed. */
879 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
880 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
881 emit_indirect_jump (r_label);
884 /* Search backwards to the jump insn and mark it as a
885 non-local goto. */
886 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
888 if (JUMP_P (insn))
890 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
891 const0_rtx, REG_NOTES (insn));
892 break;
894 else if (CALL_P (insn))
895 break;
898 return const0_rtx;
901 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
902 (not all will be used on all machines) that was passed to __builtin_setjmp.
903 It updates the stack pointer in that block to correspond to the current
904 stack pointer. */
906 static void
907 expand_builtin_update_setjmp_buf (rtx buf_addr)
909 enum machine_mode sa_mode = Pmode;
910 rtx stack_save;
913 #ifdef HAVE_save_stack_nonlocal
914 if (HAVE_save_stack_nonlocal)
915 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
916 #endif
917 #ifdef STACK_SAVEAREA_MODE
918 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
919 #endif
921 stack_save
922 = gen_rtx_MEM (sa_mode,
923 memory_address
924 (sa_mode,
925 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
927 #ifdef HAVE_setjmp
928 if (HAVE_setjmp)
929 emit_insn (gen_setjmp ());
930 #endif
932 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
935 /* Expand a call to __builtin_prefetch. For a target that does not support
936 data prefetch, evaluate the memory address argument in case it has side
937 effects. */
939 static void
940 expand_builtin_prefetch (tree arglist)
942 tree arg0, arg1, arg2;
943 rtx op0, op1, op2;
945 if (!validate_arglist (arglist, POINTER_TYPE, 0))
946 return;
948 arg0 = TREE_VALUE (arglist);
949 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
950 zero (read) and argument 2 (locality) defaults to 3 (high degree of
951 locality). */
952 if (TREE_CHAIN (arglist))
954 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
955 if (TREE_CHAIN (TREE_CHAIN (arglist)))
956 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
957 else
958 arg2 = build_int_cst (NULL_TREE, 3);
960 else
962 arg1 = integer_zero_node;
963 arg2 = build_int_cst (NULL_TREE, 3);
966 /* Argument 0 is an address. */
967 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
969 /* Argument 1 (read/write flag) must be a compile-time constant int. */
970 if (TREE_CODE (arg1) != INTEGER_CST)
972 error ("second argument to %<__builtin_prefetch%> must be a constant");
973 arg1 = integer_zero_node;
975 op1 = expand_normal (arg1);
976 /* Argument 1 must be either zero or one. */
977 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
979 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
980 " using zero");
981 op1 = const0_rtx;
984 /* Argument 2 (locality) must be a compile-time constant int. */
985 if (TREE_CODE (arg2) != INTEGER_CST)
987 error ("third argument to %<__builtin_prefetch%> must be a constant");
988 arg2 = integer_zero_node;
990 op2 = expand_normal (arg2);
991 /* Argument 2 must be 0, 1, 2, or 3. */
992 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
994 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
995 op2 = const0_rtx;
998 #ifdef HAVE_prefetch
999 if (HAVE_prefetch)
1001 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1002 (op0,
1003 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1004 || (GET_MODE (op0) != Pmode))
1006 op0 = convert_memory_address (Pmode, op0);
1007 op0 = force_reg (Pmode, op0);
1009 emit_insn (gen_prefetch (op0, op1, op2));
1011 #endif
1013 /* Don't do anything with direct references to volatile memory, but
1014 generate code to handle other side effects. */
1015 if (!MEM_P (op0) && side_effects_p (op0))
1016 emit_insn (op0);
1019 /* Get a MEM rtx for expression EXP which is the address of an operand
1020 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1021 the maximum length of the block of memory that might be accessed or
1022 NULL if unknown. */
1024 static rtx
1025 get_memory_rtx (tree exp, tree len)
1027 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1028 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1030 /* Get an expression we can use to find the attributes to assign to MEM.
1031 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1032 we can. First remove any nops. */
1033 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1034 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1035 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1036 exp = TREE_OPERAND (exp, 0);
1038 if (TREE_CODE (exp) == ADDR_EXPR)
1039 exp = TREE_OPERAND (exp, 0);
1040 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1041 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1042 else
1043 exp = NULL;
1045 /* Honor attributes derived from exp, except for the alias set
1046 (as builtin stringops may alias with anything) and the size
1047 (as stringops may access multiple array elements). */
1048 if (exp)
1050 set_mem_attributes (mem, exp, 0);
1052 /* Allow the string and memory builtins to overflow from one
1053 field into another, see http://gcc.gnu.org/PR23561.
1054 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1055 memory accessed by the string or memory builtin will fit
1056 within the field. */
1057 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1059 tree mem_expr = MEM_EXPR (mem);
1060 HOST_WIDE_INT offset = -1, length = -1;
1061 tree inner = exp;
1063 while (TREE_CODE (inner) == ARRAY_REF
1064 || TREE_CODE (inner) == NOP_EXPR
1065 || TREE_CODE (inner) == CONVERT_EXPR
1066 || TREE_CODE (inner) == NON_LVALUE_EXPR
1067 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1068 || TREE_CODE (inner) == SAVE_EXPR)
1069 inner = TREE_OPERAND (inner, 0);
1071 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1073 if (MEM_OFFSET (mem)
1074 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1075 offset = INTVAL (MEM_OFFSET (mem));
1077 if (offset >= 0 && len && host_integerp (len, 0))
1078 length = tree_low_cst (len, 0);
1080 while (TREE_CODE (inner) == COMPONENT_REF)
1082 tree field = TREE_OPERAND (inner, 1);
1083 gcc_assert (! DECL_BIT_FIELD (field));
1084 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1085 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1087 if (length >= 0
1088 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1089 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1091 HOST_WIDE_INT size
1092 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1093 /* If we can prove the memory starting at XEXP (mem, 0)
1094 and ending at XEXP (mem, 0) + LENGTH will fit into
1095 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1096 if (offset <= size
1097 && length <= size
1098 && offset + length <= size)
1099 break;
1102 if (offset >= 0
1103 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1104 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1105 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1106 / BITS_PER_UNIT;
1107 else
1109 offset = -1;
1110 length = -1;
1113 mem_expr = TREE_OPERAND (mem_expr, 0);
1114 inner = TREE_OPERAND (inner, 0);
1117 if (mem_expr == NULL)
1118 offset = -1;
1119 if (mem_expr != MEM_EXPR (mem))
1121 set_mem_expr (mem, mem_expr);
1122 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1125 set_mem_alias_set (mem, 0);
1126 set_mem_size (mem, NULL_RTX);
1129 return mem;
1132 /* Built-in functions to perform an untyped call and return. */
1134 /* For each register that may be used for calling a function, this
1135 gives a mode used to copy the register's value. VOIDmode indicates
1136 the register is not used for calling a function. If the machine
1137 has register windows, this gives only the outbound registers.
1138 INCOMING_REGNO gives the corresponding inbound register. */
1139 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1141 /* For each register that may be used for returning values, this gives
1142 a mode used to copy the register's value. VOIDmode indicates the
1143 register is not used for returning values. If the machine has
1144 register windows, this gives only the outbound registers.
1145 INCOMING_REGNO gives the corresponding inbound register. */
1146 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1148 /* For each register that may be used for calling a function, this
1149 gives the offset of that register into the block returned by
1150 __builtin_apply_args. 0 indicates that the register is not
1151 used for calling a function. */
1152 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1154 /* Return the size required for the block returned by __builtin_apply_args,
1155 and initialize apply_args_mode. */
1157 static int
1158 apply_args_size (void)
1160 static int size = -1;
1161 int align;
1162 unsigned int regno;
1163 enum machine_mode mode;
1165 /* The values computed by this function never change. */
1166 if (size < 0)
1168 /* The first value is the incoming arg-pointer. */
1169 size = GET_MODE_SIZE (Pmode);
1171 /* The second value is the structure value address unless this is
1172 passed as an "invisible" first argument. */
1173 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1174 size += GET_MODE_SIZE (Pmode);
1176 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1177 if (FUNCTION_ARG_REGNO_P (regno))
1179 mode = reg_raw_mode[regno];
1181 gcc_assert (mode != VOIDmode);
1183 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1184 if (size % align != 0)
1185 size = CEIL (size, align) * align;
1186 apply_args_reg_offset[regno] = size;
1187 size += GET_MODE_SIZE (mode);
1188 apply_args_mode[regno] = mode;
1190 else
1192 apply_args_mode[regno] = VOIDmode;
1193 apply_args_reg_offset[regno] = 0;
1196 return size;
1199 /* Return the size required for the block returned by __builtin_apply,
1200 and initialize apply_result_mode. */
1202 static int
1203 apply_result_size (void)
1205 static int size = -1;
1206 int align, regno;
1207 enum machine_mode mode;
1209 /* The values computed by this function never change. */
1210 if (size < 0)
1212 size = 0;
1214 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1215 if (FUNCTION_VALUE_REGNO_P (regno))
1217 mode = reg_raw_mode[regno];
1219 gcc_assert (mode != VOIDmode);
1221 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1222 if (size % align != 0)
1223 size = CEIL (size, align) * align;
1224 size += GET_MODE_SIZE (mode);
1225 apply_result_mode[regno] = mode;
1227 else
1228 apply_result_mode[regno] = VOIDmode;
1230 /* Allow targets that use untyped_call and untyped_return to override
1231 the size so that machine-specific information can be stored here. */
1232 #ifdef APPLY_RESULT_SIZE
1233 size = APPLY_RESULT_SIZE;
1234 #endif
1236 return size;
1239 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1240 /* Create a vector describing the result block RESULT. If SAVEP is true,
1241 the result block is used to save the values; otherwise it is used to
1242 restore the values. */
1244 static rtx
1245 result_vector (int savep, rtx result)
1247 int regno, size, align, nelts;
1248 enum machine_mode mode;
1249 rtx reg, mem;
1250 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1252 size = nelts = 0;
1253 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1254 if ((mode = apply_result_mode[regno]) != VOIDmode)
1256 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1257 if (size % align != 0)
1258 size = CEIL (size, align) * align;
1259 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1260 mem = adjust_address (result, mode, size);
1261 savevec[nelts++] = (savep
1262 ? gen_rtx_SET (VOIDmode, mem, reg)
1263 : gen_rtx_SET (VOIDmode, reg, mem));
1264 size += GET_MODE_SIZE (mode);
1266 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1268 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1270 /* Save the state required to perform an untyped call with the same
1271 arguments as were passed to the current function. */
1273 static rtx
1274 expand_builtin_apply_args_1 (void)
1276 rtx registers, tem;
1277 int size, align, regno;
1278 enum machine_mode mode;
1279 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1281 /* Create a block where the arg-pointer, structure value address,
1282 and argument registers can be saved. */
1283 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1285 /* Walk past the arg-pointer and structure value address. */
1286 size = GET_MODE_SIZE (Pmode);
1287 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1288 size += GET_MODE_SIZE (Pmode);
1290 /* Save each register used in calling a function to the block. */
1291 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1292 if ((mode = apply_args_mode[regno]) != VOIDmode)
1294 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1295 if (size % align != 0)
1296 size = CEIL (size, align) * align;
1298 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1300 emit_move_insn (adjust_address (registers, mode, size), tem);
1301 size += GET_MODE_SIZE (mode);
1304 /* Save the arg pointer to the block. */
1305 tem = copy_to_reg (virtual_incoming_args_rtx);
1306 #ifdef STACK_GROWS_DOWNWARD
1307 /* We need the pointer as the caller actually passed them to us, not
1308 as we might have pretended they were passed. Make sure it's a valid
1309 operand, as emit_move_insn isn't expected to handle a PLUS. */
1311 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1312 NULL_RTX);
1313 #endif
1314 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1316 size = GET_MODE_SIZE (Pmode);
1318 /* Save the structure value address unless this is passed as an
1319 "invisible" first argument. */
1320 if (struct_incoming_value)
1322 emit_move_insn (adjust_address (registers, Pmode, size),
1323 copy_to_reg (struct_incoming_value));
1324 size += GET_MODE_SIZE (Pmode);
1327 /* Return the address of the block. */
1328 return copy_addr_to_reg (XEXP (registers, 0));
1331 /* __builtin_apply_args returns block of memory allocated on
1332 the stack into which is stored the arg pointer, structure
1333 value address, static chain, and all the registers that might
1334 possibly be used in performing a function call. The code is
1335 moved to the start of the function so the incoming values are
1336 saved. */
1338 static rtx
1339 expand_builtin_apply_args (void)
1341 /* Don't do __builtin_apply_args more than once in a function.
1342 Save the result of the first call and reuse it. */
1343 if (apply_args_value != 0)
1344 return apply_args_value;
1346 /* When this function is called, it means that registers must be
1347 saved on entry to this function. So we migrate the
1348 call to the first insn of this function. */
1349 rtx temp;
1350 rtx seq;
1352 start_sequence ();
1353 temp = expand_builtin_apply_args_1 ();
1354 seq = get_insns ();
1355 end_sequence ();
1357 apply_args_value = temp;
1359 /* Put the insns after the NOTE that starts the function.
1360 If this is inside a start_sequence, make the outer-level insn
1361 chain current, so the code is placed at the start of the
1362 function. */
1363 push_topmost_sequence ();
1364 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1365 pop_topmost_sequence ();
1366 return temp;
1370 /* Perform an untyped call and save the state required to perform an
1371 untyped return of whatever value was returned by the given function. */
1373 static rtx
1374 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1376 int size, align, regno;
1377 enum machine_mode mode;
1378 rtx incoming_args, result, reg, dest, src, call_insn;
1379 rtx old_stack_level = 0;
1380 rtx call_fusage = 0;
1381 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1383 arguments = convert_memory_address (Pmode, arguments);
1385 /* Create a block where the return registers can be saved. */
1386 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1388 /* Fetch the arg pointer from the ARGUMENTS block. */
1389 incoming_args = gen_reg_rtx (Pmode);
1390 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1391 #ifndef STACK_GROWS_DOWNWARD
1392 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1393 incoming_args, 0, OPTAB_LIB_WIDEN);
1394 #endif
1396 /* Push a new argument block and copy the arguments. Do not allow
1397 the (potential) memcpy call below to interfere with our stack
1398 manipulations. */
1399 do_pending_stack_adjust ();
1400 NO_DEFER_POP;
1402 /* Save the stack with nonlocal if available. */
1403 #ifdef HAVE_save_stack_nonlocal
1404 if (HAVE_save_stack_nonlocal)
1405 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1406 else
1407 #endif
1408 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1410 /* Allocate a block of memory onto the stack and copy the memory
1411 arguments to the outgoing arguments address. */
1412 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1413 dest = virtual_outgoing_args_rtx;
1414 #ifndef STACK_GROWS_DOWNWARD
1415 if (GET_CODE (argsize) == CONST_INT)
1416 dest = plus_constant (dest, -INTVAL (argsize));
1417 else
1418 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1419 #endif
1420 dest = gen_rtx_MEM (BLKmode, dest);
1421 set_mem_align (dest, PARM_BOUNDARY);
1422 src = gen_rtx_MEM (BLKmode, incoming_args);
1423 set_mem_align (src, PARM_BOUNDARY);
1424 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1426 /* Refer to the argument block. */
1427 apply_args_size ();
1428 arguments = gen_rtx_MEM (BLKmode, arguments);
1429 set_mem_align (arguments, PARM_BOUNDARY);
1431 /* Walk past the arg-pointer and structure value address. */
1432 size = GET_MODE_SIZE (Pmode);
1433 if (struct_value)
1434 size += GET_MODE_SIZE (Pmode);
1436 /* Restore each of the registers previously saved. Make USE insns
1437 for each of these registers for use in making the call. */
1438 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1439 if ((mode = apply_args_mode[regno]) != VOIDmode)
1441 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1442 if (size % align != 0)
1443 size = CEIL (size, align) * align;
1444 reg = gen_rtx_REG (mode, regno);
1445 emit_move_insn (reg, adjust_address (arguments, mode, size));
1446 use_reg (&call_fusage, reg);
1447 size += GET_MODE_SIZE (mode);
1450 /* Restore the structure value address unless this is passed as an
1451 "invisible" first argument. */
1452 size = GET_MODE_SIZE (Pmode);
1453 if (struct_value)
1455 rtx value = gen_reg_rtx (Pmode);
1456 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1457 emit_move_insn (struct_value, value);
1458 if (REG_P (struct_value))
1459 use_reg (&call_fusage, struct_value);
1460 size += GET_MODE_SIZE (Pmode);
1463 /* All arguments and registers used for the call are set up by now! */
1464 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1466 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1467 and we don't want to load it into a register as an optimization,
1468 because prepare_call_address already did it if it should be done. */
1469 if (GET_CODE (function) != SYMBOL_REF)
1470 function = memory_address (FUNCTION_MODE, function);
1472 /* Generate the actual call instruction and save the return value. */
1473 #ifdef HAVE_untyped_call
1474 if (HAVE_untyped_call)
1475 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1476 result, result_vector (1, result)));
1477 else
1478 #endif
1479 #ifdef HAVE_call_value
1480 if (HAVE_call_value)
1482 rtx valreg = 0;
1484 /* Locate the unique return register. It is not possible to
1485 express a call that sets more than one return register using
1486 call_value; use untyped_call for that. In fact, untyped_call
1487 only needs to save the return registers in the given block. */
1488 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1489 if ((mode = apply_result_mode[regno]) != VOIDmode)
1491 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1493 valreg = gen_rtx_REG (mode, regno);
1496 emit_call_insn (GEN_CALL_VALUE (valreg,
1497 gen_rtx_MEM (FUNCTION_MODE, function),
1498 const0_rtx, NULL_RTX, const0_rtx));
1500 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1502 else
1503 #endif
1504 gcc_unreachable ();
1506 /* Find the CALL insn we just emitted, and attach the register usage
1507 information. */
1508 call_insn = last_call_insn ();
1509 add_function_usage_to (call_insn, call_fusage);
1511 /* Restore the stack. */
1512 #ifdef HAVE_save_stack_nonlocal
1513 if (HAVE_save_stack_nonlocal)
1514 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1515 else
1516 #endif
1517 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1519 OK_DEFER_POP;
1521 /* Return the address of the result block. */
1522 result = copy_addr_to_reg (XEXP (result, 0));
1523 return convert_memory_address (ptr_mode, result);
1526 /* Perform an untyped return. */
1528 static void
1529 expand_builtin_return (rtx result)
1531 int size, align, regno;
1532 enum machine_mode mode;
1533 rtx reg;
1534 rtx call_fusage = 0;
1536 result = convert_memory_address (Pmode, result);
1538 apply_result_size ();
1539 result = gen_rtx_MEM (BLKmode, result);
1541 #ifdef HAVE_untyped_return
1542 if (HAVE_untyped_return)
1544 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1545 emit_barrier ();
1546 return;
1548 #endif
1550 /* Restore the return value and note that each value is used. */
1551 size = 0;
1552 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1553 if ((mode = apply_result_mode[regno]) != VOIDmode)
1555 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1556 if (size % align != 0)
1557 size = CEIL (size, align) * align;
1558 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1559 emit_move_insn (reg, adjust_address (result, mode, size));
1561 push_to_sequence (call_fusage);
1562 emit_insn (gen_rtx_USE (VOIDmode, reg));
1563 call_fusage = get_insns ();
1564 end_sequence ();
1565 size += GET_MODE_SIZE (mode);
1568 /* Put the USE insns before the return. */
1569 emit_insn (call_fusage);
1571 /* Return whatever values was restored by jumping directly to the end
1572 of the function. */
1573 expand_naked_return ();
1576 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1578 static enum type_class
1579 type_to_class (tree type)
1581 switch (TREE_CODE (type))
1583 case VOID_TYPE: return void_type_class;
1584 case INTEGER_TYPE: return integer_type_class;
1585 case ENUMERAL_TYPE: return enumeral_type_class;
1586 case BOOLEAN_TYPE: return boolean_type_class;
1587 case POINTER_TYPE: return pointer_type_class;
1588 case REFERENCE_TYPE: return reference_type_class;
1589 case OFFSET_TYPE: return offset_type_class;
1590 case REAL_TYPE: return real_type_class;
1591 case COMPLEX_TYPE: return complex_type_class;
1592 case FUNCTION_TYPE: return function_type_class;
1593 case METHOD_TYPE: return method_type_class;
1594 case RECORD_TYPE: return record_type_class;
1595 case UNION_TYPE:
1596 case QUAL_UNION_TYPE: return union_type_class;
1597 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1598 ? string_type_class : array_type_class);
1599 case LANG_TYPE: return lang_type_class;
1600 default: return no_type_class;
1604 /* Expand a call to __builtin_classify_type with arguments found in
1605 ARGLIST. */
1607 static rtx
1608 expand_builtin_classify_type (tree arglist)
1610 if (arglist != 0)
1611 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1612 return GEN_INT (no_type_class);
1615 /* This helper macro, meant to be used in mathfn_built_in below,
1616 determines which among a set of three builtin math functions is
1617 appropriate for a given type mode. The `F' and `L' cases are
1618 automatically generated from the `double' case. */
1619 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1620 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1621 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1622 fcodel = BUILT_IN_MATHFN##L ; break;
1624 /* Return mathematic function equivalent to FN but operating directly
1625 on TYPE, if available. If we can't do the conversion, return zero. */
1626 tree
1627 mathfn_built_in (tree type, enum built_in_function fn)
1629 enum built_in_function fcode, fcodef, fcodel;
1631 switch (fn)
1633 CASE_MATHFN (BUILT_IN_ACOS)
1634 CASE_MATHFN (BUILT_IN_ACOSH)
1635 CASE_MATHFN (BUILT_IN_ASIN)
1636 CASE_MATHFN (BUILT_IN_ASINH)
1637 CASE_MATHFN (BUILT_IN_ATAN)
1638 CASE_MATHFN (BUILT_IN_ATAN2)
1639 CASE_MATHFN (BUILT_IN_ATANH)
1640 CASE_MATHFN (BUILT_IN_CBRT)
1641 CASE_MATHFN (BUILT_IN_CEIL)
1642 CASE_MATHFN (BUILT_IN_COPYSIGN)
1643 CASE_MATHFN (BUILT_IN_COS)
1644 CASE_MATHFN (BUILT_IN_COSH)
1645 CASE_MATHFN (BUILT_IN_DREM)
1646 CASE_MATHFN (BUILT_IN_ERF)
1647 CASE_MATHFN (BUILT_IN_ERFC)
1648 CASE_MATHFN (BUILT_IN_EXP)
1649 CASE_MATHFN (BUILT_IN_EXP10)
1650 CASE_MATHFN (BUILT_IN_EXP2)
1651 CASE_MATHFN (BUILT_IN_EXPM1)
1652 CASE_MATHFN (BUILT_IN_FABS)
1653 CASE_MATHFN (BUILT_IN_FDIM)
1654 CASE_MATHFN (BUILT_IN_FLOOR)
1655 CASE_MATHFN (BUILT_IN_FMA)
1656 CASE_MATHFN (BUILT_IN_FMAX)
1657 CASE_MATHFN (BUILT_IN_FMIN)
1658 CASE_MATHFN (BUILT_IN_FMOD)
1659 CASE_MATHFN (BUILT_IN_FREXP)
1660 CASE_MATHFN (BUILT_IN_GAMMA)
1661 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1662 CASE_MATHFN (BUILT_IN_HYPOT)
1663 CASE_MATHFN (BUILT_IN_ILOGB)
1664 CASE_MATHFN (BUILT_IN_INF)
1665 CASE_MATHFN (BUILT_IN_J0)
1666 CASE_MATHFN (BUILT_IN_J1)
1667 CASE_MATHFN (BUILT_IN_JN)
1668 CASE_MATHFN (BUILT_IN_LCEIL)
1669 CASE_MATHFN (BUILT_IN_LDEXP)
1670 CASE_MATHFN (BUILT_IN_LFLOOR)
1671 CASE_MATHFN (BUILT_IN_LGAMMA)
1672 CASE_MATHFN (BUILT_IN_LLCEIL)
1673 CASE_MATHFN (BUILT_IN_LLFLOOR)
1674 CASE_MATHFN (BUILT_IN_LLRINT)
1675 CASE_MATHFN (BUILT_IN_LLROUND)
1676 CASE_MATHFN (BUILT_IN_LOG)
1677 CASE_MATHFN (BUILT_IN_LOG10)
1678 CASE_MATHFN (BUILT_IN_LOG1P)
1679 CASE_MATHFN (BUILT_IN_LOG2)
1680 CASE_MATHFN (BUILT_IN_LOGB)
1681 CASE_MATHFN (BUILT_IN_LRINT)
1682 CASE_MATHFN (BUILT_IN_LROUND)
1683 CASE_MATHFN (BUILT_IN_MODF)
1684 CASE_MATHFN (BUILT_IN_NAN)
1685 CASE_MATHFN (BUILT_IN_NANS)
1686 CASE_MATHFN (BUILT_IN_NEARBYINT)
1687 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1688 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1689 CASE_MATHFN (BUILT_IN_POW)
1690 CASE_MATHFN (BUILT_IN_POWI)
1691 CASE_MATHFN (BUILT_IN_POW10)
1692 CASE_MATHFN (BUILT_IN_REMAINDER)
1693 CASE_MATHFN (BUILT_IN_REMQUO)
1694 CASE_MATHFN (BUILT_IN_RINT)
1695 CASE_MATHFN (BUILT_IN_ROUND)
1696 CASE_MATHFN (BUILT_IN_SCALB)
1697 CASE_MATHFN (BUILT_IN_SCALBLN)
1698 CASE_MATHFN (BUILT_IN_SCALBN)
1699 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1700 CASE_MATHFN (BUILT_IN_SIN)
1701 CASE_MATHFN (BUILT_IN_SINCOS)
1702 CASE_MATHFN (BUILT_IN_SINH)
1703 CASE_MATHFN (BUILT_IN_SQRT)
1704 CASE_MATHFN (BUILT_IN_TAN)
1705 CASE_MATHFN (BUILT_IN_TANH)
1706 CASE_MATHFN (BUILT_IN_TGAMMA)
1707 CASE_MATHFN (BUILT_IN_TRUNC)
1708 CASE_MATHFN (BUILT_IN_Y0)
1709 CASE_MATHFN (BUILT_IN_Y1)
1710 CASE_MATHFN (BUILT_IN_YN)
1712 default:
1713 return 0;
1716 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1717 return implicit_built_in_decls[fcode];
1718 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1719 return implicit_built_in_decls[fcodef];
1720 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1721 return implicit_built_in_decls[fcodel];
1722 else
1723 return 0;
1726 /* If errno must be maintained, expand the RTL to check if the result,
1727 TARGET, of a built-in function call, EXP, is NaN, and if so set
1728 errno to EDOM. */
1730 static void
1731 expand_errno_check (tree exp, rtx target)
1733 rtx lab = gen_label_rtx ();
1735 /* Test the result; if it is NaN, set errno=EDOM because
1736 the argument was not in the domain. */
1737 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1738 0, lab);
1740 #ifdef TARGET_EDOM
1741 /* If this built-in doesn't throw an exception, set errno directly. */
1742 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1744 #ifdef GEN_ERRNO_RTX
1745 rtx errno_rtx = GEN_ERRNO_RTX;
1746 #else
1747 rtx errno_rtx
1748 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1749 #endif
1750 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1751 emit_label (lab);
1752 return;
1754 #endif
1756 /* We can't set errno=EDOM directly; let the library call do it.
1757 Pop the arguments right away in case the call gets deleted. */
1758 NO_DEFER_POP;
1759 expand_call (exp, target, 0);
1760 OK_DEFER_POP;
1761 emit_label (lab);
1765 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1766 Return 0 if a normal call should be emitted rather than expanding the
1767 function in-line. EXP is the expression that is a call to the builtin
1768 function; if convenient, the result should be placed in TARGET.
1769 SUBTARGET may be used as the target for computing one of EXP's operands. */
1771 static rtx
1772 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1774 optab builtin_optab;
1775 rtx op0, insns, before_call;
1776 tree fndecl = get_callee_fndecl (exp);
1777 tree arglist = TREE_OPERAND (exp, 1);
1778 enum machine_mode mode;
1779 bool errno_set = false;
1780 tree arg, narg;
1782 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1783 return 0;
1785 arg = TREE_VALUE (arglist);
1787 switch (DECL_FUNCTION_CODE (fndecl))
1789 CASE_FLT_FN (BUILT_IN_SQRT):
1790 errno_set = ! tree_expr_nonnegative_p (arg);
1791 builtin_optab = sqrt_optab;
1792 break;
1793 CASE_FLT_FN (BUILT_IN_EXP):
1794 errno_set = true; builtin_optab = exp_optab; break;
1795 CASE_FLT_FN (BUILT_IN_EXP10):
1796 CASE_FLT_FN (BUILT_IN_POW10):
1797 errno_set = true; builtin_optab = exp10_optab; break;
1798 CASE_FLT_FN (BUILT_IN_EXP2):
1799 errno_set = true; builtin_optab = exp2_optab; break;
1800 CASE_FLT_FN (BUILT_IN_EXPM1):
1801 errno_set = true; builtin_optab = expm1_optab; break;
1802 CASE_FLT_FN (BUILT_IN_LOGB):
1803 errno_set = true; builtin_optab = logb_optab; break;
1804 CASE_FLT_FN (BUILT_IN_ILOGB):
1805 errno_set = true; builtin_optab = ilogb_optab; break;
1806 CASE_FLT_FN (BUILT_IN_LOG):
1807 errno_set = true; builtin_optab = log_optab; break;
1808 CASE_FLT_FN (BUILT_IN_LOG10):
1809 errno_set = true; builtin_optab = log10_optab; break;
1810 CASE_FLT_FN (BUILT_IN_LOG2):
1811 errno_set = true; builtin_optab = log2_optab; break;
1812 CASE_FLT_FN (BUILT_IN_LOG1P):
1813 errno_set = true; builtin_optab = log1p_optab; break;
1814 CASE_FLT_FN (BUILT_IN_ASIN):
1815 builtin_optab = asin_optab; break;
1816 CASE_FLT_FN (BUILT_IN_ACOS):
1817 builtin_optab = acos_optab; break;
1818 CASE_FLT_FN (BUILT_IN_TAN):
1819 builtin_optab = tan_optab; break;
1820 CASE_FLT_FN (BUILT_IN_ATAN):
1821 builtin_optab = atan_optab; break;
1822 CASE_FLT_FN (BUILT_IN_FLOOR):
1823 builtin_optab = floor_optab; break;
1824 CASE_FLT_FN (BUILT_IN_CEIL):
1825 builtin_optab = ceil_optab; break;
1826 CASE_FLT_FN (BUILT_IN_TRUNC):
1827 builtin_optab = btrunc_optab; break;
1828 CASE_FLT_FN (BUILT_IN_ROUND):
1829 builtin_optab = round_optab; break;
1830 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1831 builtin_optab = nearbyint_optab; break;
1832 CASE_FLT_FN (BUILT_IN_RINT):
1833 builtin_optab = rint_optab; break;
1834 CASE_FLT_FN (BUILT_IN_LRINT):
1835 CASE_FLT_FN (BUILT_IN_LLRINT):
1836 builtin_optab = lrint_optab; break;
1837 default:
1838 gcc_unreachable ();
1841 /* Make a suitable register to place result in. */
1842 mode = TYPE_MODE (TREE_TYPE (exp));
1844 if (! flag_errno_math || ! HONOR_NANS (mode))
1845 errno_set = false;
1847 /* Before working hard, check whether the instruction is available. */
1848 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1850 target = gen_reg_rtx (mode);
1852 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1853 need to expand the argument again. This way, we will not perform
1854 side-effects more the once. */
1855 narg = builtin_save_expr (arg);
1856 if (narg != arg)
1858 arg = narg;
1859 arglist = build_tree_list (NULL_TREE, arg);
1860 exp = build_function_call_expr (fndecl, arglist);
1863 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1865 start_sequence ();
1867 /* Compute into TARGET.
1868 Set TARGET to wherever the result comes back. */
1869 target = expand_unop (mode, builtin_optab, op0, target, 0);
1871 if (target != 0)
1873 if (errno_set)
1874 expand_errno_check (exp, target);
1876 /* Output the entire sequence. */
1877 insns = get_insns ();
1878 end_sequence ();
1879 emit_insn (insns);
1880 return target;
1883 /* If we were unable to expand via the builtin, stop the sequence
1884 (without outputting the insns) and call to the library function
1885 with the stabilized argument list. */
1886 end_sequence ();
1889 before_call = get_last_insn ();
1891 target = expand_call (exp, target, target == const0_rtx);
1893 /* If this is a sqrt operation and we don't care about errno, try to
1894 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1895 This allows the semantics of the libcall to be visible to the RTL
1896 optimizers. */
1897 if (builtin_optab == sqrt_optab && !errno_set)
1899 /* Search backwards through the insns emitted by expand_call looking
1900 for the instruction with the REG_RETVAL note. */
1901 rtx last = get_last_insn ();
1902 while (last != before_call)
1904 if (find_reg_note (last, REG_RETVAL, NULL))
1906 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1907 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1908 two elements, i.e. symbol_ref(sqrt) and the operand. */
1909 if (note
1910 && GET_CODE (note) == EXPR_LIST
1911 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1912 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1913 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1915 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1916 /* Check operand is a register with expected mode. */
1917 if (operand
1918 && REG_P (operand)
1919 && GET_MODE (operand) == mode)
1921 /* Replace the REG_EQUAL note with a SQRT rtx. */
1922 rtx equiv = gen_rtx_SQRT (mode, operand);
1923 set_unique_reg_note (last, REG_EQUAL, equiv);
1926 break;
1928 last = PREV_INSN (last);
1932 return target;
1935 /* Expand a call to the builtin binary math functions (pow and atan2).
1936 Return 0 if a normal call should be emitted rather than expanding the
1937 function in-line. EXP is the expression that is a call to the builtin
1938 function; if convenient, the result should be placed in TARGET.
1939 SUBTARGET may be used as the target for computing one of EXP's
1940 operands. */
1942 static rtx
1943 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1945 optab builtin_optab;
1946 rtx op0, op1, insns;
1947 int op1_type = REAL_TYPE;
1948 tree fndecl = get_callee_fndecl (exp);
1949 tree arglist = TREE_OPERAND (exp, 1);
1950 tree arg0, arg1, temp, narg;
1951 enum machine_mode mode;
1952 bool errno_set = true;
1953 bool stable = true;
1955 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1956 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1957 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1958 op1_type = INTEGER_TYPE;
1960 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1961 return 0;
1963 arg0 = TREE_VALUE (arglist);
1964 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1966 switch (DECL_FUNCTION_CODE (fndecl))
1968 CASE_FLT_FN (BUILT_IN_POW):
1969 builtin_optab = pow_optab; break;
1970 CASE_FLT_FN (BUILT_IN_ATAN2):
1971 builtin_optab = atan2_optab; break;
1972 CASE_FLT_FN (BUILT_IN_LDEXP):
1973 builtin_optab = ldexp_optab; break;
1974 CASE_FLT_FN (BUILT_IN_FMOD):
1975 builtin_optab = fmod_optab; break;
1976 CASE_FLT_FN (BUILT_IN_DREM):
1977 builtin_optab = drem_optab; break;
1978 default:
1979 gcc_unreachable ();
1982 /* Make a suitable register to place result in. */
1983 mode = TYPE_MODE (TREE_TYPE (exp));
1985 /* Before working hard, check whether the instruction is available. */
1986 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1987 return 0;
1989 target = gen_reg_rtx (mode);
1991 if (! flag_errno_math || ! HONOR_NANS (mode))
1992 errno_set = false;
1994 /* Always stabilize the argument list. */
1995 narg = builtin_save_expr (arg1);
1996 if (narg != arg1)
1998 arg1 = narg;
1999 temp = build_tree_list (NULL_TREE, narg);
2000 stable = false;
2002 else
2003 temp = TREE_CHAIN (arglist);
2005 narg = builtin_save_expr (arg0);
2006 if (narg != arg0)
2008 arg0 = narg;
2009 arglist = tree_cons (NULL_TREE, narg, temp);
2010 stable = false;
2012 else if (! stable)
2013 arglist = tree_cons (NULL_TREE, arg0, temp);
2015 if (! stable)
2016 exp = build_function_call_expr (fndecl, arglist);
2018 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2019 op1 = expand_normal (arg1);
2021 start_sequence ();
2023 /* Compute into TARGET.
2024 Set TARGET to wherever the result comes back. */
2025 target = expand_binop (mode, builtin_optab, op0, op1,
2026 target, 0, OPTAB_DIRECT);
2028 /* If we were unable to expand via the builtin, stop the sequence
2029 (without outputting the insns) and call to the library function
2030 with the stabilized argument list. */
2031 if (target == 0)
2033 end_sequence ();
2034 return expand_call (exp, target, target == const0_rtx);
2037 if (errno_set)
2038 expand_errno_check (exp, target);
2040 /* Output the entire sequence. */
2041 insns = get_insns ();
2042 end_sequence ();
2043 emit_insn (insns);
2045 return target;
2048 /* Expand a call to the builtin sin and cos math functions.
2049 Return 0 if a normal call should be emitted rather than expanding the
2050 function in-line. EXP is the expression that is a call to the builtin
2051 function; if convenient, the result should be placed in TARGET.
2052 SUBTARGET may be used as the target for computing one of EXP's
2053 operands. */
2055 static rtx
2056 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2058 optab builtin_optab;
2059 rtx op0, insns;
2060 tree fndecl = get_callee_fndecl (exp);
2061 tree arglist = TREE_OPERAND (exp, 1);
2062 enum machine_mode mode;
2063 tree arg, narg;
2065 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2066 return 0;
2068 arg = TREE_VALUE (arglist);
2070 switch (DECL_FUNCTION_CODE (fndecl))
2072 CASE_FLT_FN (BUILT_IN_SIN):
2073 CASE_FLT_FN (BUILT_IN_COS):
2074 builtin_optab = sincos_optab; break;
2075 default:
2076 gcc_unreachable ();
2079 /* Make a suitable register to place result in. */
2080 mode = TYPE_MODE (TREE_TYPE (exp));
2082 /* Check if sincos insn is available, otherwise fallback
2083 to sin or cos insn. */
2084 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2085 switch (DECL_FUNCTION_CODE (fndecl))
2087 CASE_FLT_FN (BUILT_IN_SIN):
2088 builtin_optab = sin_optab; break;
2089 CASE_FLT_FN (BUILT_IN_COS):
2090 builtin_optab = cos_optab; break;
2091 default:
2092 gcc_unreachable ();
2096 /* Before working hard, check whether the instruction is available. */
2097 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2099 target = gen_reg_rtx (mode);
2101 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2102 need to expand the argument again. This way, we will not perform
2103 side-effects more the once. */
2104 narg = save_expr (arg);
2105 if (narg != arg)
2107 arg = narg;
2108 arglist = build_tree_list (NULL_TREE, arg);
2109 exp = build_function_call_expr (fndecl, arglist);
2112 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2114 start_sequence ();
2116 /* Compute into TARGET.
2117 Set TARGET to wherever the result comes back. */
2118 if (builtin_optab == sincos_optab)
2120 int result;
2122 switch (DECL_FUNCTION_CODE (fndecl))
2124 CASE_FLT_FN (BUILT_IN_SIN):
2125 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2126 break;
2127 CASE_FLT_FN (BUILT_IN_COS):
2128 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2129 break;
2130 default:
2131 gcc_unreachable ();
2133 gcc_assert (result);
2135 else
2137 target = expand_unop (mode, builtin_optab, op0, target, 0);
2140 if (target != 0)
2142 /* Output the entire sequence. */
2143 insns = get_insns ();
2144 end_sequence ();
2145 emit_insn (insns);
2146 return target;
2149 /* If we were unable to expand via the builtin, stop the sequence
2150 (without outputting the insns) and call to the library function
2151 with the stabilized argument list. */
2152 end_sequence ();
2155 target = expand_call (exp, target, target == const0_rtx);
2157 return target;
2160 /* Expand a call to the builtin sincos math function.
2161 Return 0 if a normal call should be emitted rather than expanding the
2162 function in-line. EXP is the expression that is a call to the builtin
2163 function. */
2165 static rtx
2166 expand_builtin_sincos (tree exp)
2168 rtx op0, op1, op2, target1, target2;
2169 tree arglist = TREE_OPERAND (exp, 1);
2170 enum machine_mode mode;
2171 tree arg, sinp, cosp;
2172 int result;
2174 if (!validate_arglist (arglist, REAL_TYPE,
2175 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2176 return 0;
2178 arg = TREE_VALUE (arglist);
2179 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2180 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2182 /* Make a suitable register to place result in. */
2183 mode = TYPE_MODE (TREE_TYPE (arg));
2185 /* Check if sincos insn is available, otherwise emit the call. */
2186 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2187 return NULL_RTX;
2189 target1 = gen_reg_rtx (mode);
2190 target2 = gen_reg_rtx (mode);
2192 op0 = expand_normal (arg);
2193 op1 = expand_normal (build_fold_indirect_ref (sinp));
2194 op2 = expand_normal (build_fold_indirect_ref (cosp));
2196 /* Compute into target1 and target2.
2197 Set TARGET to wherever the result comes back. */
2198 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2199 gcc_assert (result);
2201 /* Move target1 and target2 to the memory locations indicated
2202 by op1 and op2. */
2203 emit_move_insn (op1, target1);
2204 emit_move_insn (op2, target2);
2206 return const0_rtx;
2209 /* Expand a call to one of the builtin rounding functions (lfloor).
2210 If expanding via optab fails, lower expression to (int)(floor(x)).
2211 EXP is the expression that is a call to the builtin function;
2212 if convenient, the result should be placed in TARGET. SUBTARGET may
2213 be used as the target for computing one of EXP's operands. */
2215 static rtx
2216 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2218 optab builtin_optab;
2219 rtx op0, insns, tmp;
2220 tree fndecl = get_callee_fndecl (exp);
2221 tree arglist = TREE_OPERAND (exp, 1);
2222 enum built_in_function fallback_fn;
2223 tree fallback_fndecl;
2224 enum machine_mode mode;
2225 tree arg, narg;
2227 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2228 gcc_unreachable ();
2230 arg = TREE_VALUE (arglist);
2232 switch (DECL_FUNCTION_CODE (fndecl))
2234 CASE_FLT_FN (BUILT_IN_LCEIL):
2235 CASE_FLT_FN (BUILT_IN_LLCEIL):
2236 builtin_optab = lceil_optab;
2237 fallback_fn = BUILT_IN_CEIL;
2238 break;
2240 CASE_FLT_FN (BUILT_IN_LFLOOR):
2241 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2242 builtin_optab = lfloor_optab;
2243 fallback_fn = BUILT_IN_FLOOR;
2244 break;
2246 default:
2247 gcc_unreachable ();
2250 /* Make a suitable register to place result in. */
2251 mode = TYPE_MODE (TREE_TYPE (exp));
2253 /* Before working hard, check whether the instruction is available. */
2254 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2256 target = gen_reg_rtx (mode);
2258 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2259 need to expand the argument again. This way, we will not perform
2260 side-effects more the once. */
2261 narg = builtin_save_expr (arg);
2262 if (narg != arg)
2264 arg = narg;
2265 arglist = build_tree_list (NULL_TREE, arg);
2266 exp = build_function_call_expr (fndecl, arglist);
2269 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2271 start_sequence ();
2273 /* Compute into TARGET.
2274 Set TARGET to wherever the result comes back. */
2275 target = expand_unop (mode, builtin_optab, op0, target, 0);
2277 if (target != 0)
2279 /* Output the entire sequence. */
2280 insns = get_insns ();
2281 end_sequence ();
2282 emit_insn (insns);
2283 return target;
2286 /* If we were unable to expand via the builtin, stop the sequence
2287 (without outputting the insns). */
2288 end_sequence ();
2291 /* Fall back to floating point rounding optab. */
2292 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2293 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2294 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2295 gcc_assert (fallback_fndecl != NULL_TREE);
2296 exp = build_function_call_expr (fallback_fndecl, arglist);
2298 tmp = expand_normal (exp);
2300 /* Truncate the result of floating point optab to integer
2301 via expand_fix (). */
2302 target = gen_reg_rtx (mode);
2303 expand_fix (target, tmp, 0);
2305 return target;
2308 /* To evaluate powi(x,n), the floating point value x raised to the
2309 constant integer exponent n, we use a hybrid algorithm that
2310 combines the "window method" with look-up tables. For an
2311 introduction to exponentiation algorithms and "addition chains",
2312 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2313 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2314 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2315 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2317 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2318 multiplications to inline before calling the system library's pow
2319 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2320 so this default never requires calling pow, powf or powl. */
2322 #ifndef POWI_MAX_MULTS
2323 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2324 #endif
2326 /* The size of the "optimal power tree" lookup table. All
2327 exponents less than this value are simply looked up in the
2328 powi_table below. This threshold is also used to size the
2329 cache of pseudo registers that hold intermediate results. */
2330 #define POWI_TABLE_SIZE 256
2332 /* The size, in bits of the window, used in the "window method"
2333 exponentiation algorithm. This is equivalent to a radix of
2334 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2335 #define POWI_WINDOW_SIZE 3
2337 /* The following table is an efficient representation of an
2338 "optimal power tree". For each value, i, the corresponding
2339 value, j, in the table states than an optimal evaluation
2340 sequence for calculating pow(x,i) can be found by evaluating
2341 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2342 100 integers is given in Knuth's "Seminumerical algorithms". */
2344 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2346 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2347 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2348 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2349 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2350 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2351 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2352 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2353 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2354 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2355 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2356 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2357 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2358 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2359 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2360 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2361 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2362 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2363 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2364 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2365 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2366 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2367 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2368 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2369 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2370 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2371 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2372 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2373 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2374 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2375 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2376 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2377 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2381 /* Return the number of multiplications required to calculate
2382 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2383 subroutine of powi_cost. CACHE is an array indicating
2384 which exponents have already been calculated. */
2386 static int
2387 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2389 /* If we've already calculated this exponent, then this evaluation
2390 doesn't require any additional multiplications. */
2391 if (cache[n])
2392 return 0;
2394 cache[n] = true;
2395 return powi_lookup_cost (n - powi_table[n], cache)
2396 + powi_lookup_cost (powi_table[n], cache) + 1;
2399 /* Return the number of multiplications required to calculate
2400 powi(x,n) for an arbitrary x, given the exponent N. This
2401 function needs to be kept in sync with expand_powi below. */
2403 static int
2404 powi_cost (HOST_WIDE_INT n)
2406 bool cache[POWI_TABLE_SIZE];
2407 unsigned HOST_WIDE_INT digit;
2408 unsigned HOST_WIDE_INT val;
2409 int result;
2411 if (n == 0)
2412 return 0;
2414 /* Ignore the reciprocal when calculating the cost. */
2415 val = (n < 0) ? -n : n;
2417 /* Initialize the exponent cache. */
2418 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2419 cache[1] = true;
2421 result = 0;
2423 while (val >= POWI_TABLE_SIZE)
2425 if (val & 1)
2427 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2428 result += powi_lookup_cost (digit, cache)
2429 + POWI_WINDOW_SIZE + 1;
2430 val >>= POWI_WINDOW_SIZE;
2432 else
2434 val >>= 1;
2435 result++;
2439 return result + powi_lookup_cost (val, cache);
2442 /* Recursive subroutine of expand_powi. This function takes the array,
2443 CACHE, of already calculated exponents and an exponent N and returns
2444 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2446 static rtx
2447 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2449 unsigned HOST_WIDE_INT digit;
2450 rtx target, result;
2451 rtx op0, op1;
2453 if (n < POWI_TABLE_SIZE)
2455 if (cache[n])
2456 return cache[n];
2458 target = gen_reg_rtx (mode);
2459 cache[n] = target;
2461 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2462 op1 = expand_powi_1 (mode, powi_table[n], cache);
2464 else if (n & 1)
2466 target = gen_reg_rtx (mode);
2467 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2468 op0 = expand_powi_1 (mode, n - digit, cache);
2469 op1 = expand_powi_1 (mode, digit, cache);
2471 else
2473 target = gen_reg_rtx (mode);
2474 op0 = expand_powi_1 (mode, n >> 1, cache);
2475 op1 = op0;
2478 result = expand_mult (mode, op0, op1, target, 0);
2479 if (result != target)
2480 emit_move_insn (target, result);
2481 return target;
2484 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2485 floating point operand in mode MODE, and N is the exponent. This
2486 function needs to be kept in sync with powi_cost above. */
2488 static rtx
2489 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2491 unsigned HOST_WIDE_INT val;
2492 rtx cache[POWI_TABLE_SIZE];
2493 rtx result;
2495 if (n == 0)
2496 return CONST1_RTX (mode);
2498 val = (n < 0) ? -n : n;
2500 memset (cache, 0, sizeof (cache));
2501 cache[1] = x;
2503 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2505 /* If the original exponent was negative, reciprocate the result. */
2506 if (n < 0)
2507 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2508 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2510 return result;
2513 /* Expand a call to the pow built-in mathematical function. Return 0 if
2514 a normal call should be emitted rather than expanding the function
2515 in-line. EXP is the expression that is a call to the builtin
2516 function; if convenient, the result should be placed in TARGET. */
2518 static rtx
2519 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2521 tree arglist = TREE_OPERAND (exp, 1);
2522 tree arg0, arg1;
2524 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2525 return 0;
2527 arg0 = TREE_VALUE (arglist);
2528 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2530 if (TREE_CODE (arg1) == REAL_CST
2531 && ! TREE_CONSTANT_OVERFLOW (arg1))
2533 REAL_VALUE_TYPE cint;
2534 REAL_VALUE_TYPE c;
2535 HOST_WIDE_INT n;
2537 c = TREE_REAL_CST (arg1);
2538 n = real_to_integer (&c);
2539 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2540 if (real_identical (&c, &cint))
2542 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2543 Otherwise, check the number of multiplications required.
2544 Note that pow never sets errno for an integer exponent. */
2545 if ((n >= -1 && n <= 2)
2546 || (flag_unsafe_math_optimizations
2547 && ! optimize_size
2548 && powi_cost (n) <= POWI_MAX_MULTS))
2550 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2551 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2552 op = force_reg (mode, op);
2553 return expand_powi (op, mode, n);
2558 if (! flag_unsafe_math_optimizations)
2559 return NULL_RTX;
2560 return expand_builtin_mathfn_2 (exp, target, subtarget);
2563 /* Expand a call to the powi built-in mathematical function. Return 0 if
2564 a normal call should be emitted rather than expanding the function
2565 in-line. EXP is the expression that is a call to the builtin
2566 function; if convenient, the result should be placed in TARGET. */
2568 static rtx
2569 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2571 tree arglist = TREE_OPERAND (exp, 1);
2572 tree arg0, arg1;
2573 rtx op0, op1;
2574 enum machine_mode mode;
2575 enum machine_mode mode2;
2577 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2578 return 0;
2580 arg0 = TREE_VALUE (arglist);
2581 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2582 mode = TYPE_MODE (TREE_TYPE (exp));
2584 /* Handle constant power. */
2586 if (TREE_CODE (arg1) == INTEGER_CST
2587 && ! TREE_CONSTANT_OVERFLOW (arg1))
2589 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2591 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2592 Otherwise, check the number of multiplications required. */
2593 if ((TREE_INT_CST_HIGH (arg1) == 0
2594 || TREE_INT_CST_HIGH (arg1) == -1)
2595 && ((n >= -1 && n <= 2)
2596 || (! optimize_size
2597 && powi_cost (n) <= POWI_MAX_MULTS)))
2599 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2600 op0 = force_reg (mode, op0);
2601 return expand_powi (op0, mode, n);
2605 /* Emit a libcall to libgcc. */
2607 /* Mode of the 2nd argument must match that of an int. */
2608 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2610 if (target == NULL_RTX)
2611 target = gen_reg_rtx (mode);
2613 op0 = expand_expr (arg0, subtarget, mode, 0);
2614 if (GET_MODE (op0) != mode)
2615 op0 = convert_to_mode (mode, op0, 0);
2616 op1 = expand_expr (arg1, 0, mode2, 0);
2617 if (GET_MODE (op1) != mode2)
2618 op1 = convert_to_mode (mode2, op1, 0);
2620 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2621 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2622 op0, mode, op1, mode2);
2624 return target;
2627 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2628 if we failed the caller should emit a normal call, otherwise
2629 try to get the result in TARGET, if convenient. */
2631 static rtx
2632 expand_builtin_strlen (tree arglist, rtx target,
2633 enum machine_mode target_mode)
2635 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2636 return 0;
2637 else
2639 rtx pat;
2640 tree len, src = TREE_VALUE (arglist);
2641 rtx result, src_reg, char_rtx, before_strlen;
2642 enum machine_mode insn_mode = target_mode, char_mode;
2643 enum insn_code icode = CODE_FOR_nothing;
2644 int align;
2646 /* If the length can be computed at compile-time, return it. */
2647 len = c_strlen (src, 0);
2648 if (len)
2649 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2651 /* If the length can be computed at compile-time and is constant
2652 integer, but there are side-effects in src, evaluate
2653 src for side-effects, then return len.
2654 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2655 can be optimized into: i++; x = 3; */
2656 len = c_strlen (src, 1);
2657 if (len && TREE_CODE (len) == INTEGER_CST)
2659 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2660 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2663 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2665 /* If SRC is not a pointer type, don't do this operation inline. */
2666 if (align == 0)
2667 return 0;
2669 /* Bail out if we can't compute strlen in the right mode. */
2670 while (insn_mode != VOIDmode)
2672 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2673 if (icode != CODE_FOR_nothing)
2674 break;
2676 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2678 if (insn_mode == VOIDmode)
2679 return 0;
2681 /* Make a place to write the result of the instruction. */
2682 result = target;
2683 if (! (result != 0
2684 && REG_P (result)
2685 && GET_MODE (result) == insn_mode
2686 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2687 result = gen_reg_rtx (insn_mode);
2689 /* Make a place to hold the source address. We will not expand
2690 the actual source until we are sure that the expansion will
2691 not fail -- there are trees that cannot be expanded twice. */
2692 src_reg = gen_reg_rtx (Pmode);
2694 /* Mark the beginning of the strlen sequence so we can emit the
2695 source operand later. */
2696 before_strlen = get_last_insn ();
2698 char_rtx = const0_rtx;
2699 char_mode = insn_data[(int) icode].operand[2].mode;
2700 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2701 char_mode))
2702 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2704 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2705 char_rtx, GEN_INT (align));
2706 if (! pat)
2707 return 0;
2708 emit_insn (pat);
2710 /* Now that we are assured of success, expand the source. */
2711 start_sequence ();
2712 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2713 if (pat != src_reg)
2714 emit_move_insn (src_reg, pat);
2715 pat = get_insns ();
2716 end_sequence ();
2718 if (before_strlen)
2719 emit_insn_after (pat, before_strlen);
2720 else
2721 emit_insn_before (pat, get_insns ());
2723 /* Return the value in the proper mode for this function. */
2724 if (GET_MODE (result) == target_mode)
2725 target = result;
2726 else if (target != 0)
2727 convert_move (target, result, 0);
2728 else
2729 target = convert_to_mode (target_mode, result, 0);
2731 return target;
2735 /* Expand a call to the strstr builtin. Return 0 if we failed the
2736 caller should emit a normal call, otherwise try to get the result
2737 in TARGET, if convenient (and in mode MODE if that's convenient). */
2739 static rtx
2740 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2742 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2744 tree result = fold_builtin_strstr (arglist, type);
2745 if (result)
2746 return expand_expr (result, target, mode, EXPAND_NORMAL);
2748 return 0;
2751 /* Expand a call to the strchr builtin. Return 0 if we failed the
2752 caller should emit a normal call, otherwise try to get the result
2753 in TARGET, if convenient (and in mode MODE if that's convenient). */
2755 static rtx
2756 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2758 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2760 tree result = fold_builtin_strchr (arglist, type);
2761 if (result)
2762 return expand_expr (result, target, mode, EXPAND_NORMAL);
2764 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2766 return 0;
2769 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2770 caller should emit a normal call, otherwise try to get the result
2771 in TARGET, if convenient (and in mode MODE if that's convenient). */
2773 static rtx
2774 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2776 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2778 tree result = fold_builtin_strrchr (arglist, type);
2779 if (result)
2780 return expand_expr (result, target, mode, EXPAND_NORMAL);
2782 return 0;
2785 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2786 caller should emit a normal call, otherwise try to get the result
2787 in TARGET, if convenient (and in mode MODE if that's convenient). */
2789 static rtx
2790 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2792 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2794 tree result = fold_builtin_strpbrk (arglist, type);
2795 if (result)
2796 return expand_expr (result, target, mode, EXPAND_NORMAL);
2798 return 0;
2801 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2802 bytes from constant string DATA + OFFSET and return it as target
2803 constant. */
2805 static rtx
2806 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2807 enum machine_mode mode)
2809 const char *str = (const char *) data;
2811 gcc_assert (offset >= 0
2812 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2813 <= strlen (str) + 1));
2815 return c_readstr (str + offset, mode);
2818 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2819 Return 0 if we failed, the caller should emit a normal call,
2820 otherwise try to get the result in TARGET, if convenient (and in
2821 mode MODE if that's convenient). */
2822 static rtx
2823 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2825 tree fndecl = get_callee_fndecl (exp);
2826 tree arglist = TREE_OPERAND (exp, 1);
2827 if (!validate_arglist (arglist,
2828 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2829 return 0;
2830 else
2832 tree dest = TREE_VALUE (arglist);
2833 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2834 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2835 const char *src_str;
2836 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2837 unsigned int dest_align
2838 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2839 rtx dest_mem, src_mem, dest_addr, len_rtx;
2840 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2841 false, /*endp=*/0);
2843 if (result)
2845 while (TREE_CODE (result) == COMPOUND_EXPR)
2847 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2848 EXPAND_NORMAL);
2849 result = TREE_OPERAND (result, 1);
2851 return expand_expr (result, target, mode, EXPAND_NORMAL);
2854 /* If DEST is not a pointer type, call the normal function. */
2855 if (dest_align == 0)
2856 return 0;
2858 /* If either SRC is not a pointer type, don't do this
2859 operation in-line. */
2860 if (src_align == 0)
2861 return 0;
2863 dest_mem = get_memory_rtx (dest, len);
2864 set_mem_align (dest_mem, dest_align);
2865 len_rtx = expand_normal (len);
2866 src_str = c_getstr (src);
2868 /* If SRC is a string constant and block move would be done
2869 by pieces, we can avoid loading the string from memory
2870 and only stored the computed constants. */
2871 if (src_str
2872 && GET_CODE (len_rtx) == CONST_INT
2873 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2874 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2875 (void *) src_str, dest_align))
2877 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2878 builtin_memcpy_read_str,
2879 (void *) src_str, dest_align, 0);
2880 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2881 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2882 return dest_mem;
2885 src_mem = get_memory_rtx (src, len);
2886 set_mem_align (src_mem, src_align);
2888 /* Copy word part most expediently. */
2889 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2890 CALL_EXPR_TAILCALL (exp)
2891 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2893 if (dest_addr == 0)
2895 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2896 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2898 return dest_addr;
2902 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2903 Return 0 if we failed; the caller should emit a normal call,
2904 otherwise try to get the result in TARGET, if convenient (and in
2905 mode MODE if that's convenient). If ENDP is 0 return the
2906 destination pointer, if ENDP is 1 return the end pointer ala
2907 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2908 stpcpy. */
2910 static rtx
2911 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2912 int endp)
2914 if (!validate_arglist (arglist,
2915 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2916 return 0;
2917 /* If return value is ignored, transform mempcpy into memcpy. */
2918 else if (target == const0_rtx)
2920 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2922 if (!fn)
2923 return 0;
2925 return expand_expr (build_function_call_expr (fn, arglist),
2926 target, mode, EXPAND_NORMAL);
2928 else
2930 tree dest = TREE_VALUE (arglist);
2931 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2932 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2933 const char *src_str;
2934 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2935 unsigned int dest_align
2936 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2937 rtx dest_mem, src_mem, len_rtx;
2938 tree result = fold_builtin_memory_op (arglist, type, false, endp);
2940 if (result)
2942 while (TREE_CODE (result) == COMPOUND_EXPR)
2944 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2945 EXPAND_NORMAL);
2946 result = TREE_OPERAND (result, 1);
2948 return expand_expr (result, target, mode, EXPAND_NORMAL);
2951 /* If either SRC or DEST is not a pointer type, don't do this
2952 operation in-line. */
2953 if (dest_align == 0 || src_align == 0)
2954 return 0;
2956 /* If LEN is not constant, call the normal function. */
2957 if (! host_integerp (len, 1))
2958 return 0;
2960 len_rtx = expand_normal (len);
2961 src_str = c_getstr (src);
2963 /* If SRC is a string constant and block move would be done
2964 by pieces, we can avoid loading the string from memory
2965 and only stored the computed constants. */
2966 if (src_str
2967 && GET_CODE (len_rtx) == CONST_INT
2968 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2969 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2970 (void *) src_str, dest_align))
2972 dest_mem = get_memory_rtx (dest, len);
2973 set_mem_align (dest_mem, dest_align);
2974 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2975 builtin_memcpy_read_str,
2976 (void *) src_str, dest_align, endp);
2977 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2978 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2979 return dest_mem;
2982 if (GET_CODE (len_rtx) == CONST_INT
2983 && can_move_by_pieces (INTVAL (len_rtx),
2984 MIN (dest_align, src_align)))
2986 dest_mem = get_memory_rtx (dest, len);
2987 set_mem_align (dest_mem, dest_align);
2988 src_mem = get_memory_rtx (src, len);
2989 set_mem_align (src_mem, src_align);
2990 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2991 MIN (dest_align, src_align), endp);
2992 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2993 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2994 return dest_mem;
2997 return 0;
3001 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3002 if we failed; the caller should emit a normal call. */
3004 static rtx
3005 expand_builtin_memmove (tree arglist, tree type, rtx target,
3006 enum machine_mode mode, tree orig_exp)
3008 if (!validate_arglist (arglist,
3009 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3010 return 0;
3011 else
3013 tree dest = TREE_VALUE (arglist);
3014 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3015 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3017 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3018 unsigned int dest_align
3019 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3020 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3022 if (result)
3024 while (TREE_CODE (result) == COMPOUND_EXPR)
3026 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3027 EXPAND_NORMAL);
3028 result = TREE_OPERAND (result, 1);
3030 return expand_expr (result, target, mode, EXPAND_NORMAL);
3033 /* If DEST is not a pointer type, call the normal function. */
3034 if (dest_align == 0)
3035 return 0;
3037 /* If either SRC is not a pointer type, don't do this
3038 operation in-line. */
3039 if (src_align == 0)
3040 return 0;
3042 /* If src is categorized for a readonly section we can use
3043 normal memcpy. */
3044 if (readonly_data_expr (src))
3046 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3047 if (!fn)
3048 return 0;
3049 fn = build_function_call_expr (fn, arglist);
3050 if (TREE_CODE (fn) == CALL_EXPR)
3051 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3052 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3055 /* If length is 1 and we can expand memcpy call inline,
3056 it is ok to use memcpy as well. */
3057 if (integer_onep (len))
3059 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3060 /*endp=*/0);
3061 if (ret)
3062 return ret;
3065 /* Otherwise, call the normal function. */
3066 return 0;
3070 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3071 if we failed the caller should emit a normal call. */
3073 static rtx
3074 expand_builtin_bcopy (tree exp)
3076 tree arglist = TREE_OPERAND (exp, 1);
3077 tree type = TREE_TYPE (exp);
3078 tree src, dest, size, newarglist;
3080 if (!validate_arglist (arglist,
3081 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3082 return NULL_RTX;
3084 src = TREE_VALUE (arglist);
3085 dest = TREE_VALUE (TREE_CHAIN (arglist));
3086 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3088 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3089 memmove(ptr y, ptr x, size_t z). This is done this way
3090 so that if it isn't expanded inline, we fallback to
3091 calling bcopy instead of memmove. */
3093 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3094 newarglist = tree_cons (NULL_TREE, src, newarglist);
3095 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3097 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3100 #ifndef HAVE_movstr
3101 # define HAVE_movstr 0
3102 # define CODE_FOR_movstr CODE_FOR_nothing
3103 #endif
3105 /* Expand into a movstr instruction, if one is available. Return 0 if
3106 we failed, the caller should emit a normal call, otherwise try to
3107 get the result in TARGET, if convenient. If ENDP is 0 return the
3108 destination pointer, if ENDP is 1 return the end pointer ala
3109 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3110 stpcpy. */
3112 static rtx
3113 expand_movstr (tree dest, tree src, rtx target, int endp)
3115 rtx end;
3116 rtx dest_mem;
3117 rtx src_mem;
3118 rtx insn;
3119 const struct insn_data * data;
3121 if (!HAVE_movstr)
3122 return 0;
3124 dest_mem = get_memory_rtx (dest, NULL);
3125 src_mem = get_memory_rtx (src, NULL);
3126 if (!endp)
3128 target = force_reg (Pmode, XEXP (dest_mem, 0));
3129 dest_mem = replace_equiv_address (dest_mem, target);
3130 end = gen_reg_rtx (Pmode);
3132 else
3134 if (target == 0 || target == const0_rtx)
3136 end = gen_reg_rtx (Pmode);
3137 if (target == 0)
3138 target = end;
3140 else
3141 end = target;
3144 data = insn_data + CODE_FOR_movstr;
3146 if (data->operand[0].mode != VOIDmode)
3147 end = gen_lowpart (data->operand[0].mode, end);
3149 insn = data->genfun (end, dest_mem, src_mem);
3151 gcc_assert (insn);
3153 emit_insn (insn);
3155 /* movstr is supposed to set end to the address of the NUL
3156 terminator. If the caller requested a mempcpy-like return value,
3157 adjust it. */
3158 if (endp == 1 && target != const0_rtx)
3160 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3161 emit_move_insn (target, force_operand (tem, NULL_RTX));
3164 return target;
3167 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3168 if we failed the caller should emit a normal call, otherwise try to get
3169 the result in TARGET, if convenient (and in mode MODE if that's
3170 convenient). */
3172 static rtx
3173 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3175 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3177 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3178 if (result)
3180 while (TREE_CODE (result) == COMPOUND_EXPR)
3182 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3183 EXPAND_NORMAL);
3184 result = TREE_OPERAND (result, 1);
3186 return expand_expr (result, target, mode, EXPAND_NORMAL);
3189 return expand_movstr (TREE_VALUE (arglist),
3190 TREE_VALUE (TREE_CHAIN (arglist)),
3191 target, /*endp=*/0);
3193 return 0;
3196 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3197 Return 0 if we failed the caller should emit a normal call,
3198 otherwise try to get the result in TARGET, if convenient (and in
3199 mode MODE if that's convenient). */
3201 static rtx
3202 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3204 tree arglist = TREE_OPERAND (exp, 1);
3205 /* If return value is ignored, transform stpcpy into strcpy. */
3206 if (target == const0_rtx)
3208 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3209 if (!fn)
3210 return 0;
3212 return expand_expr (build_function_call_expr (fn, arglist),
3213 target, mode, EXPAND_NORMAL);
3216 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3217 return 0;
3218 else
3220 tree dst, src, len, lenp1;
3221 tree narglist;
3222 rtx ret;
3224 /* Ensure we get an actual string whose length can be evaluated at
3225 compile-time, not an expression containing a string. This is
3226 because the latter will potentially produce pessimized code
3227 when used to produce the return value. */
3228 src = TREE_VALUE (TREE_CHAIN (arglist));
3229 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3230 return expand_movstr (TREE_VALUE (arglist),
3231 TREE_VALUE (TREE_CHAIN (arglist)),
3232 target, /*endp=*/2);
3234 dst = TREE_VALUE (arglist);
3235 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3236 narglist = build_tree_list (NULL_TREE, lenp1);
3237 narglist = tree_cons (NULL_TREE, src, narglist);
3238 narglist = tree_cons (NULL_TREE, dst, narglist);
3239 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3240 target, mode, /*endp=*/2);
3242 if (ret)
3243 return ret;
3245 if (TREE_CODE (len) == INTEGER_CST)
3247 rtx len_rtx = expand_normal (len);
3249 if (GET_CODE (len_rtx) == CONST_INT)
3251 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3252 arglist, target, mode);
3254 if (ret)
3256 if (! target)
3258 if (mode != VOIDmode)
3259 target = gen_reg_rtx (mode);
3260 else
3261 target = gen_reg_rtx (GET_MODE (ret));
3263 if (GET_MODE (target) != GET_MODE (ret))
3264 ret = gen_lowpart (GET_MODE (target), ret);
3266 ret = plus_constant (ret, INTVAL (len_rtx));
3267 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3268 gcc_assert (ret);
3270 return target;
3275 return expand_movstr (TREE_VALUE (arglist),
3276 TREE_VALUE (TREE_CHAIN (arglist)),
3277 target, /*endp=*/2);
3281 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3282 bytes from constant string DATA + OFFSET and return it as target
3283 constant. */
3285 static rtx
3286 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3287 enum machine_mode mode)
3289 const char *str = (const char *) data;
3291 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3292 return const0_rtx;
3294 return c_readstr (str + offset, mode);
3297 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3298 if we failed the caller should emit a normal call. */
3300 static rtx
3301 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3303 tree fndecl = get_callee_fndecl (exp);
3304 tree arglist = TREE_OPERAND (exp, 1);
3305 if (validate_arglist (arglist,
3306 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3308 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3309 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3310 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3312 if (result)
3314 while (TREE_CODE (result) == COMPOUND_EXPR)
3316 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3317 EXPAND_NORMAL);
3318 result = TREE_OPERAND (result, 1);
3320 return expand_expr (result, target, mode, EXPAND_NORMAL);
3323 /* We must be passed a constant len and src parameter. */
3324 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3325 return 0;
3327 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3329 /* We're required to pad with trailing zeros if the requested
3330 len is greater than strlen(s2)+1. In that case try to
3331 use store_by_pieces, if it fails, punt. */
3332 if (tree_int_cst_lt (slen, len))
3334 tree dest = TREE_VALUE (arglist);
3335 unsigned int dest_align
3336 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3337 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3338 rtx dest_mem;
3340 if (!p || dest_align == 0 || !host_integerp (len, 1)
3341 || !can_store_by_pieces (tree_low_cst (len, 1),
3342 builtin_strncpy_read_str,
3343 (void *) p, dest_align))
3344 return 0;
3346 dest_mem = get_memory_rtx (dest, len);
3347 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3348 builtin_strncpy_read_str,
3349 (void *) p, dest_align, 0);
3350 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3351 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3352 return dest_mem;
3355 return 0;
3358 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3359 bytes from constant string DATA + OFFSET and return it as target
3360 constant. */
3362 static rtx
3363 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3364 enum machine_mode mode)
3366 const char *c = (const char *) data;
3367 char *p = alloca (GET_MODE_SIZE (mode));
3369 memset (p, *c, GET_MODE_SIZE (mode));
3371 return c_readstr (p, mode);
3374 /* Callback routine for store_by_pieces. Return the RTL of a register
3375 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3376 char value given in the RTL register data. For example, if mode is
3377 4 bytes wide, return the RTL for 0x01010101*data. */
3379 static rtx
3380 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3381 enum machine_mode mode)
3383 rtx target, coeff;
3384 size_t size;
3385 char *p;
3387 size = GET_MODE_SIZE (mode);
3388 if (size == 1)
3389 return (rtx) data;
3391 p = alloca (size);
3392 memset (p, 1, size);
3393 coeff = c_readstr (p, mode);
3395 target = convert_to_mode (mode, (rtx) data, 1);
3396 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3397 return force_reg (mode, target);
3400 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3401 if we failed the caller should emit a normal call, otherwise try to get
3402 the result in TARGET, if convenient (and in mode MODE if that's
3403 convenient). */
3405 static rtx
3406 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3407 tree orig_exp)
3409 if (!validate_arglist (arglist,
3410 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3411 return 0;
3412 else
3414 tree dest = TREE_VALUE (arglist);
3415 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3416 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3417 tree fndecl, fn;
3418 enum built_in_function fcode;
3419 char c;
3420 unsigned int dest_align;
3421 rtx dest_mem, dest_addr, len_rtx;
3423 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3425 /* If DEST is not a pointer type, don't do this
3426 operation in-line. */
3427 if (dest_align == 0)
3428 return 0;
3430 /* If the LEN parameter is zero, return DEST. */
3431 if (integer_zerop (len))
3433 /* Evaluate and ignore VAL in case it has side-effects. */
3434 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3435 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3438 /* Stabilize the arguments in case we fail. */
3439 dest = builtin_save_expr (dest);
3440 val = builtin_save_expr (val);
3441 len = builtin_save_expr (len);
3443 len_rtx = expand_normal (len);
3444 dest_mem = get_memory_rtx (dest, len);
3446 if (TREE_CODE (val) != INTEGER_CST)
3448 rtx val_rtx;
3450 val_rtx = expand_normal (val);
3451 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3452 val_rtx, 0);
3454 /* Assume that we can memset by pieces if we can store the
3455 * the coefficients by pieces (in the required modes).
3456 * We can't pass builtin_memset_gen_str as that emits RTL. */
3457 c = 1;
3458 if (host_integerp (len, 1)
3459 && !(optimize_size && tree_low_cst (len, 1) > 1)
3460 && can_store_by_pieces (tree_low_cst (len, 1),
3461 builtin_memset_read_str, &c, dest_align))
3463 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3464 val_rtx);
3465 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3466 builtin_memset_gen_str, val_rtx, dest_align, 0);
3468 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3469 dest_align))
3470 goto do_libcall;
3472 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3473 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3474 return dest_mem;
3477 if (target_char_cast (val, &c))
3478 goto do_libcall;
3480 if (c)
3482 if (host_integerp (len, 1)
3483 && !(optimize_size && tree_low_cst (len, 1) > 1)
3484 && can_store_by_pieces (tree_low_cst (len, 1),
3485 builtin_memset_read_str, &c, dest_align))
3486 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3487 builtin_memset_read_str, &c, dest_align, 0);
3488 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3489 dest_align))
3490 goto do_libcall;
3492 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3493 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3494 return dest_mem;
3497 set_mem_align (dest_mem, dest_align);
3498 dest_addr = clear_storage (dest_mem, len_rtx,
3499 CALL_EXPR_TAILCALL (orig_exp)
3500 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3502 if (dest_addr == 0)
3504 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3505 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3508 return dest_addr;
3510 do_libcall:
3511 fndecl = get_callee_fndecl (orig_exp);
3512 fcode = DECL_FUNCTION_CODE (fndecl);
3513 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3514 arglist = build_tree_list (NULL_TREE, len);
3515 if (fcode == BUILT_IN_MEMSET)
3516 arglist = tree_cons (NULL_TREE, val, arglist);
3517 arglist = tree_cons (NULL_TREE, dest, arglist);
3518 fn = build_function_call_expr (fndecl, arglist);
3519 if (TREE_CODE (fn) == CALL_EXPR)
3520 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3521 return expand_call (fn, target, target == const0_rtx);
3525 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3526 if we failed the caller should emit a normal call. */
3528 static rtx
3529 expand_builtin_bzero (tree exp)
3531 tree arglist = TREE_OPERAND (exp, 1);
3532 tree dest, size, newarglist;
3534 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3535 return NULL_RTX;
3537 dest = TREE_VALUE (arglist);
3538 size = TREE_VALUE (TREE_CHAIN (arglist));
3540 /* New argument list transforming bzero(ptr x, int y) to
3541 memset(ptr x, int 0, size_t y). This is done this way
3542 so that if it isn't expanded inline, we fallback to
3543 calling bzero instead of memset. */
3545 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3546 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3547 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3549 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3552 /* Expand expression EXP, which is a call to the memcmp built-in function.
3553 ARGLIST is the argument list for this call. Return 0 if we failed and the
3554 caller should emit a normal call, otherwise try to get the result in
3555 TARGET, if convenient (and in mode MODE, if that's convenient). */
3557 static rtx
3558 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3559 enum machine_mode mode)
3561 if (!validate_arglist (arglist,
3562 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3563 return 0;
3564 else
3566 tree result = fold_builtin_memcmp (arglist);
3567 if (result)
3568 return expand_expr (result, target, mode, EXPAND_NORMAL);
3571 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3573 tree arg1 = TREE_VALUE (arglist);
3574 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3575 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3576 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3577 rtx result;
3578 rtx insn;
3580 int arg1_align
3581 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3582 int arg2_align
3583 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3584 enum machine_mode insn_mode;
3586 #ifdef HAVE_cmpmemsi
3587 if (HAVE_cmpmemsi)
3588 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3589 else
3590 #endif
3591 #ifdef HAVE_cmpstrnsi
3592 if (HAVE_cmpstrnsi)
3593 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3594 else
3595 #endif
3596 return 0;
3598 /* If we don't have POINTER_TYPE, call the function. */
3599 if (arg1_align == 0 || arg2_align == 0)
3600 return 0;
3602 /* Make a place to write the result of the instruction. */
3603 result = target;
3604 if (! (result != 0
3605 && REG_P (result) && GET_MODE (result) == insn_mode
3606 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3607 result = gen_reg_rtx (insn_mode);
3609 arg1_rtx = get_memory_rtx (arg1, len);
3610 arg2_rtx = get_memory_rtx (arg2, len);
3611 arg3_rtx = expand_normal (len);
3613 /* Set MEM_SIZE as appropriate. */
3614 if (GET_CODE (arg3_rtx) == CONST_INT)
3616 set_mem_size (arg1_rtx, arg3_rtx);
3617 set_mem_size (arg2_rtx, arg3_rtx);
3620 #ifdef HAVE_cmpmemsi
3621 if (HAVE_cmpmemsi)
3622 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3623 GEN_INT (MIN (arg1_align, arg2_align)));
3624 else
3625 #endif
3626 #ifdef HAVE_cmpstrnsi
3627 if (HAVE_cmpstrnsi)
3628 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3629 GEN_INT (MIN (arg1_align, arg2_align)));
3630 else
3631 #endif
3632 gcc_unreachable ();
3634 if (insn)
3635 emit_insn (insn);
3636 else
3637 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3638 TYPE_MODE (integer_type_node), 3,
3639 XEXP (arg1_rtx, 0), Pmode,
3640 XEXP (arg2_rtx, 0), Pmode,
3641 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3642 TYPE_UNSIGNED (sizetype)),
3643 TYPE_MODE (sizetype));
3645 /* Return the value in the proper mode for this function. */
3646 mode = TYPE_MODE (TREE_TYPE (exp));
3647 if (GET_MODE (result) == mode)
3648 return result;
3649 else if (target != 0)
3651 convert_move (target, result, 0);
3652 return target;
3654 else
3655 return convert_to_mode (mode, result, 0);
3657 #endif
3659 return 0;
3662 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3663 if we failed the caller should emit a normal call, otherwise try to get
3664 the result in TARGET, if convenient. */
3666 static rtx
3667 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3669 tree arglist = TREE_OPERAND (exp, 1);
3671 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3672 return 0;
3673 else
3675 tree result = fold_builtin_strcmp (arglist);
3676 if (result)
3677 return expand_expr (result, target, mode, EXPAND_NORMAL);
3680 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3681 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3682 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3684 rtx arg1_rtx, arg2_rtx;
3685 rtx result, insn = NULL_RTX;
3686 tree fndecl, fn;
3688 tree arg1 = TREE_VALUE (arglist);
3689 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3690 int arg1_align
3691 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3692 int arg2_align
3693 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3695 /* If we don't have POINTER_TYPE, call the function. */
3696 if (arg1_align == 0 || arg2_align == 0)
3697 return 0;
3699 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3700 arg1 = builtin_save_expr (arg1);
3701 arg2 = builtin_save_expr (arg2);
3703 arg1_rtx = get_memory_rtx (arg1, NULL);
3704 arg2_rtx = get_memory_rtx (arg2, NULL);
3706 #ifdef HAVE_cmpstrsi
3707 /* Try to call cmpstrsi. */
3708 if (HAVE_cmpstrsi)
3710 enum machine_mode insn_mode
3711 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3713 /* Make a place to write the result of the instruction. */
3714 result = target;
3715 if (! (result != 0
3716 && REG_P (result) && GET_MODE (result) == insn_mode
3717 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3718 result = gen_reg_rtx (insn_mode);
3720 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3721 GEN_INT (MIN (arg1_align, arg2_align)));
3723 #endif
3724 #ifdef HAVE_cmpstrnsi
3725 /* Try to determine at least one length and call cmpstrnsi. */
3726 if (!insn && HAVE_cmpstrnsi)
3728 tree len;
3729 rtx arg3_rtx;
3731 enum machine_mode insn_mode
3732 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3733 tree len1 = c_strlen (arg1, 1);
3734 tree len2 = c_strlen (arg2, 1);
3736 if (len1)
3737 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3738 if (len2)
3739 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3741 /* If we don't have a constant length for the first, use the length
3742 of the second, if we know it. We don't require a constant for
3743 this case; some cost analysis could be done if both are available
3744 but neither is constant. For now, assume they're equally cheap,
3745 unless one has side effects. If both strings have constant lengths,
3746 use the smaller. */
3748 if (!len1)
3749 len = len2;
3750 else if (!len2)
3751 len = len1;
3752 else if (TREE_SIDE_EFFECTS (len1))
3753 len = len2;
3754 else if (TREE_SIDE_EFFECTS (len2))
3755 len = len1;
3756 else if (TREE_CODE (len1) != INTEGER_CST)
3757 len = len2;
3758 else if (TREE_CODE (len2) != INTEGER_CST)
3759 len = len1;
3760 else if (tree_int_cst_lt (len1, len2))
3761 len = len1;
3762 else
3763 len = len2;
3765 /* If both arguments have side effects, we cannot optimize. */
3766 if (!len || TREE_SIDE_EFFECTS (len))
3767 goto do_libcall;
3769 arg3_rtx = expand_normal (len);
3771 /* Make a place to write the result of the instruction. */
3772 result = target;
3773 if (! (result != 0
3774 && REG_P (result) && GET_MODE (result) == insn_mode
3775 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3776 result = gen_reg_rtx (insn_mode);
3778 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3779 GEN_INT (MIN (arg1_align, arg2_align)));
3781 #endif
3783 if (insn)
3785 emit_insn (insn);
3787 /* Return the value in the proper mode for this function. */
3788 mode = TYPE_MODE (TREE_TYPE (exp));
3789 if (GET_MODE (result) == mode)
3790 return result;
3791 if (target == 0)
3792 return convert_to_mode (mode, result, 0);
3793 convert_move (target, result, 0);
3794 return target;
3797 /* Expand the library call ourselves using a stabilized argument
3798 list to avoid re-evaluating the function's arguments twice. */
3799 #ifdef HAVE_cmpstrnsi
3800 do_libcall:
3801 #endif
3802 arglist = build_tree_list (NULL_TREE, arg2);
3803 arglist = tree_cons (NULL_TREE, arg1, arglist);
3804 fndecl = get_callee_fndecl (exp);
3805 fn = build_function_call_expr (fndecl, arglist);
3806 if (TREE_CODE (fn) == CALL_EXPR)
3807 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3808 return expand_call (fn, target, target == const0_rtx);
3810 #endif
3811 return 0;
3814 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3815 if we failed the caller should emit a normal call, otherwise try to get
3816 the result in TARGET, if convenient. */
3818 static rtx
3819 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3821 tree arglist = TREE_OPERAND (exp, 1);
3823 if (!validate_arglist (arglist,
3824 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3825 return 0;
3826 else
3828 tree result = fold_builtin_strncmp (arglist);
3829 if (result)
3830 return expand_expr (result, target, mode, EXPAND_NORMAL);
3833 /* If c_strlen can determine an expression for one of the string
3834 lengths, and it doesn't have side effects, then emit cmpstrnsi
3835 using length MIN(strlen(string)+1, arg3). */
3836 #ifdef HAVE_cmpstrnsi
3837 if (HAVE_cmpstrnsi)
3839 tree arg1 = TREE_VALUE (arglist);
3840 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3841 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3842 tree len, len1, len2;
3843 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3844 rtx result, insn;
3845 tree fndecl, fn;
3847 int arg1_align
3848 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3849 int arg2_align
3850 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3851 enum machine_mode insn_mode
3852 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3854 len1 = c_strlen (arg1, 1);
3855 len2 = c_strlen (arg2, 1);
3857 if (len1)
3858 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3859 if (len2)
3860 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3862 /* If we don't have a constant length for the first, use the length
3863 of the second, if we know it. We don't require a constant for
3864 this case; some cost analysis could be done if both are available
3865 but neither is constant. For now, assume they're equally cheap,
3866 unless one has side effects. If both strings have constant lengths,
3867 use the smaller. */
3869 if (!len1)
3870 len = len2;
3871 else if (!len2)
3872 len = len1;
3873 else if (TREE_SIDE_EFFECTS (len1))
3874 len = len2;
3875 else if (TREE_SIDE_EFFECTS (len2))
3876 len = len1;
3877 else if (TREE_CODE (len1) != INTEGER_CST)
3878 len = len2;
3879 else if (TREE_CODE (len2) != INTEGER_CST)
3880 len = len1;
3881 else if (tree_int_cst_lt (len1, len2))
3882 len = len1;
3883 else
3884 len = len2;
3886 /* If both arguments have side effects, we cannot optimize. */
3887 if (!len || TREE_SIDE_EFFECTS (len))
3888 return 0;
3890 /* The actual new length parameter is MIN(len,arg3). */
3891 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3892 fold_convert (TREE_TYPE (len), arg3));
3894 /* If we don't have POINTER_TYPE, call the function. */
3895 if (arg1_align == 0 || arg2_align == 0)
3896 return 0;
3898 /* Make a place to write the result of the instruction. */
3899 result = target;
3900 if (! (result != 0
3901 && REG_P (result) && GET_MODE (result) == insn_mode
3902 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3903 result = gen_reg_rtx (insn_mode);
3905 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3906 arg1 = builtin_save_expr (arg1);
3907 arg2 = builtin_save_expr (arg2);
3908 len = builtin_save_expr (len);
3910 arg1_rtx = get_memory_rtx (arg1, len);
3911 arg2_rtx = get_memory_rtx (arg2, len);
3912 arg3_rtx = expand_normal (len);
3913 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3914 GEN_INT (MIN (arg1_align, arg2_align)));
3915 if (insn)
3917 emit_insn (insn);
3919 /* Return the value in the proper mode for this function. */
3920 mode = TYPE_MODE (TREE_TYPE (exp));
3921 if (GET_MODE (result) == mode)
3922 return result;
3923 if (target == 0)
3924 return convert_to_mode (mode, result, 0);
3925 convert_move (target, result, 0);
3926 return target;
3929 /* Expand the library call ourselves using a stabilized argument
3930 list to avoid re-evaluating the function's arguments twice. */
3931 arglist = build_tree_list (NULL_TREE, len);
3932 arglist = tree_cons (NULL_TREE, arg2, arglist);
3933 arglist = tree_cons (NULL_TREE, arg1, arglist);
3934 fndecl = get_callee_fndecl (exp);
3935 fn = build_function_call_expr (fndecl, arglist);
3936 if (TREE_CODE (fn) == CALL_EXPR)
3937 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3938 return expand_call (fn, target, target == const0_rtx);
3940 #endif
3941 return 0;
3944 /* Expand expression EXP, which is a call to the strcat builtin.
3945 Return 0 if we failed the caller should emit a normal call,
3946 otherwise try to get the result in TARGET, if convenient. */
3948 static rtx
3949 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3951 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3952 return 0;
3953 else
3955 tree dst = TREE_VALUE (arglist),
3956 src = TREE_VALUE (TREE_CHAIN (arglist));
3957 const char *p = c_getstr (src);
3959 /* If the string length is zero, return the dst parameter. */
3960 if (p && *p == '\0')
3961 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3963 if (!optimize_size)
3965 /* See if we can store by pieces into (dst + strlen(dst)). */
3966 tree newsrc, newdst,
3967 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3968 rtx insns;
3970 /* Stabilize the argument list. */
3971 newsrc = builtin_save_expr (src);
3972 if (newsrc != src)
3973 arglist = build_tree_list (NULL_TREE, newsrc);
3974 else
3975 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3977 dst = builtin_save_expr (dst);
3979 start_sequence ();
3981 /* Create strlen (dst). */
3982 newdst =
3983 build_function_call_expr (strlen_fn,
3984 build_tree_list (NULL_TREE, dst));
3985 /* Create (dst + (cast) strlen (dst)). */
3986 newdst = fold_convert (TREE_TYPE (dst), newdst);
3987 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3989 newdst = builtin_save_expr (newdst);
3990 arglist = tree_cons (NULL_TREE, newdst, arglist);
3992 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3994 end_sequence (); /* Stop sequence. */
3995 return 0;
3998 /* Output the entire sequence. */
3999 insns = get_insns ();
4000 end_sequence ();
4001 emit_insn (insns);
4003 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4006 return 0;
4010 /* Expand expression EXP, which is a call to the strncat builtin.
4011 Return 0 if we failed the caller should emit a normal call,
4012 otherwise try to get the result in TARGET, if convenient. */
4014 static rtx
4015 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4017 if (validate_arglist (arglist,
4018 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4020 tree result = fold_builtin_strncat (arglist);
4021 if (result)
4022 return expand_expr (result, target, mode, EXPAND_NORMAL);
4024 return 0;
4027 /* Expand expression EXP, which is a call to the strspn builtin.
4028 Return 0 if we failed the caller should emit a normal call,
4029 otherwise try to get the result in TARGET, if convenient. */
4031 static rtx
4032 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4034 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4036 tree result = fold_builtin_strspn (arglist);
4037 if (result)
4038 return expand_expr (result, target, mode, EXPAND_NORMAL);
4040 return 0;
4043 /* Expand expression EXP, which is a call to the strcspn builtin.
4044 Return 0 if we failed the caller should emit a normal call,
4045 otherwise try to get the result in TARGET, if convenient. */
4047 static rtx
4048 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4050 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4052 tree result = fold_builtin_strcspn (arglist);
4053 if (result)
4054 return expand_expr (result, target, mode, EXPAND_NORMAL);
4056 return 0;
4059 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4060 if that's convenient. */
4063 expand_builtin_saveregs (void)
4065 rtx val, seq;
4067 /* Don't do __builtin_saveregs more than once in a function.
4068 Save the result of the first call and reuse it. */
4069 if (saveregs_value != 0)
4070 return saveregs_value;
4072 /* When this function is called, it means that registers must be
4073 saved on entry to this function. So we migrate the call to the
4074 first insn of this function. */
4076 start_sequence ();
4078 /* Do whatever the machine needs done in this case. */
4079 val = targetm.calls.expand_builtin_saveregs ();
4081 seq = get_insns ();
4082 end_sequence ();
4084 saveregs_value = val;
4086 /* Put the insns after the NOTE that starts the function. If this
4087 is inside a start_sequence, make the outer-level insn chain current, so
4088 the code is placed at the start of the function. */
4089 push_topmost_sequence ();
4090 emit_insn_after (seq, entry_of_function ());
4091 pop_topmost_sequence ();
4093 return val;
4096 /* __builtin_args_info (N) returns word N of the arg space info
4097 for the current function. The number and meanings of words
4098 is controlled by the definition of CUMULATIVE_ARGS. */
4100 static rtx
4101 expand_builtin_args_info (tree arglist)
4103 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4104 int *word_ptr = (int *) &current_function_args_info;
4106 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4108 if (arglist != 0)
4110 if (!host_integerp (TREE_VALUE (arglist), 0))
4111 error ("argument of %<__builtin_args_info%> must be constant");
4112 else
4114 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4116 if (wordnum < 0 || wordnum >= nwords)
4117 error ("argument of %<__builtin_args_info%> out of range");
4118 else
4119 return GEN_INT (word_ptr[wordnum]);
4122 else
4123 error ("missing argument in %<__builtin_args_info%>");
4125 return const0_rtx;
4128 /* Expand a call to __builtin_next_arg. */
4130 static rtx
4131 expand_builtin_next_arg (void)
4133 /* Checking arguments is already done in fold_builtin_next_arg
4134 that must be called before this function. */
4135 return expand_binop (Pmode, add_optab,
4136 current_function_internal_arg_pointer,
4137 current_function_arg_offset_rtx,
4138 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4141 /* Make it easier for the backends by protecting the valist argument
4142 from multiple evaluations. */
4144 static tree
4145 stabilize_va_list (tree valist, int needs_lvalue)
4147 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4149 if (TREE_SIDE_EFFECTS (valist))
4150 valist = save_expr (valist);
4152 /* For this case, the backends will be expecting a pointer to
4153 TREE_TYPE (va_list_type_node), but it's possible we've
4154 actually been given an array (an actual va_list_type_node).
4155 So fix it. */
4156 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4158 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4159 valist = build_fold_addr_expr_with_type (valist, p1);
4162 else
4164 tree pt;
4166 if (! needs_lvalue)
4168 if (! TREE_SIDE_EFFECTS (valist))
4169 return valist;
4171 pt = build_pointer_type (va_list_type_node);
4172 valist = fold_build1 (ADDR_EXPR, pt, valist);
4173 TREE_SIDE_EFFECTS (valist) = 1;
4176 if (TREE_SIDE_EFFECTS (valist))
4177 valist = save_expr (valist);
4178 valist = build_fold_indirect_ref (valist);
4181 return valist;
4184 /* The "standard" definition of va_list is void*. */
4186 tree
4187 std_build_builtin_va_list (void)
4189 return ptr_type_node;
4192 /* The "standard" implementation of va_start: just assign `nextarg' to
4193 the variable. */
4195 void
4196 std_expand_builtin_va_start (tree valist, rtx nextarg)
4198 tree t;
4200 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4201 make_tree (ptr_type_node, nextarg));
4202 TREE_SIDE_EFFECTS (t) = 1;
4204 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4207 /* Expand ARGLIST, from a call to __builtin_va_start. */
4209 static rtx
4210 expand_builtin_va_start (tree arglist)
4212 rtx nextarg;
4213 tree chain, valist;
4215 chain = TREE_CHAIN (arglist);
4217 if (!chain)
4219 error ("too few arguments to function %<va_start%>");
4220 return const0_rtx;
4223 if (fold_builtin_next_arg (chain))
4224 return const0_rtx;
4226 nextarg = expand_builtin_next_arg ();
4227 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4229 #ifdef EXPAND_BUILTIN_VA_START
4230 EXPAND_BUILTIN_VA_START (valist, nextarg);
4231 #else
4232 std_expand_builtin_va_start (valist, nextarg);
4233 #endif
4235 return const0_rtx;
4238 /* The "standard" implementation of va_arg: read the value from the
4239 current (padded) address and increment by the (padded) size. */
4241 tree
4242 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4244 tree addr, t, type_size, rounded_size, valist_tmp;
4245 unsigned HOST_WIDE_INT align, boundary;
4246 bool indirect;
4248 #ifdef ARGS_GROW_DOWNWARD
4249 /* All of the alignment and movement below is for args-grow-up machines.
4250 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4251 implement their own specialized gimplify_va_arg_expr routines. */
4252 gcc_unreachable ();
4253 #endif
4255 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4256 if (indirect)
4257 type = build_pointer_type (type);
4259 align = PARM_BOUNDARY / BITS_PER_UNIT;
4260 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4262 /* Hoist the valist value into a temporary for the moment. */
4263 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4265 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4266 requires greater alignment, we must perform dynamic alignment. */
4267 if (boundary > align
4268 && !integer_zerop (TYPE_SIZE (type)))
4270 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4271 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4272 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4273 gimplify_and_add (t, pre_p);
4275 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4276 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4277 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4278 gimplify_and_add (t, pre_p);
4280 else
4281 boundary = align;
4283 /* If the actual alignment is less than the alignment of the type,
4284 adjust the type accordingly so that we don't assume strict alignment
4285 when deferencing the pointer. */
4286 boundary *= BITS_PER_UNIT;
4287 if (boundary < TYPE_ALIGN (type))
4289 type = build_variant_type_copy (type);
4290 TYPE_ALIGN (type) = boundary;
4293 /* Compute the rounded size of the type. */
4294 type_size = size_in_bytes (type);
4295 rounded_size = round_up (type_size, align);
4297 /* Reduce rounded_size so it's sharable with the postqueue. */
4298 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4300 /* Get AP. */
4301 addr = valist_tmp;
4302 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4304 /* Small args are padded downward. */
4305 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4306 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4307 size_binop (MINUS_EXPR, rounded_size, type_size));
4308 t = fold_convert (TREE_TYPE (addr), t);
4309 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4312 /* Compute new value for AP. */
4313 t = fold_convert (TREE_TYPE (valist), rounded_size);
4314 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4315 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4316 gimplify_and_add (t, pre_p);
4318 addr = fold_convert (build_pointer_type (type), addr);
4320 if (indirect)
4321 addr = build_va_arg_indirect_ref (addr);
4323 return build_va_arg_indirect_ref (addr);
4326 /* Build an indirect-ref expression over the given TREE, which represents a
4327 piece of a va_arg() expansion. */
4328 tree
4329 build_va_arg_indirect_ref (tree addr)
4331 addr = build_fold_indirect_ref (addr);
4333 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4334 mf_mark (addr);
4336 return addr;
4339 /* Return a dummy expression of type TYPE in order to keep going after an
4340 error. */
4342 static tree
4343 dummy_object (tree type)
4345 tree t = build_int_cst (build_pointer_type (type), 0);
4346 return build1 (INDIRECT_REF, type, t);
4349 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4350 builtin function, but a very special sort of operator. */
4352 enum gimplify_status
4353 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4355 tree promoted_type, want_va_type, have_va_type;
4356 tree valist = TREE_OPERAND (*expr_p, 0);
4357 tree type = TREE_TYPE (*expr_p);
4358 tree t;
4360 /* Verify that valist is of the proper type. */
4361 want_va_type = va_list_type_node;
4362 have_va_type = TREE_TYPE (valist);
4364 if (have_va_type == error_mark_node)
4365 return GS_ERROR;
4367 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4369 /* If va_list is an array type, the argument may have decayed
4370 to a pointer type, e.g. by being passed to another function.
4371 In that case, unwrap both types so that we can compare the
4372 underlying records. */
4373 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4374 || POINTER_TYPE_P (have_va_type))
4376 want_va_type = TREE_TYPE (want_va_type);
4377 have_va_type = TREE_TYPE (have_va_type);
4381 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4383 error ("first argument to %<va_arg%> not of type %<va_list%>");
4384 return GS_ERROR;
4387 /* Generate a diagnostic for requesting data of a type that cannot
4388 be passed through `...' due to type promotion at the call site. */
4389 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4390 != type)
4392 static bool gave_help;
4394 /* Unfortunately, this is merely undefined, rather than a constraint
4395 violation, so we cannot make this an error. If this call is never
4396 executed, the program is still strictly conforming. */
4397 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4398 type, promoted_type);
4399 if (! gave_help)
4401 gave_help = true;
4402 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4403 promoted_type, type);
4406 /* We can, however, treat "undefined" any way we please.
4407 Call abort to encourage the user to fix the program. */
4408 inform ("if this code is reached, the program will abort");
4409 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4410 NULL);
4411 append_to_statement_list (t, pre_p);
4413 /* This is dead code, but go ahead and finish so that the
4414 mode of the result comes out right. */
4415 *expr_p = dummy_object (type);
4416 return GS_ALL_DONE;
4418 else
4420 /* Make it easier for the backends by protecting the valist argument
4421 from multiple evaluations. */
4422 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4424 /* For this case, the backends will be expecting a pointer to
4425 TREE_TYPE (va_list_type_node), but it's possible we've
4426 actually been given an array (an actual va_list_type_node).
4427 So fix it. */
4428 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4430 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4431 valist = build_fold_addr_expr_with_type (valist, p1);
4433 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4435 else
4436 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4438 if (!targetm.gimplify_va_arg_expr)
4439 /* FIXME:Once most targets are converted we should merely
4440 assert this is non-null. */
4441 return GS_ALL_DONE;
4443 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4444 return GS_OK;
4448 /* Expand ARGLIST, from a call to __builtin_va_end. */
4450 static rtx
4451 expand_builtin_va_end (tree arglist)
4453 tree valist = TREE_VALUE (arglist);
4455 /* Evaluate for side effects, if needed. I hate macros that don't
4456 do that. */
4457 if (TREE_SIDE_EFFECTS (valist))
4458 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4460 return const0_rtx;
4463 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4464 builtin rather than just as an assignment in stdarg.h because of the
4465 nastiness of array-type va_list types. */
4467 static rtx
4468 expand_builtin_va_copy (tree arglist)
4470 tree dst, src, t;
4472 dst = TREE_VALUE (arglist);
4473 src = TREE_VALUE (TREE_CHAIN (arglist));
4475 dst = stabilize_va_list (dst, 1);
4476 src = stabilize_va_list (src, 0);
4478 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4480 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4481 TREE_SIDE_EFFECTS (t) = 1;
4482 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4484 else
4486 rtx dstb, srcb, size;
4488 /* Evaluate to pointers. */
4489 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4490 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4491 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4492 VOIDmode, EXPAND_NORMAL);
4494 dstb = convert_memory_address (Pmode, dstb);
4495 srcb = convert_memory_address (Pmode, srcb);
4497 /* "Dereference" to BLKmode memories. */
4498 dstb = gen_rtx_MEM (BLKmode, dstb);
4499 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4500 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4501 srcb = gen_rtx_MEM (BLKmode, srcb);
4502 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4503 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4505 /* Copy. */
4506 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4509 return const0_rtx;
4512 /* Expand a call to one of the builtin functions __builtin_frame_address or
4513 __builtin_return_address. */
4515 static rtx
4516 expand_builtin_frame_address (tree fndecl, tree arglist)
4518 /* The argument must be a nonnegative integer constant.
4519 It counts the number of frames to scan up the stack.
4520 The value is the return address saved in that frame. */
4521 if (arglist == 0)
4522 /* Warning about missing arg was already issued. */
4523 return const0_rtx;
4524 else if (! host_integerp (TREE_VALUE (arglist), 1))
4526 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4527 error ("invalid argument to %<__builtin_frame_address%>");
4528 else
4529 error ("invalid argument to %<__builtin_return_address%>");
4530 return const0_rtx;
4532 else
4534 rtx tem
4535 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4536 tree_low_cst (TREE_VALUE (arglist), 1));
4538 /* Some ports cannot access arbitrary stack frames. */
4539 if (tem == NULL)
4541 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4542 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4543 else
4544 warning (0, "unsupported argument to %<__builtin_return_address%>");
4545 return const0_rtx;
4548 /* For __builtin_frame_address, return what we've got. */
4549 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4550 return tem;
4552 if (!REG_P (tem)
4553 && ! CONSTANT_P (tem))
4554 tem = copy_to_mode_reg (Pmode, tem);
4555 return tem;
4559 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4560 we failed and the caller should emit a normal call, otherwise try to get
4561 the result in TARGET, if convenient. */
4563 static rtx
4564 expand_builtin_alloca (tree arglist, rtx target)
4566 rtx op0;
4567 rtx result;
4569 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4570 should always expand to function calls. These can be intercepted
4571 in libmudflap. */
4572 if (flag_mudflap)
4573 return 0;
4575 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4576 return 0;
4578 /* Compute the argument. */
4579 op0 = expand_normal (TREE_VALUE (arglist));
4581 /* Allocate the desired space. */
4582 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4583 result = convert_memory_address (ptr_mode, result);
4585 return result;
4588 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4589 Return 0 if a normal call should be emitted rather than expanding the
4590 function in-line. If convenient, the result should be placed in TARGET.
4591 SUBTARGET may be used as the target for computing one of EXP's operands. */
4593 static rtx
4594 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4595 rtx subtarget, optab op_optab)
4597 rtx op0;
4598 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4599 return 0;
4601 /* Compute the argument. */
4602 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4603 /* Compute op, into TARGET if possible.
4604 Set TARGET to wherever the result comes back. */
4605 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4606 op_optab, op0, target, 1);
4607 gcc_assert (target);
4609 return convert_to_mode (target_mode, target, 0);
4612 /* If the string passed to fputs is a constant and is one character
4613 long, we attempt to transform this call into __builtin_fputc(). */
4615 static rtx
4616 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4618 /* Verify the arguments in the original call. */
4619 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4621 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4622 unlocked, NULL_TREE);
4623 if (result)
4624 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4626 return 0;
4629 /* Expand a call to __builtin_expect. We return our argument and emit a
4630 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4631 a non-jump context. */
4633 static rtx
4634 expand_builtin_expect (tree arglist, rtx target)
4636 tree exp, c;
4637 rtx note, rtx_c;
4639 if (arglist == NULL_TREE
4640 || TREE_CHAIN (arglist) == NULL_TREE)
4641 return const0_rtx;
4642 exp = TREE_VALUE (arglist);
4643 c = TREE_VALUE (TREE_CHAIN (arglist));
4645 if (TREE_CODE (c) != INTEGER_CST)
4647 error ("second argument to %<__builtin_expect%> must be a constant");
4648 c = integer_zero_node;
4651 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4653 /* Don't bother with expected value notes for integral constants. */
4654 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4656 /* We do need to force this into a register so that we can be
4657 moderately sure to be able to correctly interpret the branch
4658 condition later. */
4659 target = force_reg (GET_MODE (target), target);
4661 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4663 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4664 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4667 return target;
4670 /* Like expand_builtin_expect, except do this in a jump context. This is
4671 called from do_jump if the conditional is a __builtin_expect. Return either
4672 a list of insns to emit the jump or NULL if we cannot optimize
4673 __builtin_expect. We need to optimize this at jump time so that machines
4674 like the PowerPC don't turn the test into a SCC operation, and then jump
4675 based on the test being 0/1. */
4678 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4680 tree arglist = TREE_OPERAND (exp, 1);
4681 tree arg0 = TREE_VALUE (arglist);
4682 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4683 rtx ret = NULL_RTX;
4685 /* Only handle __builtin_expect (test, 0) and
4686 __builtin_expect (test, 1). */
4687 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4688 && (integer_zerop (arg1) || integer_onep (arg1)))
4690 rtx insn, drop_through_label, temp;
4692 /* Expand the jump insns. */
4693 start_sequence ();
4694 do_jump (arg0, if_false_label, if_true_label);
4695 ret = get_insns ();
4697 drop_through_label = get_last_insn ();
4698 if (drop_through_label && NOTE_P (drop_through_label))
4699 drop_through_label = prev_nonnote_insn (drop_through_label);
4700 if (drop_through_label && !LABEL_P (drop_through_label))
4701 drop_through_label = NULL_RTX;
4702 end_sequence ();
4704 if (! if_true_label)
4705 if_true_label = drop_through_label;
4706 if (! if_false_label)
4707 if_false_label = drop_through_label;
4709 /* Go through and add the expect's to each of the conditional jumps. */
4710 insn = ret;
4711 while (insn != NULL_RTX)
4713 rtx next = NEXT_INSN (insn);
4715 if (JUMP_P (insn) && any_condjump_p (insn))
4717 rtx ifelse = SET_SRC (pc_set (insn));
4718 rtx then_dest = XEXP (ifelse, 1);
4719 rtx else_dest = XEXP (ifelse, 2);
4720 int taken = -1;
4722 /* First check if we recognize any of the labels. */
4723 if (GET_CODE (then_dest) == LABEL_REF
4724 && XEXP (then_dest, 0) == if_true_label)
4725 taken = 1;
4726 else if (GET_CODE (then_dest) == LABEL_REF
4727 && XEXP (then_dest, 0) == if_false_label)
4728 taken = 0;
4729 else if (GET_CODE (else_dest) == LABEL_REF
4730 && XEXP (else_dest, 0) == if_false_label)
4731 taken = 1;
4732 else if (GET_CODE (else_dest) == LABEL_REF
4733 && XEXP (else_dest, 0) == if_true_label)
4734 taken = 0;
4735 /* Otherwise check where we drop through. */
4736 else if (else_dest == pc_rtx)
4738 if (next && NOTE_P (next))
4739 next = next_nonnote_insn (next);
4741 if (next && JUMP_P (next)
4742 && any_uncondjump_p (next))
4743 temp = XEXP (SET_SRC (pc_set (next)), 0);
4744 else
4745 temp = next;
4747 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4748 else that can't possibly match either target label. */
4749 if (temp == if_false_label)
4750 taken = 1;
4751 else if (temp == if_true_label)
4752 taken = 0;
4754 else if (then_dest == pc_rtx)
4756 if (next && NOTE_P (next))
4757 next = next_nonnote_insn (next);
4759 if (next && JUMP_P (next)
4760 && any_uncondjump_p (next))
4761 temp = XEXP (SET_SRC (pc_set (next)), 0);
4762 else
4763 temp = next;
4765 if (temp == if_false_label)
4766 taken = 0;
4767 else if (temp == if_true_label)
4768 taken = 1;
4771 if (taken != -1)
4773 /* If the test is expected to fail, reverse the
4774 probabilities. */
4775 if (integer_zerop (arg1))
4776 taken = 1 - taken;
4777 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4781 insn = next;
4785 return ret;
4788 void
4789 expand_builtin_trap (void)
4791 #ifdef HAVE_trap
4792 if (HAVE_trap)
4793 emit_insn (gen_trap ());
4794 else
4795 #endif
4796 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4797 emit_barrier ();
4800 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4801 Return 0 if a normal call should be emitted rather than expanding
4802 the function inline. If convenient, the result should be placed
4803 in TARGET. SUBTARGET may be used as the target for computing
4804 the operand. */
4806 static rtx
4807 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4809 enum machine_mode mode;
4810 tree arg;
4811 rtx op0;
4813 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4814 return 0;
4816 arg = TREE_VALUE (arglist);
4817 mode = TYPE_MODE (TREE_TYPE (arg));
4818 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4819 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4822 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4823 Return NULL is a normal call should be emitted rather than expanding the
4824 function inline. If convenient, the result should be placed in TARGET.
4825 SUBTARGET may be used as the target for computing the operand. */
4827 static rtx
4828 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4830 rtx op0, op1;
4831 tree arg;
4833 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4834 return 0;
4836 arg = TREE_VALUE (arglist);
4837 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4839 arg = TREE_VALUE (TREE_CHAIN (arglist));
4840 op1 = expand_normal (arg);
4842 return expand_copysign (op0, op1, target);
4845 /* Create a new constant string literal and return a char* pointer to it.
4846 The STRING_CST value is the LEN characters at STR. */
4847 tree
4848 build_string_literal (int len, const char *str)
4850 tree t, elem, index, type;
4852 t = build_string (len, str);
4853 elem = build_type_variant (char_type_node, 1, 0);
4854 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4855 type = build_array_type (elem, index);
4856 TREE_TYPE (t) = type;
4857 TREE_CONSTANT (t) = 1;
4858 TREE_INVARIANT (t) = 1;
4859 TREE_READONLY (t) = 1;
4860 TREE_STATIC (t) = 1;
4862 type = build_pointer_type (type);
4863 t = build1 (ADDR_EXPR, type, t);
4865 type = build_pointer_type (elem);
4866 t = build1 (NOP_EXPR, type, t);
4867 return t;
4870 /* Expand EXP, a call to printf or printf_unlocked.
4871 Return 0 if a normal call should be emitted rather than transforming
4872 the function inline. If convenient, the result should be placed in
4873 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4874 call. */
4875 static rtx
4876 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4877 bool unlocked)
4879 tree arglist = TREE_OPERAND (exp, 1);
4880 /* If we're using an unlocked function, assume the other unlocked
4881 functions exist explicitly. */
4882 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4883 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4884 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4885 : implicit_built_in_decls[BUILT_IN_PUTS];
4886 const char *fmt_str;
4887 tree fn, fmt, arg;
4889 /* If the return value is used, don't do the transformation. */
4890 if (target != const0_rtx)
4891 return 0;
4893 /* Verify the required arguments in the original call. */
4894 if (! arglist)
4895 return 0;
4896 fmt = TREE_VALUE (arglist);
4897 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4898 return 0;
4899 arglist = TREE_CHAIN (arglist);
4901 /* Check whether the format is a literal string constant. */
4902 fmt_str = c_getstr (fmt);
4903 if (fmt_str == NULL)
4904 return 0;
4906 if (!init_target_chars())
4907 return 0;
4909 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4910 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4912 if (! arglist
4913 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4914 || TREE_CHAIN (arglist))
4915 return 0;
4916 fn = fn_puts;
4918 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4919 else if (strcmp (fmt_str, target_percent_c) == 0)
4921 if (! arglist
4922 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4923 || TREE_CHAIN (arglist))
4924 return 0;
4925 fn = fn_putchar;
4927 else
4929 /* We can't handle anything else with % args or %% ... yet. */
4930 if (strchr (fmt_str, target_percent))
4931 return 0;
4933 if (arglist)
4934 return 0;
4936 /* If the format specifier was "", printf does nothing. */
4937 if (fmt_str[0] == '\0')
4938 return const0_rtx;
4939 /* If the format specifier has length of 1, call putchar. */
4940 if (fmt_str[1] == '\0')
4942 /* Given printf("c"), (where c is any one character,)
4943 convert "c"[0] to an int and pass that to the replacement
4944 function. */
4945 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4946 arglist = build_tree_list (NULL_TREE, arg);
4947 fn = fn_putchar;
4949 else
4951 /* If the format specifier was "string\n", call puts("string"). */
4952 size_t len = strlen (fmt_str);
4953 if ((unsigned char)fmt_str[len - 1] == target_newline)
4955 /* Create a NUL-terminated string that's one char shorter
4956 than the original, stripping off the trailing '\n'. */
4957 char *newstr = alloca (len);
4958 memcpy (newstr, fmt_str, len - 1);
4959 newstr[len - 1] = 0;
4961 arg = build_string_literal (len, newstr);
4962 arglist = build_tree_list (NULL_TREE, arg);
4963 fn = fn_puts;
4965 else
4966 /* We'd like to arrange to call fputs(string,stdout) here,
4967 but we need stdout and don't have a way to get it yet. */
4968 return 0;
4972 if (!fn)
4973 return 0;
4974 fn = build_function_call_expr (fn, arglist);
4975 if (TREE_CODE (fn) == CALL_EXPR)
4976 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4977 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4980 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4981 Return 0 if a normal call should be emitted rather than transforming
4982 the function inline. If convenient, the result should be placed in
4983 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4984 call. */
4985 static rtx
4986 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4987 bool unlocked)
4989 tree arglist = TREE_OPERAND (exp, 1);
4990 /* If we're using an unlocked function, assume the other unlocked
4991 functions exist explicitly. */
4992 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4993 : implicit_built_in_decls[BUILT_IN_FPUTC];
4994 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4995 : implicit_built_in_decls[BUILT_IN_FPUTS];
4996 const char *fmt_str;
4997 tree fn, fmt, fp, arg;
4999 /* If the return value is used, don't do the transformation. */
5000 if (target != const0_rtx)
5001 return 0;
5003 /* Verify the required arguments in the original call. */
5004 if (! arglist)
5005 return 0;
5006 fp = TREE_VALUE (arglist);
5007 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5008 return 0;
5009 arglist = TREE_CHAIN (arglist);
5010 if (! arglist)
5011 return 0;
5012 fmt = TREE_VALUE (arglist);
5013 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5014 return 0;
5015 arglist = TREE_CHAIN (arglist);
5017 /* Check whether the format is a literal string constant. */
5018 fmt_str = c_getstr (fmt);
5019 if (fmt_str == NULL)
5020 return 0;
5022 if (!init_target_chars())
5023 return 0;
5025 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5026 if (strcmp (fmt_str, target_percent_s) == 0)
5028 if (! arglist
5029 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5030 || TREE_CHAIN (arglist))
5031 return 0;
5032 arg = TREE_VALUE (arglist);
5033 arglist = build_tree_list (NULL_TREE, fp);
5034 arglist = tree_cons (NULL_TREE, arg, arglist);
5035 fn = fn_fputs;
5037 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5038 else if (strcmp (fmt_str, target_percent_c) == 0)
5040 if (! arglist
5041 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5042 || TREE_CHAIN (arglist))
5043 return 0;
5044 arg = TREE_VALUE (arglist);
5045 arglist = build_tree_list (NULL_TREE, fp);
5046 arglist = tree_cons (NULL_TREE, arg, arglist);
5047 fn = fn_fputc;
5049 else
5051 /* We can't handle anything else with % args or %% ... yet. */
5052 if (strchr (fmt_str, target_percent))
5053 return 0;
5055 if (arglist)
5056 return 0;
5058 /* If the format specifier was "", fprintf does nothing. */
5059 if (fmt_str[0] == '\0')
5061 /* Evaluate and ignore FILE* argument for side-effects. */
5062 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5063 return const0_rtx;
5066 /* When "string" doesn't contain %, replace all cases of
5067 fprintf(stream,string) with fputs(string,stream). The fputs
5068 builtin will take care of special cases like length == 1. */
5069 arglist = build_tree_list (NULL_TREE, fp);
5070 arglist = tree_cons (NULL_TREE, fmt, arglist);
5071 fn = fn_fputs;
5074 if (!fn)
5075 return 0;
5076 fn = build_function_call_expr (fn, arglist);
5077 if (TREE_CODE (fn) == CALL_EXPR)
5078 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5079 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5082 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5083 a normal call should be emitted rather than expanding the function
5084 inline. If convenient, the result should be placed in TARGET with
5085 mode MODE. */
5087 static rtx
5088 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5090 tree orig_arglist, dest, fmt;
5091 const char *fmt_str;
5093 orig_arglist = arglist;
5095 /* Verify the required arguments in the original call. */
5096 if (! arglist)
5097 return 0;
5098 dest = TREE_VALUE (arglist);
5099 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5100 return 0;
5101 arglist = TREE_CHAIN (arglist);
5102 if (! arglist)
5103 return 0;
5104 fmt = TREE_VALUE (arglist);
5105 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5106 return 0;
5107 arglist = TREE_CHAIN (arglist);
5109 /* Check whether the format is a literal string constant. */
5110 fmt_str = c_getstr (fmt);
5111 if (fmt_str == NULL)
5112 return 0;
5114 if (!init_target_chars())
5115 return 0;
5117 /* If the format doesn't contain % args or %%, use strcpy. */
5118 if (strchr (fmt_str, target_percent) == 0)
5120 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5121 tree exp;
5123 if (arglist || ! fn)
5124 return 0;
5125 expand_expr (build_function_call_expr (fn, orig_arglist),
5126 const0_rtx, VOIDmode, EXPAND_NORMAL);
5127 if (target == const0_rtx)
5128 return const0_rtx;
5129 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5130 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5132 /* If the format is "%s", use strcpy if the result isn't used. */
5133 else if (strcmp (fmt_str, target_percent_s) == 0)
5135 tree fn, arg, len;
5136 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5138 if (! fn)
5139 return 0;
5141 if (! arglist || TREE_CHAIN (arglist))
5142 return 0;
5143 arg = TREE_VALUE (arglist);
5144 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5145 return 0;
5147 if (target != const0_rtx)
5149 len = c_strlen (arg, 1);
5150 if (! len || TREE_CODE (len) != INTEGER_CST)
5151 return 0;
5153 else
5154 len = NULL_TREE;
5156 arglist = build_tree_list (NULL_TREE, arg);
5157 arglist = tree_cons (NULL_TREE, dest, arglist);
5158 expand_expr (build_function_call_expr (fn, arglist),
5159 const0_rtx, VOIDmode, EXPAND_NORMAL);
5161 if (target == const0_rtx)
5162 return const0_rtx;
5163 return expand_expr (len, target, mode, EXPAND_NORMAL);
5166 return 0;
5169 /* Expand a call to either the entry or exit function profiler. */
5171 static rtx
5172 expand_builtin_profile_func (bool exitp)
5174 rtx this, which;
5176 this = DECL_RTL (current_function_decl);
5177 gcc_assert (MEM_P (this));
5178 this = XEXP (this, 0);
5180 if (exitp)
5181 which = profile_function_exit_libfunc;
5182 else
5183 which = profile_function_entry_libfunc;
5185 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5186 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5188 Pmode);
5190 return const0_rtx;
5193 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5195 static rtx
5196 round_trampoline_addr (rtx tramp)
5198 rtx temp, addend, mask;
5200 /* If we don't need too much alignment, we'll have been guaranteed
5201 proper alignment by get_trampoline_type. */
5202 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5203 return tramp;
5205 /* Round address up to desired boundary. */
5206 temp = gen_reg_rtx (Pmode);
5207 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5208 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5210 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5211 temp, 0, OPTAB_LIB_WIDEN);
5212 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5213 temp, 0, OPTAB_LIB_WIDEN);
5215 return tramp;
5218 static rtx
5219 expand_builtin_init_trampoline (tree arglist)
5221 tree t_tramp, t_func, t_chain;
5222 rtx r_tramp, r_func, r_chain;
5223 #ifdef TRAMPOLINE_TEMPLATE
5224 rtx blktramp;
5225 #endif
5227 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5228 POINTER_TYPE, VOID_TYPE))
5229 return NULL_RTX;
5231 t_tramp = TREE_VALUE (arglist);
5232 arglist = TREE_CHAIN (arglist);
5233 t_func = TREE_VALUE (arglist);
5234 arglist = TREE_CHAIN (arglist);
5235 t_chain = TREE_VALUE (arglist);
5237 r_tramp = expand_normal (t_tramp);
5238 r_func = expand_normal (t_func);
5239 r_chain = expand_normal (t_chain);
5241 /* Generate insns to initialize the trampoline. */
5242 r_tramp = round_trampoline_addr (r_tramp);
5243 #ifdef TRAMPOLINE_TEMPLATE
5244 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5245 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5246 emit_block_move (blktramp, assemble_trampoline_template (),
5247 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5248 #endif
5249 trampolines_created = 1;
5250 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5252 return const0_rtx;
5255 static rtx
5256 expand_builtin_adjust_trampoline (tree arglist)
5258 rtx tramp;
5260 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5261 return NULL_RTX;
5263 tramp = expand_normal (TREE_VALUE (arglist));
5264 tramp = round_trampoline_addr (tramp);
5265 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5266 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5267 #endif
5269 return tramp;
5272 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5273 Return NULL_RTX if a normal call should be emitted rather than expanding
5274 the function in-line. EXP is the expression that is a call to the builtin
5275 function; if convenient, the result should be placed in TARGET. */
5277 static rtx
5278 expand_builtin_signbit (tree exp, rtx target)
5280 const struct real_format *fmt;
5281 enum machine_mode fmode, imode, rmode;
5282 HOST_WIDE_INT hi, lo;
5283 tree arg, arglist;
5284 int word, bitpos;
5285 rtx temp;
5287 arglist = TREE_OPERAND (exp, 1);
5288 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5289 return 0;
5291 arg = TREE_VALUE (arglist);
5292 fmode = TYPE_MODE (TREE_TYPE (arg));
5293 rmode = TYPE_MODE (TREE_TYPE (exp));
5294 fmt = REAL_MODE_FORMAT (fmode);
5296 /* For floating point formats without a sign bit, implement signbit
5297 as "ARG < 0.0". */
5298 bitpos = fmt->signbit_ro;
5299 if (bitpos < 0)
5301 /* But we can't do this if the format supports signed zero. */
5302 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5303 return 0;
5305 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5306 build_real (TREE_TYPE (arg), dconst0));
5307 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5310 temp = expand_normal (arg);
5311 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5313 imode = int_mode_for_mode (fmode);
5314 if (imode == BLKmode)
5315 return 0;
5316 temp = gen_lowpart (imode, temp);
5318 else
5320 imode = word_mode;
5321 /* Handle targets with different FP word orders. */
5322 if (FLOAT_WORDS_BIG_ENDIAN)
5323 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5324 else
5325 word = bitpos / BITS_PER_WORD;
5326 temp = operand_subword_force (temp, word, fmode);
5327 bitpos = bitpos % BITS_PER_WORD;
5330 /* Force the intermediate word_mode (or narrower) result into a
5331 register. This avoids attempting to create paradoxical SUBREGs
5332 of floating point modes below. */
5333 temp = force_reg (imode, temp);
5335 /* If the bitpos is within the "result mode" lowpart, the operation
5336 can be implement with a single bitwise AND. Otherwise, we need
5337 a right shift and an AND. */
5339 if (bitpos < GET_MODE_BITSIZE (rmode))
5341 if (bitpos < HOST_BITS_PER_WIDE_INT)
5343 hi = 0;
5344 lo = (HOST_WIDE_INT) 1 << bitpos;
5346 else
5348 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5349 lo = 0;
5352 if (imode != rmode)
5353 temp = gen_lowpart (rmode, temp);
5354 temp = expand_binop (rmode, and_optab, temp,
5355 immed_double_const (lo, hi, rmode),
5356 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5358 else
5360 /* Perform a logical right shift to place the signbit in the least
5361 significant bit, then truncate the result to the desired mode
5362 and mask just this bit. */
5363 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5364 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5365 temp = gen_lowpart (rmode, temp);
5366 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5367 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5370 return temp;
5373 /* Expand fork or exec calls. TARGET is the desired target of the
5374 call. ARGLIST is the list of arguments of the call. FN is the
5375 identificator of the actual function. IGNORE is nonzero if the
5376 value is to be ignored. */
5378 static rtx
5379 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5381 tree id, decl;
5382 tree call;
5384 /* If we are not profiling, just call the function. */
5385 if (!profile_arc_flag)
5386 return NULL_RTX;
5388 /* Otherwise call the wrapper. This should be equivalent for the rest of
5389 compiler, so the code does not diverge, and the wrapper may run the
5390 code necessary for keeping the profiling sane. */
5392 switch (DECL_FUNCTION_CODE (fn))
5394 case BUILT_IN_FORK:
5395 id = get_identifier ("__gcov_fork");
5396 break;
5398 case BUILT_IN_EXECL:
5399 id = get_identifier ("__gcov_execl");
5400 break;
5402 case BUILT_IN_EXECV:
5403 id = get_identifier ("__gcov_execv");
5404 break;
5406 case BUILT_IN_EXECLP:
5407 id = get_identifier ("__gcov_execlp");
5408 break;
5410 case BUILT_IN_EXECLE:
5411 id = get_identifier ("__gcov_execle");
5412 break;
5414 case BUILT_IN_EXECVP:
5415 id = get_identifier ("__gcov_execvp");
5416 break;
5418 case BUILT_IN_EXECVE:
5419 id = get_identifier ("__gcov_execve");
5420 break;
5422 default:
5423 gcc_unreachable ();
5426 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5427 DECL_EXTERNAL (decl) = 1;
5428 TREE_PUBLIC (decl) = 1;
5429 DECL_ARTIFICIAL (decl) = 1;
5430 TREE_NOTHROW (decl) = 1;
5431 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5432 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5433 call = build_function_call_expr (decl, arglist);
5435 return expand_call (call, target, ignore);
5439 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5440 the pointer in these functions is void*, the tree optimizers may remove
5441 casts. The mode computed in expand_builtin isn't reliable either, due
5442 to __sync_bool_compare_and_swap.
5444 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5445 group of builtins. This gives us log2 of the mode size. */
5447 static inline enum machine_mode
5448 get_builtin_sync_mode (int fcode_diff)
5450 /* The size is not negotiable, so ask not to get BLKmode in return
5451 if the target indicates that a smaller size would be better. */
5452 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5455 /* Expand the memory expression LOC and return the appropriate memory operand
5456 for the builtin_sync operations. */
5458 static rtx
5459 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5461 rtx addr, mem;
5463 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5465 /* Note that we explicitly do not want any alias information for this
5466 memory, so that we kill all other live memories. Otherwise we don't
5467 satisfy the full barrier semantics of the intrinsic. */
5468 mem = validize_mem (gen_rtx_MEM (mode, addr));
5470 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5471 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5472 MEM_VOLATILE_P (mem) = 1;
5474 return mem;
5477 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5478 ARGLIST is the operands list to the function. CODE is the rtx code
5479 that corresponds to the arithmetic or logical operation from the name;
5480 an exception here is that NOT actually means NAND. TARGET is an optional
5481 place for us to store the results; AFTER is true if this is the
5482 fetch_and_xxx form. IGNORE is true if we don't actually care about
5483 the result of the operation at all. */
5485 static rtx
5486 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5487 enum rtx_code code, bool after,
5488 rtx target, bool ignore)
5490 rtx val, mem;
5492 /* Expand the operands. */
5493 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5495 arglist = TREE_CHAIN (arglist);
5496 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5497 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5498 val = convert_to_mode (mode, val, 1);
5500 if (ignore)
5501 return expand_sync_operation (mem, val, code);
5502 else
5503 return expand_sync_fetch_operation (mem, val, code, after, target);
5506 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5507 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5508 true if this is the boolean form. TARGET is a place for us to store the
5509 results; this is NOT optional if IS_BOOL is true. */
5511 static rtx
5512 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5513 bool is_bool, rtx target)
5515 rtx old_val, new_val, mem;
5517 /* Expand the operands. */
5518 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5520 arglist = TREE_CHAIN (arglist);
5521 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5522 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5523 old_val = convert_to_mode (mode, old_val, 1);
5525 arglist = TREE_CHAIN (arglist);
5526 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5527 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5528 new_val = convert_to_mode (mode, new_val, 1);
5530 if (is_bool)
5531 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5532 else
5533 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5536 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5537 general form is actually an atomic exchange, and some targets only
5538 support a reduced form with the second argument being a constant 1.
5539 ARGLIST is the operands list to the function; TARGET is an optional
5540 place for us to store the results. */
5542 static rtx
5543 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5544 rtx target)
5546 rtx val, mem;
5548 /* Expand the operands. */
5549 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5551 arglist = TREE_CHAIN (arglist);
5552 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5553 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5554 val = convert_to_mode (mode, val, 1);
5556 return expand_sync_lock_test_and_set (mem, val, target);
5559 /* Expand the __sync_synchronize intrinsic. */
5561 static void
5562 expand_builtin_synchronize (void)
5564 tree x;
5566 #ifdef HAVE_memory_barrier
5567 if (HAVE_memory_barrier)
5569 emit_insn (gen_memory_barrier ());
5570 return;
5572 #endif
5574 /* If no explicit memory barrier instruction is available, create an
5575 empty asm stmt with a memory clobber. */
5576 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5577 tree_cons (NULL, build_string (6, "memory"), NULL));
5578 ASM_VOLATILE_P (x) = 1;
5579 expand_asm_expr (x);
5582 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5583 to the function. */
5585 static void
5586 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5588 enum insn_code icode;
5589 rtx mem, insn;
5590 rtx val = const0_rtx;
5592 /* Expand the operands. */
5593 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5595 /* If there is an explicit operation in the md file, use it. */
5596 icode = sync_lock_release[mode];
5597 if (icode != CODE_FOR_nothing)
5599 if (!insn_data[icode].operand[1].predicate (val, mode))
5600 val = force_reg (mode, val);
5602 insn = GEN_FCN (icode) (mem, val);
5603 if (insn)
5605 emit_insn (insn);
5606 return;
5610 /* Otherwise we can implement this operation by emitting a barrier
5611 followed by a store of zero. */
5612 expand_builtin_synchronize ();
5613 emit_move_insn (mem, val);
5616 /* Expand an expression EXP that calls a built-in function,
5617 with result going to TARGET if that's convenient
5618 (and in mode MODE if that's convenient).
5619 SUBTARGET may be used as the target for computing one of EXP's operands.
5620 IGNORE is nonzero if the value is to be ignored. */
5623 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5624 int ignore)
5626 tree fndecl = get_callee_fndecl (exp);
5627 tree arglist = TREE_OPERAND (exp, 1);
5628 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5629 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5631 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5632 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5634 /* When not optimizing, generate calls to library functions for a certain
5635 set of builtins. */
5636 if (!optimize
5637 && !called_as_built_in (fndecl)
5638 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5639 && fcode != BUILT_IN_ALLOCA)
5640 return expand_call (exp, target, ignore);
5642 /* The built-in function expanders test for target == const0_rtx
5643 to determine whether the function's result will be ignored. */
5644 if (ignore)
5645 target = const0_rtx;
5647 /* If the result of a pure or const built-in function is ignored, and
5648 none of its arguments are volatile, we can avoid expanding the
5649 built-in call and just evaluate the arguments for side-effects. */
5650 if (target == const0_rtx
5651 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5653 bool volatilep = false;
5654 tree arg;
5656 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5657 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5659 volatilep = true;
5660 break;
5663 if (! volatilep)
5665 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5666 expand_expr (TREE_VALUE (arg), const0_rtx,
5667 VOIDmode, EXPAND_NORMAL);
5668 return const0_rtx;
5672 switch (fcode)
5674 CASE_FLT_FN (BUILT_IN_FABS):
5675 target = expand_builtin_fabs (arglist, target, subtarget);
5676 if (target)
5677 return target;
5678 break;
5680 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5681 target = expand_builtin_copysign (arglist, target, subtarget);
5682 if (target)
5683 return target;
5684 break;
5686 /* Just do a normal library call if we were unable to fold
5687 the values. */
5688 CASE_FLT_FN (BUILT_IN_CABS):
5689 break;
5691 CASE_FLT_FN (BUILT_IN_EXP):
5692 CASE_FLT_FN (BUILT_IN_EXP10):
5693 CASE_FLT_FN (BUILT_IN_POW10):
5694 CASE_FLT_FN (BUILT_IN_EXP2):
5695 CASE_FLT_FN (BUILT_IN_EXPM1):
5696 CASE_FLT_FN (BUILT_IN_LOGB):
5697 CASE_FLT_FN (BUILT_IN_ILOGB):
5698 CASE_FLT_FN (BUILT_IN_LOG):
5699 CASE_FLT_FN (BUILT_IN_LOG10):
5700 CASE_FLT_FN (BUILT_IN_LOG2):
5701 CASE_FLT_FN (BUILT_IN_LOG1P):
5702 CASE_FLT_FN (BUILT_IN_TAN):
5703 CASE_FLT_FN (BUILT_IN_ASIN):
5704 CASE_FLT_FN (BUILT_IN_ACOS):
5705 CASE_FLT_FN (BUILT_IN_ATAN):
5706 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5707 because of possible accuracy problems. */
5708 if (! flag_unsafe_math_optimizations)
5709 break;
5710 CASE_FLT_FN (BUILT_IN_SQRT):
5711 CASE_FLT_FN (BUILT_IN_FLOOR):
5712 CASE_FLT_FN (BUILT_IN_CEIL):
5713 CASE_FLT_FN (BUILT_IN_TRUNC):
5714 CASE_FLT_FN (BUILT_IN_ROUND):
5715 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5716 CASE_FLT_FN (BUILT_IN_RINT):
5717 CASE_FLT_FN (BUILT_IN_LRINT):
5718 CASE_FLT_FN (BUILT_IN_LLRINT):
5719 target = expand_builtin_mathfn (exp, target, subtarget);
5720 if (target)
5721 return target;
5722 break;
5724 CASE_FLT_FN (BUILT_IN_LCEIL):
5725 CASE_FLT_FN (BUILT_IN_LLCEIL):
5726 CASE_FLT_FN (BUILT_IN_LFLOOR):
5727 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5728 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5729 if (target)
5730 return target;
5731 break;
5733 CASE_FLT_FN (BUILT_IN_POW):
5734 target = expand_builtin_pow (exp, target, subtarget);
5735 if (target)
5736 return target;
5737 break;
5739 CASE_FLT_FN (BUILT_IN_POWI):
5740 target = expand_builtin_powi (exp, target, subtarget);
5741 if (target)
5742 return target;
5743 break;
5745 CASE_FLT_FN (BUILT_IN_ATAN2):
5746 CASE_FLT_FN (BUILT_IN_LDEXP):
5747 CASE_FLT_FN (BUILT_IN_FMOD):
5748 CASE_FLT_FN (BUILT_IN_DREM):
5749 if (! flag_unsafe_math_optimizations)
5750 break;
5751 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5752 if (target)
5753 return target;
5754 break;
5756 CASE_FLT_FN (BUILT_IN_SIN):
5757 CASE_FLT_FN (BUILT_IN_COS):
5758 if (! flag_unsafe_math_optimizations)
5759 break;
5760 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5761 if (target)
5762 return target;
5763 break;
5765 CASE_FLT_FN (BUILT_IN_SINCOS):
5766 if (! flag_unsafe_math_optimizations)
5767 break;
5768 target = expand_builtin_sincos (exp);
5769 if (target)
5770 return target;
5771 break;
5773 case BUILT_IN_APPLY_ARGS:
5774 return expand_builtin_apply_args ();
5776 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5777 FUNCTION with a copy of the parameters described by
5778 ARGUMENTS, and ARGSIZE. It returns a block of memory
5779 allocated on the stack into which is stored all the registers
5780 that might possibly be used for returning the result of a
5781 function. ARGUMENTS is the value returned by
5782 __builtin_apply_args. ARGSIZE is the number of bytes of
5783 arguments that must be copied. ??? How should this value be
5784 computed? We'll also need a safe worst case value for varargs
5785 functions. */
5786 case BUILT_IN_APPLY:
5787 if (!validate_arglist (arglist, POINTER_TYPE,
5788 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5789 && !validate_arglist (arglist, REFERENCE_TYPE,
5790 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5791 return const0_rtx;
5792 else
5794 int i;
5795 tree t;
5796 rtx ops[3];
5798 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5799 ops[i] = expand_normal (TREE_VALUE (t));
5801 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5804 /* __builtin_return (RESULT) causes the function to return the
5805 value described by RESULT. RESULT is address of the block of
5806 memory returned by __builtin_apply. */
5807 case BUILT_IN_RETURN:
5808 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5809 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5810 return const0_rtx;
5812 case BUILT_IN_SAVEREGS:
5813 return expand_builtin_saveregs ();
5815 case BUILT_IN_ARGS_INFO:
5816 return expand_builtin_args_info (arglist);
5818 /* Return the address of the first anonymous stack arg. */
5819 case BUILT_IN_NEXT_ARG:
5820 if (fold_builtin_next_arg (arglist))
5821 return const0_rtx;
5822 return expand_builtin_next_arg ();
5824 case BUILT_IN_CLASSIFY_TYPE:
5825 return expand_builtin_classify_type (arglist);
5827 case BUILT_IN_CONSTANT_P:
5828 return const0_rtx;
5830 case BUILT_IN_FRAME_ADDRESS:
5831 case BUILT_IN_RETURN_ADDRESS:
5832 return expand_builtin_frame_address (fndecl, arglist);
5834 /* Returns the address of the area where the structure is returned.
5835 0 otherwise. */
5836 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5837 if (arglist != 0
5838 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5839 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5840 return const0_rtx;
5841 else
5842 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5844 case BUILT_IN_ALLOCA:
5845 target = expand_builtin_alloca (arglist, target);
5846 if (target)
5847 return target;
5848 break;
5850 case BUILT_IN_STACK_SAVE:
5851 return expand_stack_save ();
5853 case BUILT_IN_STACK_RESTORE:
5854 expand_stack_restore (TREE_VALUE (arglist));
5855 return const0_rtx;
5857 CASE_INT_FN (BUILT_IN_FFS):
5858 case BUILT_IN_FFSIMAX:
5859 target = expand_builtin_unop (target_mode, arglist, target,
5860 subtarget, ffs_optab);
5861 if (target)
5862 return target;
5863 break;
5865 CASE_INT_FN (BUILT_IN_CLZ):
5866 case BUILT_IN_CLZIMAX:
5867 target = expand_builtin_unop (target_mode, arglist, target,
5868 subtarget, clz_optab);
5869 if (target)
5870 return target;
5871 break;
5873 CASE_INT_FN (BUILT_IN_CTZ):
5874 case BUILT_IN_CTZIMAX:
5875 target = expand_builtin_unop (target_mode, arglist, target,
5876 subtarget, ctz_optab);
5877 if (target)
5878 return target;
5879 break;
5881 CASE_INT_FN (BUILT_IN_POPCOUNT):
5882 case BUILT_IN_POPCOUNTIMAX:
5883 target = expand_builtin_unop (target_mode, arglist, target,
5884 subtarget, popcount_optab);
5885 if (target)
5886 return target;
5887 break;
5889 CASE_INT_FN (BUILT_IN_PARITY):
5890 case BUILT_IN_PARITYIMAX:
5891 target = expand_builtin_unop (target_mode, arglist, target,
5892 subtarget, parity_optab);
5893 if (target)
5894 return target;
5895 break;
5897 case BUILT_IN_STRLEN:
5898 target = expand_builtin_strlen (arglist, target, target_mode);
5899 if (target)
5900 return target;
5901 break;
5903 case BUILT_IN_STRCPY:
5904 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5905 if (target)
5906 return target;
5907 break;
5909 case BUILT_IN_STRNCPY:
5910 target = expand_builtin_strncpy (exp, target, mode);
5911 if (target)
5912 return target;
5913 break;
5915 case BUILT_IN_STPCPY:
5916 target = expand_builtin_stpcpy (exp, target, mode);
5917 if (target)
5918 return target;
5919 break;
5921 case BUILT_IN_STRCAT:
5922 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5923 if (target)
5924 return target;
5925 break;
5927 case BUILT_IN_STRNCAT:
5928 target = expand_builtin_strncat (arglist, target, mode);
5929 if (target)
5930 return target;
5931 break;
5933 case BUILT_IN_STRSPN:
5934 target = expand_builtin_strspn (arglist, target, mode);
5935 if (target)
5936 return target;
5937 break;
5939 case BUILT_IN_STRCSPN:
5940 target = expand_builtin_strcspn (arglist, target, mode);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_STRSTR:
5946 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_STRPBRK:
5952 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_INDEX:
5958 case BUILT_IN_STRCHR:
5959 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5960 if (target)
5961 return target;
5962 break;
5964 case BUILT_IN_RINDEX:
5965 case BUILT_IN_STRRCHR:
5966 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5967 if (target)
5968 return target;
5969 break;
5971 case BUILT_IN_MEMCPY:
5972 target = expand_builtin_memcpy (exp, target, mode);
5973 if (target)
5974 return target;
5975 break;
5977 case BUILT_IN_MEMPCPY:
5978 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5979 if (target)
5980 return target;
5981 break;
5983 case BUILT_IN_MEMMOVE:
5984 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5985 mode, exp);
5986 if (target)
5987 return target;
5988 break;
5990 case BUILT_IN_BCOPY:
5991 target = expand_builtin_bcopy (exp);
5992 if (target)
5993 return target;
5994 break;
5996 case BUILT_IN_MEMSET:
5997 target = expand_builtin_memset (arglist, target, mode, exp);
5998 if (target)
5999 return target;
6000 break;
6002 case BUILT_IN_BZERO:
6003 target = expand_builtin_bzero (exp);
6004 if (target)
6005 return target;
6006 break;
6008 case BUILT_IN_STRCMP:
6009 target = expand_builtin_strcmp (exp, target, mode);
6010 if (target)
6011 return target;
6012 break;
6014 case BUILT_IN_STRNCMP:
6015 target = expand_builtin_strncmp (exp, target, mode);
6016 if (target)
6017 return target;
6018 break;
6020 case BUILT_IN_BCMP:
6021 case BUILT_IN_MEMCMP:
6022 target = expand_builtin_memcmp (exp, arglist, target, mode);
6023 if (target)
6024 return target;
6025 break;
6027 case BUILT_IN_SETJMP:
6028 /* This should have been lowered to the builtins below. */
6029 gcc_unreachable ();
6031 case BUILT_IN_SETJMP_SETUP:
6032 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6033 and the receiver label. */
6034 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6036 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6037 VOIDmode, EXPAND_NORMAL);
6038 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6039 rtx label_r = label_rtx (label);
6041 /* This is copied from the handling of non-local gotos. */
6042 expand_builtin_setjmp_setup (buf_addr, label_r);
6043 nonlocal_goto_handler_labels
6044 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6045 nonlocal_goto_handler_labels);
6046 /* ??? Do not let expand_label treat us as such since we would
6047 not want to be both on the list of non-local labels and on
6048 the list of forced labels. */
6049 FORCED_LABEL (label) = 0;
6050 return const0_rtx;
6052 break;
6054 case BUILT_IN_SETJMP_DISPATCHER:
6055 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6056 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6058 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6059 rtx label_r = label_rtx (label);
6061 /* Remove the dispatcher label from the list of non-local labels
6062 since the receiver labels have been added to it above. */
6063 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6064 return const0_rtx;
6066 break;
6068 case BUILT_IN_SETJMP_RECEIVER:
6069 /* __builtin_setjmp_receiver is passed the receiver label. */
6070 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6072 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6073 rtx label_r = label_rtx (label);
6075 expand_builtin_setjmp_receiver (label_r);
6076 return const0_rtx;
6078 break;
6080 /* __builtin_longjmp is passed a pointer to an array of five words.
6081 It's similar to the C library longjmp function but works with
6082 __builtin_setjmp above. */
6083 case BUILT_IN_LONGJMP:
6084 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6086 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6087 VOIDmode, EXPAND_NORMAL);
6088 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6090 if (value != const1_rtx)
6092 error ("%<__builtin_longjmp%> second argument must be 1");
6093 return const0_rtx;
6096 expand_builtin_longjmp (buf_addr, value);
6097 return const0_rtx;
6099 break;
6101 case BUILT_IN_NONLOCAL_GOTO:
6102 target = expand_builtin_nonlocal_goto (arglist);
6103 if (target)
6104 return target;
6105 break;
6107 /* This updates the setjmp buffer that is its argument with the value
6108 of the current stack pointer. */
6109 case BUILT_IN_UPDATE_SETJMP_BUF:
6110 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6112 rtx buf_addr
6113 = expand_normal (TREE_VALUE (arglist));
6115 expand_builtin_update_setjmp_buf (buf_addr);
6116 return const0_rtx;
6118 break;
6120 case BUILT_IN_TRAP:
6121 expand_builtin_trap ();
6122 return const0_rtx;
6124 case BUILT_IN_PRINTF:
6125 target = expand_builtin_printf (exp, target, mode, false);
6126 if (target)
6127 return target;
6128 break;
6130 case BUILT_IN_PRINTF_UNLOCKED:
6131 target = expand_builtin_printf (exp, target, mode, true);
6132 if (target)
6133 return target;
6134 break;
6136 case BUILT_IN_FPUTS:
6137 target = expand_builtin_fputs (arglist, target, false);
6138 if (target)
6139 return target;
6140 break;
6141 case BUILT_IN_FPUTS_UNLOCKED:
6142 target = expand_builtin_fputs (arglist, target, true);
6143 if (target)
6144 return target;
6145 break;
6147 case BUILT_IN_FPRINTF:
6148 target = expand_builtin_fprintf (exp, target, mode, false);
6149 if (target)
6150 return target;
6151 break;
6153 case BUILT_IN_FPRINTF_UNLOCKED:
6154 target = expand_builtin_fprintf (exp, target, mode, true);
6155 if (target)
6156 return target;
6157 break;
6159 case BUILT_IN_SPRINTF:
6160 target = expand_builtin_sprintf (arglist, target, mode);
6161 if (target)
6162 return target;
6163 break;
6165 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6166 target = expand_builtin_signbit (exp, target);
6167 if (target)
6168 return target;
6169 break;
6171 /* Various hooks for the DWARF 2 __throw routine. */
6172 case BUILT_IN_UNWIND_INIT:
6173 expand_builtin_unwind_init ();
6174 return const0_rtx;
6175 case BUILT_IN_DWARF_CFA:
6176 return virtual_cfa_rtx;
6177 #ifdef DWARF2_UNWIND_INFO
6178 case BUILT_IN_DWARF_SP_COLUMN:
6179 return expand_builtin_dwarf_sp_column ();
6180 case BUILT_IN_INIT_DWARF_REG_SIZES:
6181 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6182 return const0_rtx;
6183 #endif
6184 case BUILT_IN_FROB_RETURN_ADDR:
6185 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6186 case BUILT_IN_EXTRACT_RETURN_ADDR:
6187 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6188 case BUILT_IN_EH_RETURN:
6189 expand_builtin_eh_return (TREE_VALUE (arglist),
6190 TREE_VALUE (TREE_CHAIN (arglist)));
6191 return const0_rtx;
6192 #ifdef EH_RETURN_DATA_REGNO
6193 case BUILT_IN_EH_RETURN_DATA_REGNO:
6194 return expand_builtin_eh_return_data_regno (arglist);
6195 #endif
6196 case BUILT_IN_EXTEND_POINTER:
6197 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6199 case BUILT_IN_VA_START:
6200 case BUILT_IN_STDARG_START:
6201 return expand_builtin_va_start (arglist);
6202 case BUILT_IN_VA_END:
6203 return expand_builtin_va_end (arglist);
6204 case BUILT_IN_VA_COPY:
6205 return expand_builtin_va_copy (arglist);
6206 case BUILT_IN_EXPECT:
6207 return expand_builtin_expect (arglist, target);
6208 case BUILT_IN_PREFETCH:
6209 expand_builtin_prefetch (arglist);
6210 return const0_rtx;
6212 case BUILT_IN_PROFILE_FUNC_ENTER:
6213 return expand_builtin_profile_func (false);
6214 case BUILT_IN_PROFILE_FUNC_EXIT:
6215 return expand_builtin_profile_func (true);
6217 case BUILT_IN_INIT_TRAMPOLINE:
6218 return expand_builtin_init_trampoline (arglist);
6219 case BUILT_IN_ADJUST_TRAMPOLINE:
6220 return expand_builtin_adjust_trampoline (arglist);
6222 case BUILT_IN_FORK:
6223 case BUILT_IN_EXECL:
6224 case BUILT_IN_EXECV:
6225 case BUILT_IN_EXECLP:
6226 case BUILT_IN_EXECLE:
6227 case BUILT_IN_EXECVP:
6228 case BUILT_IN_EXECVE:
6229 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6230 if (target)
6231 return target;
6232 break;
6234 case BUILT_IN_FETCH_AND_ADD_1:
6235 case BUILT_IN_FETCH_AND_ADD_2:
6236 case BUILT_IN_FETCH_AND_ADD_4:
6237 case BUILT_IN_FETCH_AND_ADD_8:
6238 case BUILT_IN_FETCH_AND_ADD_16:
6239 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6240 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6241 false, target, ignore);
6242 if (target)
6243 return target;
6244 break;
6246 case BUILT_IN_FETCH_AND_SUB_1:
6247 case BUILT_IN_FETCH_AND_SUB_2:
6248 case BUILT_IN_FETCH_AND_SUB_4:
6249 case BUILT_IN_FETCH_AND_SUB_8:
6250 case BUILT_IN_FETCH_AND_SUB_16:
6251 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6252 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6253 false, target, ignore);
6254 if (target)
6255 return target;
6256 break;
6258 case BUILT_IN_FETCH_AND_OR_1:
6259 case BUILT_IN_FETCH_AND_OR_2:
6260 case BUILT_IN_FETCH_AND_OR_4:
6261 case BUILT_IN_FETCH_AND_OR_8:
6262 case BUILT_IN_FETCH_AND_OR_16:
6263 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6264 target = expand_builtin_sync_operation (mode, arglist, IOR,
6265 false, target, ignore);
6266 if (target)
6267 return target;
6268 break;
6270 case BUILT_IN_FETCH_AND_AND_1:
6271 case BUILT_IN_FETCH_AND_AND_2:
6272 case BUILT_IN_FETCH_AND_AND_4:
6273 case BUILT_IN_FETCH_AND_AND_8:
6274 case BUILT_IN_FETCH_AND_AND_16:
6275 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6276 target = expand_builtin_sync_operation (mode, arglist, AND,
6277 false, target, ignore);
6278 if (target)
6279 return target;
6280 break;
6282 case BUILT_IN_FETCH_AND_XOR_1:
6283 case BUILT_IN_FETCH_AND_XOR_2:
6284 case BUILT_IN_FETCH_AND_XOR_4:
6285 case BUILT_IN_FETCH_AND_XOR_8:
6286 case BUILT_IN_FETCH_AND_XOR_16:
6287 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6288 target = expand_builtin_sync_operation (mode, arglist, XOR,
6289 false, target, ignore);
6290 if (target)
6291 return target;
6292 break;
6294 case BUILT_IN_FETCH_AND_NAND_1:
6295 case BUILT_IN_FETCH_AND_NAND_2:
6296 case BUILT_IN_FETCH_AND_NAND_4:
6297 case BUILT_IN_FETCH_AND_NAND_8:
6298 case BUILT_IN_FETCH_AND_NAND_16:
6299 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6300 target = expand_builtin_sync_operation (mode, arglist, NOT,
6301 false, target, ignore);
6302 if (target)
6303 return target;
6304 break;
6306 case BUILT_IN_ADD_AND_FETCH_1:
6307 case BUILT_IN_ADD_AND_FETCH_2:
6308 case BUILT_IN_ADD_AND_FETCH_4:
6309 case BUILT_IN_ADD_AND_FETCH_8:
6310 case BUILT_IN_ADD_AND_FETCH_16:
6311 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6312 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6313 true, target, ignore);
6314 if (target)
6315 return target;
6316 break;
6318 case BUILT_IN_SUB_AND_FETCH_1:
6319 case BUILT_IN_SUB_AND_FETCH_2:
6320 case BUILT_IN_SUB_AND_FETCH_4:
6321 case BUILT_IN_SUB_AND_FETCH_8:
6322 case BUILT_IN_SUB_AND_FETCH_16:
6323 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6324 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6325 true, target, ignore);
6326 if (target)
6327 return target;
6328 break;
6330 case BUILT_IN_OR_AND_FETCH_1:
6331 case BUILT_IN_OR_AND_FETCH_2:
6332 case BUILT_IN_OR_AND_FETCH_4:
6333 case BUILT_IN_OR_AND_FETCH_8:
6334 case BUILT_IN_OR_AND_FETCH_16:
6335 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6336 target = expand_builtin_sync_operation (mode, arglist, IOR,
6337 true, target, ignore);
6338 if (target)
6339 return target;
6340 break;
6342 case BUILT_IN_AND_AND_FETCH_1:
6343 case BUILT_IN_AND_AND_FETCH_2:
6344 case BUILT_IN_AND_AND_FETCH_4:
6345 case BUILT_IN_AND_AND_FETCH_8:
6346 case BUILT_IN_AND_AND_FETCH_16:
6347 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6348 target = expand_builtin_sync_operation (mode, arglist, AND,
6349 true, target, ignore);
6350 if (target)
6351 return target;
6352 break;
6354 case BUILT_IN_XOR_AND_FETCH_1:
6355 case BUILT_IN_XOR_AND_FETCH_2:
6356 case BUILT_IN_XOR_AND_FETCH_4:
6357 case BUILT_IN_XOR_AND_FETCH_8:
6358 case BUILT_IN_XOR_AND_FETCH_16:
6359 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6360 target = expand_builtin_sync_operation (mode, arglist, XOR,
6361 true, target, ignore);
6362 if (target)
6363 return target;
6364 break;
6366 case BUILT_IN_NAND_AND_FETCH_1:
6367 case BUILT_IN_NAND_AND_FETCH_2:
6368 case BUILT_IN_NAND_AND_FETCH_4:
6369 case BUILT_IN_NAND_AND_FETCH_8:
6370 case BUILT_IN_NAND_AND_FETCH_16:
6371 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6372 target = expand_builtin_sync_operation (mode, arglist, NOT,
6373 true, target, ignore);
6374 if (target)
6375 return target;
6376 break;
6378 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6379 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6380 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6381 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6382 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6383 if (mode == VOIDmode)
6384 mode = TYPE_MODE (boolean_type_node);
6385 if (!target || !register_operand (target, mode))
6386 target = gen_reg_rtx (mode);
6388 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6389 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6390 if (target)
6391 return target;
6392 break;
6394 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6395 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6396 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6397 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6398 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6399 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6400 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6401 if (target)
6402 return target;
6403 break;
6405 case BUILT_IN_LOCK_TEST_AND_SET_1:
6406 case BUILT_IN_LOCK_TEST_AND_SET_2:
6407 case BUILT_IN_LOCK_TEST_AND_SET_4:
6408 case BUILT_IN_LOCK_TEST_AND_SET_8:
6409 case BUILT_IN_LOCK_TEST_AND_SET_16:
6410 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6411 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6412 if (target)
6413 return target;
6414 break;
6416 case BUILT_IN_LOCK_RELEASE_1:
6417 case BUILT_IN_LOCK_RELEASE_2:
6418 case BUILT_IN_LOCK_RELEASE_4:
6419 case BUILT_IN_LOCK_RELEASE_8:
6420 case BUILT_IN_LOCK_RELEASE_16:
6421 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6422 expand_builtin_lock_release (mode, arglist);
6423 return const0_rtx;
6425 case BUILT_IN_SYNCHRONIZE:
6426 expand_builtin_synchronize ();
6427 return const0_rtx;
6429 case BUILT_IN_OBJECT_SIZE:
6430 return expand_builtin_object_size (exp);
6432 case BUILT_IN_MEMCPY_CHK:
6433 case BUILT_IN_MEMPCPY_CHK:
6434 case BUILT_IN_MEMMOVE_CHK:
6435 case BUILT_IN_MEMSET_CHK:
6436 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6437 if (target)
6438 return target;
6439 break;
6441 case BUILT_IN_STRCPY_CHK:
6442 case BUILT_IN_STPCPY_CHK:
6443 case BUILT_IN_STRNCPY_CHK:
6444 case BUILT_IN_STRCAT_CHK:
6445 case BUILT_IN_SNPRINTF_CHK:
6446 case BUILT_IN_VSNPRINTF_CHK:
6447 maybe_emit_chk_warning (exp, fcode);
6448 break;
6450 case BUILT_IN_SPRINTF_CHK:
6451 case BUILT_IN_VSPRINTF_CHK:
6452 maybe_emit_sprintf_chk_warning (exp, fcode);
6453 break;
6455 default: /* just do library call, if unknown builtin */
6456 break;
6459 /* The switch statement above can drop through to cause the function
6460 to be called normally. */
6461 return expand_call (exp, target, ignore);
6464 /* Determine whether a tree node represents a call to a built-in
6465 function. If the tree T is a call to a built-in function with
6466 the right number of arguments of the appropriate types, return
6467 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6468 Otherwise the return value is END_BUILTINS. */
6470 enum built_in_function
6471 builtin_mathfn_code (tree t)
6473 tree fndecl, arglist, parmlist;
6474 tree argtype, parmtype;
6476 if (TREE_CODE (t) != CALL_EXPR
6477 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6478 return END_BUILTINS;
6480 fndecl = get_callee_fndecl (t);
6481 if (fndecl == NULL_TREE
6482 || TREE_CODE (fndecl) != FUNCTION_DECL
6483 || ! DECL_BUILT_IN (fndecl)
6484 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6485 return END_BUILTINS;
6487 arglist = TREE_OPERAND (t, 1);
6488 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6489 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6491 /* If a function doesn't take a variable number of arguments,
6492 the last element in the list will have type `void'. */
6493 parmtype = TREE_VALUE (parmlist);
6494 if (VOID_TYPE_P (parmtype))
6496 if (arglist)
6497 return END_BUILTINS;
6498 return DECL_FUNCTION_CODE (fndecl);
6501 if (! arglist)
6502 return END_BUILTINS;
6504 argtype = TREE_TYPE (TREE_VALUE (arglist));
6506 if (SCALAR_FLOAT_TYPE_P (parmtype))
6508 if (! SCALAR_FLOAT_TYPE_P (argtype))
6509 return END_BUILTINS;
6511 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6513 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6514 return END_BUILTINS;
6516 else if (POINTER_TYPE_P (parmtype))
6518 if (! POINTER_TYPE_P (argtype))
6519 return END_BUILTINS;
6521 else if (INTEGRAL_TYPE_P (parmtype))
6523 if (! INTEGRAL_TYPE_P (argtype))
6524 return END_BUILTINS;
6526 else
6527 return END_BUILTINS;
6529 arglist = TREE_CHAIN (arglist);
6532 /* Variable-length argument list. */
6533 return DECL_FUNCTION_CODE (fndecl);
6536 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6537 constant. ARGLIST is the argument list of the call. */
6539 static tree
6540 fold_builtin_constant_p (tree arglist)
6542 if (arglist == 0)
6543 return 0;
6545 arglist = TREE_VALUE (arglist);
6547 /* We return 1 for a numeric type that's known to be a constant
6548 value at compile-time or for an aggregate type that's a
6549 literal constant. */
6550 STRIP_NOPS (arglist);
6552 /* If we know this is a constant, emit the constant of one. */
6553 if (CONSTANT_CLASS_P (arglist)
6554 || (TREE_CODE (arglist) == CONSTRUCTOR
6555 && TREE_CONSTANT (arglist)))
6556 return integer_one_node;
6557 if (TREE_CODE (arglist) == ADDR_EXPR)
6559 tree op = TREE_OPERAND (arglist, 0);
6560 if (TREE_CODE (op) == STRING_CST
6561 || (TREE_CODE (op) == ARRAY_REF
6562 && integer_zerop (TREE_OPERAND (op, 1))
6563 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6564 return integer_one_node;
6567 /* If this expression has side effects, show we don't know it to be a
6568 constant. Likewise if it's a pointer or aggregate type since in
6569 those case we only want literals, since those are only optimized
6570 when generating RTL, not later.
6571 And finally, if we are compiling an initializer, not code, we
6572 need to return a definite result now; there's not going to be any
6573 more optimization done. */
6574 if (TREE_SIDE_EFFECTS (arglist)
6575 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6576 || POINTER_TYPE_P (TREE_TYPE (arglist))
6577 || cfun == 0
6578 || folding_initializer)
6579 return integer_zero_node;
6581 return 0;
6584 /* Fold a call to __builtin_expect, if we expect that a comparison against
6585 the argument will fold to a constant. In practice, this means a true
6586 constant or the address of a non-weak symbol. ARGLIST is the argument
6587 list of the call. */
6589 static tree
6590 fold_builtin_expect (tree arglist)
6592 tree arg, inner;
6594 if (arglist == 0)
6595 return 0;
6597 arg = TREE_VALUE (arglist);
6599 /* If the argument isn't invariant, then there's nothing we can do. */
6600 if (!TREE_INVARIANT (arg))
6601 return 0;
6603 /* If we're looking at an address of a weak decl, then do not fold. */
6604 inner = arg;
6605 STRIP_NOPS (inner);
6606 if (TREE_CODE (inner) == ADDR_EXPR)
6610 inner = TREE_OPERAND (inner, 0);
6612 while (TREE_CODE (inner) == COMPONENT_REF
6613 || TREE_CODE (inner) == ARRAY_REF);
6614 if (DECL_P (inner) && DECL_WEAK (inner))
6615 return 0;
6618 /* Otherwise, ARG already has the proper type for the return value. */
6619 return arg;
6622 /* Fold a call to __builtin_classify_type. */
6624 static tree
6625 fold_builtin_classify_type (tree arglist)
6627 if (arglist == 0)
6628 return build_int_cst (NULL_TREE, no_type_class);
6630 return build_int_cst (NULL_TREE,
6631 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6634 /* Fold a call to __builtin_strlen. */
6636 static tree
6637 fold_builtin_strlen (tree arglist)
6639 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6640 return NULL_TREE;
6641 else
6643 tree len = c_strlen (TREE_VALUE (arglist), 0);
6645 if (len)
6647 /* Convert from the internal "sizetype" type to "size_t". */
6648 if (size_type_node)
6649 len = fold_convert (size_type_node, len);
6650 return len;
6653 return NULL_TREE;
6657 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6659 static tree
6660 fold_builtin_inf (tree type, int warn)
6662 REAL_VALUE_TYPE real;
6664 /* __builtin_inff is intended to be usable to define INFINITY on all
6665 targets. If an infinity is not available, INFINITY expands "to a
6666 positive constant of type float that overflows at translation
6667 time", footnote "In this case, using INFINITY will violate the
6668 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6669 Thus we pedwarn to ensure this constraint violation is
6670 diagnosed. */
6671 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6672 pedwarn ("target format does not support infinity");
6674 real_inf (&real);
6675 return build_real (type, real);
6678 /* Fold a call to __builtin_nan or __builtin_nans. */
6680 static tree
6681 fold_builtin_nan (tree arglist, tree type, int quiet)
6683 REAL_VALUE_TYPE real;
6684 const char *str;
6686 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6687 return 0;
6688 str = c_getstr (TREE_VALUE (arglist));
6689 if (!str)
6690 return 0;
6692 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6693 return 0;
6695 return build_real (type, real);
6698 /* Return true if the floating point expression T has an integer value.
6699 We also allow +Inf, -Inf and NaN to be considered integer values. */
6701 static bool
6702 integer_valued_real_p (tree t)
6704 switch (TREE_CODE (t))
6706 case FLOAT_EXPR:
6707 return true;
6709 case ABS_EXPR:
6710 case SAVE_EXPR:
6711 case NON_LVALUE_EXPR:
6712 return integer_valued_real_p (TREE_OPERAND (t, 0));
6714 case COMPOUND_EXPR:
6715 case MODIFY_EXPR:
6716 case BIND_EXPR:
6717 return integer_valued_real_p (TREE_OPERAND (t, 1));
6719 case PLUS_EXPR:
6720 case MINUS_EXPR:
6721 case MULT_EXPR:
6722 case MIN_EXPR:
6723 case MAX_EXPR:
6724 return integer_valued_real_p (TREE_OPERAND (t, 0))
6725 && integer_valued_real_p (TREE_OPERAND (t, 1));
6727 case COND_EXPR:
6728 return integer_valued_real_p (TREE_OPERAND (t, 1))
6729 && integer_valued_real_p (TREE_OPERAND (t, 2));
6731 case REAL_CST:
6732 if (! TREE_CONSTANT_OVERFLOW (t))
6734 REAL_VALUE_TYPE c, cint;
6736 c = TREE_REAL_CST (t);
6737 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6738 return real_identical (&c, &cint);
6740 break;
6742 case NOP_EXPR:
6744 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6745 if (TREE_CODE (type) == INTEGER_TYPE)
6746 return true;
6747 if (TREE_CODE (type) == REAL_TYPE)
6748 return integer_valued_real_p (TREE_OPERAND (t, 0));
6749 break;
6752 case CALL_EXPR:
6753 switch (builtin_mathfn_code (t))
6755 CASE_FLT_FN (BUILT_IN_CEIL):
6756 CASE_FLT_FN (BUILT_IN_FLOOR):
6757 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6758 CASE_FLT_FN (BUILT_IN_RINT):
6759 CASE_FLT_FN (BUILT_IN_ROUND):
6760 CASE_FLT_FN (BUILT_IN_TRUNC):
6761 return true;
6763 default:
6764 break;
6766 break;
6768 default:
6769 break;
6771 return false;
6774 /* EXP is assumed to be builtin call where truncation can be propagated
6775 across (for instance floor((double)f) == (double)floorf (f).
6776 Do the transformation. */
6778 static tree
6779 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6781 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6782 tree arg;
6784 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6785 return 0;
6787 arg = TREE_VALUE (arglist);
6788 /* Integer rounding functions are idempotent. */
6789 if (fcode == builtin_mathfn_code (arg))
6790 return arg;
6792 /* If argument is already integer valued, and we don't need to worry
6793 about setting errno, there's no need to perform rounding. */
6794 if (! flag_errno_math && integer_valued_real_p (arg))
6795 return arg;
6797 if (optimize)
6799 tree arg0 = strip_float_extensions (arg);
6800 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6801 tree newtype = TREE_TYPE (arg0);
6802 tree decl;
6804 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6805 && (decl = mathfn_built_in (newtype, fcode)))
6807 arglist =
6808 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6809 return fold_convert (ftype,
6810 build_function_call_expr (decl, arglist));
6813 return 0;
6816 /* EXP is assumed to be builtin call which can narrow the FP type of
6817 the argument, for instance lround((double)f) -> lroundf (f). */
6819 static tree
6820 fold_fixed_mathfn (tree fndecl, tree arglist)
6822 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6823 tree arg;
6825 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6826 return 0;
6828 arg = TREE_VALUE (arglist);
6830 /* If argument is already integer valued, and we don't need to worry
6831 about setting errno, there's no need to perform rounding. */
6832 if (! flag_errno_math && integer_valued_real_p (arg))
6833 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6835 if (optimize)
6837 tree ftype = TREE_TYPE (arg);
6838 tree arg0 = strip_float_extensions (arg);
6839 tree newtype = TREE_TYPE (arg0);
6840 tree decl;
6842 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6843 && (decl = mathfn_built_in (newtype, fcode)))
6845 arglist =
6846 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6847 return build_function_call_expr (decl, arglist);
6851 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6852 sizeof (long long) == sizeof (long). */
6853 if (TYPE_PRECISION (long_long_integer_type_node)
6854 == TYPE_PRECISION (long_integer_type_node))
6856 tree newfn = NULL_TREE;
6857 switch (fcode)
6859 CASE_FLT_FN (BUILT_IN_LLCEIL):
6860 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6861 break;
6863 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6864 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6865 break;
6867 CASE_FLT_FN (BUILT_IN_LLROUND):
6868 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6869 break;
6871 CASE_FLT_FN (BUILT_IN_LLRINT):
6872 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6873 break;
6875 default:
6876 break;
6879 if (newfn)
6881 tree newcall = build_function_call_expr (newfn, arglist);
6882 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6886 return 0;
6889 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6890 is the argument list, TYPE is the return type and FNDECL is the
6891 original function DECL. Return NULL_TREE if no if no simplification
6892 can be made. */
6894 static tree
6895 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6897 tree arg;
6899 if (!arglist || TREE_CHAIN (arglist))
6900 return NULL_TREE;
6902 arg = TREE_VALUE (arglist);
6903 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6904 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6905 return NULL_TREE;
6907 /* Evaluate cabs of a constant at compile-time. */
6908 if (flag_unsafe_math_optimizations
6909 && TREE_CODE (arg) == COMPLEX_CST
6910 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6911 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6912 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6913 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6915 REAL_VALUE_TYPE r, i;
6917 r = TREE_REAL_CST (TREE_REALPART (arg));
6918 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6920 real_arithmetic (&r, MULT_EXPR, &r, &r);
6921 real_arithmetic (&i, MULT_EXPR, &i, &i);
6922 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6923 if (real_sqrt (&r, TYPE_MODE (type), &r)
6924 || ! flag_trapping_math)
6925 return build_real (type, r);
6928 /* If either part is zero, cabs is fabs of the other. */
6929 if (TREE_CODE (arg) == COMPLEX_EXPR
6930 && real_zerop (TREE_OPERAND (arg, 0)))
6931 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6932 if (TREE_CODE (arg) == COMPLEX_EXPR
6933 && real_zerop (TREE_OPERAND (arg, 1)))
6934 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6936 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6937 if (TREE_CODE (arg) == NEGATE_EXPR
6938 || TREE_CODE (arg) == CONJ_EXPR)
6940 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6941 return build_function_call_expr (fndecl, arglist);
6944 /* Don't do this when optimizing for size. */
6945 if (flag_unsafe_math_optimizations
6946 && optimize && !optimize_size)
6948 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6950 if (sqrtfn != NULL_TREE)
6952 tree rpart, ipart, result, arglist;
6954 arg = builtin_save_expr (arg);
6956 rpart = fold_build1 (REALPART_EXPR, type, arg);
6957 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6959 rpart = builtin_save_expr (rpart);
6960 ipart = builtin_save_expr (ipart);
6962 result = fold_build2 (PLUS_EXPR, type,
6963 fold_build2 (MULT_EXPR, type,
6964 rpart, rpart),
6965 fold_build2 (MULT_EXPR, type,
6966 ipart, ipart));
6968 arglist = build_tree_list (NULL_TREE, result);
6969 return build_function_call_expr (sqrtfn, arglist);
6973 return NULL_TREE;
6976 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6977 NULL_TREE if no simplification can be made. */
6979 static tree
6980 fold_builtin_sqrt (tree arglist, tree type)
6983 enum built_in_function fcode;
6984 tree arg = TREE_VALUE (arglist);
6986 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6987 return NULL_TREE;
6989 /* Optimize sqrt of constant value. */
6990 if (TREE_CODE (arg) == REAL_CST
6991 && ! TREE_CONSTANT_OVERFLOW (arg))
6993 REAL_VALUE_TYPE r, x;
6995 x = TREE_REAL_CST (arg);
6996 if (real_sqrt (&r, TYPE_MODE (type), &x)
6997 || (!flag_trapping_math && !flag_errno_math))
6998 return build_real (type, r);
7001 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7002 fcode = builtin_mathfn_code (arg);
7003 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7005 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7006 arg = fold_build2 (MULT_EXPR, type,
7007 TREE_VALUE (TREE_OPERAND (arg, 1)),
7008 build_real (type, dconsthalf));
7009 arglist = build_tree_list (NULL_TREE, arg);
7010 return build_function_call_expr (expfn, arglist);
7013 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7014 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7016 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7018 if (powfn)
7020 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7021 tree tree_root;
7022 /* The inner root was either sqrt or cbrt. */
7023 REAL_VALUE_TYPE dconstroot =
7024 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7026 /* Adjust for the outer root. */
7027 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7028 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7029 tree_root = build_real (type, dconstroot);
7030 arglist = tree_cons (NULL_TREE, arg0,
7031 build_tree_list (NULL_TREE, tree_root));
7032 return build_function_call_expr (powfn, arglist);
7036 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7037 if (flag_unsafe_math_optimizations
7038 && (fcode == BUILT_IN_POW
7039 || fcode == BUILT_IN_POWF
7040 || fcode == BUILT_IN_POWL))
7042 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7043 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7044 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7045 tree narg1;
7046 if (!tree_expr_nonnegative_p (arg0))
7047 arg0 = build1 (ABS_EXPR, type, arg0);
7048 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7049 build_real (type, dconsthalf));
7050 arglist = tree_cons (NULL_TREE, arg0,
7051 build_tree_list (NULL_TREE, narg1));
7052 return build_function_call_expr (powfn, arglist);
7055 return NULL_TREE;
7058 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7059 NULL_TREE if no simplification can be made. */
7060 static tree
7061 fold_builtin_cbrt (tree arglist, tree type)
7063 tree arg = TREE_VALUE (arglist);
7064 const enum built_in_function fcode = builtin_mathfn_code (arg);
7066 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7067 return NULL_TREE;
7069 /* Optimize cbrt of constant value. */
7070 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7071 return arg;
7073 if (flag_unsafe_math_optimizations)
7075 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7076 if (BUILTIN_EXPONENT_P (fcode))
7078 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7079 const REAL_VALUE_TYPE third_trunc =
7080 real_value_truncate (TYPE_MODE (type), dconstthird);
7081 arg = fold_build2 (MULT_EXPR, type,
7082 TREE_VALUE (TREE_OPERAND (arg, 1)),
7083 build_real (type, third_trunc));
7084 arglist = build_tree_list (NULL_TREE, arg);
7085 return build_function_call_expr (expfn, arglist);
7088 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7089 if (BUILTIN_SQRT_P (fcode))
7091 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7093 if (powfn)
7095 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7096 tree tree_root;
7097 REAL_VALUE_TYPE dconstroot = dconstthird;
7099 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7100 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7101 tree_root = build_real (type, dconstroot);
7102 arglist = tree_cons (NULL_TREE, arg0,
7103 build_tree_list (NULL_TREE, tree_root));
7104 return build_function_call_expr (powfn, arglist);
7108 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7109 if (BUILTIN_CBRT_P (fcode))
7111 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7112 if (tree_expr_nonnegative_p (arg0))
7114 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7116 if (powfn)
7118 tree tree_root;
7119 REAL_VALUE_TYPE dconstroot;
7121 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7122 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7123 tree_root = build_real (type, dconstroot);
7124 arglist = tree_cons (NULL_TREE, arg0,
7125 build_tree_list (NULL_TREE, tree_root));
7126 return build_function_call_expr (powfn, arglist);
7131 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7132 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7133 || fcode == BUILT_IN_POWL)
7135 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7136 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7137 if (tree_expr_nonnegative_p (arg00))
7139 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7140 const REAL_VALUE_TYPE dconstroot
7141 = real_value_truncate (TYPE_MODE (type), dconstthird);
7142 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7143 build_real (type, dconstroot));
7144 arglist = tree_cons (NULL_TREE, arg00,
7145 build_tree_list (NULL_TREE, narg01));
7146 return build_function_call_expr (powfn, arglist);
7150 return NULL_TREE;
7153 /* Fold function call to builtin sin, sinf, or sinl. Return
7154 NULL_TREE if no simplification can be made. */
7155 static tree
7156 fold_builtin_sin (tree arglist)
7158 tree arg = TREE_VALUE (arglist);
7160 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7161 return NULL_TREE;
7163 /* Optimize sin (0.0) = 0.0. */
7164 if (real_zerop (arg))
7165 return arg;
7167 return NULL_TREE;
7170 /* Fold function call to builtin cos, cosf, or cosl. Return
7171 NULL_TREE if no simplification can be made. */
7172 static tree
7173 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7175 tree arg = TREE_VALUE (arglist);
7177 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7178 return NULL_TREE;
7180 /* Optimize cos (0.0) = 1.0. */
7181 if (real_zerop (arg))
7182 return build_real (type, dconst1);
7184 /* Optimize cos(-x) into cos (x). */
7185 if (TREE_CODE (arg) == NEGATE_EXPR)
7187 tree args = build_tree_list (NULL_TREE,
7188 TREE_OPERAND (arg, 0));
7189 return build_function_call_expr (fndecl, args);
7192 return NULL_TREE;
7195 /* Fold function call to builtin tan, tanf, or tanl. Return
7196 NULL_TREE if no simplification can be made. */
7197 static tree
7198 fold_builtin_tan (tree arglist)
7200 enum built_in_function fcode;
7201 tree arg = TREE_VALUE (arglist);
7203 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7204 return NULL_TREE;
7206 /* Optimize tan(0.0) = 0.0. */
7207 if (real_zerop (arg))
7208 return arg;
7210 /* Optimize tan(atan(x)) = x. */
7211 fcode = builtin_mathfn_code (arg);
7212 if (flag_unsafe_math_optimizations
7213 && (fcode == BUILT_IN_ATAN
7214 || fcode == BUILT_IN_ATANF
7215 || fcode == BUILT_IN_ATANL))
7216 return TREE_VALUE (TREE_OPERAND (arg, 1));
7218 return NULL_TREE;
7221 /* Fold function call to builtin atan, atanf, or atanl. Return
7222 NULL_TREE if no simplification can be made. */
7224 static tree
7225 fold_builtin_atan (tree arglist, tree type)
7228 tree arg = TREE_VALUE (arglist);
7230 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7231 return NULL_TREE;
7233 /* Optimize atan(0.0) = 0.0. */
7234 if (real_zerop (arg))
7235 return arg;
7237 /* Optimize atan(1.0) = pi/4. */
7238 if (real_onep (arg))
7240 REAL_VALUE_TYPE cst;
7242 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7243 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7244 return build_real (type, cst);
7247 return NULL_TREE;
7250 /* Fold function call to builtin trunc, truncf or truncl. Return
7251 NULL_TREE if no simplification can be made. */
7253 static tree
7254 fold_builtin_trunc (tree fndecl, tree arglist)
7256 tree arg;
7258 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7259 return 0;
7261 /* Optimize trunc of constant value. */
7262 arg = TREE_VALUE (arglist);
7263 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7265 REAL_VALUE_TYPE r, x;
7266 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7268 x = TREE_REAL_CST (arg);
7269 real_trunc (&r, TYPE_MODE (type), &x);
7270 return build_real (type, r);
7273 return fold_trunc_transparent_mathfn (fndecl, arglist);
7276 /* Fold function call to builtin floor, floorf or floorl. Return
7277 NULL_TREE if no simplification can be made. */
7279 static tree
7280 fold_builtin_floor (tree fndecl, tree arglist)
7282 tree arg;
7284 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7285 return 0;
7287 /* Optimize floor of constant value. */
7288 arg = TREE_VALUE (arglist);
7289 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7291 REAL_VALUE_TYPE x;
7293 x = TREE_REAL_CST (arg);
7294 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7296 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7297 REAL_VALUE_TYPE r;
7299 real_floor (&r, TYPE_MODE (type), &x);
7300 return build_real (type, r);
7304 return fold_trunc_transparent_mathfn (fndecl, arglist);
7307 /* Fold function call to builtin ceil, ceilf or ceill. Return
7308 NULL_TREE if no simplification can be made. */
7310 static tree
7311 fold_builtin_ceil (tree fndecl, tree arglist)
7313 tree arg;
7315 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7316 return 0;
7318 /* Optimize ceil of constant value. */
7319 arg = TREE_VALUE (arglist);
7320 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7322 REAL_VALUE_TYPE x;
7324 x = TREE_REAL_CST (arg);
7325 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7327 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7328 REAL_VALUE_TYPE r;
7330 real_ceil (&r, TYPE_MODE (type), &x);
7331 return build_real (type, r);
7335 return fold_trunc_transparent_mathfn (fndecl, arglist);
7338 /* Fold function call to builtin round, roundf or roundl. Return
7339 NULL_TREE if no simplification can be made. */
7341 static tree
7342 fold_builtin_round (tree fndecl, tree arglist)
7344 tree arg;
7346 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7347 return 0;
7349 /* Optimize round of constant value. */
7350 arg = TREE_VALUE (arglist);
7351 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7353 REAL_VALUE_TYPE x;
7355 x = TREE_REAL_CST (arg);
7356 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7358 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7359 REAL_VALUE_TYPE r;
7361 real_round (&r, TYPE_MODE (type), &x);
7362 return build_real (type, r);
7366 return fold_trunc_transparent_mathfn (fndecl, arglist);
7369 /* Fold function call to builtin lround, lroundf or lroundl (or the
7370 corresponding long long versions) and other rounding functions.
7371 Return NULL_TREE if no simplification can be made. */
7373 static tree
7374 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7376 tree arg;
7378 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7379 return 0;
7381 /* Optimize lround of constant value. */
7382 arg = TREE_VALUE (arglist);
7383 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7385 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7387 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7389 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7390 tree ftype = TREE_TYPE (arg), result;
7391 HOST_WIDE_INT hi, lo;
7392 REAL_VALUE_TYPE r;
7394 switch (DECL_FUNCTION_CODE (fndecl))
7396 CASE_FLT_FN (BUILT_IN_LFLOOR):
7397 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7398 real_floor (&r, TYPE_MODE (ftype), &x);
7399 break;
7401 CASE_FLT_FN (BUILT_IN_LCEIL):
7402 CASE_FLT_FN (BUILT_IN_LLCEIL):
7403 real_ceil (&r, TYPE_MODE (ftype), &x);
7404 break;
7406 CASE_FLT_FN (BUILT_IN_LROUND):
7407 CASE_FLT_FN (BUILT_IN_LLROUND):
7408 real_round (&r, TYPE_MODE (ftype), &x);
7409 break;
7411 default:
7412 gcc_unreachable ();
7415 REAL_VALUE_TO_INT (&lo, &hi, r);
7416 result = build_int_cst_wide (NULL_TREE, lo, hi);
7417 if (int_fits_type_p (result, itype))
7418 return fold_convert (itype, result);
7422 return fold_fixed_mathfn (fndecl, arglist);
7425 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7426 and their long and long long variants (i.e. ffsl and ffsll).
7427 Return NULL_TREE if no simplification can be made. */
7429 static tree
7430 fold_builtin_bitop (tree fndecl, tree arglist)
7432 tree arg;
7434 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7435 return NULL_TREE;
7437 /* Optimize for constant argument. */
7438 arg = TREE_VALUE (arglist);
7439 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7441 HOST_WIDE_INT hi, width, result;
7442 unsigned HOST_WIDE_INT lo;
7443 tree type;
7445 type = TREE_TYPE (arg);
7446 width = TYPE_PRECISION (type);
7447 lo = TREE_INT_CST_LOW (arg);
7449 /* Clear all the bits that are beyond the type's precision. */
7450 if (width > HOST_BITS_PER_WIDE_INT)
7452 hi = TREE_INT_CST_HIGH (arg);
7453 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7454 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7456 else
7458 hi = 0;
7459 if (width < HOST_BITS_PER_WIDE_INT)
7460 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7463 switch (DECL_FUNCTION_CODE (fndecl))
7465 CASE_INT_FN (BUILT_IN_FFS):
7466 if (lo != 0)
7467 result = exact_log2 (lo & -lo) + 1;
7468 else if (hi != 0)
7469 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7470 else
7471 result = 0;
7472 break;
7474 CASE_INT_FN (BUILT_IN_CLZ):
7475 if (hi != 0)
7476 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7477 else if (lo != 0)
7478 result = width - floor_log2 (lo) - 1;
7479 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7480 result = width;
7481 break;
7483 CASE_INT_FN (BUILT_IN_CTZ):
7484 if (lo != 0)
7485 result = exact_log2 (lo & -lo);
7486 else if (hi != 0)
7487 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7488 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7489 result = width;
7490 break;
7492 CASE_INT_FN (BUILT_IN_POPCOUNT):
7493 result = 0;
7494 while (lo)
7495 result++, lo &= lo - 1;
7496 while (hi)
7497 result++, hi &= hi - 1;
7498 break;
7500 CASE_INT_FN (BUILT_IN_PARITY):
7501 result = 0;
7502 while (lo)
7503 result++, lo &= lo - 1;
7504 while (hi)
7505 result++, hi &= hi - 1;
7506 result &= 1;
7507 break;
7509 default:
7510 gcc_unreachable ();
7513 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7516 return NULL_TREE;
7519 /* Return true if EXPR is the real constant contained in VALUE. */
7521 static bool
7522 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7524 STRIP_NOPS (expr);
7526 return ((TREE_CODE (expr) == REAL_CST
7527 && ! TREE_CONSTANT_OVERFLOW (expr)
7528 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7529 || (TREE_CODE (expr) == COMPLEX_CST
7530 && real_dconstp (TREE_REALPART (expr), value)
7531 && real_zerop (TREE_IMAGPART (expr))));
7534 /* A subroutine of fold_builtin to fold the various logarithmic
7535 functions. EXP is the CALL_EXPR of a call to a builtin logN
7536 function. VALUE is the base of the logN function. */
7538 static tree
7539 fold_builtin_logarithm (tree fndecl, tree arglist,
7540 const REAL_VALUE_TYPE *value)
7542 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7544 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7545 tree arg = TREE_VALUE (arglist);
7546 const enum built_in_function fcode = builtin_mathfn_code (arg);
7548 /* Optimize logN(1.0) = 0.0. */
7549 if (real_onep (arg))
7550 return build_real (type, dconst0);
7552 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7553 exactly, then only do this if flag_unsafe_math_optimizations. */
7554 if (exact_real_truncate (TYPE_MODE (type), value)
7555 || flag_unsafe_math_optimizations)
7557 const REAL_VALUE_TYPE value_truncate =
7558 real_value_truncate (TYPE_MODE (type), *value);
7559 if (real_dconstp (arg, &value_truncate))
7560 return build_real (type, dconst1);
7563 /* Special case, optimize logN(expN(x)) = x. */
7564 if (flag_unsafe_math_optimizations
7565 && ((value == &dconste
7566 && (fcode == BUILT_IN_EXP
7567 || fcode == BUILT_IN_EXPF
7568 || fcode == BUILT_IN_EXPL))
7569 || (value == &dconst2
7570 && (fcode == BUILT_IN_EXP2
7571 || fcode == BUILT_IN_EXP2F
7572 || fcode == BUILT_IN_EXP2L))
7573 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7574 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7576 /* Optimize logN(func()) for various exponential functions. We
7577 want to determine the value "x" and the power "exponent" in
7578 order to transform logN(x**exponent) into exponent*logN(x). */
7579 if (flag_unsafe_math_optimizations)
7581 tree exponent = 0, x = 0;
7583 switch (fcode)
7585 CASE_FLT_FN (BUILT_IN_EXP):
7586 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7587 x = build_real (type,
7588 real_value_truncate (TYPE_MODE (type), dconste));
7589 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7590 break;
7591 CASE_FLT_FN (BUILT_IN_EXP2):
7592 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7593 x = build_real (type, dconst2);
7594 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7595 break;
7596 CASE_FLT_FN (BUILT_IN_EXP10):
7597 CASE_FLT_FN (BUILT_IN_POW10):
7598 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7599 x = build_real (type, dconst10);
7600 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7601 break;
7602 CASE_FLT_FN (BUILT_IN_SQRT):
7603 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7604 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7605 exponent = build_real (type, dconsthalf);
7606 break;
7607 CASE_FLT_FN (BUILT_IN_CBRT):
7608 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7609 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7610 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7611 dconstthird));
7612 break;
7613 CASE_FLT_FN (BUILT_IN_POW):
7614 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7615 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7616 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7617 break;
7618 default:
7619 break;
7622 /* Now perform the optimization. */
7623 if (x && exponent)
7625 tree logfn;
7626 arglist = build_tree_list (NULL_TREE, x);
7627 logfn = build_function_call_expr (fndecl, arglist);
7628 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7633 return 0;
7636 /* Fold a builtin function call to pow, powf, or powl. Return
7637 NULL_TREE if no simplification can be made. */
7638 static tree
7639 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7641 tree arg0 = TREE_VALUE (arglist);
7642 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7644 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7645 return NULL_TREE;
7647 /* Optimize pow(1.0,y) = 1.0. */
7648 if (real_onep (arg0))
7649 return omit_one_operand (type, build_real (type, dconst1), arg1);
7651 if (TREE_CODE (arg1) == REAL_CST
7652 && ! TREE_CONSTANT_OVERFLOW (arg1))
7654 REAL_VALUE_TYPE cint;
7655 REAL_VALUE_TYPE c;
7656 HOST_WIDE_INT n;
7658 c = TREE_REAL_CST (arg1);
7660 /* Optimize pow(x,0.0) = 1.0. */
7661 if (REAL_VALUES_EQUAL (c, dconst0))
7662 return omit_one_operand (type, build_real (type, dconst1),
7663 arg0);
7665 /* Optimize pow(x,1.0) = x. */
7666 if (REAL_VALUES_EQUAL (c, dconst1))
7667 return arg0;
7669 /* Optimize pow(x,-1.0) = 1.0/x. */
7670 if (REAL_VALUES_EQUAL (c, dconstm1))
7671 return fold_build2 (RDIV_EXPR, type,
7672 build_real (type, dconst1), arg0);
7674 /* Optimize pow(x,0.5) = sqrt(x). */
7675 if (flag_unsafe_math_optimizations
7676 && REAL_VALUES_EQUAL (c, dconsthalf))
7678 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7680 if (sqrtfn != NULL_TREE)
7682 tree arglist = build_tree_list (NULL_TREE, arg0);
7683 return build_function_call_expr (sqrtfn, arglist);
7687 /* Check for an integer exponent. */
7688 n = real_to_integer (&c);
7689 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7690 if (real_identical (&c, &cint))
7692 /* Attempt to evaluate pow at compile-time. */
7693 if (TREE_CODE (arg0) == REAL_CST
7694 && ! TREE_CONSTANT_OVERFLOW (arg0))
7696 REAL_VALUE_TYPE x;
7697 bool inexact;
7699 x = TREE_REAL_CST (arg0);
7700 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7701 if (flag_unsafe_math_optimizations || !inexact)
7702 return build_real (type, x);
7705 /* Strip sign ops from even integer powers. */
7706 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7708 tree narg0 = fold_strip_sign_ops (arg0);
7709 if (narg0)
7711 arglist = build_tree_list (NULL_TREE, arg1);
7712 arglist = tree_cons (NULL_TREE, narg0, arglist);
7713 return build_function_call_expr (fndecl, arglist);
7719 if (flag_unsafe_math_optimizations)
7721 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7723 /* Optimize pow(expN(x),y) = expN(x*y). */
7724 if (BUILTIN_EXPONENT_P (fcode))
7726 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7727 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7728 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7729 arglist = build_tree_list (NULL_TREE, arg);
7730 return build_function_call_expr (expfn, arglist);
7733 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7734 if (BUILTIN_SQRT_P (fcode))
7736 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7737 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7738 build_real (type, dconsthalf));
7740 arglist = tree_cons (NULL_TREE, narg0,
7741 build_tree_list (NULL_TREE, narg1));
7742 return build_function_call_expr (fndecl, arglist);
7745 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7746 if (BUILTIN_CBRT_P (fcode))
7748 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7749 if (tree_expr_nonnegative_p (arg))
7751 const REAL_VALUE_TYPE dconstroot
7752 = real_value_truncate (TYPE_MODE (type), dconstthird);
7753 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7754 build_real (type, dconstroot));
7755 arglist = tree_cons (NULL_TREE, arg,
7756 build_tree_list (NULL_TREE, narg1));
7757 return build_function_call_expr (fndecl, arglist);
7761 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7762 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7763 || fcode == BUILT_IN_POWL)
7765 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7766 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7767 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7768 arglist = tree_cons (NULL_TREE, arg00,
7769 build_tree_list (NULL_TREE, narg1));
7770 return build_function_call_expr (fndecl, arglist);
7774 return NULL_TREE;
7777 /* Fold a builtin function call to powi, powif, or powil. Return
7778 NULL_TREE if no simplification can be made. */
7779 static tree
7780 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7782 tree arg0 = TREE_VALUE (arglist);
7783 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7785 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7786 return NULL_TREE;
7788 /* Optimize pow(1.0,y) = 1.0. */
7789 if (real_onep (arg0))
7790 return omit_one_operand (type, build_real (type, dconst1), arg1);
7792 if (host_integerp (arg1, 0))
7794 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7796 /* Evaluate powi at compile-time. */
7797 if (TREE_CODE (arg0) == REAL_CST
7798 && ! TREE_CONSTANT_OVERFLOW (arg0))
7800 REAL_VALUE_TYPE x;
7801 x = TREE_REAL_CST (arg0);
7802 real_powi (&x, TYPE_MODE (type), &x, c);
7803 return build_real (type, x);
7806 /* Optimize pow(x,0) = 1.0. */
7807 if (c == 0)
7808 return omit_one_operand (type, build_real (type, dconst1),
7809 arg0);
7811 /* Optimize pow(x,1) = x. */
7812 if (c == 1)
7813 return arg0;
7815 /* Optimize pow(x,-1) = 1.0/x. */
7816 if (c == -1)
7817 return fold_build2 (RDIV_EXPR, type,
7818 build_real (type, dconst1), arg0);
7821 return NULL_TREE;
7824 /* A subroutine of fold_builtin to fold the various exponent
7825 functions. EXP is the CALL_EXPR of a call to a builtin function.
7826 VALUE is the value which will be raised to a power. */
7828 static tree
7829 fold_builtin_exponent (tree fndecl, tree arglist,
7830 const REAL_VALUE_TYPE *value)
7832 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7834 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7835 tree arg = TREE_VALUE (arglist);
7837 /* Optimize exp*(0.0) = 1.0. */
7838 if (real_zerop (arg))
7839 return build_real (type, dconst1);
7841 /* Optimize expN(1.0) = N. */
7842 if (real_onep (arg))
7844 REAL_VALUE_TYPE cst;
7846 real_convert (&cst, TYPE_MODE (type), value);
7847 return build_real (type, cst);
7850 /* Attempt to evaluate expN(integer) at compile-time. */
7851 if (flag_unsafe_math_optimizations
7852 && TREE_CODE (arg) == REAL_CST
7853 && ! TREE_CONSTANT_OVERFLOW (arg))
7855 REAL_VALUE_TYPE cint;
7856 REAL_VALUE_TYPE c;
7857 HOST_WIDE_INT n;
7859 c = TREE_REAL_CST (arg);
7860 n = real_to_integer (&c);
7861 real_from_integer (&cint, VOIDmode, n,
7862 n < 0 ? -1 : 0, 0);
7863 if (real_identical (&c, &cint))
7865 REAL_VALUE_TYPE x;
7867 real_powi (&x, TYPE_MODE (type), value, n);
7868 return build_real (type, x);
7872 /* Optimize expN(logN(x)) = x. */
7873 if (flag_unsafe_math_optimizations)
7875 const enum built_in_function fcode = builtin_mathfn_code (arg);
7877 if ((value == &dconste
7878 && (fcode == BUILT_IN_LOG
7879 || fcode == BUILT_IN_LOGF
7880 || fcode == BUILT_IN_LOGL))
7881 || (value == &dconst2
7882 && (fcode == BUILT_IN_LOG2
7883 || fcode == BUILT_IN_LOG2F
7884 || fcode == BUILT_IN_LOG2L))
7885 || (value == &dconst10
7886 && (fcode == BUILT_IN_LOG10
7887 || fcode == BUILT_IN_LOG10F
7888 || fcode == BUILT_IN_LOG10L)))
7889 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7893 return 0;
7896 /* Fold function call to builtin memset. Return
7897 NULL_TREE if no simplification can be made. */
7899 static tree
7900 fold_builtin_memset (tree arglist, tree type, bool ignore)
7902 tree dest, c, len, var, ret;
7903 unsigned HOST_WIDE_INT length, cval;
7905 if (!validate_arglist (arglist,
7906 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
7907 return 0;
7909 dest = TREE_VALUE (arglist);
7910 c = TREE_VALUE (TREE_CHAIN (arglist));
7911 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7913 if (! host_integerp (len, 1))
7914 return 0;
7916 /* If the LEN parameter is zero, return DEST. */
7917 if (integer_zerop (len))
7918 return omit_one_operand (type, dest, c);
7920 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
7921 return 0;
7923 var = dest;
7924 STRIP_NOPS (var);
7925 if (TREE_CODE (var) != ADDR_EXPR)
7926 return 0;
7928 var = TREE_OPERAND (var, 0);
7929 if (TREE_THIS_VOLATILE (var))
7930 return 0;
7932 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
7933 && !POINTER_TYPE_P (TREE_TYPE (var)))
7934 return 0;
7936 length = tree_low_cst (len, 1);
7937 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
7938 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
7939 < (int) length)
7940 return 0;
7942 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
7943 return 0;
7945 if (integer_zerop (c))
7946 cval = 0;
7947 else
7949 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
7950 return 0;
7952 cval = tree_low_cst (c, 1);
7953 cval &= 0xff;
7954 cval |= cval << 8;
7955 cval |= cval << 16;
7956 cval |= (cval << 31) << 1;
7959 ret = build_int_cst_type (TREE_TYPE (var), cval);
7960 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
7961 if (ignore)
7962 return ret;
7964 return omit_one_operand (type, dest, ret);
7967 /* Fold function call to builtin memset. Return
7968 NULL_TREE if no simplification can be made. */
7970 static tree
7971 fold_builtin_bzero (tree arglist, bool ignore)
7973 tree dest, size, newarglist;
7975 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7976 return 0;
7978 if (!ignore)
7979 return 0;
7981 dest = TREE_VALUE (arglist);
7982 size = TREE_VALUE (TREE_CHAIN (arglist));
7984 /* New argument list transforming bzero(ptr x, int y) to
7985 memset(ptr x, int 0, size_t y). This is done this way
7986 so that if it isn't expanded inline, we fallback to
7987 calling bzero instead of memset. */
7989 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
7990 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
7991 newarglist = tree_cons (NULL_TREE, dest, newarglist);
7992 return fold_builtin_memset (newarglist, void_type_node, ignore);
7995 /* Fold function call to builtin mem{{,p}cpy,move}. Return
7996 NULL_TREE if no simplification can be made.
7997 If ENDP is 0, return DEST (like memcpy).
7998 If ENDP is 1, return DEST+LEN (like mempcpy).
7999 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8000 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8001 (memmove). */
8003 static tree
8004 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8006 tree dest, src, len, destvar, srcvar, expr;
8007 unsigned HOST_WIDE_INT length;
8009 if (! validate_arglist (arglist,
8010 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8011 return 0;
8013 dest = TREE_VALUE (arglist);
8014 src = TREE_VALUE (TREE_CHAIN (arglist));
8015 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8017 /* If the LEN parameter is zero, return DEST. */
8018 if (integer_zerop (len))
8019 return omit_one_operand (type, dest, src);
8021 /* If SRC and DEST are the same (and not volatile), return
8022 DEST{,+LEN,+LEN-1}. */
8023 if (operand_equal_p (src, dest, 0))
8024 expr = len;
8025 else
8027 if (! host_integerp (len, 1))
8028 return 0;
8030 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8031 return 0;
8033 destvar = dest;
8034 STRIP_NOPS (destvar);
8035 if (TREE_CODE (destvar) != ADDR_EXPR)
8036 return 0;
8038 destvar = TREE_OPERAND (destvar, 0);
8039 if (TREE_THIS_VOLATILE (destvar))
8040 return 0;
8042 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8043 && !POINTER_TYPE_P (TREE_TYPE (destvar))
8044 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8045 return 0;
8047 srcvar = src;
8048 STRIP_NOPS (srcvar);
8049 if (TREE_CODE (srcvar) != ADDR_EXPR)
8050 return 0;
8052 srcvar = TREE_OPERAND (srcvar, 0);
8053 if (TREE_THIS_VOLATILE (srcvar))
8054 return 0;
8056 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8057 && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8058 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8059 return 0;
8061 length = tree_low_cst (len, 1);
8062 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8063 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8064 < (int) length
8065 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8066 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8067 < (int) length)
8068 return 0;
8070 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8071 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8072 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8073 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8074 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8075 else
8076 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8077 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8080 if (ignore)
8081 return expr;
8083 if (endp == 0 || endp == 3)
8084 return omit_one_operand (type, dest, expr);
8086 if (expr == len)
8087 expr = 0;
8089 if (endp == 2)
8090 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8091 ssize_int (1));
8093 len = fold_convert (TREE_TYPE (dest), len);
8094 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8095 dest = fold_convert (type, dest);
8096 if (expr)
8097 dest = omit_one_operand (type, dest, expr);
8098 return dest;
8101 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8102 simplification can be made. */
8104 static tree
8105 fold_builtin_bcopy (tree arglist, bool ignore)
8107 tree src, dest, size, newarglist;
8109 if (!validate_arglist (arglist,
8110 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8111 return 0;
8113 if (! ignore)
8114 return 0;
8116 src = TREE_VALUE (arglist);
8117 dest = TREE_VALUE (TREE_CHAIN (arglist));
8118 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8120 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8121 memmove(ptr y, ptr x, size_t z). This is done this way
8122 so that if it isn't expanded inline, we fallback to
8123 calling bcopy instead of memmove. */
8125 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8126 newarglist = tree_cons (NULL_TREE, src, newarglist);
8127 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8129 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8132 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8133 the length of the string to be copied. Return NULL_TREE if no
8134 simplification can be made. */
8136 tree
8137 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8139 tree dest, src, fn;
8141 if (!validate_arglist (arglist,
8142 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8143 return 0;
8145 dest = TREE_VALUE (arglist);
8146 src = TREE_VALUE (TREE_CHAIN (arglist));
8148 /* If SRC and DEST are the same (and not volatile), return DEST. */
8149 if (operand_equal_p (src, dest, 0))
8150 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8152 if (optimize_size)
8153 return 0;
8155 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8156 if (!fn)
8157 return 0;
8159 if (!len)
8161 len = c_strlen (src, 1);
8162 if (! len || TREE_SIDE_EFFECTS (len))
8163 return 0;
8166 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8167 arglist = build_tree_list (NULL_TREE, len);
8168 arglist = tree_cons (NULL_TREE, src, arglist);
8169 arglist = tree_cons (NULL_TREE, dest, arglist);
8170 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8171 build_function_call_expr (fn, arglist));
8174 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8175 the length of the source string. Return NULL_TREE if no simplification
8176 can be made. */
8178 tree
8179 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8181 tree dest, src, len, fn;
8183 if (!validate_arglist (arglist,
8184 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8185 return 0;
8187 dest = TREE_VALUE (arglist);
8188 src = TREE_VALUE (TREE_CHAIN (arglist));
8189 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8191 /* If the LEN parameter is zero, return DEST. */
8192 if (integer_zerop (len))
8193 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8195 /* We can't compare slen with len as constants below if len is not a
8196 constant. */
8197 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8198 return 0;
8200 if (!slen)
8201 slen = c_strlen (src, 1);
8203 /* Now, we must be passed a constant src ptr parameter. */
8204 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8205 return 0;
8207 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8209 /* We do not support simplification of this case, though we do
8210 support it when expanding trees into RTL. */
8211 /* FIXME: generate a call to __builtin_memset. */
8212 if (tree_int_cst_lt (slen, len))
8213 return 0;
8215 /* OK transform into builtin memcpy. */
8216 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8217 if (!fn)
8218 return 0;
8219 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8220 build_function_call_expr (fn, arglist));
8223 /* Fold function call to builtin memcmp. Return
8224 NULL_TREE if no simplification can be made. */
8226 static tree
8227 fold_builtin_memcmp (tree arglist)
8229 tree arg1, arg2, len;
8230 const char *p1, *p2;
8232 if (!validate_arglist (arglist,
8233 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8234 return 0;
8236 arg1 = TREE_VALUE (arglist);
8237 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8238 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8240 /* If the LEN parameter is zero, return zero. */
8241 if (integer_zerop (len))
8242 return omit_two_operands (integer_type_node, integer_zero_node,
8243 arg1, arg2);
8245 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8246 if (operand_equal_p (arg1, arg2, 0))
8247 return omit_one_operand (integer_type_node, integer_zero_node, len);
8249 p1 = c_getstr (arg1);
8250 p2 = c_getstr (arg2);
8252 /* If all arguments are constant, and the value of len is not greater
8253 than the lengths of arg1 and arg2, evaluate at compile-time. */
8254 if (host_integerp (len, 1) && p1 && p2
8255 && compare_tree_int (len, strlen (p1) + 1) <= 0
8256 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8258 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8260 if (r > 0)
8261 return integer_one_node;
8262 else if (r < 0)
8263 return integer_minus_one_node;
8264 else
8265 return integer_zero_node;
8268 /* If len parameter is one, return an expression corresponding to
8269 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8270 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8272 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8273 tree cst_uchar_ptr_node
8274 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8276 tree ind1 = fold_convert (integer_type_node,
8277 build1 (INDIRECT_REF, cst_uchar_node,
8278 fold_convert (cst_uchar_ptr_node,
8279 arg1)));
8280 tree ind2 = fold_convert (integer_type_node,
8281 build1 (INDIRECT_REF, cst_uchar_node,
8282 fold_convert (cst_uchar_ptr_node,
8283 arg2)));
8284 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8287 return 0;
8290 /* Fold function call to builtin strcmp. Return
8291 NULL_TREE if no simplification can be made. */
8293 static tree
8294 fold_builtin_strcmp (tree arglist)
8296 tree arg1, arg2;
8297 const char *p1, *p2;
8299 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8300 return 0;
8302 arg1 = TREE_VALUE (arglist);
8303 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8305 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8306 if (operand_equal_p (arg1, arg2, 0))
8307 return integer_zero_node;
8309 p1 = c_getstr (arg1);
8310 p2 = c_getstr (arg2);
8312 if (p1 && p2)
8314 const int i = strcmp (p1, p2);
8315 if (i < 0)
8316 return integer_minus_one_node;
8317 else if (i > 0)
8318 return integer_one_node;
8319 else
8320 return integer_zero_node;
8323 /* If the second arg is "", return *(const unsigned char*)arg1. */
8324 if (p2 && *p2 == '\0')
8326 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8327 tree cst_uchar_ptr_node
8328 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8330 return fold_convert (integer_type_node,
8331 build1 (INDIRECT_REF, cst_uchar_node,
8332 fold_convert (cst_uchar_ptr_node,
8333 arg1)));
8336 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8337 if (p1 && *p1 == '\0')
8339 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8340 tree cst_uchar_ptr_node
8341 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8343 tree temp = fold_convert (integer_type_node,
8344 build1 (INDIRECT_REF, cst_uchar_node,
8345 fold_convert (cst_uchar_ptr_node,
8346 arg2)));
8347 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8350 return 0;
8353 /* Fold function call to builtin strncmp. Return
8354 NULL_TREE if no simplification can be made. */
8356 static tree
8357 fold_builtin_strncmp (tree arglist)
8359 tree arg1, arg2, len;
8360 const char *p1, *p2;
8362 if (!validate_arglist (arglist,
8363 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8364 return 0;
8366 arg1 = TREE_VALUE (arglist);
8367 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8368 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8370 /* If the LEN parameter is zero, return zero. */
8371 if (integer_zerop (len))
8372 return omit_two_operands (integer_type_node, integer_zero_node,
8373 arg1, arg2);
8375 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8376 if (operand_equal_p (arg1, arg2, 0))
8377 return omit_one_operand (integer_type_node, integer_zero_node, len);
8379 p1 = c_getstr (arg1);
8380 p2 = c_getstr (arg2);
8382 if (host_integerp (len, 1) && p1 && p2)
8384 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8385 if (i > 0)
8386 return integer_one_node;
8387 else if (i < 0)
8388 return integer_minus_one_node;
8389 else
8390 return integer_zero_node;
8393 /* If the second arg is "", and the length is greater than zero,
8394 return *(const unsigned char*)arg1. */
8395 if (p2 && *p2 == '\0'
8396 && TREE_CODE (len) == INTEGER_CST
8397 && tree_int_cst_sgn (len) == 1)
8399 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8400 tree cst_uchar_ptr_node
8401 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8403 return fold_convert (integer_type_node,
8404 build1 (INDIRECT_REF, cst_uchar_node,
8405 fold_convert (cst_uchar_ptr_node,
8406 arg1)));
8409 /* If the first arg is "", and the length is greater than zero,
8410 return -*(const unsigned char*)arg2. */
8411 if (p1 && *p1 == '\0'
8412 && TREE_CODE (len) == INTEGER_CST
8413 && tree_int_cst_sgn (len) == 1)
8415 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8416 tree cst_uchar_ptr_node
8417 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8419 tree temp = fold_convert (integer_type_node,
8420 build1 (INDIRECT_REF, cst_uchar_node,
8421 fold_convert (cst_uchar_ptr_node,
8422 arg2)));
8423 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8426 /* If len parameter is one, return an expression corresponding to
8427 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8428 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8430 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8431 tree cst_uchar_ptr_node
8432 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8434 tree ind1 = fold_convert (integer_type_node,
8435 build1 (INDIRECT_REF, cst_uchar_node,
8436 fold_convert (cst_uchar_ptr_node,
8437 arg1)));
8438 tree ind2 = fold_convert (integer_type_node,
8439 build1 (INDIRECT_REF, cst_uchar_node,
8440 fold_convert (cst_uchar_ptr_node,
8441 arg2)));
8442 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8445 return 0;
8448 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8449 NULL_TREE if no simplification can be made. */
8451 static tree
8452 fold_builtin_signbit (tree fndecl, tree arglist)
8454 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8455 tree arg, temp;
8457 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8458 return NULL_TREE;
8460 arg = TREE_VALUE (arglist);
8462 /* If ARG is a compile-time constant, determine the result. */
8463 if (TREE_CODE (arg) == REAL_CST
8464 && !TREE_CONSTANT_OVERFLOW (arg))
8466 REAL_VALUE_TYPE c;
8468 c = TREE_REAL_CST (arg);
8469 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8470 return fold_convert (type, temp);
8473 /* If ARG is non-negative, the result is always zero. */
8474 if (tree_expr_nonnegative_p (arg))
8475 return omit_one_operand (type, integer_zero_node, arg);
8477 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8478 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8479 return fold_build2 (LT_EXPR, type, arg,
8480 build_real (TREE_TYPE (arg), dconst0));
8482 return NULL_TREE;
8485 /* Fold function call to builtin copysign, copysignf or copysignl.
8486 Return NULL_TREE if no simplification can be made. */
8488 static tree
8489 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8491 tree arg1, arg2, tem;
8493 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8494 return NULL_TREE;
8496 arg1 = TREE_VALUE (arglist);
8497 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8499 /* copysign(X,X) is X. */
8500 if (operand_equal_p (arg1, arg2, 0))
8501 return fold_convert (type, arg1);
8503 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8504 if (TREE_CODE (arg1) == REAL_CST
8505 && TREE_CODE (arg2) == REAL_CST
8506 && !TREE_CONSTANT_OVERFLOW (arg1)
8507 && !TREE_CONSTANT_OVERFLOW (arg2))
8509 REAL_VALUE_TYPE c1, c2;
8511 c1 = TREE_REAL_CST (arg1);
8512 c2 = TREE_REAL_CST (arg2);
8513 /* c1.sign := c2.sign. */
8514 real_copysign (&c1, &c2);
8515 return build_real (type, c1);
8518 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8519 Remember to evaluate Y for side-effects. */
8520 if (tree_expr_nonnegative_p (arg2))
8521 return omit_one_operand (type,
8522 fold_build1 (ABS_EXPR, type, arg1),
8523 arg2);
8525 /* Strip sign changing operations for the first argument. */
8526 tem = fold_strip_sign_ops (arg1);
8527 if (tem)
8529 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8530 return build_function_call_expr (fndecl, arglist);
8533 return NULL_TREE;
8536 /* Fold a call to builtin isascii. */
8538 static tree
8539 fold_builtin_isascii (tree arglist)
8541 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8542 return 0;
8543 else
8545 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8546 tree arg = TREE_VALUE (arglist);
8548 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8549 build_int_cst (NULL_TREE,
8550 ~ (unsigned HOST_WIDE_INT) 0x7f));
8551 arg = fold_build2 (EQ_EXPR, integer_type_node,
8552 arg, integer_zero_node);
8554 if (in_gimple_form && !TREE_CONSTANT (arg))
8555 return NULL_TREE;
8556 else
8557 return arg;
8561 /* Fold a call to builtin toascii. */
8563 static tree
8564 fold_builtin_toascii (tree arglist)
8566 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8567 return 0;
8568 else
8570 /* Transform toascii(c) -> (c & 0x7f). */
8571 tree arg = TREE_VALUE (arglist);
8573 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8574 build_int_cst (NULL_TREE, 0x7f));
8578 /* Fold a call to builtin isdigit. */
8580 static tree
8581 fold_builtin_isdigit (tree arglist)
8583 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8584 return 0;
8585 else
8587 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8588 /* According to the C standard, isdigit is unaffected by locale.
8589 However, it definitely is affected by the target character set. */
8590 tree arg;
8591 unsigned HOST_WIDE_INT target_digit0
8592 = lang_hooks.to_target_charset ('0');
8594 if (target_digit0 == 0)
8595 return NULL_TREE;
8597 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8598 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8599 build_int_cst (unsigned_type_node, target_digit0));
8600 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8601 build_int_cst (unsigned_type_node, 9));
8602 if (in_gimple_form && !TREE_CONSTANT (arg))
8603 return NULL_TREE;
8604 else
8605 return arg;
8609 /* Fold a call to fabs, fabsf or fabsl. */
8611 static tree
8612 fold_builtin_fabs (tree arglist, tree type)
8614 tree arg;
8616 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8617 return 0;
8619 arg = TREE_VALUE (arglist);
8620 arg = fold_convert (type, arg);
8621 if (TREE_CODE (arg) == REAL_CST)
8622 return fold_abs_const (arg, type);
8623 return fold_build1 (ABS_EXPR, type, arg);
8626 /* Fold a call to abs, labs, llabs or imaxabs. */
8628 static tree
8629 fold_builtin_abs (tree arglist, tree type)
8631 tree arg;
8633 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8634 return 0;
8636 arg = TREE_VALUE (arglist);
8637 arg = fold_convert (type, arg);
8638 if (TREE_CODE (arg) == INTEGER_CST)
8639 return fold_abs_const (arg, type);
8640 return fold_build1 (ABS_EXPR, type, arg);
8643 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8644 EXP is the CALL_EXPR for the call. */
8646 static tree
8647 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8649 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8650 tree arg;
8651 REAL_VALUE_TYPE r;
8653 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8655 /* Check that we have exactly one argument. */
8656 if (arglist == 0)
8658 error ("too few arguments to function %qs",
8659 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8660 return error_mark_node;
8662 else if (TREE_CHAIN (arglist) != 0)
8664 error ("too many arguments to function %qs",
8665 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8666 return error_mark_node;
8668 else
8670 error ("non-floating-point argument to function %qs",
8671 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8672 return error_mark_node;
8676 arg = TREE_VALUE (arglist);
8677 switch (builtin_index)
8679 case BUILT_IN_ISINF:
8680 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8681 return omit_one_operand (type, integer_zero_node, arg);
8683 if (TREE_CODE (arg) == REAL_CST)
8685 r = TREE_REAL_CST (arg);
8686 if (real_isinf (&r))
8687 return real_compare (GT_EXPR, &r, &dconst0)
8688 ? integer_one_node : integer_minus_one_node;
8689 else
8690 return integer_zero_node;
8693 return NULL_TREE;
8695 case BUILT_IN_FINITE:
8696 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8697 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8698 return omit_one_operand (type, integer_zero_node, arg);
8700 if (TREE_CODE (arg) == REAL_CST)
8702 r = TREE_REAL_CST (arg);
8703 return real_isinf (&r) || real_isnan (&r)
8704 ? integer_zero_node : integer_one_node;
8707 return NULL_TREE;
8709 case BUILT_IN_ISNAN:
8710 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8711 return omit_one_operand (type, integer_zero_node, arg);
8713 if (TREE_CODE (arg) == REAL_CST)
8715 r = TREE_REAL_CST (arg);
8716 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8719 arg = builtin_save_expr (arg);
8720 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8722 default:
8723 gcc_unreachable ();
8727 /* Fold a call to an unordered comparison function such as
8728 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8729 being called and ARGLIST is the argument list for the call.
8730 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8731 the opposite of the desired result. UNORDERED_CODE is used
8732 for modes that can hold NaNs and ORDERED_CODE is used for
8733 the rest. */
8735 static tree
8736 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8737 enum tree_code unordered_code,
8738 enum tree_code ordered_code)
8740 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8741 enum tree_code code;
8742 tree arg0, arg1;
8743 tree type0, type1;
8744 enum tree_code code0, code1;
8745 tree cmp_type = NULL_TREE;
8747 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8749 /* Check that we have exactly two arguments. */
8750 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8752 error ("too few arguments to function %qs",
8753 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8754 return error_mark_node;
8756 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8758 error ("too many arguments to function %qs",
8759 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8760 return error_mark_node;
8764 arg0 = TREE_VALUE (arglist);
8765 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8767 type0 = TREE_TYPE (arg0);
8768 type1 = TREE_TYPE (arg1);
8770 code0 = TREE_CODE (type0);
8771 code1 = TREE_CODE (type1);
8773 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8774 /* Choose the wider of two real types. */
8775 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8776 ? type0 : type1;
8777 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8778 cmp_type = type0;
8779 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8780 cmp_type = type1;
8781 else
8783 error ("non-floating-point argument to function %qs",
8784 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8785 return error_mark_node;
8788 arg0 = fold_convert (cmp_type, arg0);
8789 arg1 = fold_convert (cmp_type, arg1);
8791 if (unordered_code == UNORDERED_EXPR)
8793 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8794 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8795 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8798 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8799 : ordered_code;
8800 return fold_build1 (TRUTH_NOT_EXPR, type,
8801 fold_build2 (code, type, arg0, arg1));
8804 /* Used by constant folding to simplify calls to builtin functions. EXP is
8805 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8806 result of the function call is ignored. This function returns NULL_TREE
8807 if no simplification was possible. */
8809 static tree
8810 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8812 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8813 enum built_in_function fcode;
8815 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8816 return targetm.fold_builtin (fndecl, arglist, ignore);
8818 fcode = DECL_FUNCTION_CODE (fndecl);
8819 switch (fcode)
8821 case BUILT_IN_FPUTS:
8822 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8824 case BUILT_IN_FPUTS_UNLOCKED:
8825 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8827 case BUILT_IN_STRSTR:
8828 return fold_builtin_strstr (arglist, type);
8830 case BUILT_IN_STRCAT:
8831 return fold_builtin_strcat (arglist);
8833 case BUILT_IN_STRNCAT:
8834 return fold_builtin_strncat (arglist);
8836 case BUILT_IN_STRSPN:
8837 return fold_builtin_strspn (arglist);
8839 case BUILT_IN_STRCSPN:
8840 return fold_builtin_strcspn (arglist);
8842 case BUILT_IN_STRCHR:
8843 case BUILT_IN_INDEX:
8844 return fold_builtin_strchr (arglist, type);
8846 case BUILT_IN_STRRCHR:
8847 case BUILT_IN_RINDEX:
8848 return fold_builtin_strrchr (arglist, type);
8850 case BUILT_IN_STRCPY:
8851 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8853 case BUILT_IN_STRNCPY:
8854 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8856 case BUILT_IN_STRCMP:
8857 return fold_builtin_strcmp (arglist);
8859 case BUILT_IN_STRNCMP:
8860 return fold_builtin_strncmp (arglist);
8862 case BUILT_IN_STRPBRK:
8863 return fold_builtin_strpbrk (arglist, type);
8865 case BUILT_IN_BCMP:
8866 case BUILT_IN_MEMCMP:
8867 return fold_builtin_memcmp (arglist);
8869 case BUILT_IN_SPRINTF:
8870 return fold_builtin_sprintf (arglist, ignore);
8872 case BUILT_IN_CONSTANT_P:
8874 tree val;
8876 val = fold_builtin_constant_p (arglist);
8877 /* Gimplification will pull the CALL_EXPR for the builtin out of
8878 an if condition. When not optimizing, we'll not CSE it back.
8879 To avoid link error types of regressions, return false now. */
8880 if (!val && !optimize)
8881 val = integer_zero_node;
8883 return val;
8886 case BUILT_IN_EXPECT:
8887 return fold_builtin_expect (arglist);
8889 case BUILT_IN_CLASSIFY_TYPE:
8890 return fold_builtin_classify_type (arglist);
8892 case BUILT_IN_STRLEN:
8893 return fold_builtin_strlen (arglist);
8895 CASE_FLT_FN (BUILT_IN_FABS):
8896 return fold_builtin_fabs (arglist, type);
8898 case BUILT_IN_ABS:
8899 case BUILT_IN_LABS:
8900 case BUILT_IN_LLABS:
8901 case BUILT_IN_IMAXABS:
8902 return fold_builtin_abs (arglist, type);
8904 CASE_FLT_FN (BUILT_IN_CONJ):
8905 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8906 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8907 break;
8909 CASE_FLT_FN (BUILT_IN_CREAL):
8910 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8911 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8912 TREE_VALUE (arglist)));
8913 break;
8915 CASE_FLT_FN (BUILT_IN_CIMAG):
8916 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8917 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8918 TREE_VALUE (arglist)));
8919 break;
8921 CASE_FLT_FN (BUILT_IN_CABS):
8922 return fold_builtin_cabs (arglist, type, fndecl);
8924 CASE_FLT_FN (BUILT_IN_SQRT):
8925 return fold_builtin_sqrt (arglist, type);
8927 CASE_FLT_FN (BUILT_IN_CBRT):
8928 return fold_builtin_cbrt (arglist, type);
8930 CASE_FLT_FN (BUILT_IN_SIN):
8931 return fold_builtin_sin (arglist);
8933 CASE_FLT_FN (BUILT_IN_COS):
8934 return fold_builtin_cos (arglist, type, fndecl);
8936 CASE_FLT_FN (BUILT_IN_EXP):
8937 return fold_builtin_exponent (fndecl, arglist, &dconste);
8939 CASE_FLT_FN (BUILT_IN_EXP2):
8940 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8942 CASE_FLT_FN (BUILT_IN_EXP10):
8943 CASE_FLT_FN (BUILT_IN_POW10):
8944 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8946 CASE_FLT_FN (BUILT_IN_LOG):
8947 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8949 CASE_FLT_FN (BUILT_IN_LOG2):
8950 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8952 CASE_FLT_FN (BUILT_IN_LOG10):
8953 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8955 CASE_FLT_FN (BUILT_IN_TAN):
8956 return fold_builtin_tan (arglist);
8958 CASE_FLT_FN (BUILT_IN_ATAN):
8959 return fold_builtin_atan (arglist, type);
8961 CASE_FLT_FN (BUILT_IN_POW):
8962 return fold_builtin_pow (fndecl, arglist, type);
8964 CASE_FLT_FN (BUILT_IN_POWI):
8965 return fold_builtin_powi (fndecl, arglist, type);
8967 CASE_FLT_FN (BUILT_IN_INF):
8968 case BUILT_IN_INFD32:
8969 case BUILT_IN_INFD64:
8970 case BUILT_IN_INFD128:
8971 return fold_builtin_inf (type, true);
8973 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8974 return fold_builtin_inf (type, false);
8976 CASE_FLT_FN (BUILT_IN_NAN):
8977 case BUILT_IN_NAND32:
8978 case BUILT_IN_NAND64:
8979 case BUILT_IN_NAND128:
8980 return fold_builtin_nan (arglist, type, true);
8982 CASE_FLT_FN (BUILT_IN_NANS):
8983 return fold_builtin_nan (arglist, type, false);
8985 CASE_FLT_FN (BUILT_IN_FLOOR):
8986 return fold_builtin_floor (fndecl, arglist);
8988 CASE_FLT_FN (BUILT_IN_CEIL):
8989 return fold_builtin_ceil (fndecl, arglist);
8991 CASE_FLT_FN (BUILT_IN_TRUNC):
8992 return fold_builtin_trunc (fndecl, arglist);
8994 CASE_FLT_FN (BUILT_IN_ROUND):
8995 return fold_builtin_round (fndecl, arglist);
8997 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8998 CASE_FLT_FN (BUILT_IN_RINT):
8999 return fold_trunc_transparent_mathfn (fndecl, arglist);
9001 CASE_FLT_FN (BUILT_IN_LCEIL):
9002 CASE_FLT_FN (BUILT_IN_LLCEIL):
9003 CASE_FLT_FN (BUILT_IN_LFLOOR):
9004 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9005 CASE_FLT_FN (BUILT_IN_LROUND):
9006 CASE_FLT_FN (BUILT_IN_LLROUND):
9007 return fold_builtin_int_roundingfn (fndecl, arglist);
9009 CASE_FLT_FN (BUILT_IN_LRINT):
9010 CASE_FLT_FN (BUILT_IN_LLRINT):
9011 return fold_fixed_mathfn (fndecl, arglist);
9013 CASE_INT_FN (BUILT_IN_FFS):
9014 CASE_INT_FN (BUILT_IN_CLZ):
9015 CASE_INT_FN (BUILT_IN_CTZ):
9016 CASE_INT_FN (BUILT_IN_POPCOUNT):
9017 CASE_INT_FN (BUILT_IN_PARITY):
9018 return fold_builtin_bitop (fndecl, arglist);
9020 case BUILT_IN_MEMSET:
9021 return fold_builtin_memset (arglist, type, ignore);
9023 case BUILT_IN_MEMCPY:
9024 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9026 case BUILT_IN_MEMPCPY:
9027 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9029 case BUILT_IN_MEMMOVE:
9030 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9032 case BUILT_IN_BZERO:
9033 return fold_builtin_bzero (arglist, ignore);
9035 case BUILT_IN_BCOPY:
9036 return fold_builtin_bcopy (arglist, ignore);
9038 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9039 return fold_builtin_signbit (fndecl, arglist);
9041 case BUILT_IN_ISASCII:
9042 return fold_builtin_isascii (arglist);
9044 case BUILT_IN_TOASCII:
9045 return fold_builtin_toascii (arglist);
9047 case BUILT_IN_ISDIGIT:
9048 return fold_builtin_isdigit (arglist);
9050 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9051 return fold_builtin_copysign (fndecl, arglist, type);
9053 CASE_FLT_FN (BUILT_IN_FINITE):
9054 case BUILT_IN_FINITED32:
9055 case BUILT_IN_FINITED64:
9056 case BUILT_IN_FINITED128:
9057 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9059 CASE_FLT_FN (BUILT_IN_ISINF):
9060 case BUILT_IN_ISINFD32:
9061 case BUILT_IN_ISINFD64:
9062 case BUILT_IN_ISINFD128:
9063 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9065 CASE_FLT_FN (BUILT_IN_ISNAN):
9066 case BUILT_IN_ISNAND32:
9067 case BUILT_IN_ISNAND64:
9068 case BUILT_IN_ISNAND128:
9069 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9071 case BUILT_IN_ISGREATER:
9072 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9073 case BUILT_IN_ISGREATEREQUAL:
9074 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9075 case BUILT_IN_ISLESS:
9076 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9077 case BUILT_IN_ISLESSEQUAL:
9078 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9079 case BUILT_IN_ISLESSGREATER:
9080 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9081 case BUILT_IN_ISUNORDERED:
9082 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9083 NOP_EXPR);
9085 /* We do the folding for va_start in the expander. */
9086 case BUILT_IN_VA_START:
9087 break;
9089 case BUILT_IN_OBJECT_SIZE:
9090 return fold_builtin_object_size (arglist);
9091 case BUILT_IN_MEMCPY_CHK:
9092 case BUILT_IN_MEMPCPY_CHK:
9093 case BUILT_IN_MEMMOVE_CHK:
9094 case BUILT_IN_MEMSET_CHK:
9095 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9096 DECL_FUNCTION_CODE (fndecl));
9097 case BUILT_IN_STRCPY_CHK:
9098 case BUILT_IN_STPCPY_CHK:
9099 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9100 DECL_FUNCTION_CODE (fndecl));
9101 case BUILT_IN_STRNCPY_CHK:
9102 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9103 case BUILT_IN_STRCAT_CHK:
9104 return fold_builtin_strcat_chk (fndecl, arglist);
9105 case BUILT_IN_STRNCAT_CHK:
9106 return fold_builtin_strncat_chk (fndecl, arglist);
9107 case BUILT_IN_SPRINTF_CHK:
9108 case BUILT_IN_VSPRINTF_CHK:
9109 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9110 case BUILT_IN_SNPRINTF_CHK:
9111 case BUILT_IN_VSNPRINTF_CHK:
9112 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9113 DECL_FUNCTION_CODE (fndecl));
9115 case BUILT_IN_PRINTF:
9116 case BUILT_IN_PRINTF_UNLOCKED:
9117 case BUILT_IN_VPRINTF:
9118 case BUILT_IN_PRINTF_CHK:
9119 case BUILT_IN_VPRINTF_CHK:
9120 return fold_builtin_printf (fndecl, arglist, ignore,
9121 DECL_FUNCTION_CODE (fndecl));
9123 case BUILT_IN_FPRINTF:
9124 case BUILT_IN_FPRINTF_UNLOCKED:
9125 case BUILT_IN_VFPRINTF:
9126 case BUILT_IN_FPRINTF_CHK:
9127 case BUILT_IN_VFPRINTF_CHK:
9128 return fold_builtin_fprintf (fndecl, arglist, ignore,
9129 DECL_FUNCTION_CODE (fndecl));
9131 default:
9132 break;
9135 return 0;
9138 /* A wrapper function for builtin folding that prevents warnings for
9139 "statement without effect" and the like, caused by removing the
9140 call node earlier than the warning is generated. */
9142 tree
9143 fold_builtin (tree fndecl, tree arglist, bool ignore)
9145 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9146 if (exp)
9148 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9149 TREE_NO_WARNING (exp) = 1;
9152 return exp;
9155 /* Conveniently construct a function call expression. */
9157 tree
9158 build_function_call_expr (tree fn, tree arglist)
9160 tree call_expr;
9162 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9163 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9164 call_expr, arglist, NULL_TREE);
9167 /* This function validates the types of a function call argument list
9168 represented as a tree chain of parameters against a specified list
9169 of tree_codes. If the last specifier is a 0, that represents an
9170 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9172 static int
9173 validate_arglist (tree arglist, ...)
9175 enum tree_code code;
9176 int res = 0;
9177 va_list ap;
9179 va_start (ap, arglist);
9183 code = va_arg (ap, enum tree_code);
9184 switch (code)
9186 case 0:
9187 /* This signifies an ellipses, any further arguments are all ok. */
9188 res = 1;
9189 goto end;
9190 case VOID_TYPE:
9191 /* This signifies an endlink, if no arguments remain, return
9192 true, otherwise return false. */
9193 res = arglist == 0;
9194 goto end;
9195 default:
9196 /* If no parameters remain or the parameter's code does not
9197 match the specified code, return false. Otherwise continue
9198 checking any remaining arguments. */
9199 if (arglist == 0)
9200 goto end;
9201 if (code == POINTER_TYPE)
9203 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9204 goto end;
9206 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9207 goto end;
9208 break;
9210 arglist = TREE_CHAIN (arglist);
9212 while (1);
9214 /* We need gotos here since we can only have one VA_CLOSE in a
9215 function. */
9216 end: ;
9217 va_end (ap);
9219 return res;
9222 /* Default target-specific builtin expander that does nothing. */
9225 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9226 rtx target ATTRIBUTE_UNUSED,
9227 rtx subtarget ATTRIBUTE_UNUSED,
9228 enum machine_mode mode ATTRIBUTE_UNUSED,
9229 int ignore ATTRIBUTE_UNUSED)
9231 return NULL_RTX;
9234 /* Returns true is EXP represents data that would potentially reside
9235 in a readonly section. */
9237 static bool
9238 readonly_data_expr (tree exp)
9240 STRIP_NOPS (exp);
9242 if (TREE_CODE (exp) != ADDR_EXPR)
9243 return false;
9245 exp = get_base_address (TREE_OPERAND (exp, 0));
9246 if (!exp)
9247 return false;
9249 /* Make sure we call decl_readonly_section only for trees it
9250 can handle (since it returns true for everything it doesn't
9251 understand). */
9252 if (TREE_CODE (exp) == STRING_CST
9253 || TREE_CODE (exp) == CONSTRUCTOR
9254 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9255 return decl_readonly_section (exp, 0);
9256 else
9257 return false;
9260 /* Simplify a call to the strstr builtin.
9262 Return 0 if no simplification was possible, otherwise return the
9263 simplified form of the call as a tree.
9265 The simplified form may be a constant or other expression which
9266 computes the same value, but in a more efficient manner (including
9267 calls to other builtin functions).
9269 The call may contain arguments which need to be evaluated, but
9270 which are not useful to determine the result of the call. In
9271 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9272 COMPOUND_EXPR will be an argument which must be evaluated.
9273 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9274 COMPOUND_EXPR in the chain will contain the tree for the simplified
9275 form of the builtin function call. */
9277 static tree
9278 fold_builtin_strstr (tree arglist, tree type)
9280 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9281 return 0;
9282 else
9284 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9285 tree fn;
9286 const char *p1, *p2;
9288 p2 = c_getstr (s2);
9289 if (p2 == NULL)
9290 return 0;
9292 p1 = c_getstr (s1);
9293 if (p1 != NULL)
9295 const char *r = strstr (p1, p2);
9296 tree tem;
9298 if (r == NULL)
9299 return build_int_cst (TREE_TYPE (s1), 0);
9301 /* Return an offset into the constant string argument. */
9302 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9303 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9304 return fold_convert (type, tem);
9307 /* The argument is const char *, and the result is char *, so we need
9308 a type conversion here to avoid a warning. */
9309 if (p2[0] == '\0')
9310 return fold_convert (type, s1);
9312 if (p2[1] != '\0')
9313 return 0;
9315 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9316 if (!fn)
9317 return 0;
9319 /* New argument list transforming strstr(s1, s2) to
9320 strchr(s1, s2[0]). */
9321 arglist = build_tree_list (NULL_TREE,
9322 build_int_cst (NULL_TREE, p2[0]));
9323 arglist = tree_cons (NULL_TREE, s1, arglist);
9324 return build_function_call_expr (fn, arglist);
9328 /* Simplify a call to the strchr builtin.
9330 Return 0 if no simplification was possible, otherwise return the
9331 simplified form of the call as a tree.
9333 The simplified form may be a constant or other expression which
9334 computes the same value, but in a more efficient manner (including
9335 calls to other builtin functions).
9337 The call may contain arguments which need to be evaluated, but
9338 which are not useful to determine the result of the call. In
9339 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9340 COMPOUND_EXPR will be an argument which must be evaluated.
9341 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9342 COMPOUND_EXPR in the chain will contain the tree for the simplified
9343 form of the builtin function call. */
9345 static tree
9346 fold_builtin_strchr (tree arglist, tree type)
9348 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9349 return 0;
9350 else
9352 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9353 const char *p1;
9355 if (TREE_CODE (s2) != INTEGER_CST)
9356 return 0;
9358 p1 = c_getstr (s1);
9359 if (p1 != NULL)
9361 char c;
9362 const char *r;
9363 tree tem;
9365 if (target_char_cast (s2, &c))
9366 return 0;
9368 r = strchr (p1, c);
9370 if (r == NULL)
9371 return build_int_cst (TREE_TYPE (s1), 0);
9373 /* Return an offset into the constant string argument. */
9374 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9375 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9376 return fold_convert (type, tem);
9378 return 0;
9382 /* Simplify a call to the strrchr builtin.
9384 Return 0 if no simplification was possible, otherwise return the
9385 simplified form of the call as a tree.
9387 The simplified form may be a constant or other expression which
9388 computes the same value, but in a more efficient manner (including
9389 calls to other builtin functions).
9391 The call may contain arguments which need to be evaluated, but
9392 which are not useful to determine the result of the call. In
9393 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9394 COMPOUND_EXPR will be an argument which must be evaluated.
9395 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9396 COMPOUND_EXPR in the chain will contain the tree for the simplified
9397 form of the builtin function call. */
9399 static tree
9400 fold_builtin_strrchr (tree arglist, tree type)
9402 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9403 return 0;
9404 else
9406 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9407 tree fn;
9408 const char *p1;
9410 if (TREE_CODE (s2) != INTEGER_CST)
9411 return 0;
9413 p1 = c_getstr (s1);
9414 if (p1 != NULL)
9416 char c;
9417 const char *r;
9418 tree tem;
9420 if (target_char_cast (s2, &c))
9421 return 0;
9423 r = strrchr (p1, c);
9425 if (r == NULL)
9426 return build_int_cst (TREE_TYPE (s1), 0);
9428 /* Return an offset into the constant string argument. */
9429 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9430 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9431 return fold_convert (type, tem);
9434 if (! integer_zerop (s2))
9435 return 0;
9437 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9438 if (!fn)
9439 return 0;
9441 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9442 return build_function_call_expr (fn, arglist);
9446 /* Simplify a call to the strpbrk builtin.
9448 Return 0 if no simplification was possible, otherwise return the
9449 simplified form of the call as a tree.
9451 The simplified form may be a constant or other expression which
9452 computes the same value, but in a more efficient manner (including
9453 calls to other builtin functions).
9455 The call may contain arguments which need to be evaluated, but
9456 which are not useful to determine the result of the call. In
9457 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9458 COMPOUND_EXPR will be an argument which must be evaluated.
9459 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9460 COMPOUND_EXPR in the chain will contain the tree for the simplified
9461 form of the builtin function call. */
9463 static tree
9464 fold_builtin_strpbrk (tree arglist, tree type)
9466 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9467 return 0;
9468 else
9470 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9471 tree fn;
9472 const char *p1, *p2;
9474 p2 = c_getstr (s2);
9475 if (p2 == NULL)
9476 return 0;
9478 p1 = c_getstr (s1);
9479 if (p1 != NULL)
9481 const char *r = strpbrk (p1, p2);
9482 tree tem;
9484 if (r == NULL)
9485 return build_int_cst (TREE_TYPE (s1), 0);
9487 /* Return an offset into the constant string argument. */
9488 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9489 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9490 return fold_convert (type, tem);
9493 if (p2[0] == '\0')
9494 /* strpbrk(x, "") == NULL.
9495 Evaluate and ignore s1 in case it had side-effects. */
9496 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9498 if (p2[1] != '\0')
9499 return 0; /* Really call strpbrk. */
9501 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9502 if (!fn)
9503 return 0;
9505 /* New argument list transforming strpbrk(s1, s2) to
9506 strchr(s1, s2[0]). */
9507 arglist = build_tree_list (NULL_TREE,
9508 build_int_cst (NULL_TREE, p2[0]));
9509 arglist = tree_cons (NULL_TREE, s1, arglist);
9510 return build_function_call_expr (fn, arglist);
9514 /* Simplify a call to the strcat builtin.
9516 Return 0 if no simplification was possible, otherwise return the
9517 simplified form of the call as a tree.
9519 The simplified form may be a constant or other expression which
9520 computes the same value, but in a more efficient manner (including
9521 calls to other builtin functions).
9523 The call may contain arguments which need to be evaluated, but
9524 which are not useful to determine the result of the call. In
9525 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9526 COMPOUND_EXPR will be an argument which must be evaluated.
9527 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9528 COMPOUND_EXPR in the chain will contain the tree for the simplified
9529 form of the builtin function call. */
9531 static tree
9532 fold_builtin_strcat (tree arglist)
9534 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9535 return 0;
9536 else
9538 tree dst = TREE_VALUE (arglist),
9539 src = TREE_VALUE (TREE_CHAIN (arglist));
9540 const char *p = c_getstr (src);
9542 /* If the string length is zero, return the dst parameter. */
9543 if (p && *p == '\0')
9544 return dst;
9546 return 0;
9550 /* Simplify a call to the strncat builtin.
9552 Return 0 if no simplification was possible, otherwise return the
9553 simplified form of the call as a tree.
9555 The simplified form may be a constant or other expression which
9556 computes the same value, but in a more efficient manner (including
9557 calls to other builtin functions).
9559 The call may contain arguments which need to be evaluated, but
9560 which are not useful to determine the result of the call. In
9561 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9562 COMPOUND_EXPR will be an argument which must be evaluated.
9563 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9564 COMPOUND_EXPR in the chain will contain the tree for the simplified
9565 form of the builtin function call. */
9567 static tree
9568 fold_builtin_strncat (tree arglist)
9570 if (!validate_arglist (arglist,
9571 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9572 return 0;
9573 else
9575 tree dst = TREE_VALUE (arglist);
9576 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9577 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9578 const char *p = c_getstr (src);
9580 /* If the requested length is zero, or the src parameter string
9581 length is zero, return the dst parameter. */
9582 if (integer_zerop (len) || (p && *p == '\0'))
9583 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9585 /* If the requested len is greater than or equal to the string
9586 length, call strcat. */
9587 if (TREE_CODE (len) == INTEGER_CST && p
9588 && compare_tree_int (len, strlen (p)) >= 0)
9590 tree newarglist
9591 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9592 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9594 /* If the replacement _DECL isn't initialized, don't do the
9595 transformation. */
9596 if (!fn)
9597 return 0;
9599 return build_function_call_expr (fn, newarglist);
9601 return 0;
9605 /* Simplify a call to the strspn builtin.
9607 Return 0 if no simplification was possible, otherwise return the
9608 simplified form of the call as a tree.
9610 The simplified form may be a constant or other expression which
9611 computes the same value, but in a more efficient manner (including
9612 calls to other builtin functions).
9614 The call may contain arguments which need to be evaluated, but
9615 which are not useful to determine the result of the call. In
9616 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9617 COMPOUND_EXPR will be an argument which must be evaluated.
9618 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9619 COMPOUND_EXPR in the chain will contain the tree for the simplified
9620 form of the builtin function call. */
9622 static tree
9623 fold_builtin_strspn (tree arglist)
9625 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9626 return 0;
9627 else
9629 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9630 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9632 /* If both arguments are constants, evaluate at compile-time. */
9633 if (p1 && p2)
9635 const size_t r = strspn (p1, p2);
9636 return size_int (r);
9639 /* If either argument is "", return 0. */
9640 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9641 /* Evaluate and ignore both arguments in case either one has
9642 side-effects. */
9643 return omit_two_operands (integer_type_node, integer_zero_node,
9644 s1, s2);
9645 return 0;
9649 /* Simplify a call to the strcspn builtin.
9651 Return 0 if no simplification was possible, otherwise return the
9652 simplified form of the call as a tree.
9654 The simplified form may be a constant or other expression which
9655 computes the same value, but in a more efficient manner (including
9656 calls to other builtin functions).
9658 The call may contain arguments which need to be evaluated, but
9659 which are not useful to determine the result of the call. In
9660 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9661 COMPOUND_EXPR will be an argument which must be evaluated.
9662 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9663 COMPOUND_EXPR in the chain will contain the tree for the simplified
9664 form of the builtin function call. */
9666 static tree
9667 fold_builtin_strcspn (tree arglist)
9669 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9670 return 0;
9671 else
9673 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9674 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9676 /* If both arguments are constants, evaluate at compile-time. */
9677 if (p1 && p2)
9679 const size_t r = strcspn (p1, p2);
9680 return size_int (r);
9683 /* If the first argument is "", return 0. */
9684 if (p1 && *p1 == '\0')
9686 /* Evaluate and ignore argument s2 in case it has
9687 side-effects. */
9688 return omit_one_operand (integer_type_node,
9689 integer_zero_node, s2);
9692 /* If the second argument is "", return __builtin_strlen(s1). */
9693 if (p2 && *p2 == '\0')
9695 tree newarglist = build_tree_list (NULL_TREE, s1),
9696 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9698 /* If the replacement _DECL isn't initialized, don't do the
9699 transformation. */
9700 if (!fn)
9701 return 0;
9703 return build_function_call_expr (fn, newarglist);
9705 return 0;
9709 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9710 by the builtin will be ignored. UNLOCKED is true is true if this
9711 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9712 the known length of the string. Return NULL_TREE if no simplification
9713 was possible. */
9715 tree
9716 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9718 tree fn;
9719 /* If we're using an unlocked function, assume the other unlocked
9720 functions exist explicitly. */
9721 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9722 : implicit_built_in_decls[BUILT_IN_FPUTC];
9723 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9724 : implicit_built_in_decls[BUILT_IN_FWRITE];
9726 /* If the return value is used, don't do the transformation. */
9727 if (!ignore)
9728 return 0;
9730 /* Verify the arguments in the original call. */
9731 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9732 return 0;
9734 if (! len)
9735 len = c_strlen (TREE_VALUE (arglist), 0);
9737 /* Get the length of the string passed to fputs. If the length
9738 can't be determined, punt. */
9739 if (!len
9740 || TREE_CODE (len) != INTEGER_CST)
9741 return 0;
9743 switch (compare_tree_int (len, 1))
9745 case -1: /* length is 0, delete the call entirely . */
9746 return omit_one_operand (integer_type_node, integer_zero_node,
9747 TREE_VALUE (TREE_CHAIN (arglist)));
9749 case 0: /* length is 1, call fputc. */
9751 const char *p = c_getstr (TREE_VALUE (arglist));
9753 if (p != NULL)
9755 /* New argument list transforming fputs(string, stream) to
9756 fputc(string[0], stream). */
9757 arglist = build_tree_list (NULL_TREE,
9758 TREE_VALUE (TREE_CHAIN (arglist)));
9759 arglist = tree_cons (NULL_TREE,
9760 build_int_cst (NULL_TREE, p[0]),
9761 arglist);
9762 fn = fn_fputc;
9763 break;
9766 /* FALLTHROUGH */
9767 case 1: /* length is greater than 1, call fwrite. */
9769 tree string_arg;
9771 /* If optimizing for size keep fputs. */
9772 if (optimize_size)
9773 return 0;
9774 string_arg = TREE_VALUE (arglist);
9775 /* New argument list transforming fputs(string, stream) to
9776 fwrite(string, 1, len, stream). */
9777 arglist = build_tree_list (NULL_TREE,
9778 TREE_VALUE (TREE_CHAIN (arglist)));
9779 arglist = tree_cons (NULL_TREE, len, arglist);
9780 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9781 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9782 fn = fn_fwrite;
9783 break;
9785 default:
9786 gcc_unreachable ();
9789 /* If the replacement _DECL isn't initialized, don't do the
9790 transformation. */
9791 if (!fn)
9792 return 0;
9794 /* These optimizations are only performed when the result is ignored,
9795 hence there's no need to cast the result to integer_type_node. */
9796 return build_function_call_expr (fn, arglist);
9799 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9800 produced. False otherwise. This is done so that we don't output the error
9801 or warning twice or three times. */
9802 bool
9803 fold_builtin_next_arg (tree arglist)
9805 tree fntype = TREE_TYPE (current_function_decl);
9807 if (TYPE_ARG_TYPES (fntype) == 0
9808 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9809 == void_type_node))
9811 error ("%<va_start%> used in function with fixed args");
9812 return true;
9814 else if (!arglist)
9816 /* Evidently an out of date version of <stdarg.h>; can't validate
9817 va_start's second argument, but can still work as intended. */
9818 warning (0, "%<__builtin_next_arg%> called without an argument");
9819 return true;
9821 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9822 when we checked the arguments and if needed issued a warning. */
9823 else if (!TREE_CHAIN (arglist)
9824 || !integer_zerop (TREE_VALUE (arglist))
9825 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9826 || TREE_CHAIN (TREE_CHAIN (arglist)))
9828 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9829 tree arg = TREE_VALUE (arglist);
9831 if (TREE_CHAIN (arglist))
9833 error ("%<va_start%> used with too many arguments");
9834 return true;
9837 /* Strip off all nops for the sake of the comparison. This
9838 is not quite the same as STRIP_NOPS. It does more.
9839 We must also strip off INDIRECT_EXPR for C++ reference
9840 parameters. */
9841 while (TREE_CODE (arg) == NOP_EXPR
9842 || TREE_CODE (arg) == CONVERT_EXPR
9843 || TREE_CODE (arg) == NON_LVALUE_EXPR
9844 || TREE_CODE (arg) == INDIRECT_REF)
9845 arg = TREE_OPERAND (arg, 0);
9846 if (arg != last_parm)
9848 /* FIXME: Sometimes with the tree optimizers we can get the
9849 not the last argument even though the user used the last
9850 argument. We just warn and set the arg to be the last
9851 argument so that we will get wrong-code because of
9852 it. */
9853 warning (0, "second parameter of %<va_start%> not last named argument");
9855 /* We want to verify the second parameter just once before the tree
9856 optimizers are run and then avoid keeping it in the tree,
9857 as otherwise we could warn even for correct code like:
9858 void foo (int i, ...)
9859 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9860 TREE_VALUE (arglist) = integer_zero_node;
9861 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9863 return false;
9867 /* Simplify a call to the sprintf builtin.
9869 Return 0 if no simplification was possible, otherwise return the
9870 simplified form of the call as a tree. If IGNORED is true, it means that
9871 the caller does not use the returned value of the function. */
9873 static tree
9874 fold_builtin_sprintf (tree arglist, int ignored)
9876 tree call, retval, dest, fmt;
9877 const char *fmt_str = NULL;
9879 /* Verify the required arguments in the original call. We deal with two
9880 types of sprintf() calls: 'sprintf (str, fmt)' and
9881 'sprintf (dest, "%s", orig)'. */
9882 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9883 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9884 VOID_TYPE))
9885 return NULL_TREE;
9887 /* Get the destination string and the format specifier. */
9888 dest = TREE_VALUE (arglist);
9889 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9891 /* Check whether the format is a literal string constant. */
9892 fmt_str = c_getstr (fmt);
9893 if (fmt_str == NULL)
9894 return NULL_TREE;
9896 call = NULL_TREE;
9897 retval = NULL_TREE;
9899 if (!init_target_chars())
9900 return 0;
9902 /* If the format doesn't contain % args or %%, use strcpy. */
9903 if (strchr (fmt_str, target_percent) == NULL)
9905 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9907 if (!fn)
9908 return NULL_TREE;
9910 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9911 'format' is known to contain no % formats. */
9912 arglist = build_tree_list (NULL_TREE, fmt);
9913 arglist = tree_cons (NULL_TREE, dest, arglist);
9914 call = build_function_call_expr (fn, arglist);
9915 if (!ignored)
9916 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9919 /* If the format is "%s", use strcpy if the result isn't used. */
9920 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9922 tree fn, orig;
9923 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9925 if (!fn)
9926 return NULL_TREE;
9928 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9929 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9930 arglist = build_tree_list (NULL_TREE, orig);
9931 arglist = tree_cons (NULL_TREE, dest, arglist);
9932 if (!ignored)
9934 retval = c_strlen (orig, 1);
9935 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9936 return NULL_TREE;
9938 call = build_function_call_expr (fn, arglist);
9941 if (call && retval)
9943 retval = fold_convert
9944 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9945 retval);
9946 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9948 else
9949 return call;
9952 /* Expand a call to __builtin_object_size. */
9955 expand_builtin_object_size (tree exp)
9957 tree ost;
9958 int object_size_type;
9959 tree fndecl = get_callee_fndecl (exp);
9960 tree arglist = TREE_OPERAND (exp, 1);
9961 location_t locus = EXPR_LOCATION (exp);
9963 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9965 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9966 &locus, fndecl);
9967 expand_builtin_trap ();
9968 return const0_rtx;
9971 ost = TREE_VALUE (TREE_CHAIN (arglist));
9972 STRIP_NOPS (ost);
9974 if (TREE_CODE (ost) != INTEGER_CST
9975 || tree_int_cst_sgn (ost) < 0
9976 || compare_tree_int (ost, 3) > 0)
9978 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9979 &locus, fndecl);
9980 expand_builtin_trap ();
9981 return const0_rtx;
9984 object_size_type = tree_low_cst (ost, 0);
9986 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9989 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9990 FCODE is the BUILT_IN_* to use.
9991 Return 0 if we failed; the caller should emit a normal call,
9992 otherwise try to get the result in TARGET, if convenient (and in
9993 mode MODE if that's convenient). */
9995 static rtx
9996 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9997 enum built_in_function fcode)
9999 tree arglist = TREE_OPERAND (exp, 1);
10000 tree dest, src, len, size;
10002 if (!validate_arglist (arglist,
10003 POINTER_TYPE,
10004 fcode == BUILT_IN_MEMSET_CHK
10005 ? INTEGER_TYPE : POINTER_TYPE,
10006 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10007 return 0;
10009 dest = TREE_VALUE (arglist);
10010 src = TREE_VALUE (TREE_CHAIN (arglist));
10011 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10012 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10014 if (! host_integerp (size, 1))
10015 return 0;
10017 if (host_integerp (len, 1) || integer_all_onesp (size))
10019 tree fn;
10021 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10023 location_t locus = EXPR_LOCATION (exp);
10024 warning (0, "%Hcall to %D will always overflow destination buffer",
10025 &locus, get_callee_fndecl (exp));
10026 return 0;
10029 arglist = build_tree_list (NULL_TREE, len);
10030 arglist = tree_cons (NULL_TREE, src, arglist);
10031 arglist = tree_cons (NULL_TREE, dest, arglist);
10033 fn = NULL_TREE;
10034 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10035 mem{cpy,pcpy,move,set} is available. */
10036 switch (fcode)
10038 case BUILT_IN_MEMCPY_CHK:
10039 fn = built_in_decls[BUILT_IN_MEMCPY];
10040 break;
10041 case BUILT_IN_MEMPCPY_CHK:
10042 fn = built_in_decls[BUILT_IN_MEMPCPY];
10043 break;
10044 case BUILT_IN_MEMMOVE_CHK:
10045 fn = built_in_decls[BUILT_IN_MEMMOVE];
10046 break;
10047 case BUILT_IN_MEMSET_CHK:
10048 fn = built_in_decls[BUILT_IN_MEMSET];
10049 break;
10050 default:
10051 break;
10054 if (! fn)
10055 return 0;
10057 fn = build_function_call_expr (fn, arglist);
10058 if (TREE_CODE (fn) == CALL_EXPR)
10059 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10060 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10062 else if (fcode == BUILT_IN_MEMSET_CHK)
10063 return 0;
10064 else
10066 unsigned int dest_align
10067 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10069 /* If DEST is not a pointer type, call the normal function. */
10070 if (dest_align == 0)
10071 return 0;
10073 /* If SRC and DEST are the same (and not volatile), do nothing. */
10074 if (operand_equal_p (src, dest, 0))
10076 tree expr;
10078 if (fcode != BUILT_IN_MEMPCPY_CHK)
10080 /* Evaluate and ignore LEN in case it has side-effects. */
10081 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10082 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10085 len = fold_convert (TREE_TYPE (dest), len);
10086 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10087 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10090 /* __memmove_chk special case. */
10091 if (fcode == BUILT_IN_MEMMOVE_CHK)
10093 unsigned int src_align
10094 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10096 if (src_align == 0)
10097 return 0;
10099 /* If src is categorized for a readonly section we can use
10100 normal __memcpy_chk. */
10101 if (readonly_data_expr (src))
10103 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10104 if (!fn)
10105 return 0;
10106 fn = build_function_call_expr (fn, arglist);
10107 if (TREE_CODE (fn) == CALL_EXPR)
10108 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10109 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10112 return 0;
10116 /* Emit warning if a buffer overflow is detected at compile time. */
10118 static void
10119 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10121 int arg_mask, is_strlen = 0;
10122 tree arglist = TREE_OPERAND (exp, 1), a;
10123 tree len, size;
10124 location_t locus;
10126 switch (fcode)
10128 case BUILT_IN_STRCPY_CHK:
10129 case BUILT_IN_STPCPY_CHK:
10130 /* For __strcat_chk the warning will be emitted only if overflowing
10131 by at least strlen (dest) + 1 bytes. */
10132 case BUILT_IN_STRCAT_CHK:
10133 arg_mask = 6;
10134 is_strlen = 1;
10135 break;
10136 case BUILT_IN_STRNCPY_CHK:
10137 arg_mask = 12;
10138 break;
10139 case BUILT_IN_SNPRINTF_CHK:
10140 case BUILT_IN_VSNPRINTF_CHK:
10141 arg_mask = 10;
10142 break;
10143 default:
10144 gcc_unreachable ();
10147 len = NULL_TREE;
10148 size = NULL_TREE;
10149 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10150 if (arg_mask & 1)
10152 if (len)
10153 size = a;
10154 else
10155 len = a;
10158 if (!len || !size)
10159 return;
10161 len = TREE_VALUE (len);
10162 size = TREE_VALUE (size);
10164 if (! host_integerp (size, 1) || integer_all_onesp (size))
10165 return;
10167 if (is_strlen)
10169 len = c_strlen (len, 1);
10170 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10171 return;
10173 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10174 return;
10176 locus = EXPR_LOCATION (exp);
10177 warning (0, "%Hcall to %D will always overflow destination buffer",
10178 &locus, get_callee_fndecl (exp));
10181 /* Emit warning if a buffer overflow is detected at compile time
10182 in __sprintf_chk/__vsprintf_chk calls. */
10184 static void
10185 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10187 tree arglist = TREE_OPERAND (exp, 1);
10188 tree dest, size, len, fmt, flag;
10189 const char *fmt_str;
10191 /* Verify the required arguments in the original call. */
10192 if (! arglist)
10193 return;
10194 dest = TREE_VALUE (arglist);
10195 arglist = TREE_CHAIN (arglist);
10196 if (! arglist)
10197 return;
10198 flag = TREE_VALUE (arglist);
10199 arglist = TREE_CHAIN (arglist);
10200 if (! arglist)
10201 return;
10202 size = TREE_VALUE (arglist);
10203 arglist = TREE_CHAIN (arglist);
10204 if (! arglist)
10205 return;
10206 fmt = TREE_VALUE (arglist);
10207 arglist = TREE_CHAIN (arglist);
10209 if (! host_integerp (size, 1) || integer_all_onesp (size))
10210 return;
10212 /* Check whether the format is a literal string constant. */
10213 fmt_str = c_getstr (fmt);
10214 if (fmt_str == NULL)
10215 return;
10217 if (!init_target_chars())
10218 return;
10220 /* If the format doesn't contain % args or %%, we know its size. */
10221 if (strchr (fmt_str, target_percent) == 0)
10222 len = build_int_cstu (size_type_node, strlen (fmt_str));
10223 /* If the format is "%s" and first ... argument is a string literal,
10224 we know it too. */
10225 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10227 tree arg;
10229 if (! arglist)
10230 return;
10231 arg = TREE_VALUE (arglist);
10232 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10233 return;
10235 len = c_strlen (arg, 1);
10236 if (!len || ! host_integerp (len, 1))
10237 return;
10239 else
10240 return;
10242 if (! tree_int_cst_lt (len, size))
10244 location_t locus = EXPR_LOCATION (exp);
10245 warning (0, "%Hcall to %D will always overflow destination buffer",
10246 &locus, get_callee_fndecl (exp));
10250 /* Fold a call to __builtin_object_size, if possible. */
10252 tree
10253 fold_builtin_object_size (tree arglist)
10255 tree ptr, ost, ret = 0;
10256 int object_size_type;
10258 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10259 return 0;
10261 ptr = TREE_VALUE (arglist);
10262 ost = TREE_VALUE (TREE_CHAIN (arglist));
10263 STRIP_NOPS (ost);
10265 if (TREE_CODE (ost) != INTEGER_CST
10266 || tree_int_cst_sgn (ost) < 0
10267 || compare_tree_int (ost, 3) > 0)
10268 return 0;
10270 object_size_type = tree_low_cst (ost, 0);
10272 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10273 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10274 and (size_t) 0 for types 2 and 3. */
10275 if (TREE_SIDE_EFFECTS (ptr))
10276 return fold_convert (size_type_node,
10277 object_size_type < 2
10278 ? integer_minus_one_node : integer_zero_node);
10280 if (TREE_CODE (ptr) == ADDR_EXPR)
10281 ret = build_int_cstu (size_type_node,
10282 compute_builtin_object_size (ptr, object_size_type));
10284 else if (TREE_CODE (ptr) == SSA_NAME)
10286 unsigned HOST_WIDE_INT bytes;
10288 /* If object size is not known yet, delay folding until
10289 later. Maybe subsequent passes will help determining
10290 it. */
10291 bytes = compute_builtin_object_size (ptr, object_size_type);
10292 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10293 ? -1 : 0))
10294 ret = build_int_cstu (size_type_node, bytes);
10297 if (ret)
10299 ret = force_fit_type (ret, -1, false, false);
10300 if (TREE_CONSTANT_OVERFLOW (ret))
10301 ret = 0;
10304 return ret;
10307 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10308 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10309 code of the builtin. If MAXLEN is not NULL, it is maximum length
10310 passed as third argument. */
10312 tree
10313 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10314 enum built_in_function fcode)
10316 tree dest, src, len, size, fn;
10318 if (!validate_arglist (arglist,
10319 POINTER_TYPE,
10320 fcode == BUILT_IN_MEMSET_CHK
10321 ? INTEGER_TYPE : POINTER_TYPE,
10322 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10323 return 0;
10325 dest = TREE_VALUE (arglist);
10326 /* Actually val for __memset_chk, but it doesn't matter. */
10327 src = TREE_VALUE (TREE_CHAIN (arglist));
10328 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10329 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10331 /* If SRC and DEST are the same (and not volatile), return DEST
10332 (resp. DEST+LEN for __mempcpy_chk). */
10333 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10335 if (fcode != BUILT_IN_MEMPCPY_CHK)
10336 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10337 else
10339 tree temp = fold_convert (TREE_TYPE (dest), len);
10340 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10341 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10345 if (! host_integerp (size, 1))
10346 return 0;
10348 if (! integer_all_onesp (size))
10350 if (! host_integerp (len, 1))
10352 /* If LEN is not constant, try MAXLEN too.
10353 For MAXLEN only allow optimizing into non-_ocs function
10354 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10355 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10357 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10359 /* (void) __mempcpy_chk () can be optimized into
10360 (void) __memcpy_chk (). */
10361 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10362 if (!fn)
10363 return 0;
10365 return build_function_call_expr (fn, arglist);
10367 return 0;
10370 else
10371 maxlen = len;
10373 if (tree_int_cst_lt (size, maxlen))
10374 return 0;
10377 arglist = build_tree_list (NULL_TREE, len);
10378 arglist = tree_cons (NULL_TREE, src, arglist);
10379 arglist = tree_cons (NULL_TREE, dest, arglist);
10381 fn = NULL_TREE;
10382 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10383 mem{cpy,pcpy,move,set} is available. */
10384 switch (fcode)
10386 case BUILT_IN_MEMCPY_CHK:
10387 fn = built_in_decls[BUILT_IN_MEMCPY];
10388 break;
10389 case BUILT_IN_MEMPCPY_CHK:
10390 fn = built_in_decls[BUILT_IN_MEMPCPY];
10391 break;
10392 case BUILT_IN_MEMMOVE_CHK:
10393 fn = built_in_decls[BUILT_IN_MEMMOVE];
10394 break;
10395 case BUILT_IN_MEMSET_CHK:
10396 fn = built_in_decls[BUILT_IN_MEMSET];
10397 break;
10398 default:
10399 break;
10402 if (!fn)
10403 return 0;
10405 return build_function_call_expr (fn, arglist);
10408 /* Fold a call to the __st[rp]cpy_chk builtin.
10409 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10410 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10411 strings passed as second argument. */
10413 tree
10414 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10415 enum built_in_function fcode)
10417 tree dest, src, size, len, fn;
10419 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10420 VOID_TYPE))
10421 return 0;
10423 dest = TREE_VALUE (arglist);
10424 src = TREE_VALUE (TREE_CHAIN (arglist));
10425 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10427 /* If SRC and DEST are the same (and not volatile), return DEST. */
10428 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10429 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10431 if (! host_integerp (size, 1))
10432 return 0;
10434 if (! integer_all_onesp (size))
10436 len = c_strlen (src, 1);
10437 if (! len || ! host_integerp (len, 1))
10439 /* If LEN is not constant, try MAXLEN too.
10440 For MAXLEN only allow optimizing into non-_ocs function
10441 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10442 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10444 if (fcode == BUILT_IN_STPCPY_CHK)
10446 if (! ignore)
10447 return 0;
10449 /* If return value of __stpcpy_chk is ignored,
10450 optimize into __strcpy_chk. */
10451 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10452 if (!fn)
10453 return 0;
10455 return build_function_call_expr (fn, arglist);
10458 if (! len || TREE_SIDE_EFFECTS (len))
10459 return 0;
10461 /* If c_strlen returned something, but not a constant,
10462 transform __strcpy_chk into __memcpy_chk. */
10463 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10464 if (!fn)
10465 return 0;
10467 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10468 arglist = build_tree_list (NULL_TREE, size);
10469 arglist = tree_cons (NULL_TREE, len, arglist);
10470 arglist = tree_cons (NULL_TREE, src, arglist);
10471 arglist = tree_cons (NULL_TREE, dest, arglist);
10472 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10473 build_function_call_expr (fn, arglist));
10476 else
10477 maxlen = len;
10479 if (! tree_int_cst_lt (maxlen, size))
10480 return 0;
10483 arglist = build_tree_list (NULL_TREE, src);
10484 arglist = tree_cons (NULL_TREE, dest, arglist);
10486 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10487 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10488 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10489 if (!fn)
10490 return 0;
10492 return build_function_call_expr (fn, arglist);
10495 /* Fold a call to the __strncpy_chk builtin.
10496 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10498 tree
10499 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10501 tree dest, src, size, len, fn;
10503 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10504 INTEGER_TYPE, VOID_TYPE))
10505 return 0;
10507 dest = TREE_VALUE (arglist);
10508 src = TREE_VALUE (TREE_CHAIN (arglist));
10509 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10510 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10512 if (! host_integerp (size, 1))
10513 return 0;
10515 if (! integer_all_onesp (size))
10517 if (! host_integerp (len, 1))
10519 /* If LEN is not constant, try MAXLEN too.
10520 For MAXLEN only allow optimizing into non-_ocs function
10521 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10522 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10523 return 0;
10525 else
10526 maxlen = len;
10528 if (tree_int_cst_lt (size, maxlen))
10529 return 0;
10532 arglist = build_tree_list (NULL_TREE, len);
10533 arglist = tree_cons (NULL_TREE, src, arglist);
10534 arglist = tree_cons (NULL_TREE, dest, arglist);
10536 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10537 fn = built_in_decls[BUILT_IN_STRNCPY];
10538 if (!fn)
10539 return 0;
10541 return build_function_call_expr (fn, arglist);
10544 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10546 static tree
10547 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10549 tree dest, src, size, fn;
10550 const char *p;
10552 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10553 VOID_TYPE))
10554 return 0;
10556 dest = TREE_VALUE (arglist);
10557 src = TREE_VALUE (TREE_CHAIN (arglist));
10558 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10560 p = c_getstr (src);
10561 /* If the SRC parameter is "", return DEST. */
10562 if (p && *p == '\0')
10563 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10565 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10566 return 0;
10568 arglist = build_tree_list (NULL_TREE, src);
10569 arglist = tree_cons (NULL_TREE, dest, arglist);
10571 /* If __builtin_strcat_chk is used, assume strcat is available. */
10572 fn = built_in_decls[BUILT_IN_STRCAT];
10573 if (!fn)
10574 return 0;
10576 return build_function_call_expr (fn, arglist);
10579 /* Fold a call to the __strncat_chk builtin EXP. */
10581 static tree
10582 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10584 tree dest, src, size, len, fn;
10585 const char *p;
10587 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10588 INTEGER_TYPE, VOID_TYPE))
10589 return 0;
10591 dest = TREE_VALUE (arglist);
10592 src = TREE_VALUE (TREE_CHAIN (arglist));
10593 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10594 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10596 p = c_getstr (src);
10597 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10598 if (p && *p == '\0')
10599 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10600 else if (integer_zerop (len))
10601 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10603 if (! host_integerp (size, 1))
10604 return 0;
10606 if (! integer_all_onesp (size))
10608 tree src_len = c_strlen (src, 1);
10609 if (src_len
10610 && host_integerp (src_len, 1)
10611 && host_integerp (len, 1)
10612 && ! tree_int_cst_lt (len, src_len))
10614 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10615 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10616 if (!fn)
10617 return 0;
10619 arglist = build_tree_list (NULL_TREE, size);
10620 arglist = tree_cons (NULL_TREE, src, arglist);
10621 arglist = tree_cons (NULL_TREE, dest, arglist);
10622 return build_function_call_expr (fn, arglist);
10624 return 0;
10627 arglist = build_tree_list (NULL_TREE, len);
10628 arglist = tree_cons (NULL_TREE, src, arglist);
10629 arglist = tree_cons (NULL_TREE, dest, arglist);
10631 /* If __builtin_strncat_chk is used, assume strncat is available. */
10632 fn = built_in_decls[BUILT_IN_STRNCAT];
10633 if (!fn)
10634 return 0;
10636 return build_function_call_expr (fn, arglist);
10639 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10640 a normal call should be emitted rather than expanding the function
10641 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10643 static tree
10644 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10646 tree dest, size, len, fn, fmt, flag;
10647 const char *fmt_str;
10649 /* Verify the required arguments in the original call. */
10650 if (! arglist)
10651 return 0;
10652 dest = TREE_VALUE (arglist);
10653 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10654 return 0;
10655 arglist = TREE_CHAIN (arglist);
10656 if (! arglist)
10657 return 0;
10658 flag = TREE_VALUE (arglist);
10659 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10660 return 0;
10661 arglist = TREE_CHAIN (arglist);
10662 if (! arglist)
10663 return 0;
10664 size = TREE_VALUE (arglist);
10665 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10666 return 0;
10667 arglist = TREE_CHAIN (arglist);
10668 if (! arglist)
10669 return 0;
10670 fmt = TREE_VALUE (arglist);
10671 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10672 return 0;
10673 arglist = TREE_CHAIN (arglist);
10675 if (! host_integerp (size, 1))
10676 return 0;
10678 len = NULL_TREE;
10680 if (!init_target_chars())
10681 return 0;
10683 /* Check whether the format is a literal string constant. */
10684 fmt_str = c_getstr (fmt);
10685 if (fmt_str != NULL)
10687 /* If the format doesn't contain % args or %%, we know the size. */
10688 if (strchr (fmt_str, target_percent) == 0)
10690 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10691 len = build_int_cstu (size_type_node, strlen (fmt_str));
10693 /* If the format is "%s" and first ... argument is a string literal,
10694 we know the size too. */
10695 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10697 tree arg;
10699 if (arglist && !TREE_CHAIN (arglist))
10701 arg = TREE_VALUE (arglist);
10702 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10704 len = c_strlen (arg, 1);
10705 if (! len || ! host_integerp (len, 1))
10706 len = NULL_TREE;
10712 if (! integer_all_onesp (size))
10714 if (! len || ! tree_int_cst_lt (len, size))
10715 return 0;
10718 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10719 or if format doesn't contain % chars or is "%s". */
10720 if (! integer_zerop (flag))
10722 if (fmt_str == NULL)
10723 return 0;
10724 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10725 return 0;
10728 arglist = tree_cons (NULL_TREE, fmt, arglist);
10729 arglist = tree_cons (NULL_TREE, dest, arglist);
10731 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10732 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10733 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10734 if (!fn)
10735 return 0;
10737 return build_function_call_expr (fn, arglist);
10740 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10741 a normal call should be emitted rather than expanding the function
10742 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10743 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10744 passed as second argument. */
10746 tree
10747 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10748 enum built_in_function fcode)
10750 tree dest, size, len, fn, fmt, flag;
10751 const char *fmt_str;
10753 /* Verify the required arguments in the original call. */
10754 if (! arglist)
10755 return 0;
10756 dest = TREE_VALUE (arglist);
10757 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10758 return 0;
10759 arglist = TREE_CHAIN (arglist);
10760 if (! arglist)
10761 return 0;
10762 len = TREE_VALUE (arglist);
10763 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10764 return 0;
10765 arglist = TREE_CHAIN (arglist);
10766 if (! arglist)
10767 return 0;
10768 flag = TREE_VALUE (arglist);
10769 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10770 return 0;
10771 arglist = TREE_CHAIN (arglist);
10772 if (! arglist)
10773 return 0;
10774 size = TREE_VALUE (arglist);
10775 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10776 return 0;
10777 arglist = TREE_CHAIN (arglist);
10778 if (! arglist)
10779 return 0;
10780 fmt = TREE_VALUE (arglist);
10781 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10782 return 0;
10783 arglist = TREE_CHAIN (arglist);
10785 if (! host_integerp (size, 1))
10786 return 0;
10788 if (! integer_all_onesp (size))
10790 if (! host_integerp (len, 1))
10792 /* If LEN is not constant, try MAXLEN too.
10793 For MAXLEN only allow optimizing into non-_ocs function
10794 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10795 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10796 return 0;
10798 else
10799 maxlen = len;
10801 if (tree_int_cst_lt (size, maxlen))
10802 return 0;
10805 if (!init_target_chars())
10806 return 0;
10808 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10809 or if format doesn't contain % chars or is "%s". */
10810 if (! integer_zerop (flag))
10812 fmt_str = c_getstr (fmt);
10813 if (fmt_str == NULL)
10814 return 0;
10815 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10816 return 0;
10819 arglist = tree_cons (NULL_TREE, fmt, arglist);
10820 arglist = tree_cons (NULL_TREE, len, arglist);
10821 arglist = tree_cons (NULL_TREE, dest, arglist);
10823 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10824 available. */
10825 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10826 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10827 if (!fn)
10828 return 0;
10830 return build_function_call_expr (fn, arglist);
10833 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10835 Return 0 if no simplification was possible, otherwise return the
10836 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10837 code of the function to be simplified. */
10839 static tree
10840 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10841 enum built_in_function fcode)
10843 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10844 const char *fmt_str = NULL;
10846 /* If the return value is used, don't do the transformation. */
10847 if (! ignore)
10848 return 0;
10850 /* Verify the required arguments in the original call. */
10851 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10853 tree flag;
10855 if (! arglist)
10856 return 0;
10857 flag = TREE_VALUE (arglist);
10858 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10859 || TREE_SIDE_EFFECTS (flag))
10860 return 0;
10861 arglist = TREE_CHAIN (arglist);
10864 if (! arglist)
10865 return 0;
10866 fmt = TREE_VALUE (arglist);
10867 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10868 return 0;
10869 arglist = TREE_CHAIN (arglist);
10871 /* Check whether the format is a literal string constant. */
10872 fmt_str = c_getstr (fmt);
10873 if (fmt_str == NULL)
10874 return NULL_TREE;
10876 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10878 /* If we're using an unlocked function, assume the other
10879 unlocked functions exist explicitly. */
10880 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10881 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10883 else
10885 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10886 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10889 if (!init_target_chars())
10890 return 0;
10892 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10894 const char *str;
10896 if (strcmp (fmt_str, target_percent_s) == 0)
10898 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10899 return 0;
10901 if (! arglist
10902 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10903 || TREE_CHAIN (arglist))
10904 return 0;
10906 str = c_getstr (TREE_VALUE (arglist));
10907 if (str == NULL)
10908 return 0;
10910 else
10912 /* The format specifier doesn't contain any '%' characters. */
10913 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10914 && arglist)
10915 return 0;
10916 str = fmt_str;
10919 /* If the string was "", printf does nothing. */
10920 if (str[0] == '\0')
10921 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10923 /* If the string has length of 1, call putchar. */
10924 if (str[1] == '\0')
10926 /* Given printf("c"), (where c is any one character,)
10927 convert "c"[0] to an int and pass that to the replacement
10928 function. */
10929 arg = build_int_cst (NULL_TREE, str[0]);
10930 arglist = build_tree_list (NULL_TREE, arg);
10931 fn = fn_putchar;
10933 else
10935 /* If the string was "string\n", call puts("string"). */
10936 size_t len = strlen (str);
10937 if ((unsigned char)str[len - 1] == target_newline)
10939 /* Create a NUL-terminated string that's one char shorter
10940 than the original, stripping off the trailing '\n'. */
10941 char *newstr = alloca (len);
10942 memcpy (newstr, str, len - 1);
10943 newstr[len - 1] = 0;
10945 arg = build_string_literal (len, newstr);
10946 arglist = build_tree_list (NULL_TREE, arg);
10947 fn = fn_puts;
10949 else
10950 /* We'd like to arrange to call fputs(string,stdout) here,
10951 but we need stdout and don't have a way to get it yet. */
10952 return 0;
10956 /* The other optimizations can be done only on the non-va_list variants. */
10957 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10958 return 0;
10960 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10961 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10963 if (! arglist
10964 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10965 || TREE_CHAIN (arglist))
10966 return 0;
10967 fn = fn_puts;
10970 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10971 else if (strcmp (fmt_str, target_percent_c) == 0)
10973 if (! arglist
10974 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10975 || TREE_CHAIN (arglist))
10976 return 0;
10977 fn = fn_putchar;
10980 if (!fn)
10981 return 0;
10983 call = build_function_call_expr (fn, arglist);
10984 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10987 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10989 Return 0 if no simplification was possible, otherwise return the
10990 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10991 code of the function to be simplified. */
10993 static tree
10994 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10995 enum built_in_function fcode)
10997 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10998 const char *fmt_str = NULL;
11000 /* If the return value is used, don't do the transformation. */
11001 if (! ignore)
11002 return 0;
11004 /* Verify the required arguments in the original call. */
11005 if (! arglist)
11006 return 0;
11007 fp = TREE_VALUE (arglist);
11008 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11009 return 0;
11010 arglist = TREE_CHAIN (arglist);
11012 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11014 tree flag;
11016 if (! arglist)
11017 return 0;
11018 flag = TREE_VALUE (arglist);
11019 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11020 || TREE_SIDE_EFFECTS (flag))
11021 return 0;
11022 arglist = TREE_CHAIN (arglist);
11025 if (! arglist)
11026 return 0;
11027 fmt = TREE_VALUE (arglist);
11028 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11029 return 0;
11030 arglist = TREE_CHAIN (arglist);
11032 /* Check whether the format is a literal string constant. */
11033 fmt_str = c_getstr (fmt);
11034 if (fmt_str == NULL)
11035 return NULL_TREE;
11037 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11039 /* If we're using an unlocked function, assume the other
11040 unlocked functions exist explicitly. */
11041 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11042 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11044 else
11046 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11047 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11050 if (!init_target_chars())
11051 return 0;
11053 /* If the format doesn't contain % args or %%, use strcpy. */
11054 if (strchr (fmt_str, target_percent) == NULL)
11056 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11057 && arglist)
11058 return 0;
11060 /* If the format specifier was "", fprintf does nothing. */
11061 if (fmt_str[0] == '\0')
11063 /* If FP has side-effects, just wait until gimplification is
11064 done. */
11065 if (TREE_SIDE_EFFECTS (fp))
11066 return 0;
11068 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11071 /* When "string" doesn't contain %, replace all cases of
11072 fprintf (fp, string) with fputs (string, fp). The fputs
11073 builtin will take care of special cases like length == 1. */
11074 arglist = build_tree_list (NULL_TREE, fp);
11075 arglist = tree_cons (NULL_TREE, fmt, arglist);
11076 fn = fn_fputs;
11079 /* The other optimizations can be done only on the non-va_list variants. */
11080 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11081 return 0;
11083 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11084 else if (strcmp (fmt_str, target_percent_s) == 0)
11086 if (! arglist
11087 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11088 || TREE_CHAIN (arglist))
11089 return 0;
11090 arg = TREE_VALUE (arglist);
11091 arglist = build_tree_list (NULL_TREE, fp);
11092 arglist = tree_cons (NULL_TREE, arg, arglist);
11093 fn = fn_fputs;
11096 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11097 else if (strcmp (fmt_str, target_percent_c) == 0)
11099 if (! arglist
11100 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11101 || TREE_CHAIN (arglist))
11102 return 0;
11103 arg = TREE_VALUE (arglist);
11104 arglist = build_tree_list (NULL_TREE, fp);
11105 arglist = tree_cons (NULL_TREE, arg, arglist);
11106 fn = fn_fputc;
11109 if (!fn)
11110 return 0;
11112 call = build_function_call_expr (fn, arglist);
11113 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11116 /* Initialize format string characters in the target charset. */
11118 static bool
11119 init_target_chars (void)
11121 static bool init;
11122 if (!init)
11124 target_newline = lang_hooks.to_target_charset ('\n');
11125 target_percent = lang_hooks.to_target_charset ('%');
11126 target_c = lang_hooks.to_target_charset ('c');
11127 target_s = lang_hooks.to_target_charset ('s');
11128 if (target_newline == 0 || target_percent == 0 || target_c == 0
11129 || target_s == 0)
11130 return false;
11132 target_percent_c[0] = target_percent;
11133 target_percent_c[1] = target_c;
11134 target_percent_c[2] = '\0';
11136 target_percent_s[0] = target_percent;
11137 target_percent_s[1] = target_s;
11138 target_percent_s[2] = '\0';
11140 target_percent_s_newline[0] = target_percent;
11141 target_percent_s_newline[1] = target_s;
11142 target_percent_s_newline[2] = target_newline;
11143 target_percent_s_newline[3] = '\0';
11145 init = true;
11147 return true;