Remove tm.h and xm.h handling, as it wasn't used. Use nm.h only when needed.
[dragonfly.git] / contrib / gcc-4.1 / gcc / builtins.c
blobc51291b30a47982172939ed7c24f07809d0fdf56
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 tree build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx result_vector (int, rtx);
84 #endif
85 static rtx expand_builtin_setjmp (tree, rtx);
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_sin (tree);
155 static tree fold_builtin_cos (tree, tree, tree);
156 static tree fold_builtin_tan (tree);
157 static tree fold_builtin_atan (tree, tree);
158 static tree fold_builtin_trunc (tree, tree);
159 static tree fold_builtin_floor (tree, tree);
160 static tree fold_builtin_ceil (tree, tree);
161 static tree fold_builtin_round (tree, tree);
162 static tree fold_builtin_int_roundingfn (tree, tree);
163 static tree fold_builtin_bitop (tree, tree);
164 static tree fold_builtin_memcpy (tree, tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree, tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree, tree);
172 static tree fold_builtin_copysign (tree, tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 enum tree_code);
180 static tree fold_builtin_1 (tree, tree, bool);
182 static tree fold_builtin_strpbrk (tree, tree);
183 static tree fold_builtin_strstr (tree, tree);
184 static tree fold_builtin_strrchr (tree, tree);
185 static tree fold_builtin_strcat (tree);
186 static tree fold_builtin_strncat (tree);
187 static tree fold_builtin_strspn (tree);
188 static tree fold_builtin_strcspn (tree);
189 static tree fold_builtin_sprintf (tree, int);
191 static rtx expand_builtin_object_size (tree);
192 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193 enum built_in_function);
194 static void maybe_emit_chk_warning (tree, enum built_in_function);
195 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196 static tree fold_builtin_object_size (tree);
197 static tree fold_builtin_strcat_chk (tree, tree);
198 static tree fold_builtin_strncat_chk (tree, tree);
199 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline;
205 static unsigned HOST_WIDE_INT target_percent;
206 static unsigned HOST_WIDE_INT target_c;
207 static unsigned HOST_WIDE_INT target_s;
208 static char target_percent_c[3];
209 static char target_percent_s[3];
210 static char target_percent_s_newline[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node)
218 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
219 if (strncmp (name, "__builtin_", 10) == 0)
220 return true;
221 if (strncmp (name, "__sync_", 7) == 0)
222 return true;
223 return false;
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
234 static int
235 get_pointer_alignment (tree exp, unsigned int max_align)
237 unsigned int align, inner;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
240 return 0;
242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243 align = MIN (align, max_align);
245 while (1)
247 switch (TREE_CODE (exp))
249 case NOP_EXPR:
250 case CONVERT_EXPR:
251 case NON_LVALUE_EXPR:
252 exp = TREE_OPERAND (exp, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254 return align;
256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257 align = MIN (inner, max_align);
258 break;
260 case PLUS_EXPR:
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
263 ALIGN. */
264 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265 return align;
267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268 & (max_align / BITS_PER_UNIT - 1))
269 != 0)
270 max_align >>= 1;
272 exp = TREE_OPERAND (exp, 0);
273 break;
275 case ADDR_EXPR:
276 /* See what we are pointing at and look at its alignment. */
277 exp = TREE_OPERAND (exp, 0);
278 inner = max_align;
279 if (handled_component_p (exp))
281 HOST_WIDE_INT bitsize, bitpos;
282 tree offset;
283 enum machine_mode mode;
284 int unsignedp, volatilep;
286 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
287 &mode, &unsignedp, &volatilep, true);
288 if (bitpos)
289 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
290 if (offset && TREE_CODE (offset) == PLUS_EXPR
291 && host_integerp (TREE_OPERAND (offset, 1), 1))
293 /* Any overflow in calculating offset_bits won't change
294 the alignment. */
295 unsigned offset_bits
296 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
297 * BITS_PER_UNIT);
299 if (offset_bits)
300 inner = MIN (inner, (offset_bits & -offset_bits));
301 offset = TREE_OPERAND (offset, 0);
303 if (offset && TREE_CODE (offset) == MULT_EXPR
304 && host_integerp (TREE_OPERAND (offset, 1), 1))
306 /* Any overflow in calculating offset_factor won't change
307 the alignment. */
308 unsigned offset_factor
309 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
310 * BITS_PER_UNIT);
312 if (offset_factor)
313 inner = MIN (inner, (offset_factor & -offset_factor));
315 else if (offset)
316 inner = MIN (inner, BITS_PER_UNIT);
318 if (TREE_CODE (exp) == FUNCTION_DECL)
319 align = FUNCTION_BOUNDARY;
320 else if (DECL_P (exp))
321 align = MIN (inner, DECL_ALIGN (exp));
322 #ifdef CONSTANT_ALIGNMENT
323 else if (CONSTANT_CLASS_P (exp))
324 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
325 #endif
326 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
327 || TREE_CODE (exp) == INDIRECT_REF)
328 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
329 else
330 align = MIN (align, inner);
331 return MIN (align, max_align);
333 default:
334 return align;
339 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
340 way, because it could contain a zero byte in the middle.
341 TREE_STRING_LENGTH is the size of the character array, not the string.
343 ONLY_VALUE should be nonzero if the result is not going to be emitted
344 into the instruction stream and zero if it is going to be expanded.
345 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
346 is returned, otherwise NULL, since
347 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
348 evaluate the side-effects.
350 The value returned is of type `ssizetype'.
352 Unfortunately, string_constant can't access the values of const char
353 arrays with initializers, so neither can we do so here. */
355 tree
356 c_strlen (tree src, int only_value)
358 tree offset_node;
359 HOST_WIDE_INT offset;
360 int max;
361 const char *ptr;
363 STRIP_NOPS (src);
364 if (TREE_CODE (src) == COND_EXPR
365 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
367 tree len1, len2;
369 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
370 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
371 if (tree_int_cst_equal (len1, len2))
372 return len1;
375 if (TREE_CODE (src) == COMPOUND_EXPR
376 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
377 return c_strlen (TREE_OPERAND (src, 1), only_value);
379 src = string_constant (src, &offset_node);
380 if (src == 0)
381 return 0;
383 max = TREE_STRING_LENGTH (src) - 1;
384 ptr = TREE_STRING_POINTER (src);
386 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
388 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
389 compute the offset to the following null if we don't know where to
390 start searching for it. */
391 int i;
393 for (i = 0; i < max; i++)
394 if (ptr[i] == 0)
395 return 0;
397 /* We don't know the starting offset, but we do know that the string
398 has no internal zero bytes. We can assume that the offset falls
399 within the bounds of the string; otherwise, the programmer deserves
400 what he gets. Subtract the offset from the length of the string,
401 and return that. This would perhaps not be valid if we were dealing
402 with named arrays in addition to literal string constants. */
404 return size_diffop (size_int (max), offset_node);
407 /* We have a known offset into the string. Start searching there for
408 a null character if we can represent it as a single HOST_WIDE_INT. */
409 if (offset_node == 0)
410 offset = 0;
411 else if (! host_integerp (offset_node, 0))
412 offset = -1;
413 else
414 offset = tree_low_cst (offset_node, 0);
416 /* If the offset is known to be out of bounds, warn, and call strlen at
417 runtime. */
418 if (offset < 0 || offset > max)
420 warning (0, "offset outside bounds of constant string");
421 return 0;
424 /* Use strlen to search for the first zero byte. Since any strings
425 constructed with build_string will have nulls appended, we win even
426 if we get handed something like (char[4])"abcd".
428 Since OFFSET is our starting index into the string, no further
429 calculation is needed. */
430 return ssize_int (strlen (ptr + offset));
433 /* Return a char pointer for a C string if it is a string constant
434 or sum of string constant and integer constant. */
436 static const char *
437 c_getstr (tree src)
439 tree offset_node;
441 src = string_constant (src, &offset_node);
442 if (src == 0)
443 return 0;
445 if (offset_node == 0)
446 return TREE_STRING_POINTER (src);
447 else if (!host_integerp (offset_node, 1)
448 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
449 return 0;
451 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
454 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
455 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
457 static rtx
458 c_readstr (const char *str, enum machine_mode mode)
460 HOST_WIDE_INT c[2];
461 HOST_WIDE_INT ch;
462 unsigned int i, j;
464 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
466 c[0] = 0;
467 c[1] = 0;
468 ch = 1;
469 for (i = 0; i < GET_MODE_SIZE (mode); i++)
471 j = i;
472 if (WORDS_BIG_ENDIAN)
473 j = GET_MODE_SIZE (mode) - i - 1;
474 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
475 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
476 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
477 j *= BITS_PER_UNIT;
478 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
480 if (ch)
481 ch = (unsigned char) str[i];
482 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
484 return immed_double_const (c[0], c[1], mode);
487 /* Cast a target constant CST to target CHAR and if that value fits into
488 host char type, return zero and put that value into variable pointed to by
489 P. */
491 static int
492 target_char_cast (tree cst, char *p)
494 unsigned HOST_WIDE_INT val, hostval;
496 if (!host_integerp (cst, 1)
497 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
498 return 1;
500 val = tree_low_cst (cst, 1);
501 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
502 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
504 hostval = val;
505 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
506 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
508 if (val != hostval)
509 return 1;
511 *p = hostval;
512 return 0;
515 /* Similar to save_expr, but assumes that arbitrary code is not executed
516 in between the multiple evaluations. In particular, we assume that a
517 non-addressable local variable will not be modified. */
519 static tree
520 builtin_save_expr (tree exp)
522 if (TREE_ADDRESSABLE (exp) == 0
523 && (TREE_CODE (exp) == PARM_DECL
524 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
525 return exp;
527 return save_expr (exp);
530 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
531 times to get the address of either a higher stack frame, or a return
532 address located within it (depending on FNDECL_CODE). */
534 static rtx
535 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
537 int i;
539 #ifdef INITIAL_FRAME_ADDRESS_RTX
540 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
541 #else
542 rtx tem;
544 /* For a zero count, we don't care what frame address we return, so frame
545 pointer elimination is OK, and using the soft frame pointer is OK.
546 For a non-zero count, we require a stable offset from the current frame
547 pointer to the previous one, so we must use the hard frame pointer, and
548 we must disable frame pointer elimination. */
549 if (count == 0)
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. */
591 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
592 return tem;
594 /* For __builtin_return_address, Get the return address from that
595 frame. */
596 #ifdef RETURN_ADDR_RTX
597 tem = RETURN_ADDR_RTX (count, tem);
598 #else
599 tem = memory_address (Pmode,
600 plus_constant (tem, GET_MODE_SIZE (Pmode)));
601 tem = gen_frame_mem (Pmode, tem);
602 #endif
603 return tem;
606 /* Alias set used for setjmp buffer. */
607 static HOST_WIDE_INT setjmp_alias_set = -1;
609 /* Construct the leading half of a __builtin_setjmp call. Control will
610 return to RECEIVER_LABEL. This is used directly by sjlj exception
611 handling code. */
613 void
614 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
616 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
617 rtx stack_save;
618 rtx mem;
620 if (setjmp_alias_set == -1)
621 setjmp_alias_set = new_alias_set ();
623 buf_addr = convert_memory_address (Pmode, buf_addr);
625 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
627 /* We store the frame pointer and the address of receiver_label in
628 the buffer and use the rest of it for the stack save area, which
629 is machine-dependent. */
631 mem = gen_rtx_MEM (Pmode, buf_addr);
632 set_mem_alias_set (mem, setjmp_alias_set);
633 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
635 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
636 set_mem_alias_set (mem, setjmp_alias_set);
638 emit_move_insn (validize_mem (mem),
639 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
641 stack_save = gen_rtx_MEM (sa_mode,
642 plus_constant (buf_addr,
643 2 * GET_MODE_SIZE (Pmode)));
644 set_mem_alias_set (stack_save, setjmp_alias_set);
645 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
647 /* If there is further processing to do, do it. */
648 #ifdef HAVE_builtin_setjmp_setup
649 if (HAVE_builtin_setjmp_setup)
650 emit_insn (gen_builtin_setjmp_setup (buf_addr));
651 #endif
653 /* Tell optimize_save_area_alloca that extra work is going to
654 need to go on during alloca. */
655 current_function_calls_setjmp = 1;
657 /* Set this so all the registers get saved in our frame; we need to be
658 able to copy the saved values for any registers from frames we unwind. */
659 current_function_has_nonlocal_label = 1;
662 /* Construct the trailing part of a __builtin_setjmp call.
663 This is used directly by sjlj exception handling code. */
665 void
666 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
668 /* Clobber the FP when we get here, so we have to make sure it's
669 marked as used by this function. */
670 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
672 /* Mark the static chain as clobbered here so life information
673 doesn't get messed up for it. */
674 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
676 /* Now put in the code to restore the frame pointer, and argument
677 pointer, if needed. */
678 #ifdef HAVE_nonlocal_goto
679 if (! HAVE_nonlocal_goto)
680 #endif
682 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
683 /* This might change the hard frame pointer in ways that aren't
684 apparent to early optimization passes, so force a clobber. */
685 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
688 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
689 if (fixed_regs[ARG_POINTER_REGNUM])
691 #ifdef ELIMINABLE_REGS
692 size_t i;
693 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
695 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
696 if (elim_regs[i].from == ARG_POINTER_REGNUM
697 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
698 break;
700 if (i == ARRAY_SIZE (elim_regs))
701 #endif
703 /* Now restore our arg pointer from the address at which it
704 was saved in our stack frame. */
705 emit_move_insn (virtual_incoming_args_rtx,
706 copy_to_reg (get_arg_pointer_save_area (cfun)));
709 #endif
711 #ifdef HAVE_builtin_setjmp_receiver
712 if (HAVE_builtin_setjmp_receiver)
713 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
714 else
715 #endif
716 #ifdef HAVE_nonlocal_goto_receiver
717 if (HAVE_nonlocal_goto_receiver)
718 emit_insn (gen_nonlocal_goto_receiver ());
719 else
720 #endif
721 { /* Nothing */ }
723 /* @@@ This is a kludge. Not all machine descriptions define a blockage
724 insn, but we must not allow the code we just generated to be reordered
725 by scheduling. Specifically, the update of the frame pointer must
726 happen immediately, not later. So emit an ASM_INPUT to act as blockage
727 insn. */
728 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
731 /* __builtin_setjmp is passed a pointer to an array of five words (not
732 all will be used on all machines). It operates similarly to the C
733 library function of the same name, but is more efficient. Much of
734 the code below (and for longjmp) is copied from the handling of
735 non-local gotos.
737 NOTE: This is intended for use by GNAT and the exception handling
738 scheme in the compiler and will only work in the method used by
739 them. */
741 static rtx
742 expand_builtin_setjmp (tree arglist, rtx target)
744 rtx buf_addr, next_lab, cont_lab;
746 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
747 return NULL_RTX;
749 if (target == 0 || !REG_P (target)
750 || REGNO (target) < FIRST_PSEUDO_REGISTER)
751 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
753 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
755 next_lab = gen_label_rtx ();
756 cont_lab = gen_label_rtx ();
758 expand_builtin_setjmp_setup (buf_addr, next_lab);
760 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
761 ensure that pending stack adjustments are flushed. */
762 emit_move_insn (target, const0_rtx);
763 emit_jump (cont_lab);
765 emit_label (next_lab);
767 /* Because setjmp and longjmp are not represented in the CFG, a cfgcleanup
768 may find that the basic block starting with NEXT_LAB is unreachable.
769 The whole block, along with NEXT_LAB, would be removed (see PR26983).
770 Make sure that never happens. */
771 LABEL_PRESERVE_P (next_lab) = 1;
773 expand_builtin_setjmp_receiver (next_lab);
775 /* Set TARGET to one. */
776 emit_move_insn (target, const1_rtx);
777 emit_label (cont_lab);
779 /* Tell flow about the strange goings on. Putting `next_lab' on
780 `nonlocal_goto_handler_labels' to indicates that function
781 calls may traverse the arc back to this label. */
783 current_function_has_nonlocal_label = 1;
784 nonlocal_goto_handler_labels
785 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
787 return target;
790 /* __builtin_longjmp is passed a pointer to an array of five words (not
791 all will be used on all machines). It operates similarly to the C
792 library function of the same name, but is more efficient. Much of
793 the code below is copied from the handling of non-local gotos.
795 NOTE: This is intended for use by GNAT and the exception handling
796 scheme in the compiler and will only work in the method used by
797 them. */
799 static void
800 expand_builtin_longjmp (rtx buf_addr, rtx value)
802 rtx fp, lab, stack, insn, last;
803 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
805 if (setjmp_alias_set == -1)
806 setjmp_alias_set = new_alias_set ();
808 buf_addr = convert_memory_address (Pmode, buf_addr);
810 buf_addr = force_reg (Pmode, buf_addr);
812 /* We used to store value in static_chain_rtx, but that fails if pointers
813 are smaller than integers. We instead require that the user must pass
814 a second argument of 1, because that is what builtin_setjmp will
815 return. This also makes EH slightly more efficient, since we are no
816 longer copying around a value that we don't care about. */
817 gcc_assert (value == const1_rtx);
819 last = get_last_insn ();
820 #ifdef HAVE_builtin_longjmp
821 if (HAVE_builtin_longjmp)
822 emit_insn (gen_builtin_longjmp (buf_addr));
823 else
824 #endif
826 fp = gen_rtx_MEM (Pmode, buf_addr);
827 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
828 GET_MODE_SIZE (Pmode)));
830 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
831 2 * GET_MODE_SIZE (Pmode)));
832 set_mem_alias_set (fp, setjmp_alias_set);
833 set_mem_alias_set (lab, setjmp_alias_set);
834 set_mem_alias_set (stack, setjmp_alias_set);
836 /* Pick up FP, label, and SP from the block and jump. This code is
837 from expand_goto in stmt.c; see there for detailed comments. */
838 #if HAVE_nonlocal_goto
839 if (HAVE_nonlocal_goto)
840 /* We have to pass a value to the nonlocal_goto pattern that will
841 get copied into the static_chain pointer, but it does not matter
842 what that value is, because builtin_setjmp does not use it. */
843 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
844 else
845 #endif
847 lab = copy_to_reg (lab);
849 emit_insn (gen_rtx_CLOBBER (VOIDmode,
850 gen_rtx_MEM (BLKmode,
851 gen_rtx_SCRATCH (VOIDmode))));
852 emit_insn (gen_rtx_CLOBBER (VOIDmode,
853 gen_rtx_MEM (BLKmode,
854 hard_frame_pointer_rtx)));
856 emit_move_insn (hard_frame_pointer_rtx, fp);
857 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
859 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
860 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
861 emit_indirect_jump (lab);
865 /* Search backwards and mark the jump insn as a non-local goto.
866 Note that this precludes the use of __builtin_longjmp to a
867 __builtin_setjmp target in the same function. However, we've
868 already cautioned the user that these functions are for
869 internal exception handling use only. */
870 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
872 gcc_assert (insn != last);
874 if (JUMP_P (insn))
876 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
877 REG_NOTES (insn));
878 break;
880 else if (CALL_P (insn))
881 break;
885 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
886 and the address of the save area. */
888 static rtx
889 expand_builtin_nonlocal_goto (tree arglist)
891 tree t_label, t_save_area;
892 rtx r_label, r_save_area, r_fp, r_sp, insn;
894 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
895 return NULL_RTX;
897 t_label = TREE_VALUE (arglist);
898 arglist = TREE_CHAIN (arglist);
899 t_save_area = TREE_VALUE (arglist);
901 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
902 r_label = convert_memory_address (Pmode, r_label);
903 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
904 r_save_area = convert_memory_address (Pmode, r_save_area);
905 r_fp = gen_rtx_MEM (Pmode, r_save_area);
906 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
907 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
909 current_function_has_nonlocal_goto = 1;
911 #if HAVE_nonlocal_goto
912 /* ??? We no longer need to pass the static chain value, afaik. */
913 if (HAVE_nonlocal_goto)
914 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
915 else
916 #endif
918 r_label = copy_to_reg (r_label);
920 emit_insn (gen_rtx_CLOBBER (VOIDmode,
921 gen_rtx_MEM (BLKmode,
922 gen_rtx_SCRATCH (VOIDmode))));
924 emit_insn (gen_rtx_CLOBBER (VOIDmode,
925 gen_rtx_MEM (BLKmode,
926 hard_frame_pointer_rtx)));
928 /* Restore frame pointer for containing function.
929 This sets the actual hard register used for the frame pointer
930 to the location of the function's incoming static chain info.
931 The non-local goto handler will then adjust it to contain the
932 proper value and reload the argument pointer, if needed. */
933 emit_move_insn (hard_frame_pointer_rtx, r_fp);
934 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
936 /* USE of hard_frame_pointer_rtx added for consistency;
937 not clear if really needed. */
938 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
939 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
940 emit_indirect_jump (r_label);
943 /* Search backwards to the jump insn and mark it as a
944 non-local goto. */
945 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
947 if (JUMP_P (insn))
949 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
950 const0_rtx, REG_NOTES (insn));
951 break;
953 else if (CALL_P (insn))
954 break;
957 return const0_rtx;
960 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
961 (not all will be used on all machines) that was passed to __builtin_setjmp.
962 It updates the stack pointer in that block to correspond to the current
963 stack pointer. */
965 static void
966 expand_builtin_update_setjmp_buf (rtx buf_addr)
968 enum machine_mode sa_mode = Pmode;
969 rtx stack_save;
972 #ifdef HAVE_save_stack_nonlocal
973 if (HAVE_save_stack_nonlocal)
974 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
975 #endif
976 #ifdef STACK_SAVEAREA_MODE
977 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
978 #endif
980 stack_save
981 = gen_rtx_MEM (sa_mode,
982 memory_address
983 (sa_mode,
984 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
986 #ifdef HAVE_setjmp
987 if (HAVE_setjmp)
988 emit_insn (gen_setjmp ());
989 #endif
991 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
994 /* Expand a call to __builtin_prefetch. For a target that does not support
995 data prefetch, evaluate the memory address argument in case it has side
996 effects. */
998 static void
999 expand_builtin_prefetch (tree arglist)
1001 tree arg0, arg1, arg2;
1002 rtx op0, op1, op2;
1004 if (!validate_arglist (arglist, POINTER_TYPE, 0))
1005 return;
1007 arg0 = TREE_VALUE (arglist);
1008 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1009 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1010 locality). */
1011 if (TREE_CHAIN (arglist))
1013 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1014 if (TREE_CHAIN (TREE_CHAIN (arglist)))
1015 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1016 else
1017 arg2 = build_int_cst (NULL_TREE, 3);
1019 else
1021 arg1 = integer_zero_node;
1022 arg2 = build_int_cst (NULL_TREE, 3);
1025 /* Argument 0 is an address. */
1026 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1028 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1029 if (TREE_CODE (arg1) != INTEGER_CST)
1031 error ("second argument to %<__builtin_prefetch%> must be a constant");
1032 arg1 = integer_zero_node;
1034 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1035 /* Argument 1 must be either zero or one. */
1036 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1038 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1039 " using zero");
1040 op1 = const0_rtx;
1043 /* Argument 2 (locality) must be a compile-time constant int. */
1044 if (TREE_CODE (arg2) != INTEGER_CST)
1046 error ("third argument to %<__builtin_prefetch%> must be a constant");
1047 arg2 = integer_zero_node;
1049 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1050 /* Argument 2 must be 0, 1, 2, or 3. */
1051 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1053 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1054 op2 = const0_rtx;
1057 #ifdef HAVE_prefetch
1058 if (HAVE_prefetch)
1060 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1061 (op0,
1062 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1063 || (GET_MODE (op0) != Pmode))
1065 op0 = convert_memory_address (Pmode, op0);
1066 op0 = force_reg (Pmode, op0);
1068 emit_insn (gen_prefetch (op0, op1, op2));
1070 #endif
1072 /* Don't do anything with direct references to volatile memory, but
1073 generate code to handle other side effects. */
1074 if (!MEM_P (op0) && side_effects_p (op0))
1075 emit_insn (op0);
1078 /* Get a MEM rtx for expression EXP which is the address of an operand
1079 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1080 the maximum length of the block of memory that might be accessed or
1081 NULL if unknown. */
1083 static rtx
1084 get_memory_rtx (tree exp, tree len)
1086 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1087 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1089 /* Get an expression we can use to find the attributes to assign to MEM.
1090 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1091 we can. First remove any nops. */
1092 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1093 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1094 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1095 exp = TREE_OPERAND (exp, 0);
1097 if (TREE_CODE (exp) == ADDR_EXPR)
1098 exp = TREE_OPERAND (exp, 0);
1099 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1100 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1101 else
1102 exp = NULL;
1104 /* Honor attributes derived from exp, except for the alias set
1105 (as builtin stringops may alias with anything) and the size
1106 (as stringops may access multiple array elements). */
1107 if (exp)
1109 set_mem_attributes (mem, exp, 0);
1111 /* Allow the string and memory builtins to overflow from one
1112 field into another, see http://gcc.gnu.org/PR23561.
1113 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1114 memory accessed by the string or memory builtin will fit
1115 within the field. */
1116 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1118 tree mem_expr = MEM_EXPR (mem);
1119 HOST_WIDE_INT offset = -1, length = -1;
1120 tree inner = exp;
1122 while (TREE_CODE (inner) == ARRAY_REF
1123 || TREE_CODE (inner) == NOP_EXPR
1124 || TREE_CODE (inner) == CONVERT_EXPR
1125 || TREE_CODE (inner) == NON_LVALUE_EXPR
1126 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1127 || TREE_CODE (inner) == SAVE_EXPR)
1128 inner = TREE_OPERAND (inner, 0);
1130 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1132 if (MEM_OFFSET (mem)
1133 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1134 offset = INTVAL (MEM_OFFSET (mem));
1136 if (offset >= 0 && len && host_integerp (len, 0))
1137 length = tree_low_cst (len, 0);
1139 while (TREE_CODE (inner) == COMPONENT_REF)
1141 tree field = TREE_OPERAND (inner, 1);
1142 gcc_assert (! DECL_BIT_FIELD (field));
1143 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1144 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1146 if (length >= 0
1147 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1148 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1150 HOST_WIDE_INT size
1151 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1152 /* If we can prove the memory starting at XEXP (mem, 0)
1153 and ending at XEXP (mem, 0) + LENGTH will fit into
1154 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1155 if (offset <= size
1156 && length <= size
1157 && offset + length <= size)
1158 break;
1161 if (offset >= 0
1162 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1163 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1164 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1165 / BITS_PER_UNIT;
1166 else
1168 offset = -1;
1169 length = -1;
1172 mem_expr = TREE_OPERAND (mem_expr, 0);
1173 inner = TREE_OPERAND (inner, 0);
1176 if (mem_expr == NULL)
1177 offset = -1;
1178 if (mem_expr != MEM_EXPR (mem))
1180 set_mem_expr (mem, mem_expr);
1181 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1184 set_mem_alias_set (mem, 0);
1185 set_mem_size (mem, NULL_RTX);
1188 return mem;
1191 /* Built-in functions to perform an untyped call and return. */
1193 /* For each register that may be used for calling a function, this
1194 gives a mode used to copy the register's value. VOIDmode indicates
1195 the register is not used for calling a function. If the machine
1196 has register windows, this gives only the outbound registers.
1197 INCOMING_REGNO gives the corresponding inbound register. */
1198 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1200 /* For each register that may be used for returning values, this gives
1201 a mode used to copy the register's value. VOIDmode indicates the
1202 register is not used for returning values. If the machine has
1203 register windows, this gives only the outbound registers.
1204 INCOMING_REGNO gives the corresponding inbound register. */
1205 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1207 /* For each register that may be used for calling a function, this
1208 gives the offset of that register into the block returned by
1209 __builtin_apply_args. 0 indicates that the register is not
1210 used for calling a function. */
1211 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1213 /* Return the size required for the block returned by __builtin_apply_args,
1214 and initialize apply_args_mode. */
1216 static int
1217 apply_args_size (void)
1219 static int size = -1;
1220 int align;
1221 unsigned int regno;
1222 enum machine_mode mode;
1224 /* The values computed by this function never change. */
1225 if (size < 0)
1227 /* The first value is the incoming arg-pointer. */
1228 size = GET_MODE_SIZE (Pmode);
1230 /* The second value is the structure value address unless this is
1231 passed as an "invisible" first argument. */
1232 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1233 size += GET_MODE_SIZE (Pmode);
1235 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1236 if (FUNCTION_ARG_REGNO_P (regno))
1238 mode = reg_raw_mode[regno];
1240 gcc_assert (mode != VOIDmode);
1242 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1243 if (size % align != 0)
1244 size = CEIL (size, align) * align;
1245 apply_args_reg_offset[regno] = size;
1246 size += GET_MODE_SIZE (mode);
1247 apply_args_mode[regno] = mode;
1249 else
1251 apply_args_mode[regno] = VOIDmode;
1252 apply_args_reg_offset[regno] = 0;
1255 return size;
1258 /* Return the size required for the block returned by __builtin_apply,
1259 and initialize apply_result_mode. */
1261 static int
1262 apply_result_size (void)
1264 static int size = -1;
1265 int align, regno;
1266 enum machine_mode mode;
1268 /* The values computed by this function never change. */
1269 if (size < 0)
1271 size = 0;
1273 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1274 if (FUNCTION_VALUE_REGNO_P (regno))
1276 mode = reg_raw_mode[regno];
1278 gcc_assert (mode != VOIDmode);
1280 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1281 if (size % align != 0)
1282 size = CEIL (size, align) * align;
1283 size += GET_MODE_SIZE (mode);
1284 apply_result_mode[regno] = mode;
1286 else
1287 apply_result_mode[regno] = VOIDmode;
1289 /* Allow targets that use untyped_call and untyped_return to override
1290 the size so that machine-specific information can be stored here. */
1291 #ifdef APPLY_RESULT_SIZE
1292 size = APPLY_RESULT_SIZE;
1293 #endif
1295 return size;
1298 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1299 /* Create a vector describing the result block RESULT. If SAVEP is true,
1300 the result block is used to save the values; otherwise it is used to
1301 restore the values. */
1303 static rtx
1304 result_vector (int savep, rtx result)
1306 int regno, size, align, nelts;
1307 enum machine_mode mode;
1308 rtx reg, mem;
1309 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1311 size = nelts = 0;
1312 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1313 if ((mode = apply_result_mode[regno]) != VOIDmode)
1315 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1316 if (size % align != 0)
1317 size = CEIL (size, align) * align;
1318 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1319 mem = adjust_address (result, mode, size);
1320 savevec[nelts++] = (savep
1321 ? gen_rtx_SET (VOIDmode, mem, reg)
1322 : gen_rtx_SET (VOIDmode, reg, mem));
1323 size += GET_MODE_SIZE (mode);
1325 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1327 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1329 /* Save the state required to perform an untyped call with the same
1330 arguments as were passed to the current function. */
1332 static rtx
1333 expand_builtin_apply_args_1 (void)
1335 rtx registers, tem;
1336 int size, align, regno;
1337 enum machine_mode mode;
1338 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1340 /* Create a block where the arg-pointer, structure value address,
1341 and argument registers can be saved. */
1342 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1344 /* Walk past the arg-pointer and structure value address. */
1345 size = GET_MODE_SIZE (Pmode);
1346 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1347 size += GET_MODE_SIZE (Pmode);
1349 /* Save each register used in calling a function to the block. */
1350 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1351 if ((mode = apply_args_mode[regno]) != VOIDmode)
1353 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1354 if (size % align != 0)
1355 size = CEIL (size, align) * align;
1357 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1359 emit_move_insn (adjust_address (registers, mode, size), tem);
1360 size += GET_MODE_SIZE (mode);
1363 /* Save the arg pointer to the block. */
1364 tem = copy_to_reg (virtual_incoming_args_rtx);
1365 #ifdef STACK_GROWS_DOWNWARD
1366 /* We need the pointer as the caller actually passed them to us, not
1367 as we might have pretended they were passed. Make sure it's a valid
1368 operand, as emit_move_insn isn't expected to handle a PLUS. */
1370 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1371 NULL_RTX);
1372 #endif
1373 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1375 size = GET_MODE_SIZE (Pmode);
1377 /* Save the structure value address unless this is passed as an
1378 "invisible" first argument. */
1379 if (struct_incoming_value)
1381 emit_move_insn (adjust_address (registers, Pmode, size),
1382 copy_to_reg (struct_incoming_value));
1383 size += GET_MODE_SIZE (Pmode);
1386 /* Return the address of the block. */
1387 return copy_addr_to_reg (XEXP (registers, 0));
1390 /* __builtin_apply_args returns block of memory allocated on
1391 the stack into which is stored the arg pointer, structure
1392 value address, static chain, and all the registers that might
1393 possibly be used in performing a function call. The code is
1394 moved to the start of the function so the incoming values are
1395 saved. */
1397 static rtx
1398 expand_builtin_apply_args (void)
1400 /* Don't do __builtin_apply_args more than once in a function.
1401 Save the result of the first call and reuse it. */
1402 if (apply_args_value != 0)
1403 return apply_args_value;
1405 /* When this function is called, it means that registers must be
1406 saved on entry to this function. So we migrate the
1407 call to the first insn of this function. */
1408 rtx temp;
1409 rtx seq;
1411 start_sequence ();
1412 temp = expand_builtin_apply_args_1 ();
1413 seq = get_insns ();
1414 end_sequence ();
1416 apply_args_value = temp;
1418 /* Put the insns after the NOTE that starts the function.
1419 If this is inside a start_sequence, make the outer-level insn
1420 chain current, so the code is placed at the start of the
1421 function. */
1422 push_topmost_sequence ();
1423 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1424 pop_topmost_sequence ();
1425 return temp;
1429 /* Perform an untyped call and save the state required to perform an
1430 untyped return of whatever value was returned by the given function. */
1432 static rtx
1433 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1435 int size, align, regno;
1436 enum machine_mode mode;
1437 rtx incoming_args, result, reg, dest, src, call_insn;
1438 rtx old_stack_level = 0;
1439 rtx call_fusage = 0;
1440 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1442 arguments = convert_memory_address (Pmode, arguments);
1444 /* Create a block where the return registers can be saved. */
1445 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1447 /* Fetch the arg pointer from the ARGUMENTS block. */
1448 incoming_args = gen_reg_rtx (Pmode);
1449 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1450 #ifndef STACK_GROWS_DOWNWARD
1451 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1452 incoming_args, 0, OPTAB_LIB_WIDEN);
1453 #endif
1455 /* Push a new argument block and copy the arguments. Do not allow
1456 the (potential) memcpy call below to interfere with our stack
1457 manipulations. */
1458 do_pending_stack_adjust ();
1459 NO_DEFER_POP;
1461 /* Save the stack with nonlocal if available. */
1462 #ifdef HAVE_save_stack_nonlocal
1463 if (HAVE_save_stack_nonlocal)
1464 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1465 else
1466 #endif
1467 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1469 /* Allocate a block of memory onto the stack and copy the memory
1470 arguments to the outgoing arguments address. */
1471 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1472 dest = virtual_outgoing_args_rtx;
1473 #ifndef STACK_GROWS_DOWNWARD
1474 if (GET_CODE (argsize) == CONST_INT)
1475 dest = plus_constant (dest, -INTVAL (argsize));
1476 else
1477 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1478 #endif
1479 dest = gen_rtx_MEM (BLKmode, dest);
1480 set_mem_align (dest, PARM_BOUNDARY);
1481 src = gen_rtx_MEM (BLKmode, incoming_args);
1482 set_mem_align (src, PARM_BOUNDARY);
1483 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1485 /* Refer to the argument block. */
1486 apply_args_size ();
1487 arguments = gen_rtx_MEM (BLKmode, arguments);
1488 set_mem_align (arguments, PARM_BOUNDARY);
1490 /* Walk past the arg-pointer and structure value address. */
1491 size = GET_MODE_SIZE (Pmode);
1492 if (struct_value)
1493 size += GET_MODE_SIZE (Pmode);
1495 /* Restore each of the registers previously saved. Make USE insns
1496 for each of these registers for use in making the call. */
1497 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1498 if ((mode = apply_args_mode[regno]) != VOIDmode)
1500 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1501 if (size % align != 0)
1502 size = CEIL (size, align) * align;
1503 reg = gen_rtx_REG (mode, regno);
1504 emit_move_insn (reg, adjust_address (arguments, mode, size));
1505 use_reg (&call_fusage, reg);
1506 size += GET_MODE_SIZE (mode);
1509 /* Restore the structure value address unless this is passed as an
1510 "invisible" first argument. */
1511 size = GET_MODE_SIZE (Pmode);
1512 if (struct_value)
1514 rtx value = gen_reg_rtx (Pmode);
1515 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1516 emit_move_insn (struct_value, value);
1517 if (REG_P (struct_value))
1518 use_reg (&call_fusage, struct_value);
1519 size += GET_MODE_SIZE (Pmode);
1522 /* All arguments and registers used for the call are set up by now! */
1523 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1525 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1526 and we don't want to load it into a register as an optimization,
1527 because prepare_call_address already did it if it should be done. */
1528 if (GET_CODE (function) != SYMBOL_REF)
1529 function = memory_address (FUNCTION_MODE, function);
1531 /* Generate the actual call instruction and save the return value. */
1532 #ifdef HAVE_untyped_call
1533 if (HAVE_untyped_call)
1534 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1535 result, result_vector (1, result)));
1536 else
1537 #endif
1538 #ifdef HAVE_call_value
1539 if (HAVE_call_value)
1541 rtx valreg = 0;
1543 /* Locate the unique return register. It is not possible to
1544 express a call that sets more than one return register using
1545 call_value; use untyped_call for that. In fact, untyped_call
1546 only needs to save the return registers in the given block. */
1547 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1548 if ((mode = apply_result_mode[regno]) != VOIDmode)
1550 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1552 valreg = gen_rtx_REG (mode, regno);
1555 emit_call_insn (GEN_CALL_VALUE (valreg,
1556 gen_rtx_MEM (FUNCTION_MODE, function),
1557 const0_rtx, NULL_RTX, const0_rtx));
1559 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1561 else
1562 #endif
1563 gcc_unreachable ();
1565 /* Find the CALL insn we just emitted, and attach the register usage
1566 information. */
1567 call_insn = last_call_insn ();
1568 add_function_usage_to (call_insn, call_fusage);
1570 /* Restore the stack. */
1571 #ifdef HAVE_save_stack_nonlocal
1572 if (HAVE_save_stack_nonlocal)
1573 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1574 else
1575 #endif
1576 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1578 OK_DEFER_POP;
1580 /* Return the address of the result block. */
1581 result = copy_addr_to_reg (XEXP (result, 0));
1582 return convert_memory_address (ptr_mode, result);
1585 /* Perform an untyped return. */
1587 static void
1588 expand_builtin_return (rtx result)
1590 int size, align, regno;
1591 enum machine_mode mode;
1592 rtx reg;
1593 rtx call_fusage = 0;
1595 result = convert_memory_address (Pmode, result);
1597 apply_result_size ();
1598 result = gen_rtx_MEM (BLKmode, result);
1600 #ifdef HAVE_untyped_return
1601 if (HAVE_untyped_return)
1603 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1604 emit_barrier ();
1605 return;
1607 #endif
1609 /* Restore the return value and note that each value is used. */
1610 size = 0;
1611 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1612 if ((mode = apply_result_mode[regno]) != VOIDmode)
1614 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1615 if (size % align != 0)
1616 size = CEIL (size, align) * align;
1617 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1618 emit_move_insn (reg, adjust_address (result, mode, size));
1620 push_to_sequence (call_fusage);
1621 emit_insn (gen_rtx_USE (VOIDmode, reg));
1622 call_fusage = get_insns ();
1623 end_sequence ();
1624 size += GET_MODE_SIZE (mode);
1627 /* Put the USE insns before the return. */
1628 emit_insn (call_fusage);
1630 /* Return whatever values was restored by jumping directly to the end
1631 of the function. */
1632 expand_naked_return ();
1635 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1637 static enum type_class
1638 type_to_class (tree type)
1640 switch (TREE_CODE (type))
1642 case VOID_TYPE: return void_type_class;
1643 case INTEGER_TYPE: return integer_type_class;
1644 case CHAR_TYPE: return char_type_class;
1645 case ENUMERAL_TYPE: return enumeral_type_class;
1646 case BOOLEAN_TYPE: return boolean_type_class;
1647 case POINTER_TYPE: return pointer_type_class;
1648 case REFERENCE_TYPE: return reference_type_class;
1649 case OFFSET_TYPE: return offset_type_class;
1650 case REAL_TYPE: return real_type_class;
1651 case COMPLEX_TYPE: return complex_type_class;
1652 case FUNCTION_TYPE: return function_type_class;
1653 case METHOD_TYPE: return method_type_class;
1654 case RECORD_TYPE: return record_type_class;
1655 case UNION_TYPE:
1656 case QUAL_UNION_TYPE: return union_type_class;
1657 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1658 ? string_type_class : array_type_class);
1659 case LANG_TYPE: return lang_type_class;
1660 default: return no_type_class;
1664 /* Expand a call to __builtin_classify_type with arguments found in
1665 ARGLIST. */
1667 static rtx
1668 expand_builtin_classify_type (tree arglist)
1670 if (arglist != 0)
1671 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1672 return GEN_INT (no_type_class);
1675 /* This helper macro, meant to be used in mathfn_built_in below,
1676 determines which among a set of three builtin math functions is
1677 appropriate for a given type mode. The `F' and `L' cases are
1678 automatically generated from the `double' case. */
1679 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1680 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1681 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1682 fcodel = BUILT_IN_MATHFN##L ; break;
1684 /* Return mathematic function equivalent to FN but operating directly
1685 on TYPE, if available. If we can't do the conversion, return zero. */
1686 tree
1687 mathfn_built_in (tree type, enum built_in_function fn)
1689 enum built_in_function fcode, fcodef, fcodel;
1691 switch (fn)
1693 CASE_MATHFN (BUILT_IN_ACOS)
1694 CASE_MATHFN (BUILT_IN_ACOSH)
1695 CASE_MATHFN (BUILT_IN_ASIN)
1696 CASE_MATHFN (BUILT_IN_ASINH)
1697 CASE_MATHFN (BUILT_IN_ATAN)
1698 CASE_MATHFN (BUILT_IN_ATAN2)
1699 CASE_MATHFN (BUILT_IN_ATANH)
1700 CASE_MATHFN (BUILT_IN_CBRT)
1701 CASE_MATHFN (BUILT_IN_CEIL)
1702 CASE_MATHFN (BUILT_IN_COPYSIGN)
1703 CASE_MATHFN (BUILT_IN_COS)
1704 CASE_MATHFN (BUILT_IN_COSH)
1705 CASE_MATHFN (BUILT_IN_DREM)
1706 CASE_MATHFN (BUILT_IN_ERF)
1707 CASE_MATHFN (BUILT_IN_ERFC)
1708 CASE_MATHFN (BUILT_IN_EXP)
1709 CASE_MATHFN (BUILT_IN_EXP10)
1710 CASE_MATHFN (BUILT_IN_EXP2)
1711 CASE_MATHFN (BUILT_IN_EXPM1)
1712 CASE_MATHFN (BUILT_IN_FABS)
1713 CASE_MATHFN (BUILT_IN_FDIM)
1714 CASE_MATHFN (BUILT_IN_FLOOR)
1715 CASE_MATHFN (BUILT_IN_FMA)
1716 CASE_MATHFN (BUILT_IN_FMAX)
1717 CASE_MATHFN (BUILT_IN_FMIN)
1718 CASE_MATHFN (BUILT_IN_FMOD)
1719 CASE_MATHFN (BUILT_IN_FREXP)
1720 CASE_MATHFN (BUILT_IN_GAMMA)
1721 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1722 CASE_MATHFN (BUILT_IN_HYPOT)
1723 CASE_MATHFN (BUILT_IN_ILOGB)
1724 CASE_MATHFN (BUILT_IN_INF)
1725 CASE_MATHFN (BUILT_IN_J0)
1726 CASE_MATHFN (BUILT_IN_J1)
1727 CASE_MATHFN (BUILT_IN_JN)
1728 CASE_MATHFN (BUILT_IN_LCEIL)
1729 CASE_MATHFN (BUILT_IN_LDEXP)
1730 CASE_MATHFN (BUILT_IN_LFLOOR)
1731 CASE_MATHFN (BUILT_IN_LGAMMA)
1732 CASE_MATHFN (BUILT_IN_LLCEIL)
1733 CASE_MATHFN (BUILT_IN_LLFLOOR)
1734 CASE_MATHFN (BUILT_IN_LLRINT)
1735 CASE_MATHFN (BUILT_IN_LLROUND)
1736 CASE_MATHFN (BUILT_IN_LOG)
1737 CASE_MATHFN (BUILT_IN_LOG10)
1738 CASE_MATHFN (BUILT_IN_LOG1P)
1739 CASE_MATHFN (BUILT_IN_LOG2)
1740 CASE_MATHFN (BUILT_IN_LOGB)
1741 CASE_MATHFN (BUILT_IN_LRINT)
1742 CASE_MATHFN (BUILT_IN_LROUND)
1743 CASE_MATHFN (BUILT_IN_MODF)
1744 CASE_MATHFN (BUILT_IN_NAN)
1745 CASE_MATHFN (BUILT_IN_NANS)
1746 CASE_MATHFN (BUILT_IN_NEARBYINT)
1747 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1748 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1749 CASE_MATHFN (BUILT_IN_POW)
1750 CASE_MATHFN (BUILT_IN_POWI)
1751 CASE_MATHFN (BUILT_IN_POW10)
1752 CASE_MATHFN (BUILT_IN_REMAINDER)
1753 CASE_MATHFN (BUILT_IN_REMQUO)
1754 CASE_MATHFN (BUILT_IN_RINT)
1755 CASE_MATHFN (BUILT_IN_ROUND)
1756 CASE_MATHFN (BUILT_IN_SCALB)
1757 CASE_MATHFN (BUILT_IN_SCALBLN)
1758 CASE_MATHFN (BUILT_IN_SCALBN)
1759 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1760 CASE_MATHFN (BUILT_IN_SIN)
1761 CASE_MATHFN (BUILT_IN_SINCOS)
1762 CASE_MATHFN (BUILT_IN_SINH)
1763 CASE_MATHFN (BUILT_IN_SQRT)
1764 CASE_MATHFN (BUILT_IN_TAN)
1765 CASE_MATHFN (BUILT_IN_TANH)
1766 CASE_MATHFN (BUILT_IN_TGAMMA)
1767 CASE_MATHFN (BUILT_IN_TRUNC)
1768 CASE_MATHFN (BUILT_IN_Y0)
1769 CASE_MATHFN (BUILT_IN_Y1)
1770 CASE_MATHFN (BUILT_IN_YN)
1772 default:
1773 return 0;
1776 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1777 return implicit_built_in_decls[fcode];
1778 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1779 return implicit_built_in_decls[fcodef];
1780 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1781 return implicit_built_in_decls[fcodel];
1782 else
1783 return 0;
1786 /* If errno must be maintained, expand the RTL to check if the result,
1787 TARGET, of a built-in function call, EXP, is NaN, and if so set
1788 errno to EDOM. */
1790 static void
1791 expand_errno_check (tree exp, rtx target)
1793 rtx lab = gen_label_rtx ();
1795 /* Test the result; if it is NaN, set errno=EDOM because
1796 the argument was not in the domain. */
1797 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1798 0, lab);
1800 #ifdef TARGET_EDOM
1801 /* If this built-in doesn't throw an exception, set errno directly. */
1802 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1804 #ifdef GEN_ERRNO_RTX
1805 rtx errno_rtx = GEN_ERRNO_RTX;
1806 #else
1807 rtx errno_rtx
1808 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1809 #endif
1810 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1811 emit_label (lab);
1812 return;
1814 #endif
1816 /* We can't set errno=EDOM directly; let the library call do it.
1817 Pop the arguments right away in case the call gets deleted. */
1818 NO_DEFER_POP;
1819 expand_call (exp, target, 0);
1820 OK_DEFER_POP;
1821 emit_label (lab);
1825 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1826 Return 0 if a normal call should be emitted rather than expanding the
1827 function in-line. EXP is the expression that is a call to the builtin
1828 function; if convenient, the result should be placed in TARGET.
1829 SUBTARGET may be used as the target for computing one of EXP's operands. */
1831 static rtx
1832 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1834 optab builtin_optab;
1835 rtx op0, insns, before_call;
1836 tree fndecl = get_callee_fndecl (exp);
1837 tree arglist = TREE_OPERAND (exp, 1);
1838 enum machine_mode mode;
1839 bool errno_set = false;
1840 tree arg, narg;
1842 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1843 return 0;
1845 arg = TREE_VALUE (arglist);
1847 switch (DECL_FUNCTION_CODE (fndecl))
1849 case BUILT_IN_SQRT:
1850 case BUILT_IN_SQRTF:
1851 case BUILT_IN_SQRTL:
1852 errno_set = ! tree_expr_nonnegative_p (arg);
1853 builtin_optab = sqrt_optab;
1854 break;
1855 case BUILT_IN_EXP:
1856 case BUILT_IN_EXPF:
1857 case BUILT_IN_EXPL:
1858 errno_set = true; builtin_optab = exp_optab; break;
1859 case BUILT_IN_EXP10:
1860 case BUILT_IN_EXP10F:
1861 case BUILT_IN_EXP10L:
1862 case BUILT_IN_POW10:
1863 case BUILT_IN_POW10F:
1864 case BUILT_IN_POW10L:
1865 errno_set = true; builtin_optab = exp10_optab; break;
1866 case BUILT_IN_EXP2:
1867 case BUILT_IN_EXP2F:
1868 case BUILT_IN_EXP2L:
1869 errno_set = true; builtin_optab = exp2_optab; break;
1870 case BUILT_IN_EXPM1:
1871 case BUILT_IN_EXPM1F:
1872 case BUILT_IN_EXPM1L:
1873 errno_set = true; builtin_optab = expm1_optab; break;
1874 case BUILT_IN_LOGB:
1875 case BUILT_IN_LOGBF:
1876 case BUILT_IN_LOGBL:
1877 errno_set = true; builtin_optab = logb_optab; break;
1878 case BUILT_IN_ILOGB:
1879 case BUILT_IN_ILOGBF:
1880 case BUILT_IN_ILOGBL:
1881 errno_set = true; builtin_optab = ilogb_optab; break;
1882 case BUILT_IN_LOG:
1883 case BUILT_IN_LOGF:
1884 case BUILT_IN_LOGL:
1885 errno_set = true; builtin_optab = log_optab; break;
1886 case BUILT_IN_LOG10:
1887 case BUILT_IN_LOG10F:
1888 case BUILT_IN_LOG10L:
1889 errno_set = true; builtin_optab = log10_optab; break;
1890 case BUILT_IN_LOG2:
1891 case BUILT_IN_LOG2F:
1892 case BUILT_IN_LOG2L:
1893 errno_set = true; builtin_optab = log2_optab; break;
1894 case BUILT_IN_LOG1P:
1895 case BUILT_IN_LOG1PF:
1896 case BUILT_IN_LOG1PL:
1897 errno_set = true; builtin_optab = log1p_optab; break;
1898 case BUILT_IN_ASIN:
1899 case BUILT_IN_ASINF:
1900 case BUILT_IN_ASINL:
1901 builtin_optab = asin_optab; break;
1902 case BUILT_IN_ACOS:
1903 case BUILT_IN_ACOSF:
1904 case BUILT_IN_ACOSL:
1905 builtin_optab = acos_optab; break;
1906 case BUILT_IN_TAN:
1907 case BUILT_IN_TANF:
1908 case BUILT_IN_TANL:
1909 builtin_optab = tan_optab; break;
1910 case BUILT_IN_ATAN:
1911 case BUILT_IN_ATANF:
1912 case BUILT_IN_ATANL:
1913 builtin_optab = atan_optab; break;
1914 case BUILT_IN_FLOOR:
1915 case BUILT_IN_FLOORF:
1916 case BUILT_IN_FLOORL:
1917 builtin_optab = floor_optab; break;
1918 case BUILT_IN_CEIL:
1919 case BUILT_IN_CEILF:
1920 case BUILT_IN_CEILL:
1921 builtin_optab = ceil_optab; break;
1922 case BUILT_IN_TRUNC:
1923 case BUILT_IN_TRUNCF:
1924 case BUILT_IN_TRUNCL:
1925 builtin_optab = btrunc_optab; break;
1926 case BUILT_IN_ROUND:
1927 case BUILT_IN_ROUNDF:
1928 case BUILT_IN_ROUNDL:
1929 builtin_optab = round_optab; break;
1930 case BUILT_IN_NEARBYINT:
1931 case BUILT_IN_NEARBYINTF:
1932 case BUILT_IN_NEARBYINTL:
1933 builtin_optab = nearbyint_optab; break;
1934 case BUILT_IN_RINT:
1935 case BUILT_IN_RINTF:
1936 case BUILT_IN_RINTL:
1937 builtin_optab = rint_optab; break;
1938 case BUILT_IN_LRINT:
1939 case BUILT_IN_LRINTF:
1940 case BUILT_IN_LRINTL:
1941 case BUILT_IN_LLRINT:
1942 case BUILT_IN_LLRINTF:
1943 case BUILT_IN_LLRINTL:
1944 builtin_optab = lrint_optab; break;
1945 default:
1946 gcc_unreachable ();
1949 /* Make a suitable register to place result in. */
1950 mode = TYPE_MODE (TREE_TYPE (exp));
1952 if (! flag_errno_math || ! HONOR_NANS (mode))
1953 errno_set = false;
1955 /* Before working hard, check whether the instruction is available. */
1956 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1958 target = gen_reg_rtx (mode);
1960 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1961 need to expand the argument again. This way, we will not perform
1962 side-effects more the once. */
1963 narg = builtin_save_expr (arg);
1964 if (narg != arg)
1966 arg = narg;
1967 arglist = build_tree_list (NULL_TREE, arg);
1968 exp = build_function_call_expr (fndecl, arglist);
1971 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1973 start_sequence ();
1975 /* Compute into TARGET.
1976 Set TARGET to wherever the result comes back. */
1977 target = expand_unop (mode, builtin_optab, op0, target, 0);
1979 if (target != 0)
1981 if (errno_set)
1982 expand_errno_check (exp, target);
1984 /* Output the entire sequence. */
1985 insns = get_insns ();
1986 end_sequence ();
1987 emit_insn (insns);
1988 return target;
1991 /* If we were unable to expand via the builtin, stop the sequence
1992 (without outputting the insns) and call to the library function
1993 with the stabilized argument list. */
1994 end_sequence ();
1997 before_call = get_last_insn ();
1999 target = expand_call (exp, target, target == const0_rtx);
2001 /* If this is a sqrt operation and we don't care about errno, try to
2002 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
2003 This allows the semantics of the libcall to be visible to the RTL
2004 optimizers. */
2005 if (builtin_optab == sqrt_optab && !errno_set)
2007 /* Search backwards through the insns emitted by expand_call looking
2008 for the instruction with the REG_RETVAL note. */
2009 rtx last = get_last_insn ();
2010 while (last != before_call)
2012 if (find_reg_note (last, REG_RETVAL, NULL))
2014 rtx note = find_reg_note (last, REG_EQUAL, NULL);
2015 /* Check that the REQ_EQUAL note is an EXPR_LIST with
2016 two elements, i.e. symbol_ref(sqrt) and the operand. */
2017 if (note
2018 && GET_CODE (note) == EXPR_LIST
2019 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
2020 && XEXP (XEXP (note, 0), 1) != NULL_RTX
2021 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
2023 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
2024 /* Check operand is a register with expected mode. */
2025 if (operand
2026 && REG_P (operand)
2027 && GET_MODE (operand) == mode)
2029 /* Replace the REG_EQUAL note with a SQRT rtx. */
2030 rtx equiv = gen_rtx_SQRT (mode, operand);
2031 set_unique_reg_note (last, REG_EQUAL, equiv);
2034 break;
2036 last = PREV_INSN (last);
2040 return target;
2043 /* Expand a call to the builtin binary math functions (pow and atan2).
2044 Return 0 if a normal call should be emitted rather than expanding the
2045 function in-line. EXP is the expression that is a call to the builtin
2046 function; if convenient, the result should be placed in TARGET.
2047 SUBTARGET may be used as the target for computing one of EXP's
2048 operands. */
2050 static rtx
2051 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2053 optab builtin_optab;
2054 rtx op0, op1, insns;
2055 int op1_type = REAL_TYPE;
2056 tree fndecl = get_callee_fndecl (exp);
2057 tree arglist = TREE_OPERAND (exp, 1);
2058 tree arg0, arg1, temp, narg;
2059 enum machine_mode mode;
2060 bool errno_set = true;
2061 bool stable = true;
2063 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2064 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2065 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2066 op1_type = INTEGER_TYPE;
2068 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2069 return 0;
2071 arg0 = TREE_VALUE (arglist);
2072 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2074 switch (DECL_FUNCTION_CODE (fndecl))
2076 case BUILT_IN_POW:
2077 case BUILT_IN_POWF:
2078 case BUILT_IN_POWL:
2079 builtin_optab = pow_optab; break;
2080 case BUILT_IN_ATAN2:
2081 case BUILT_IN_ATAN2F:
2082 case BUILT_IN_ATAN2L:
2083 builtin_optab = atan2_optab; break;
2084 case BUILT_IN_LDEXP:
2085 case BUILT_IN_LDEXPF:
2086 case BUILT_IN_LDEXPL:
2087 builtin_optab = ldexp_optab; break;
2088 case BUILT_IN_FMOD:
2089 case BUILT_IN_FMODF:
2090 case BUILT_IN_FMODL:
2091 builtin_optab = fmod_optab; break;
2092 case BUILT_IN_DREM:
2093 case BUILT_IN_DREMF:
2094 case BUILT_IN_DREML:
2095 builtin_optab = drem_optab; break;
2096 default:
2097 gcc_unreachable ();
2100 /* Make a suitable register to place result in. */
2101 mode = TYPE_MODE (TREE_TYPE (exp));
2103 /* Before working hard, check whether the instruction is available. */
2104 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2105 return 0;
2107 target = gen_reg_rtx (mode);
2109 if (! flag_errno_math || ! HONOR_NANS (mode))
2110 errno_set = false;
2112 /* Always stabilize the argument list. */
2113 narg = builtin_save_expr (arg1);
2114 if (narg != arg1)
2116 arg1 = narg;
2117 temp = build_tree_list (NULL_TREE, narg);
2118 stable = false;
2120 else
2121 temp = TREE_CHAIN (arglist);
2123 narg = builtin_save_expr (arg0);
2124 if (narg != arg0)
2126 arg0 = narg;
2127 arglist = tree_cons (NULL_TREE, narg, temp);
2128 stable = false;
2130 else if (! stable)
2131 arglist = tree_cons (NULL_TREE, arg0, temp);
2133 if (! stable)
2134 exp = build_function_call_expr (fndecl, arglist);
2136 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2137 op1 = expand_expr (arg1, 0, VOIDmode, 0);
2139 start_sequence ();
2141 /* Compute into TARGET.
2142 Set TARGET to wherever the result comes back. */
2143 target = expand_binop (mode, builtin_optab, op0, op1,
2144 target, 0, OPTAB_DIRECT);
2146 /* If we were unable to expand via the builtin, stop the sequence
2147 (without outputting the insns) and call to the library function
2148 with the stabilized argument list. */
2149 if (target == 0)
2151 end_sequence ();
2152 return expand_call (exp, target, target == const0_rtx);
2155 if (errno_set)
2156 expand_errno_check (exp, target);
2158 /* Output the entire sequence. */
2159 insns = get_insns ();
2160 end_sequence ();
2161 emit_insn (insns);
2163 return target;
2166 /* Expand a call to the builtin sin and cos math functions.
2167 Return 0 if a normal call should be emitted rather than expanding the
2168 function in-line. EXP is the expression that is a call to the builtin
2169 function; if convenient, the result should be placed in TARGET.
2170 SUBTARGET may be used as the target for computing one of EXP's
2171 operands. */
2173 static rtx
2174 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2176 optab builtin_optab;
2177 rtx op0, insns;
2178 tree fndecl = get_callee_fndecl (exp);
2179 tree arglist = TREE_OPERAND (exp, 1);
2180 enum machine_mode mode;
2181 bool errno_set = false;
2182 tree arg, narg;
2184 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2185 return 0;
2187 arg = TREE_VALUE (arglist);
2189 switch (DECL_FUNCTION_CODE (fndecl))
2191 case BUILT_IN_SIN:
2192 case BUILT_IN_SINF:
2193 case BUILT_IN_SINL:
2194 case BUILT_IN_COS:
2195 case BUILT_IN_COSF:
2196 case BUILT_IN_COSL:
2197 builtin_optab = sincos_optab; break;
2198 default:
2199 gcc_unreachable ();
2202 /* Make a suitable register to place result in. */
2203 mode = TYPE_MODE (TREE_TYPE (exp));
2205 if (! flag_errno_math || ! HONOR_NANS (mode))
2206 errno_set = false;
2208 /* Check if sincos insn is available, otherwise fallback
2209 to sin or cos insn. */
2210 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2211 switch (DECL_FUNCTION_CODE (fndecl))
2213 case BUILT_IN_SIN:
2214 case BUILT_IN_SINF:
2215 case BUILT_IN_SINL:
2216 builtin_optab = sin_optab; break;
2217 case BUILT_IN_COS:
2218 case BUILT_IN_COSF:
2219 case BUILT_IN_COSL:
2220 builtin_optab = cos_optab; break;
2221 default:
2222 gcc_unreachable ();
2226 /* Before working hard, check whether the instruction is available. */
2227 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2229 target = gen_reg_rtx (mode);
2231 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2232 need to expand the argument again. This way, we will not perform
2233 side-effects more the once. */
2234 narg = save_expr (arg);
2235 if (narg != arg)
2237 arg = narg;
2238 arglist = build_tree_list (NULL_TREE, arg);
2239 exp = build_function_call_expr (fndecl, arglist);
2242 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2244 start_sequence ();
2246 /* Compute into TARGET.
2247 Set TARGET to wherever the result comes back. */
2248 if (builtin_optab == sincos_optab)
2250 int result;
2252 switch (DECL_FUNCTION_CODE (fndecl))
2254 case BUILT_IN_SIN:
2255 case BUILT_IN_SINF:
2256 case BUILT_IN_SINL:
2257 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2258 break;
2259 case BUILT_IN_COS:
2260 case BUILT_IN_COSF:
2261 case BUILT_IN_COSL:
2262 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2263 break;
2264 default:
2265 gcc_unreachable ();
2267 gcc_assert (result);
2269 else
2271 target = expand_unop (mode, builtin_optab, op0, target, 0);
2274 if (target != 0)
2276 if (errno_set)
2277 expand_errno_check (exp, target);
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) and call to the library function
2288 with the stabilized argument list. */
2289 end_sequence ();
2292 target = expand_call (exp, target, target == const0_rtx);
2294 return target;
2297 /* Expand a call to one of the builtin rounding functions (lfloor).
2298 If expanding via optab fails, lower expression to (int)(floor(x)).
2299 EXP is the expression that is a call to the builtin function;
2300 if convenient, the result should be placed in TARGET. SUBTARGET may
2301 be used as the target for computing one of EXP's operands. */
2303 static rtx
2304 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2306 optab builtin_optab;
2307 rtx op0, insns, tmp;
2308 tree fndecl = get_callee_fndecl (exp);
2309 tree arglist = TREE_OPERAND (exp, 1);
2310 enum built_in_function fallback_fn;
2311 tree fallback_fndecl;
2312 enum machine_mode mode;
2313 tree arg, narg;
2315 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2316 gcc_unreachable ();
2318 arg = TREE_VALUE (arglist);
2320 switch (DECL_FUNCTION_CODE (fndecl))
2322 case BUILT_IN_LCEIL:
2323 case BUILT_IN_LCEILF:
2324 case BUILT_IN_LCEILL:
2325 case BUILT_IN_LLCEIL:
2326 case BUILT_IN_LLCEILF:
2327 case BUILT_IN_LLCEILL:
2328 builtin_optab = lceil_optab;
2329 fallback_fn = BUILT_IN_CEIL;
2330 break;
2332 case BUILT_IN_LFLOOR:
2333 case BUILT_IN_LFLOORF:
2334 case BUILT_IN_LFLOORL:
2335 case BUILT_IN_LLFLOOR:
2336 case BUILT_IN_LLFLOORF:
2337 case BUILT_IN_LLFLOORL:
2338 builtin_optab = lfloor_optab;
2339 fallback_fn = BUILT_IN_FLOOR;
2340 break;
2342 default:
2343 gcc_unreachable ();
2346 /* Make a suitable register to place result in. */
2347 mode = TYPE_MODE (TREE_TYPE (exp));
2349 /* Before working hard, check whether the instruction is available. */
2350 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2352 target = gen_reg_rtx (mode);
2354 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2355 need to expand the argument again. This way, we will not perform
2356 side-effects more the once. */
2357 narg = builtin_save_expr (arg);
2358 if (narg != arg)
2360 arg = narg;
2361 arglist = build_tree_list (NULL_TREE, arg);
2362 exp = build_function_call_expr (fndecl, arglist);
2365 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2367 start_sequence ();
2369 /* Compute into TARGET.
2370 Set TARGET to wherever the result comes back. */
2371 target = expand_unop (mode, builtin_optab, op0, target, 0);
2373 if (target != 0)
2375 /* Output the entire sequence. */
2376 insns = get_insns ();
2377 end_sequence ();
2378 emit_insn (insns);
2379 return target;
2382 /* If we were unable to expand via the builtin, stop the sequence
2383 (without outputting the insns). */
2384 end_sequence ();
2387 /* Fall back to floating point rounding optab. */
2388 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2389 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2390 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2391 gcc_assert (fallback_fndecl != NULL_TREE);
2392 exp = build_function_call_expr (fallback_fndecl, arglist);
2394 tmp = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2396 /* Truncate the result of floating point optab to integer
2397 via expand_fix (). */
2398 target = gen_reg_rtx (mode);
2399 expand_fix (target, tmp, 0);
2401 return target;
2404 /* To evaluate powi(x,n), the floating point value x raised to the
2405 constant integer exponent n, we use a hybrid algorithm that
2406 combines the "window method" with look-up tables. For an
2407 introduction to exponentiation algorithms and "addition chains",
2408 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2409 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2410 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2411 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2413 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2414 multiplications to inline before calling the system library's pow
2415 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2416 so this default never requires calling pow, powf or powl. */
2418 #ifndef POWI_MAX_MULTS
2419 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2420 #endif
2422 /* The size of the "optimal power tree" lookup table. All
2423 exponents less than this value are simply looked up in the
2424 powi_table below. This threshold is also used to size the
2425 cache of pseudo registers that hold intermediate results. */
2426 #define POWI_TABLE_SIZE 256
2428 /* The size, in bits of the window, used in the "window method"
2429 exponentiation algorithm. This is equivalent to a radix of
2430 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2431 #define POWI_WINDOW_SIZE 3
2433 /* The following table is an efficient representation of an
2434 "optimal power tree". For each value, i, the corresponding
2435 value, j, in the table states than an optimal evaluation
2436 sequence for calculating pow(x,i) can be found by evaluating
2437 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2438 100 integers is given in Knuth's "Seminumerical algorithms". */
2440 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2442 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2443 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2444 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2445 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2446 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2447 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2448 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2449 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2450 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2451 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2452 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2453 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2454 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2455 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2456 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2457 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2458 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2459 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2460 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2461 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2462 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2463 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2464 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2465 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2466 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2467 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2468 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2469 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2470 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2471 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2472 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2473 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2477 /* Return the number of multiplications required to calculate
2478 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2479 subroutine of powi_cost. CACHE is an array indicating
2480 which exponents have already been calculated. */
2482 static int
2483 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2485 /* If we've already calculated this exponent, then this evaluation
2486 doesn't require any additional multiplications. */
2487 if (cache[n])
2488 return 0;
2490 cache[n] = true;
2491 return powi_lookup_cost (n - powi_table[n], cache)
2492 + powi_lookup_cost (powi_table[n], cache) + 1;
2495 /* Return the number of multiplications required to calculate
2496 powi(x,n) for an arbitrary x, given the exponent N. This
2497 function needs to be kept in sync with expand_powi below. */
2499 static int
2500 powi_cost (HOST_WIDE_INT n)
2502 bool cache[POWI_TABLE_SIZE];
2503 unsigned HOST_WIDE_INT digit;
2504 unsigned HOST_WIDE_INT val;
2505 int result;
2507 if (n == 0)
2508 return 0;
2510 /* Ignore the reciprocal when calculating the cost. */
2511 val = (n < 0) ? -n : n;
2513 /* Initialize the exponent cache. */
2514 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2515 cache[1] = true;
2517 result = 0;
2519 while (val >= POWI_TABLE_SIZE)
2521 if (val & 1)
2523 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2524 result += powi_lookup_cost (digit, cache)
2525 + POWI_WINDOW_SIZE + 1;
2526 val >>= POWI_WINDOW_SIZE;
2528 else
2530 val >>= 1;
2531 result++;
2535 return result + powi_lookup_cost (val, cache);
2538 /* Recursive subroutine of expand_powi. This function takes the array,
2539 CACHE, of already calculated exponents and an exponent N and returns
2540 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2542 static rtx
2543 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2545 unsigned HOST_WIDE_INT digit;
2546 rtx target, result;
2547 rtx op0, op1;
2549 if (n < POWI_TABLE_SIZE)
2551 if (cache[n])
2552 return cache[n];
2554 target = gen_reg_rtx (mode);
2555 cache[n] = target;
2557 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2558 op1 = expand_powi_1 (mode, powi_table[n], cache);
2560 else if (n & 1)
2562 target = gen_reg_rtx (mode);
2563 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2564 op0 = expand_powi_1 (mode, n - digit, cache);
2565 op1 = expand_powi_1 (mode, digit, cache);
2567 else
2569 target = gen_reg_rtx (mode);
2570 op0 = expand_powi_1 (mode, n >> 1, cache);
2571 op1 = op0;
2574 result = expand_mult (mode, op0, op1, target, 0);
2575 if (result != target)
2576 emit_move_insn (target, result);
2577 return target;
2580 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2581 floating point operand in mode MODE, and N is the exponent. This
2582 function needs to be kept in sync with powi_cost above. */
2584 static rtx
2585 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2587 unsigned HOST_WIDE_INT val;
2588 rtx cache[POWI_TABLE_SIZE];
2589 rtx result;
2591 if (n == 0)
2592 return CONST1_RTX (mode);
2594 val = (n < 0) ? -n : n;
2596 memset (cache, 0, sizeof (cache));
2597 cache[1] = x;
2599 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2601 /* If the original exponent was negative, reciprocate the result. */
2602 if (n < 0)
2603 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2604 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2606 return result;
2609 /* Expand a call to the pow built-in mathematical function. Return 0 if
2610 a normal call should be emitted rather than expanding the function
2611 in-line. EXP is the expression that is a call to the builtin
2612 function; if convenient, the result should be placed in TARGET. */
2614 static rtx
2615 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2617 tree arglist = TREE_OPERAND (exp, 1);
2618 tree arg0, arg1;
2620 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2621 return 0;
2623 arg0 = TREE_VALUE (arglist);
2624 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2626 if (TREE_CODE (arg1) == REAL_CST
2627 && ! TREE_CONSTANT_OVERFLOW (arg1))
2629 REAL_VALUE_TYPE cint;
2630 REAL_VALUE_TYPE c;
2631 HOST_WIDE_INT n;
2633 c = TREE_REAL_CST (arg1);
2634 n = real_to_integer (&c);
2635 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2636 if (real_identical (&c, &cint))
2638 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2639 Otherwise, check the number of multiplications required.
2640 Note that pow never sets errno for an integer exponent. */
2641 if ((n >= -1 && n <= 2)
2642 || (flag_unsafe_math_optimizations
2643 && ! optimize_size
2644 && powi_cost (n) <= POWI_MAX_MULTS))
2646 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2647 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2648 op = force_reg (mode, op);
2649 return expand_powi (op, mode, n);
2654 if (! flag_unsafe_math_optimizations)
2655 return NULL_RTX;
2656 return expand_builtin_mathfn_2 (exp, target, subtarget);
2659 /* Expand a call to the powi built-in mathematical function. Return 0 if
2660 a normal call should be emitted rather than expanding the function
2661 in-line. EXP is the expression that is a call to the builtin
2662 function; if convenient, the result should be placed in TARGET. */
2664 static rtx
2665 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2667 tree arglist = TREE_OPERAND (exp, 1);
2668 tree arg0, arg1;
2669 rtx op0, op1;
2670 enum machine_mode mode;
2671 enum machine_mode mode2;
2673 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2674 return 0;
2676 arg0 = TREE_VALUE (arglist);
2677 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2678 mode = TYPE_MODE (TREE_TYPE (exp));
2680 /* Handle constant power. */
2682 if (TREE_CODE (arg1) == INTEGER_CST
2683 && ! TREE_CONSTANT_OVERFLOW (arg1))
2685 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2687 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2688 Otherwise, check the number of multiplications required. */
2689 if ((TREE_INT_CST_HIGH (arg1) == 0
2690 || TREE_INT_CST_HIGH (arg1) == -1)
2691 && ((n >= -1 && n <= 2)
2692 || (! optimize_size
2693 && powi_cost (n) <= POWI_MAX_MULTS)))
2695 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2696 op0 = force_reg (mode, op0);
2697 return expand_powi (op0, mode, n);
2701 /* Emit a libcall to libgcc. */
2703 /* Mode of the 2nd argument must match that of an int. */
2704 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2706 if (target == NULL_RTX)
2707 target = gen_reg_rtx (mode);
2709 op0 = expand_expr (arg0, subtarget, mode, 0);
2710 if (GET_MODE (op0) != mode)
2711 op0 = convert_to_mode (mode, op0, 0);
2712 op1 = expand_expr (arg1, 0, mode2, 0);
2713 if (GET_MODE (op1) != mode2)
2714 op1 = convert_to_mode (mode2, op1, 0);
2716 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2717 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2718 op0, mode, op1, mode2);
2720 return target;
2723 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2724 if we failed the caller should emit a normal call, otherwise
2725 try to get the result in TARGET, if convenient. */
2727 static rtx
2728 expand_builtin_strlen (tree arglist, rtx target,
2729 enum machine_mode target_mode)
2731 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2732 return 0;
2733 else
2735 rtx pat;
2736 tree len, src = TREE_VALUE (arglist);
2737 rtx result, src_reg, char_rtx, before_strlen;
2738 enum machine_mode insn_mode = target_mode, char_mode;
2739 enum insn_code icode = CODE_FOR_nothing;
2740 int align;
2742 /* If the length can be computed at compile-time, return it. */
2743 len = c_strlen (src, 0);
2744 if (len)
2745 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2747 /* If the length can be computed at compile-time and is constant
2748 integer, but there are side-effects in src, evaluate
2749 src for side-effects, then return len.
2750 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2751 can be optimized into: i++; x = 3; */
2752 len = c_strlen (src, 1);
2753 if (len && TREE_CODE (len) == INTEGER_CST)
2755 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2756 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2759 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2761 /* If SRC is not a pointer type, don't do this operation inline. */
2762 if (align == 0)
2763 return 0;
2765 /* Bail out if we can't compute strlen in the right mode. */
2766 while (insn_mode != VOIDmode)
2768 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2769 if (icode != CODE_FOR_nothing)
2770 break;
2772 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2774 if (insn_mode == VOIDmode)
2775 return 0;
2777 /* Make a place to write the result of the instruction. */
2778 result = target;
2779 if (! (result != 0
2780 && REG_P (result)
2781 && GET_MODE (result) == insn_mode
2782 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2783 result = gen_reg_rtx (insn_mode);
2785 /* Make a place to hold the source address. We will not expand
2786 the actual source until we are sure that the expansion will
2787 not fail -- there are trees that cannot be expanded twice. */
2788 src_reg = gen_reg_rtx (Pmode);
2790 /* Mark the beginning of the strlen sequence so we can emit the
2791 source operand later. */
2792 before_strlen = get_last_insn ();
2794 char_rtx = const0_rtx;
2795 char_mode = insn_data[(int) icode].operand[2].mode;
2796 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2797 char_mode))
2798 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2800 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2801 char_rtx, GEN_INT (align));
2802 if (! pat)
2803 return 0;
2804 emit_insn (pat);
2806 /* Now that we are assured of success, expand the source. */
2807 start_sequence ();
2808 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2809 if (pat != src_reg)
2810 emit_move_insn (src_reg, pat);
2811 pat = get_insns ();
2812 end_sequence ();
2814 if (before_strlen)
2815 emit_insn_after (pat, before_strlen);
2816 else
2817 emit_insn_before (pat, get_insns ());
2819 /* Return the value in the proper mode for this function. */
2820 if (GET_MODE (result) == target_mode)
2821 target = result;
2822 else if (target != 0)
2823 convert_move (target, result, 0);
2824 else
2825 target = convert_to_mode (target_mode, result, 0);
2827 return target;
2831 /* Expand a call to the strstr builtin. Return 0 if we failed the
2832 caller should emit a normal call, otherwise try to get the result
2833 in TARGET, if convenient (and in mode MODE if that's convenient). */
2835 static rtx
2836 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2838 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2840 tree result = fold_builtin_strstr (arglist, type);
2841 if (result)
2842 return expand_expr (result, target, mode, EXPAND_NORMAL);
2844 return 0;
2847 /* Expand a call to the strchr builtin. Return 0 if we failed the
2848 caller should emit a normal call, otherwise try to get the result
2849 in TARGET, if convenient (and in mode MODE if that's convenient). */
2851 static rtx
2852 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2854 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2856 tree result = fold_builtin_strchr (arglist, type);
2857 if (result)
2858 return expand_expr (result, target, mode, EXPAND_NORMAL);
2860 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2862 return 0;
2865 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2866 caller should emit a normal call, otherwise try to get the result
2867 in TARGET, if convenient (and in mode MODE if that's convenient). */
2869 static rtx
2870 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2872 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2874 tree result = fold_builtin_strrchr (arglist, type);
2875 if (result)
2876 return expand_expr (result, target, mode, EXPAND_NORMAL);
2878 return 0;
2881 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2882 caller should emit a normal call, otherwise try to get the result
2883 in TARGET, if convenient (and in mode MODE if that's convenient). */
2885 static rtx
2886 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2888 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2890 tree result = fold_builtin_strpbrk (arglist, type);
2891 if (result)
2892 return expand_expr (result, target, mode, EXPAND_NORMAL);
2894 return 0;
2897 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2898 bytes from constant string DATA + OFFSET and return it as target
2899 constant. */
2901 static rtx
2902 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2903 enum machine_mode mode)
2905 const char *str = (const char *) data;
2907 gcc_assert (offset >= 0
2908 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2909 <= strlen (str) + 1));
2911 return c_readstr (str + offset, mode);
2914 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2915 Return 0 if we failed, the caller should emit a normal call,
2916 otherwise try to get the result in TARGET, if convenient (and in
2917 mode MODE if that's convenient). */
2918 static rtx
2919 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2921 tree fndecl = get_callee_fndecl (exp);
2922 tree arglist = TREE_OPERAND (exp, 1);
2923 if (!validate_arglist (arglist,
2924 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2925 return 0;
2926 else
2928 tree dest = TREE_VALUE (arglist);
2929 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2930 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2931 const char *src_str;
2932 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2933 unsigned int dest_align
2934 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2935 rtx dest_mem, src_mem, dest_addr, len_rtx;
2936 tree result = fold_builtin_memcpy (fndecl, arglist);
2938 if (result)
2939 return expand_expr (result, target, mode, EXPAND_NORMAL);
2941 /* If DEST is not a pointer type, call the normal function. */
2942 if (dest_align == 0)
2943 return 0;
2945 /* If either SRC is not a pointer type, don't do this
2946 operation in-line. */
2947 if (src_align == 0)
2948 return 0;
2950 dest_mem = get_memory_rtx (dest, len);
2951 set_mem_align (dest_mem, dest_align);
2952 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2953 src_str = c_getstr (src);
2955 /* If SRC is a string constant and block move would be done
2956 by pieces, we can avoid loading the string from memory
2957 and only stored the computed constants. */
2958 if (src_str
2959 && GET_CODE (len_rtx) == CONST_INT
2960 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2961 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2962 (void *) src_str, dest_align))
2964 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2965 builtin_memcpy_read_str,
2966 (void *) src_str, dest_align, 0);
2967 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2968 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2969 return dest_mem;
2972 src_mem = get_memory_rtx (src, len);
2973 set_mem_align (src_mem, src_align);
2975 /* Copy word part most expediently. */
2976 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2977 CALL_EXPR_TAILCALL (exp)
2978 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2980 if (dest_addr == 0)
2982 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2983 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2985 return dest_addr;
2989 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2990 Return 0 if we failed; the caller should emit a normal call,
2991 otherwise try to get the result in TARGET, if convenient (and in
2992 mode MODE if that's convenient). If ENDP is 0 return the
2993 destination pointer, if ENDP is 1 return the end pointer ala
2994 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2995 stpcpy. */
2997 static rtx
2998 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2999 int endp)
3001 if (!validate_arglist (arglist,
3002 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3003 return 0;
3004 /* If return value is ignored, transform mempcpy into memcpy. */
3005 else if (target == const0_rtx)
3007 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3009 if (!fn)
3010 return 0;
3012 return expand_expr (build_function_call_expr (fn, arglist),
3013 target, mode, EXPAND_NORMAL);
3015 else
3017 tree dest = TREE_VALUE (arglist);
3018 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3019 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3020 const char *src_str;
3021 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3022 unsigned int dest_align
3023 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3024 rtx dest_mem, src_mem, len_rtx;
3025 tree result = fold_builtin_mempcpy (arglist, type, endp);
3027 if (result)
3028 return expand_expr (result, target, mode, EXPAND_NORMAL);
3030 /* If either SRC or DEST is not a pointer type, don't do this
3031 operation in-line. */
3032 if (dest_align == 0 || src_align == 0)
3033 return 0;
3035 /* If LEN is not constant, call the normal function. */
3036 if (! host_integerp (len, 1))
3037 return 0;
3039 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3040 src_str = c_getstr (src);
3042 /* If SRC is a string constant and block move would be done
3043 by pieces, we can avoid loading the string from memory
3044 and only stored the computed constants. */
3045 if (src_str
3046 && GET_CODE (len_rtx) == CONST_INT
3047 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3048 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3049 (void *) src_str, dest_align))
3051 dest_mem = get_memory_rtx (dest, len);
3052 set_mem_align (dest_mem, dest_align);
3053 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3054 builtin_memcpy_read_str,
3055 (void *) src_str, dest_align, endp);
3056 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3057 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3058 return dest_mem;
3061 if (GET_CODE (len_rtx) == CONST_INT
3062 && can_move_by_pieces (INTVAL (len_rtx),
3063 MIN (dest_align, src_align)))
3065 dest_mem = get_memory_rtx (dest, len);
3066 set_mem_align (dest_mem, dest_align);
3067 src_mem = get_memory_rtx (src, len);
3068 set_mem_align (src_mem, src_align);
3069 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3070 MIN (dest_align, src_align), endp);
3071 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3072 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3073 return dest_mem;
3076 return 0;
3080 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3081 if we failed; the caller should emit a normal call. */
3083 static rtx
3084 expand_builtin_memmove (tree arglist, tree type, rtx target,
3085 enum machine_mode mode, tree orig_exp)
3087 if (!validate_arglist (arglist,
3088 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3089 return 0;
3090 else
3092 tree dest = TREE_VALUE (arglist);
3093 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3094 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3096 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3097 unsigned int dest_align
3098 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3099 tree result = fold_builtin_memmove (arglist, type);
3101 if (result)
3102 return expand_expr (result, target, mode, EXPAND_NORMAL);
3104 /* If DEST is not a pointer type, call the normal function. */
3105 if (dest_align == 0)
3106 return 0;
3108 /* If either SRC is not a pointer type, don't do this
3109 operation in-line. */
3110 if (src_align == 0)
3111 return 0;
3113 /* If src is categorized for a readonly section we can use
3114 normal memcpy. */
3115 if (readonly_data_expr (src))
3117 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3118 if (!fn)
3119 return 0;
3120 fn = build_function_call_expr (fn, arglist);
3121 if (TREE_CODE (fn) == CALL_EXPR)
3122 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3123 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3126 /* If length is 1 and we can expand memcpy call inline,
3127 it is ok to use memcpy as well. */
3128 if (integer_onep (len))
3130 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3131 /*endp=*/0);
3132 if (ret)
3133 return ret;
3136 /* Otherwise, call the normal function. */
3137 return 0;
3141 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3142 if we failed the caller should emit a normal call. */
3144 static rtx
3145 expand_builtin_bcopy (tree exp)
3147 tree arglist = TREE_OPERAND (exp, 1);
3148 tree type = TREE_TYPE (exp);
3149 tree src, dest, size, newarglist;
3151 if (!validate_arglist (arglist,
3152 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3153 return NULL_RTX;
3155 src = TREE_VALUE (arglist);
3156 dest = TREE_VALUE (TREE_CHAIN (arglist));
3157 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3159 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3160 memmove(ptr y, ptr x, size_t z). This is done this way
3161 so that if it isn't expanded inline, we fallback to
3162 calling bcopy instead of memmove. */
3164 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3165 newarglist = tree_cons (NULL_TREE, src, newarglist);
3166 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3168 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3171 #ifndef HAVE_movstr
3172 # define HAVE_movstr 0
3173 # define CODE_FOR_movstr CODE_FOR_nothing
3174 #endif
3176 /* Expand into a movstr instruction, if one is available. Return 0 if
3177 we failed, the caller should emit a normal call, otherwise try to
3178 get the result in TARGET, if convenient. If ENDP is 0 return the
3179 destination pointer, if ENDP is 1 return the end pointer ala
3180 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3181 stpcpy. */
3183 static rtx
3184 expand_movstr (tree dest, tree src, rtx target, int endp)
3186 rtx end;
3187 rtx dest_mem;
3188 rtx src_mem;
3189 rtx insn;
3190 const struct insn_data * data;
3192 if (!HAVE_movstr)
3193 return 0;
3195 dest_mem = get_memory_rtx (dest, NULL);
3196 src_mem = get_memory_rtx (src, NULL);
3197 if (!endp)
3199 target = force_reg (Pmode, XEXP (dest_mem, 0));
3200 dest_mem = replace_equiv_address (dest_mem, target);
3201 end = gen_reg_rtx (Pmode);
3203 else
3205 if (target == 0 || target == const0_rtx)
3207 end = gen_reg_rtx (Pmode);
3208 if (target == 0)
3209 target = end;
3211 else
3212 end = target;
3215 data = insn_data + CODE_FOR_movstr;
3217 if (data->operand[0].mode != VOIDmode)
3218 end = gen_lowpart (data->operand[0].mode, end);
3220 insn = data->genfun (end, dest_mem, src_mem);
3222 gcc_assert (insn);
3224 emit_insn (insn);
3226 /* movstr is supposed to set end to the address of the NUL
3227 terminator. If the caller requested a mempcpy-like return value,
3228 adjust it. */
3229 if (endp == 1 && target != const0_rtx)
3231 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3232 emit_move_insn (target, force_operand (tem, NULL_RTX));
3235 return target;
3238 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3239 if we failed the caller should emit a normal call, otherwise try to get
3240 the result in TARGET, if convenient (and in mode MODE if that's
3241 convenient). */
3243 static rtx
3244 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3246 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3248 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3249 if (result)
3250 return expand_expr (result, target, mode, EXPAND_NORMAL);
3252 return expand_movstr (TREE_VALUE (arglist),
3253 TREE_VALUE (TREE_CHAIN (arglist)),
3254 target, /*endp=*/0);
3256 return 0;
3259 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3260 Return 0 if we failed the caller should emit a normal call,
3261 otherwise try to get the result in TARGET, if convenient (and in
3262 mode MODE if that's convenient). */
3264 static rtx
3265 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3267 tree arglist = TREE_OPERAND (exp, 1);
3268 /* If return value is ignored, transform stpcpy into strcpy. */
3269 if (target == const0_rtx)
3271 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3272 if (!fn)
3273 return 0;
3275 return expand_expr (build_function_call_expr (fn, arglist),
3276 target, mode, EXPAND_NORMAL);
3279 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3280 return 0;
3281 else
3283 tree dst, src, len, lenp1;
3284 tree narglist;
3285 rtx ret;
3287 /* Ensure we get an actual string whose length can be evaluated at
3288 compile-time, not an expression containing a string. This is
3289 because the latter will potentially produce pessimized code
3290 when used to produce the return value. */
3291 src = TREE_VALUE (TREE_CHAIN (arglist));
3292 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3293 return expand_movstr (TREE_VALUE (arglist),
3294 TREE_VALUE (TREE_CHAIN (arglist)),
3295 target, /*endp=*/2);
3297 dst = TREE_VALUE (arglist);
3298 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3299 narglist = build_tree_list (NULL_TREE, lenp1);
3300 narglist = tree_cons (NULL_TREE, src, narglist);
3301 narglist = tree_cons (NULL_TREE, dst, narglist);
3302 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3303 target, mode, /*endp=*/2);
3305 if (ret)
3306 return ret;
3308 if (TREE_CODE (len) == INTEGER_CST)
3310 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3312 if (GET_CODE (len_rtx) == CONST_INT)
3314 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3315 arglist, target, mode);
3317 if (ret)
3319 if (! target)
3321 if (mode != VOIDmode)
3322 target = gen_reg_rtx (mode);
3323 else
3324 target = gen_reg_rtx (GET_MODE (ret));
3326 if (GET_MODE (target) != GET_MODE (ret))
3327 ret = gen_lowpart (GET_MODE (target), ret);
3329 ret = plus_constant (ret, INTVAL (len_rtx));
3330 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3331 gcc_assert (ret);
3333 return target;
3338 return expand_movstr (TREE_VALUE (arglist),
3339 TREE_VALUE (TREE_CHAIN (arglist)),
3340 target, /*endp=*/2);
3344 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3345 bytes from constant string DATA + OFFSET and return it as target
3346 constant. */
3348 static rtx
3349 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3350 enum machine_mode mode)
3352 const char *str = (const char *) data;
3354 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3355 return const0_rtx;
3357 return c_readstr (str + offset, mode);
3360 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3361 if we failed the caller should emit a normal call. */
3363 static rtx
3364 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3366 tree fndecl = get_callee_fndecl (exp);
3367 tree arglist = TREE_OPERAND (exp, 1);
3368 if (validate_arglist (arglist,
3369 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3371 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3372 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3373 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3375 if (result)
3376 return expand_expr (result, target, mode, EXPAND_NORMAL);
3378 /* We must be passed a constant len and src parameter. */
3379 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3380 return 0;
3382 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3384 /* We're required to pad with trailing zeros if the requested
3385 len is greater than strlen(s2)+1. In that case try to
3386 use store_by_pieces, if it fails, punt. */
3387 if (tree_int_cst_lt (slen, len))
3389 tree dest = TREE_VALUE (arglist);
3390 unsigned int dest_align
3391 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3392 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3393 rtx dest_mem;
3395 if (!p || dest_align == 0 || !host_integerp (len, 1)
3396 || !can_store_by_pieces (tree_low_cst (len, 1),
3397 builtin_strncpy_read_str,
3398 (void *) p, dest_align))
3399 return 0;
3401 dest_mem = get_memory_rtx (dest, len);
3402 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3403 builtin_strncpy_read_str,
3404 (void *) p, dest_align, 0);
3405 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3406 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3407 return dest_mem;
3410 return 0;
3413 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3414 bytes from constant string DATA + OFFSET and return it as target
3415 constant. */
3417 static rtx
3418 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3419 enum machine_mode mode)
3421 const char *c = (const char *) data;
3422 char *p = alloca (GET_MODE_SIZE (mode));
3424 memset (p, *c, GET_MODE_SIZE (mode));
3426 return c_readstr (p, mode);
3429 /* Callback routine for store_by_pieces. Return the RTL of a register
3430 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3431 char value given in the RTL register data. For example, if mode is
3432 4 bytes wide, return the RTL for 0x01010101*data. */
3434 static rtx
3435 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3436 enum machine_mode mode)
3438 rtx target, coeff;
3439 size_t size;
3440 char *p;
3442 size = GET_MODE_SIZE (mode);
3443 if (size == 1)
3444 return (rtx) data;
3446 p = alloca (size);
3447 memset (p, 1, size);
3448 coeff = c_readstr (p, mode);
3450 target = convert_to_mode (mode, (rtx) data, 1);
3451 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3452 return force_reg (mode, target);
3455 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3456 if we failed the caller should emit a normal call, otherwise try to get
3457 the result in TARGET, if convenient (and in mode MODE if that's
3458 convenient). */
3460 static rtx
3461 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3462 tree orig_exp)
3464 if (!validate_arglist (arglist,
3465 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3466 return 0;
3467 else
3469 tree dest = TREE_VALUE (arglist);
3470 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3471 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3472 tree fndecl, fn;
3473 enum built_in_function fcode;
3474 char c;
3475 unsigned int dest_align;
3476 rtx dest_mem, dest_addr, len_rtx;
3478 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3480 /* If DEST is not a pointer type, don't do this
3481 operation in-line. */
3482 if (dest_align == 0)
3483 return 0;
3485 /* If the LEN parameter is zero, return DEST. */
3486 if (integer_zerop (len))
3488 /* Evaluate and ignore VAL in case it has side-effects. */
3489 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3490 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3493 /* Stabilize the arguments in case we fail. */
3494 dest = builtin_save_expr (dest);
3495 val = builtin_save_expr (val);
3496 len = builtin_save_expr (len);
3498 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3499 dest_mem = get_memory_rtx (dest, len);
3501 if (TREE_CODE (val) != INTEGER_CST)
3503 rtx val_rtx;
3505 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3506 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3507 val_rtx, 0);
3509 /* Assume that we can memset by pieces if we can store the
3510 * the coefficients by pieces (in the required modes).
3511 * We can't pass builtin_memset_gen_str as that emits RTL. */
3512 c = 1;
3513 if (host_integerp (len, 1)
3514 && !(optimize_size && tree_low_cst (len, 1) > 1)
3515 && can_store_by_pieces (tree_low_cst (len, 1),
3516 builtin_memset_read_str, &c, dest_align))
3518 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3519 val_rtx);
3520 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3521 builtin_memset_gen_str, val_rtx, dest_align, 0);
3523 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3524 dest_align))
3525 goto do_libcall;
3527 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3528 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3529 return dest_mem;
3532 if (target_char_cast (val, &c))
3533 goto do_libcall;
3535 if (c)
3537 if (host_integerp (len, 1)
3538 && !(optimize_size && tree_low_cst (len, 1) > 1)
3539 && can_store_by_pieces (tree_low_cst (len, 1),
3540 builtin_memset_read_str, &c, dest_align))
3541 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3542 builtin_memset_read_str, &c, dest_align, 0);
3543 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3544 dest_align))
3545 goto do_libcall;
3547 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3548 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3549 return dest_mem;
3552 set_mem_align (dest_mem, dest_align);
3553 dest_addr = clear_storage (dest_mem, len_rtx,
3554 CALL_EXPR_TAILCALL (orig_exp)
3555 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3557 if (dest_addr == 0)
3559 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3560 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3563 return dest_addr;
3565 do_libcall:
3566 fndecl = get_callee_fndecl (orig_exp);
3567 fcode = DECL_FUNCTION_CODE (fndecl);
3568 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3569 arglist = build_tree_list (NULL_TREE, len);
3570 if (fcode == BUILT_IN_MEMSET)
3571 arglist = tree_cons (NULL_TREE, val, arglist);
3572 arglist = tree_cons (NULL_TREE, dest, arglist);
3573 fn = build_function_call_expr (fndecl, arglist);
3574 if (TREE_CODE (fn) == CALL_EXPR)
3575 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3576 return expand_call (fn, target, target == const0_rtx);
3580 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3581 if we failed the caller should emit a normal call. */
3583 static rtx
3584 expand_builtin_bzero (tree exp)
3586 tree arglist = TREE_OPERAND (exp, 1);
3587 tree dest, size, newarglist;
3589 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3590 return NULL_RTX;
3592 dest = TREE_VALUE (arglist);
3593 size = TREE_VALUE (TREE_CHAIN (arglist));
3595 /* New argument list transforming bzero(ptr x, int y) to
3596 memset(ptr x, int 0, size_t y). This is done this way
3597 so that if it isn't expanded inline, we fallback to
3598 calling bzero instead of memset. */
3600 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3601 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3602 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3604 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3607 /* Expand expression EXP, which is a call to the memcmp built-in function.
3608 ARGLIST is the argument list for this call. Return 0 if we failed and the
3609 caller should emit a normal call, otherwise try to get the result in
3610 TARGET, if convenient (and in mode MODE, if that's convenient). */
3612 static rtx
3613 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3614 enum machine_mode mode)
3616 if (!validate_arglist (arglist,
3617 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3618 return 0;
3619 else
3621 tree result = fold_builtin_memcmp (arglist);
3622 if (result)
3623 return expand_expr (result, target, mode, EXPAND_NORMAL);
3626 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3628 tree arg1 = TREE_VALUE (arglist);
3629 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3630 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3631 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3632 rtx result;
3633 rtx insn;
3635 int arg1_align
3636 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3637 int arg2_align
3638 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3639 enum machine_mode insn_mode;
3641 #ifdef HAVE_cmpmemsi
3642 if (HAVE_cmpmemsi)
3643 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3644 else
3645 #endif
3646 #ifdef HAVE_cmpstrnsi
3647 if (HAVE_cmpstrnsi)
3648 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3649 else
3650 #endif
3651 return 0;
3653 /* If we don't have POINTER_TYPE, call the function. */
3654 if (arg1_align == 0 || arg2_align == 0)
3655 return 0;
3657 /* Make a place to write the result of the instruction. */
3658 result = target;
3659 if (! (result != 0
3660 && REG_P (result) && GET_MODE (result) == insn_mode
3661 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3662 result = gen_reg_rtx (insn_mode);
3664 arg1_rtx = get_memory_rtx (arg1, len);
3665 arg2_rtx = get_memory_rtx (arg2, len);
3666 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3668 /* Set MEM_SIZE as appropriate. */
3669 if (GET_CODE (arg3_rtx) == CONST_INT)
3671 set_mem_size (arg1_rtx, arg3_rtx);
3672 set_mem_size (arg2_rtx, arg3_rtx);
3675 #ifdef HAVE_cmpmemsi
3676 if (HAVE_cmpmemsi)
3677 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3678 GEN_INT (MIN (arg1_align, arg2_align)));
3679 else
3680 #endif
3681 #ifdef HAVE_cmpstrnsi
3682 if (HAVE_cmpstrnsi)
3683 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3684 GEN_INT (MIN (arg1_align, arg2_align)));
3685 else
3686 #endif
3687 gcc_unreachable ();
3689 if (insn)
3690 emit_insn (insn);
3691 else
3692 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3693 TYPE_MODE (integer_type_node), 3,
3694 XEXP (arg1_rtx, 0), Pmode,
3695 XEXP (arg2_rtx, 0), Pmode,
3696 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3697 TYPE_UNSIGNED (sizetype)),
3698 TYPE_MODE (sizetype));
3700 /* Return the value in the proper mode for this function. */
3701 mode = TYPE_MODE (TREE_TYPE (exp));
3702 if (GET_MODE (result) == mode)
3703 return result;
3704 else if (target != 0)
3706 convert_move (target, result, 0);
3707 return target;
3709 else
3710 return convert_to_mode (mode, result, 0);
3712 #endif
3714 return 0;
3717 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3718 if we failed the caller should emit a normal call, otherwise try to get
3719 the result in TARGET, if convenient. */
3721 static rtx
3722 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3724 tree arglist = TREE_OPERAND (exp, 1);
3726 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3727 return 0;
3728 else
3730 tree result = fold_builtin_strcmp (arglist);
3731 if (result)
3732 return expand_expr (result, target, mode, EXPAND_NORMAL);
3735 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3736 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3737 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3739 rtx arg1_rtx, arg2_rtx;
3740 rtx result, insn = NULL_RTX;
3741 tree fndecl, fn;
3743 tree arg1 = TREE_VALUE (arglist);
3744 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3745 int arg1_align
3746 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3747 int arg2_align
3748 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3750 /* If we don't have POINTER_TYPE, call the function. */
3751 if (arg1_align == 0 || arg2_align == 0)
3752 return 0;
3754 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3755 arg1 = builtin_save_expr (arg1);
3756 arg2 = builtin_save_expr (arg2);
3758 arg1_rtx = get_memory_rtx (arg1, NULL);
3759 arg2_rtx = get_memory_rtx (arg2, NULL);
3761 #ifdef HAVE_cmpstrsi
3762 /* Try to call cmpstrsi. */
3763 if (HAVE_cmpstrsi)
3765 enum machine_mode insn_mode
3766 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3768 /* Make a place to write the result of the instruction. */
3769 result = target;
3770 if (! (result != 0
3771 && REG_P (result) && GET_MODE (result) == insn_mode
3772 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3773 result = gen_reg_rtx (insn_mode);
3775 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3776 GEN_INT (MIN (arg1_align, arg2_align)));
3778 #endif
3779 #if HAVE_cmpstrnsi
3780 /* Try to determine at least one length and call cmpstrnsi. */
3781 if (!insn && HAVE_cmpstrnsi)
3783 tree len;
3784 rtx arg3_rtx;
3786 enum machine_mode insn_mode
3787 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3788 tree len1 = c_strlen (arg1, 1);
3789 tree len2 = c_strlen (arg2, 1);
3791 if (len1)
3792 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3793 if (len2)
3794 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3796 /* If we don't have a constant length for the first, use the length
3797 of the second, if we know it. We don't require a constant for
3798 this case; some cost analysis could be done if both are available
3799 but neither is constant. For now, assume they're equally cheap,
3800 unless one has side effects. If both strings have constant lengths,
3801 use the smaller. */
3803 if (!len1)
3804 len = len2;
3805 else if (!len2)
3806 len = len1;
3807 else if (TREE_SIDE_EFFECTS (len1))
3808 len = len2;
3809 else if (TREE_SIDE_EFFECTS (len2))
3810 len = len1;
3811 else if (TREE_CODE (len1) != INTEGER_CST)
3812 len = len2;
3813 else if (TREE_CODE (len2) != INTEGER_CST)
3814 len = len1;
3815 else if (tree_int_cst_lt (len1, len2))
3816 len = len1;
3817 else
3818 len = len2;
3820 /* If both arguments have side effects, we cannot optimize. */
3821 if (!len || TREE_SIDE_EFFECTS (len))
3822 goto do_libcall;
3824 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3826 /* Make a place to write the result of the instruction. */
3827 result = target;
3828 if (! (result != 0
3829 && REG_P (result) && GET_MODE (result) == insn_mode
3830 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3831 result = gen_reg_rtx (insn_mode);
3833 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3834 GEN_INT (MIN (arg1_align, arg2_align)));
3836 #endif
3838 if (insn)
3840 emit_insn (insn);
3842 /* Return the value in the proper mode for this function. */
3843 mode = TYPE_MODE (TREE_TYPE (exp));
3844 if (GET_MODE (result) == mode)
3845 return result;
3846 if (target == 0)
3847 return convert_to_mode (mode, result, 0);
3848 convert_move (target, result, 0);
3849 return target;
3852 /* Expand the library call ourselves using a stabilized argument
3853 list to avoid re-evaluating the function's arguments twice. */
3854 #if HAVE_cmpstrnsi
3855 do_libcall:
3856 #endif
3857 arglist = build_tree_list (NULL_TREE, arg2);
3858 arglist = tree_cons (NULL_TREE, arg1, arglist);
3859 fndecl = get_callee_fndecl (exp);
3860 fn = build_function_call_expr (fndecl, arglist);
3861 if (TREE_CODE (fn) == CALL_EXPR)
3862 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3863 return expand_call (fn, target, target == const0_rtx);
3865 #endif
3866 return 0;
3869 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3870 if we failed the caller should emit a normal call, otherwise try to get
3871 the result in TARGET, if convenient. */
3873 static rtx
3874 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3876 tree arglist = TREE_OPERAND (exp, 1);
3878 if (!validate_arglist (arglist,
3879 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3880 return 0;
3881 else
3883 tree result = fold_builtin_strncmp (arglist);
3884 if (result)
3885 return expand_expr (result, target, mode, EXPAND_NORMAL);
3888 /* If c_strlen can determine an expression for one of the string
3889 lengths, and it doesn't have side effects, then emit cmpstrnsi
3890 using length MIN(strlen(string)+1, arg3). */
3891 #ifdef HAVE_cmpstrnsi
3892 if (HAVE_cmpstrnsi)
3894 tree arg1 = TREE_VALUE (arglist);
3895 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3896 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3897 tree len, len1, len2;
3898 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3899 rtx result, insn;
3900 tree fndecl, fn;
3902 int arg1_align
3903 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3904 int arg2_align
3905 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3906 enum machine_mode insn_mode
3907 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3909 len1 = c_strlen (arg1, 1);
3910 len2 = c_strlen (arg2, 1);
3912 if (len1)
3913 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3914 if (len2)
3915 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3917 /* If we don't have a constant length for the first, use the length
3918 of the second, if we know it. We don't require a constant for
3919 this case; some cost analysis could be done if both are available
3920 but neither is constant. For now, assume they're equally cheap,
3921 unless one has side effects. If both strings have constant lengths,
3922 use the smaller. */
3924 if (!len1)
3925 len = len2;
3926 else if (!len2)
3927 len = len1;
3928 else if (TREE_SIDE_EFFECTS (len1))
3929 len = len2;
3930 else if (TREE_SIDE_EFFECTS (len2))
3931 len = len1;
3932 else if (TREE_CODE (len1) != INTEGER_CST)
3933 len = len2;
3934 else if (TREE_CODE (len2) != INTEGER_CST)
3935 len = len1;
3936 else if (tree_int_cst_lt (len1, len2))
3937 len = len1;
3938 else
3939 len = len2;
3941 /* If both arguments have side effects, we cannot optimize. */
3942 if (!len || TREE_SIDE_EFFECTS (len))
3943 return 0;
3945 /* The actual new length parameter is MIN(len,arg3). */
3946 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3947 fold_convert (TREE_TYPE (len), arg3));
3949 /* If we don't have POINTER_TYPE, call the function. */
3950 if (arg1_align == 0 || arg2_align == 0)
3951 return 0;
3953 /* Make a place to write the result of the instruction. */
3954 result = target;
3955 if (! (result != 0
3956 && REG_P (result) && GET_MODE (result) == insn_mode
3957 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3958 result = gen_reg_rtx (insn_mode);
3960 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3961 arg1 = builtin_save_expr (arg1);
3962 arg2 = builtin_save_expr (arg2);
3963 len = builtin_save_expr (len);
3965 arg1_rtx = get_memory_rtx (arg1, len);
3966 arg2_rtx = get_memory_rtx (arg2, len);
3967 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3968 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3969 GEN_INT (MIN (arg1_align, arg2_align)));
3970 if (insn)
3972 emit_insn (insn);
3974 /* Return the value in the proper mode for this function. */
3975 mode = TYPE_MODE (TREE_TYPE (exp));
3976 if (GET_MODE (result) == mode)
3977 return result;
3978 if (target == 0)
3979 return convert_to_mode (mode, result, 0);
3980 convert_move (target, result, 0);
3981 return target;
3984 /* Expand the library call ourselves using a stabilized argument
3985 list to avoid re-evaluating the function's arguments twice. */
3986 arglist = build_tree_list (NULL_TREE, len);
3987 arglist = tree_cons (NULL_TREE, arg2, arglist);
3988 arglist = tree_cons (NULL_TREE, arg1, arglist);
3989 fndecl = get_callee_fndecl (exp);
3990 fn = build_function_call_expr (fndecl, arglist);
3991 if (TREE_CODE (fn) == CALL_EXPR)
3992 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3993 return expand_call (fn, target, target == const0_rtx);
3995 #endif
3996 return 0;
3999 /* Expand expression EXP, which is a call to the strcat builtin.
4000 Return 0 if we failed the caller should emit a normal call,
4001 otherwise try to get the result in TARGET, if convenient. */
4003 static rtx
4004 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4006 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4007 return 0;
4008 else
4010 tree dst = TREE_VALUE (arglist),
4011 src = TREE_VALUE (TREE_CHAIN (arglist));
4012 const char *p = c_getstr (src);
4014 /* If the string length is zero, return the dst parameter. */
4015 if (p && *p == '\0')
4016 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4018 if (!optimize_size)
4020 /* See if we can store by pieces into (dst + strlen(dst)). */
4021 tree newsrc, newdst,
4022 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4023 rtx insns;
4025 /* Stabilize the argument list. */
4026 newsrc = builtin_save_expr (src);
4027 if (newsrc != src)
4028 arglist = build_tree_list (NULL_TREE, newsrc);
4029 else
4030 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4032 dst = builtin_save_expr (dst);
4034 start_sequence ();
4036 /* Create strlen (dst). */
4037 newdst =
4038 build_function_call_expr (strlen_fn,
4039 build_tree_list (NULL_TREE, dst));
4040 /* Create (dst + (cast) strlen (dst)). */
4041 newdst = fold_convert (TREE_TYPE (dst), newdst);
4042 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4044 newdst = builtin_save_expr (newdst);
4045 arglist = tree_cons (NULL_TREE, newdst, arglist);
4047 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4049 end_sequence (); /* Stop sequence. */
4050 return 0;
4053 /* Output the entire sequence. */
4054 insns = get_insns ();
4055 end_sequence ();
4056 emit_insn (insns);
4058 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4061 return 0;
4065 /* Expand expression EXP, which is a call to the strncat builtin.
4066 Return 0 if we failed the caller should emit a normal call,
4067 otherwise try to get the result in TARGET, if convenient. */
4069 static rtx
4070 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4072 if (validate_arglist (arglist,
4073 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4075 tree result = fold_builtin_strncat (arglist);
4076 if (result)
4077 return expand_expr (result, target, mode, EXPAND_NORMAL);
4079 return 0;
4082 /* Expand expression EXP, which is a call to the strspn builtin.
4083 Return 0 if we failed the caller should emit a normal call,
4084 otherwise try to get the result in TARGET, if convenient. */
4086 static rtx
4087 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4089 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4091 tree result = fold_builtin_strspn (arglist);
4092 if (result)
4093 return expand_expr (result, target, mode, EXPAND_NORMAL);
4095 return 0;
4098 /* Expand expression EXP, which is a call to the strcspn builtin.
4099 Return 0 if we failed the caller should emit a normal call,
4100 otherwise try to get the result in TARGET, if convenient. */
4102 static rtx
4103 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4105 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4107 tree result = fold_builtin_strcspn (arglist);
4108 if (result)
4109 return expand_expr (result, target, mode, EXPAND_NORMAL);
4111 return 0;
4114 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4115 if that's convenient. */
4118 expand_builtin_saveregs (void)
4120 rtx val, seq;
4122 /* Don't do __builtin_saveregs more than once in a function.
4123 Save the result of the first call and reuse it. */
4124 if (saveregs_value != 0)
4125 return saveregs_value;
4127 /* When this function is called, it means that registers must be
4128 saved on entry to this function. So we migrate the call to the
4129 first insn of this function. */
4131 start_sequence ();
4133 /* Do whatever the machine needs done in this case. */
4134 val = targetm.calls.expand_builtin_saveregs ();
4136 seq = get_insns ();
4137 end_sequence ();
4139 saveregs_value = val;
4141 /* Put the insns after the NOTE that starts the function. If this
4142 is inside a start_sequence, make the outer-level insn chain current, so
4143 the code is placed at the start of the function. */
4144 push_topmost_sequence ();
4145 emit_insn_after (seq, entry_of_function ());
4146 pop_topmost_sequence ();
4148 return val;
4151 /* __builtin_args_info (N) returns word N of the arg space info
4152 for the current function. The number and meanings of words
4153 is controlled by the definition of CUMULATIVE_ARGS. */
4155 static rtx
4156 expand_builtin_args_info (tree arglist)
4158 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4159 int *word_ptr = (int *) &current_function_args_info;
4161 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4163 if (arglist != 0)
4165 if (!host_integerp (TREE_VALUE (arglist), 0))
4166 error ("argument of %<__builtin_args_info%> must be constant");
4167 else
4169 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4171 if (wordnum < 0 || wordnum >= nwords)
4172 error ("argument of %<__builtin_args_info%> out of range");
4173 else
4174 return GEN_INT (word_ptr[wordnum]);
4177 else
4178 error ("missing argument in %<__builtin_args_info%>");
4180 return const0_rtx;
4183 /* Expand a call to __builtin_next_arg. */
4185 static rtx
4186 expand_builtin_next_arg (void)
4188 /* Checking arguments is already done in fold_builtin_next_arg
4189 that must be called before this function. */
4190 return expand_binop (Pmode, add_optab,
4191 current_function_internal_arg_pointer,
4192 current_function_arg_offset_rtx,
4193 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4196 /* Make it easier for the backends by protecting the valist argument
4197 from multiple evaluations. */
4199 static tree
4200 stabilize_va_list (tree valist, int needs_lvalue)
4202 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4204 if (TREE_SIDE_EFFECTS (valist))
4205 valist = save_expr (valist);
4207 /* For this case, the backends will be expecting a pointer to
4208 TREE_TYPE (va_list_type_node), but it's possible we've
4209 actually been given an array (an actual va_list_type_node).
4210 So fix it. */
4211 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4213 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4214 valist = build_fold_addr_expr_with_type (valist, p1);
4217 else
4219 tree pt;
4221 if (! needs_lvalue)
4223 if (! TREE_SIDE_EFFECTS (valist))
4224 return valist;
4226 pt = build_pointer_type (va_list_type_node);
4227 valist = fold_build1 (ADDR_EXPR, pt, valist);
4228 TREE_SIDE_EFFECTS (valist) = 1;
4231 if (TREE_SIDE_EFFECTS (valist))
4232 valist = save_expr (valist);
4233 valist = build_fold_indirect_ref (valist);
4236 return valist;
4239 /* The "standard" definition of va_list is void*. */
4241 tree
4242 std_build_builtin_va_list (void)
4244 return ptr_type_node;
4247 /* The "standard" implementation of va_start: just assign `nextarg' to
4248 the variable. */
4250 void
4251 std_expand_builtin_va_start (tree valist, rtx nextarg)
4253 tree t;
4255 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4256 make_tree (ptr_type_node, nextarg));
4257 TREE_SIDE_EFFECTS (t) = 1;
4259 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4262 /* Expand ARGLIST, from a call to __builtin_va_start. */
4264 static rtx
4265 expand_builtin_va_start (tree arglist)
4267 rtx nextarg;
4268 tree chain, valist;
4270 chain = TREE_CHAIN (arglist);
4272 if (!chain)
4274 error ("too few arguments to function %<va_start%>");
4275 return const0_rtx;
4278 if (fold_builtin_next_arg (chain))
4279 return const0_rtx;
4281 nextarg = expand_builtin_next_arg ();
4282 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4284 #ifdef EXPAND_BUILTIN_VA_START
4285 EXPAND_BUILTIN_VA_START (valist, nextarg);
4286 #else
4287 std_expand_builtin_va_start (valist, nextarg);
4288 #endif
4290 return const0_rtx;
4293 /* The "standard" implementation of va_arg: read the value from the
4294 current (padded) address and increment by the (padded) size. */
4296 tree
4297 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4299 tree addr, t, type_size, rounded_size, valist_tmp;
4300 unsigned HOST_WIDE_INT align, boundary;
4301 bool indirect;
4303 #ifdef ARGS_GROW_DOWNWARD
4304 /* All of the alignment and movement below is for args-grow-up machines.
4305 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4306 implement their own specialized gimplify_va_arg_expr routines. */
4307 gcc_unreachable ();
4308 #endif
4310 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4311 if (indirect)
4312 type = build_pointer_type (type);
4314 align = PARM_BOUNDARY / BITS_PER_UNIT;
4315 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4317 /* Hoist the valist value into a temporary for the moment. */
4318 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4320 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4321 requires greater alignment, we must perform dynamic alignment. */
4322 if (boundary > align
4323 && !integer_zerop (TYPE_SIZE (type)))
4325 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4326 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4327 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4328 gimplify_and_add (t, pre_p);
4330 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4331 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4332 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4333 gimplify_and_add (t, pre_p);
4335 else
4336 boundary = align;
4338 /* If the actual alignment is less than the alignment of the type,
4339 adjust the type accordingly so that we don't assume strict alignment
4340 when deferencing the pointer. */
4341 boundary *= BITS_PER_UNIT;
4342 if (boundary < TYPE_ALIGN (type))
4344 type = build_variant_type_copy (type);
4345 TYPE_ALIGN (type) = boundary;
4348 /* Compute the rounded size of the type. */
4349 type_size = size_in_bytes (type);
4350 rounded_size = round_up (type_size, align);
4352 /* Reduce rounded_size so it's sharable with the postqueue. */
4353 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4355 /* Get AP. */
4356 addr = valist_tmp;
4357 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4359 /* Small args are padded downward. */
4360 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4361 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4362 size_binop (MINUS_EXPR, rounded_size, type_size));
4363 t = fold_convert (TREE_TYPE (addr), t);
4364 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4367 /* Compute new value for AP. */
4368 t = fold_convert (TREE_TYPE (valist), rounded_size);
4369 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4370 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4371 gimplify_and_add (t, pre_p);
4373 addr = fold_convert (build_pointer_type (type), addr);
4375 if (indirect)
4376 addr = build_va_arg_indirect_ref (addr);
4378 return build_va_arg_indirect_ref (addr);
4381 /* Build an indirect-ref expression over the given TREE, which represents a
4382 piece of a va_arg() expansion. */
4383 tree
4384 build_va_arg_indirect_ref (tree addr)
4386 addr = build_fold_indirect_ref (addr);
4388 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4389 mf_mark (addr);
4391 return addr;
4394 /* Return a dummy expression of type TYPE in order to keep going after an
4395 error. */
4397 static tree
4398 dummy_object (tree type)
4400 tree t = convert (build_pointer_type (type), null_pointer_node);
4401 return build1 (INDIRECT_REF, type, t);
4404 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4405 builtin function, but a very special sort of operator. */
4407 enum gimplify_status
4408 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4410 tree promoted_type, want_va_type, have_va_type;
4411 tree valist = TREE_OPERAND (*expr_p, 0);
4412 tree type = TREE_TYPE (*expr_p);
4413 tree t;
4415 /* Verify that valist is of the proper type. */
4416 want_va_type = va_list_type_node;
4417 have_va_type = TREE_TYPE (valist);
4419 if (have_va_type == error_mark_node)
4420 return GS_ERROR;
4422 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4424 /* If va_list is an array type, the argument may have decayed
4425 to a pointer type, e.g. by being passed to another function.
4426 In that case, unwrap both types so that we can compare the
4427 underlying records. */
4428 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4429 || POINTER_TYPE_P (have_va_type))
4431 want_va_type = TREE_TYPE (want_va_type);
4432 have_va_type = TREE_TYPE (have_va_type);
4436 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4438 error ("first argument to %<va_arg%> not of type %<va_list%>");
4439 return GS_ERROR;
4442 /* Generate a diagnostic for requesting data of a type that cannot
4443 be passed through `...' due to type promotion at the call site. */
4444 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4445 != type)
4447 static bool gave_help;
4449 /* Unfortunately, this is merely undefined, rather than a constraint
4450 violation, so we cannot make this an error. If this call is never
4451 executed, the program is still strictly conforming. */
4452 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4453 type, promoted_type);
4454 if (! gave_help)
4456 gave_help = true;
4457 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4458 promoted_type, type);
4461 /* We can, however, treat "undefined" any way we please.
4462 Call abort to encourage the user to fix the program. */
4463 inform ("if this code is reached, the program will abort");
4464 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4465 NULL);
4466 append_to_statement_list (t, pre_p);
4468 /* This is dead code, but go ahead and finish so that the
4469 mode of the result comes out right. */
4470 *expr_p = dummy_object (type);
4471 return GS_ALL_DONE;
4473 else
4475 /* Make it easier for the backends by protecting the valist argument
4476 from multiple evaluations. */
4477 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4479 /* For this case, the backends will be expecting a pointer to
4480 TREE_TYPE (va_list_type_node), but it's possible we've
4481 actually been given an array (an actual va_list_type_node).
4482 So fix it. */
4483 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4485 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4486 valist = build_fold_addr_expr_with_type (valist, p1);
4488 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4490 else
4491 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4493 if (!targetm.gimplify_va_arg_expr)
4494 /* FIXME:Once most targets are converted we should merely
4495 assert this is non-null. */
4496 return GS_ALL_DONE;
4498 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4499 return GS_OK;
4503 /* Expand ARGLIST, from a call to __builtin_va_end. */
4505 static rtx
4506 expand_builtin_va_end (tree arglist)
4508 tree valist = TREE_VALUE (arglist);
4510 /* Evaluate for side effects, if needed. I hate macros that don't
4511 do that. */
4512 if (TREE_SIDE_EFFECTS (valist))
4513 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4515 return const0_rtx;
4518 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4519 builtin rather than just as an assignment in stdarg.h because of the
4520 nastiness of array-type va_list types. */
4522 static rtx
4523 expand_builtin_va_copy (tree arglist)
4525 tree dst, src, t;
4527 dst = TREE_VALUE (arglist);
4528 src = TREE_VALUE (TREE_CHAIN (arglist));
4530 dst = stabilize_va_list (dst, 1);
4531 src = stabilize_va_list (src, 0);
4533 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4535 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4536 TREE_SIDE_EFFECTS (t) = 1;
4537 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4539 else
4541 rtx dstb, srcb, size;
4543 /* Evaluate to pointers. */
4544 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4545 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4546 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4547 VOIDmode, EXPAND_NORMAL);
4549 dstb = convert_memory_address (Pmode, dstb);
4550 srcb = convert_memory_address (Pmode, srcb);
4552 /* "Dereference" to BLKmode memories. */
4553 dstb = gen_rtx_MEM (BLKmode, dstb);
4554 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4555 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4556 srcb = gen_rtx_MEM (BLKmode, srcb);
4557 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4558 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4560 /* Copy. */
4561 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4564 return const0_rtx;
4567 /* Expand a call to one of the builtin functions __builtin_frame_address or
4568 __builtin_return_address. */
4570 static rtx
4571 expand_builtin_frame_address (tree fndecl, tree arglist)
4573 /* The argument must be a nonnegative integer constant.
4574 It counts the number of frames to scan up the stack.
4575 The value is the return address saved in that frame. */
4576 if (arglist == 0)
4577 /* Warning about missing arg was already issued. */
4578 return const0_rtx;
4579 else if (! host_integerp (TREE_VALUE (arglist), 1))
4581 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4582 error ("invalid argument to %<__builtin_frame_address%>");
4583 else
4584 error ("invalid argument to %<__builtin_return_address%>");
4585 return const0_rtx;
4587 else
4589 rtx tem
4590 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4591 tree_low_cst (TREE_VALUE (arglist), 1));
4593 /* Some ports cannot access arbitrary stack frames. */
4594 if (tem == NULL)
4596 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4597 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4598 else
4599 warning (0, "unsupported argument to %<__builtin_return_address%>");
4600 return const0_rtx;
4603 /* For __builtin_frame_address, return what we've got. */
4604 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4605 return tem;
4607 if (!REG_P (tem)
4608 && ! CONSTANT_P (tem))
4609 tem = copy_to_mode_reg (Pmode, tem);
4610 return tem;
4614 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4615 we failed and the caller should emit a normal call, otherwise try to get
4616 the result in TARGET, if convenient. */
4618 static rtx
4619 expand_builtin_alloca (tree arglist, rtx target)
4621 rtx op0;
4622 rtx result;
4624 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4625 should always expand to function calls. These can be intercepted
4626 in libmudflap. */
4627 if (flag_mudflap)
4628 return 0;
4630 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4631 return 0;
4633 /* Compute the argument. */
4634 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4636 /* Allocate the desired space. */
4637 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4638 result = convert_memory_address (ptr_mode, result);
4640 return result;
4643 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4644 Return 0 if a normal call should be emitted rather than expanding the
4645 function in-line. If convenient, the result should be placed in TARGET.
4646 SUBTARGET may be used as the target for computing one of EXP's operands. */
4648 static rtx
4649 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4650 rtx subtarget, optab op_optab)
4652 rtx op0;
4653 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4654 return 0;
4656 /* Compute the argument. */
4657 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4658 /* Compute op, into TARGET if possible.
4659 Set TARGET to wherever the result comes back. */
4660 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4661 op_optab, op0, target, 1);
4662 gcc_assert (target);
4664 return convert_to_mode (target_mode, target, 0);
4667 /* If the string passed to fputs is a constant and is one character
4668 long, we attempt to transform this call into __builtin_fputc(). */
4670 static rtx
4671 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4673 /* Verify the arguments in the original call. */
4674 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4676 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4677 unlocked, NULL_TREE);
4678 if (result)
4679 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4681 return 0;
4684 /* Expand a call to __builtin_expect. We return our argument and emit a
4685 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4686 a non-jump context. */
4688 static rtx
4689 expand_builtin_expect (tree arglist, rtx target)
4691 tree exp, c;
4692 rtx note, rtx_c;
4694 if (arglist == NULL_TREE
4695 || TREE_CHAIN (arglist) == NULL_TREE)
4696 return const0_rtx;
4697 exp = TREE_VALUE (arglist);
4698 c = TREE_VALUE (TREE_CHAIN (arglist));
4700 if (TREE_CODE (c) != INTEGER_CST)
4702 error ("second argument to %<__builtin_expect%> must be a constant");
4703 c = integer_zero_node;
4706 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4708 /* Don't bother with expected value notes for integral constants. */
4709 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4711 /* We do need to force this into a register so that we can be
4712 moderately sure to be able to correctly interpret the branch
4713 condition later. */
4714 target = force_reg (GET_MODE (target), target);
4716 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4718 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4719 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4722 return target;
4725 /* Like expand_builtin_expect, except do this in a jump context. This is
4726 called from do_jump if the conditional is a __builtin_expect. Return either
4727 a list of insns to emit the jump or NULL if we cannot optimize
4728 __builtin_expect. We need to optimize this at jump time so that machines
4729 like the PowerPC don't turn the test into a SCC operation, and then jump
4730 based on the test being 0/1. */
4733 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4735 tree arglist = TREE_OPERAND (exp, 1);
4736 tree arg0 = TREE_VALUE (arglist);
4737 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4738 rtx ret = NULL_RTX;
4740 /* Only handle __builtin_expect (test, 0) and
4741 __builtin_expect (test, 1). */
4742 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4743 && (integer_zerop (arg1) || integer_onep (arg1)))
4745 rtx insn, drop_through_label, temp;
4747 /* Expand the jump insns. */
4748 start_sequence ();
4749 do_jump (arg0, if_false_label, if_true_label);
4750 ret = get_insns ();
4752 drop_through_label = get_last_insn ();
4753 if (drop_through_label && NOTE_P (drop_through_label))
4754 drop_through_label = prev_nonnote_insn (drop_through_label);
4755 if (drop_through_label && !LABEL_P (drop_through_label))
4756 drop_through_label = NULL_RTX;
4757 end_sequence ();
4759 if (! if_true_label)
4760 if_true_label = drop_through_label;
4761 if (! if_false_label)
4762 if_false_label = drop_through_label;
4764 /* Go through and add the expect's to each of the conditional jumps. */
4765 insn = ret;
4766 while (insn != NULL_RTX)
4768 rtx next = NEXT_INSN (insn);
4770 if (JUMP_P (insn) && any_condjump_p (insn))
4772 rtx ifelse = SET_SRC (pc_set (insn));
4773 rtx then_dest = XEXP (ifelse, 1);
4774 rtx else_dest = XEXP (ifelse, 2);
4775 int taken = -1;
4777 /* First check if we recognize any of the labels. */
4778 if (GET_CODE (then_dest) == LABEL_REF
4779 && XEXP (then_dest, 0) == if_true_label)
4780 taken = 1;
4781 else if (GET_CODE (then_dest) == LABEL_REF
4782 && XEXP (then_dest, 0) == if_false_label)
4783 taken = 0;
4784 else if (GET_CODE (else_dest) == LABEL_REF
4785 && XEXP (else_dest, 0) == if_false_label)
4786 taken = 1;
4787 else if (GET_CODE (else_dest) == LABEL_REF
4788 && XEXP (else_dest, 0) == if_true_label)
4789 taken = 0;
4790 /* Otherwise check where we drop through. */
4791 else if (else_dest == pc_rtx)
4793 if (next && NOTE_P (next))
4794 next = next_nonnote_insn (next);
4796 if (next && JUMP_P (next)
4797 && any_uncondjump_p (next))
4798 temp = XEXP (SET_SRC (pc_set (next)), 0);
4799 else
4800 temp = next;
4802 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4803 else that can't possibly match either target label. */
4804 if (temp == if_false_label)
4805 taken = 1;
4806 else if (temp == if_true_label)
4807 taken = 0;
4809 else if (then_dest == pc_rtx)
4811 if (next && NOTE_P (next))
4812 next = next_nonnote_insn (next);
4814 if (next && JUMP_P (next)
4815 && any_uncondjump_p (next))
4816 temp = XEXP (SET_SRC (pc_set (next)), 0);
4817 else
4818 temp = next;
4820 if (temp == if_false_label)
4821 taken = 0;
4822 else if (temp == if_true_label)
4823 taken = 1;
4826 if (taken != -1)
4828 /* If the test is expected to fail, reverse the
4829 probabilities. */
4830 if (integer_zerop (arg1))
4831 taken = 1 - taken;
4832 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4836 insn = next;
4840 return ret;
4843 void
4844 expand_builtin_trap (void)
4846 #ifdef HAVE_trap
4847 if (HAVE_trap)
4848 emit_insn (gen_trap ());
4849 else
4850 #endif
4851 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4852 emit_barrier ();
4855 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4856 Return 0 if a normal call should be emitted rather than expanding
4857 the function inline. If convenient, the result should be placed
4858 in TARGET. SUBTARGET may be used as the target for computing
4859 the operand. */
4861 static rtx
4862 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4864 enum machine_mode mode;
4865 tree arg;
4866 rtx op0;
4868 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4869 return 0;
4871 arg = TREE_VALUE (arglist);
4872 mode = TYPE_MODE (TREE_TYPE (arg));
4873 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4874 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4877 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4878 Return NULL is a normal call should be emitted rather than expanding the
4879 function inline. If convenient, the result should be placed in TARGET.
4880 SUBTARGET may be used as the target for computing the operand. */
4882 static rtx
4883 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4885 rtx op0, op1;
4886 tree arg;
4888 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4889 return 0;
4891 arg = TREE_VALUE (arglist);
4892 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4894 arg = TREE_VALUE (TREE_CHAIN (arglist));
4895 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4897 return expand_copysign (op0, op1, target);
4900 /* Create a new constant string literal and return a char* pointer to it.
4901 The STRING_CST value is the LEN characters at STR. */
4902 static tree
4903 build_string_literal (int len, const char *str)
4905 tree t, elem, index, type;
4907 t = build_string (len, str);
4908 elem = build_type_variant (char_type_node, 1, 0);
4909 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4910 type = build_array_type (elem, index);
4911 TREE_TYPE (t) = type;
4912 TREE_CONSTANT (t) = 1;
4913 TREE_INVARIANT (t) = 1;
4914 TREE_READONLY (t) = 1;
4915 TREE_STATIC (t) = 1;
4917 type = build_pointer_type (type);
4918 t = build1 (ADDR_EXPR, type, t);
4920 type = build_pointer_type (elem);
4921 t = build1 (NOP_EXPR, type, t);
4922 return t;
4925 /* Expand EXP, a call to printf or printf_unlocked.
4926 Return 0 if a normal call should be emitted rather than transforming
4927 the function inline. If convenient, the result should be placed in
4928 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4929 call. */
4930 static rtx
4931 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4932 bool unlocked)
4934 tree arglist = TREE_OPERAND (exp, 1);
4935 /* If we're using an unlocked function, assume the other unlocked
4936 functions exist explicitly. */
4937 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4938 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4939 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4940 : implicit_built_in_decls[BUILT_IN_PUTS];
4941 const char *fmt_str;
4942 tree fn, fmt, arg;
4944 /* If the return value is used, don't do the transformation. */
4945 if (target != const0_rtx)
4946 return 0;
4948 /* Verify the required arguments in the original call. */
4949 if (! arglist)
4950 return 0;
4951 fmt = TREE_VALUE (arglist);
4952 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4953 return 0;
4954 arglist = TREE_CHAIN (arglist);
4956 /* Check whether the format is a literal string constant. */
4957 fmt_str = c_getstr (fmt);
4958 if (fmt_str == NULL)
4959 return 0;
4961 if (!init_target_chars())
4962 return 0;
4964 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4965 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4967 if (! arglist
4968 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4969 || TREE_CHAIN (arglist))
4970 return 0;
4971 fn = fn_puts;
4973 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4974 else if (strcmp (fmt_str, target_percent_c) == 0)
4976 if (! arglist
4977 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4978 || TREE_CHAIN (arglist))
4979 return 0;
4980 fn = fn_putchar;
4982 else
4984 /* We can't handle anything else with % args or %% ... yet. */
4985 if (strchr (fmt_str, target_percent))
4986 return 0;
4988 if (arglist)
4989 return 0;
4991 /* If the format specifier was "", printf does nothing. */
4992 if (fmt_str[0] == '\0')
4993 return const0_rtx;
4994 /* If the format specifier has length of 1, call putchar. */
4995 if (fmt_str[1] == '\0')
4997 /* Given printf("c"), (where c is any one character,)
4998 convert "c"[0] to an int and pass that to the replacement
4999 function. */
5000 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5001 arglist = build_tree_list (NULL_TREE, arg);
5002 fn = fn_putchar;
5004 else
5006 /* If the format specifier was "string\n", call puts("string"). */
5007 size_t len = strlen (fmt_str);
5008 if ((unsigned char)fmt_str[len - 1] == target_newline)
5010 /* Create a NUL-terminated string that's one char shorter
5011 than the original, stripping off the trailing '\n'. */
5012 char *newstr = alloca (len);
5013 memcpy (newstr, fmt_str, len - 1);
5014 newstr[len - 1] = 0;
5016 arg = build_string_literal (len, newstr);
5017 arglist = build_tree_list (NULL_TREE, arg);
5018 fn = fn_puts;
5020 else
5021 /* We'd like to arrange to call fputs(string,stdout) here,
5022 but we need stdout and don't have a way to get it yet. */
5023 return 0;
5027 if (!fn)
5028 return 0;
5029 fn = build_function_call_expr (fn, arglist);
5030 if (TREE_CODE (fn) == CALL_EXPR)
5031 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5032 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5035 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5036 Return 0 if a normal call should be emitted rather than transforming
5037 the function inline. If convenient, the result should be placed in
5038 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5039 call. */
5040 static rtx
5041 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5042 bool unlocked)
5044 tree arglist = TREE_OPERAND (exp, 1);
5045 /* If we're using an unlocked function, assume the other unlocked
5046 functions exist explicitly. */
5047 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5048 : implicit_built_in_decls[BUILT_IN_FPUTC];
5049 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5050 : implicit_built_in_decls[BUILT_IN_FPUTS];
5051 const char *fmt_str;
5052 tree fn, fmt, fp, arg;
5054 /* If the return value is used, don't do the transformation. */
5055 if (target != const0_rtx)
5056 return 0;
5058 /* Verify the required arguments in the original call. */
5059 if (! arglist)
5060 return 0;
5061 fp = TREE_VALUE (arglist);
5062 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5063 return 0;
5064 arglist = TREE_CHAIN (arglist);
5065 if (! arglist)
5066 return 0;
5067 fmt = TREE_VALUE (arglist);
5068 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5069 return 0;
5070 arglist = TREE_CHAIN (arglist);
5072 /* Check whether the format is a literal string constant. */
5073 fmt_str = c_getstr (fmt);
5074 if (fmt_str == NULL)
5075 return 0;
5077 if (!init_target_chars())
5078 return 0;
5080 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5081 if (strcmp (fmt_str, target_percent_s) == 0)
5083 if (! arglist
5084 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5085 || TREE_CHAIN (arglist))
5086 return 0;
5087 arg = TREE_VALUE (arglist);
5088 arglist = build_tree_list (NULL_TREE, fp);
5089 arglist = tree_cons (NULL_TREE, arg, arglist);
5090 fn = fn_fputs;
5092 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5093 else if (strcmp (fmt_str, target_percent_c) == 0)
5095 if (! arglist
5096 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5097 || TREE_CHAIN (arglist))
5098 return 0;
5099 arg = TREE_VALUE (arglist);
5100 arglist = build_tree_list (NULL_TREE, fp);
5101 arglist = tree_cons (NULL_TREE, arg, arglist);
5102 fn = fn_fputc;
5104 else
5106 /* We can't handle anything else with % args or %% ... yet. */
5107 if (strchr (fmt_str, target_percent))
5108 return 0;
5110 if (arglist)
5111 return 0;
5113 /* If the format specifier was "", fprintf does nothing. */
5114 if (fmt_str[0] == '\0')
5116 /* Evaluate and ignore FILE* argument for side-effects. */
5117 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5118 return const0_rtx;
5121 /* When "string" doesn't contain %, replace all cases of
5122 fprintf(stream,string) with fputs(string,stream). The fputs
5123 builtin will take care of special cases like length == 1. */
5124 arglist = build_tree_list (NULL_TREE, fp);
5125 arglist = tree_cons (NULL_TREE, fmt, arglist);
5126 fn = fn_fputs;
5129 if (!fn)
5130 return 0;
5131 fn = build_function_call_expr (fn, arglist);
5132 if (TREE_CODE (fn) == CALL_EXPR)
5133 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5134 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5137 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5138 a normal call should be emitted rather than expanding the function
5139 inline. If convenient, the result should be placed in TARGET with
5140 mode MODE. */
5142 static rtx
5143 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5145 tree orig_arglist, dest, fmt;
5146 const char *fmt_str;
5148 orig_arglist = arglist;
5150 /* Verify the required arguments in the original call. */
5151 if (! arglist)
5152 return 0;
5153 dest = TREE_VALUE (arglist);
5154 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5155 return 0;
5156 arglist = TREE_CHAIN (arglist);
5157 if (! arglist)
5158 return 0;
5159 fmt = TREE_VALUE (arglist);
5160 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5161 return 0;
5162 arglist = TREE_CHAIN (arglist);
5164 /* Check whether the format is a literal string constant. */
5165 fmt_str = c_getstr (fmt);
5166 if (fmt_str == NULL)
5167 return 0;
5169 if (!init_target_chars())
5170 return 0;
5172 /* If the format doesn't contain % args or %%, use strcpy. */
5173 if (strchr (fmt_str, target_percent) == 0)
5175 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5176 tree exp;
5178 if (arglist || ! fn)
5179 return 0;
5180 expand_expr (build_function_call_expr (fn, orig_arglist),
5181 const0_rtx, VOIDmode, EXPAND_NORMAL);
5182 if (target == const0_rtx)
5183 return const0_rtx;
5184 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5185 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5187 /* If the format is "%s", use strcpy if the result isn't used. */
5188 else if (strcmp (fmt_str, target_percent_s) == 0)
5190 tree fn, arg, len;
5191 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5193 if (! fn)
5194 return 0;
5196 if (! arglist || TREE_CHAIN (arglist))
5197 return 0;
5198 arg = TREE_VALUE (arglist);
5199 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5200 return 0;
5202 if (target != const0_rtx)
5204 len = c_strlen (arg, 1);
5205 if (! len || TREE_CODE (len) != INTEGER_CST)
5206 return 0;
5208 else
5209 len = NULL_TREE;
5211 arglist = build_tree_list (NULL_TREE, arg);
5212 arglist = tree_cons (NULL_TREE, dest, arglist);
5213 expand_expr (build_function_call_expr (fn, arglist),
5214 const0_rtx, VOIDmode, EXPAND_NORMAL);
5216 if (target == const0_rtx)
5217 return const0_rtx;
5218 return expand_expr (len, target, mode, EXPAND_NORMAL);
5221 return 0;
5224 /* Expand a call to either the entry or exit function profiler. */
5226 static rtx
5227 expand_builtin_profile_func (bool exitp)
5229 rtx this, which;
5231 this = DECL_RTL (current_function_decl);
5232 gcc_assert (MEM_P (this));
5233 this = XEXP (this, 0);
5235 if (exitp)
5236 which = profile_function_exit_libfunc;
5237 else
5238 which = profile_function_entry_libfunc;
5240 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5241 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5243 Pmode);
5245 return const0_rtx;
5248 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5250 static rtx
5251 round_trampoline_addr (rtx tramp)
5253 rtx temp, addend, mask;
5255 /* If we don't need too much alignment, we'll have been guaranteed
5256 proper alignment by get_trampoline_type. */
5257 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5258 return tramp;
5260 /* Round address up to desired boundary. */
5261 temp = gen_reg_rtx (Pmode);
5262 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5263 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5265 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5266 temp, 0, OPTAB_LIB_WIDEN);
5267 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5268 temp, 0, OPTAB_LIB_WIDEN);
5270 return tramp;
5273 static rtx
5274 expand_builtin_init_trampoline (tree arglist)
5276 tree t_tramp, t_func, t_chain;
5277 rtx r_tramp, r_func, r_chain;
5278 #ifdef TRAMPOLINE_TEMPLATE
5279 rtx blktramp;
5280 #endif
5282 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5283 POINTER_TYPE, VOID_TYPE))
5284 return NULL_RTX;
5286 t_tramp = TREE_VALUE (arglist);
5287 arglist = TREE_CHAIN (arglist);
5288 t_func = TREE_VALUE (arglist);
5289 arglist = TREE_CHAIN (arglist);
5290 t_chain = TREE_VALUE (arglist);
5292 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5293 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5294 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5296 /* Generate insns to initialize the trampoline. */
5297 r_tramp = round_trampoline_addr (r_tramp);
5298 #ifdef TRAMPOLINE_TEMPLATE
5299 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5300 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5301 emit_block_move (blktramp, assemble_trampoline_template (),
5302 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5303 #endif
5304 trampolines_created = 1;
5305 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5307 return const0_rtx;
5310 static rtx
5311 expand_builtin_adjust_trampoline (tree arglist)
5313 rtx tramp;
5315 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5316 return NULL_RTX;
5318 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5319 tramp = round_trampoline_addr (tramp);
5320 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5321 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5322 #endif
5324 return tramp;
5327 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5328 Return NULL_RTX if a normal call should be emitted rather than expanding
5329 the function in-line. EXP is the expression that is a call to the builtin
5330 function; if convenient, the result should be placed in TARGET. */
5332 static rtx
5333 expand_builtin_signbit (tree exp, rtx target)
5335 const struct real_format *fmt;
5336 enum machine_mode fmode, imode, rmode;
5337 HOST_WIDE_INT hi, lo;
5338 tree arg, arglist;
5339 int word, bitpos;
5340 rtx temp;
5342 arglist = TREE_OPERAND (exp, 1);
5343 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5344 return 0;
5346 arg = TREE_VALUE (arglist);
5347 fmode = TYPE_MODE (TREE_TYPE (arg));
5348 rmode = TYPE_MODE (TREE_TYPE (exp));
5349 fmt = REAL_MODE_FORMAT (fmode);
5351 /* For floating point formats without a sign bit, implement signbit
5352 as "ARG < 0.0". */
5353 bitpos = fmt->signbit_ro;
5354 if (bitpos < 0)
5356 /* But we can't do this if the format supports signed zero. */
5357 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5358 return 0;
5360 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5361 build_real (TREE_TYPE (arg), dconst0));
5362 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5365 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5366 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5368 imode = int_mode_for_mode (fmode);
5369 if (imode == BLKmode)
5370 return 0;
5371 temp = gen_lowpart (imode, temp);
5373 else
5375 imode = word_mode;
5376 /* Handle targets with different FP word orders. */
5377 if (FLOAT_WORDS_BIG_ENDIAN)
5378 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5379 else
5380 word = bitpos / BITS_PER_WORD;
5381 temp = operand_subword_force (temp, word, fmode);
5382 bitpos = bitpos % BITS_PER_WORD;
5385 /* Force the intermediate word_mode (or narrower) result into a
5386 register. This avoids attempting to create paradoxical SUBREGs
5387 of floating point modes below. */
5388 temp = force_reg (imode, temp);
5390 /* If the bitpos is within the "result mode" lowpart, the operation
5391 can be implement with a single bitwise AND. Otherwise, we need
5392 a right shift and an AND. */
5394 if (bitpos < GET_MODE_BITSIZE (rmode))
5396 if (bitpos < HOST_BITS_PER_WIDE_INT)
5398 hi = 0;
5399 lo = (HOST_WIDE_INT) 1 << bitpos;
5401 else
5403 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5404 lo = 0;
5407 if (imode != rmode)
5408 temp = gen_lowpart (rmode, temp);
5409 temp = expand_binop (rmode, and_optab, temp,
5410 immed_double_const (lo, hi, rmode),
5411 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5413 else
5415 /* Perform a logical right shift to place the signbit in the least
5416 significant bit, then truncate the result to the desired mode
5417 and mask just this bit. */
5418 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5419 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5420 temp = gen_lowpart (rmode, temp);
5421 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5422 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5425 return temp;
5428 /* Expand fork or exec calls. TARGET is the desired target of the
5429 call. ARGLIST is the list of arguments of the call. FN is the
5430 identificator of the actual function. IGNORE is nonzero if the
5431 value is to be ignored. */
5433 static rtx
5434 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5436 tree id, decl;
5437 tree call;
5439 /* If we are not profiling, just call the function. */
5440 if (!profile_arc_flag)
5441 return NULL_RTX;
5443 /* Otherwise call the wrapper. This should be equivalent for the rest of
5444 compiler, so the code does not diverge, and the wrapper may run the
5445 code necessary for keeping the profiling sane. */
5447 switch (DECL_FUNCTION_CODE (fn))
5449 case BUILT_IN_FORK:
5450 id = get_identifier ("__gcov_fork");
5451 break;
5453 case BUILT_IN_EXECL:
5454 id = get_identifier ("__gcov_execl");
5455 break;
5457 case BUILT_IN_EXECV:
5458 id = get_identifier ("__gcov_execv");
5459 break;
5461 case BUILT_IN_EXECLP:
5462 id = get_identifier ("__gcov_execlp");
5463 break;
5465 case BUILT_IN_EXECLE:
5466 id = get_identifier ("__gcov_execle");
5467 break;
5469 case BUILT_IN_EXECVP:
5470 id = get_identifier ("__gcov_execvp");
5471 break;
5473 case BUILT_IN_EXECVE:
5474 id = get_identifier ("__gcov_execve");
5475 break;
5477 default:
5478 gcc_unreachable ();
5481 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5482 DECL_EXTERNAL (decl) = 1;
5483 TREE_PUBLIC (decl) = 1;
5484 DECL_ARTIFICIAL (decl) = 1;
5485 TREE_NOTHROW (decl) = 1;
5486 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5487 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5488 call = build_function_call_expr (decl, arglist);
5490 return expand_call (call, target, ignore);
5494 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5495 the pointer in these functions is void*, the tree optimizers may remove
5496 casts. The mode computed in expand_builtin isn't reliable either, due
5497 to __sync_bool_compare_and_swap.
5499 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5500 group of builtins. This gives us log2 of the mode size. */
5502 static inline enum machine_mode
5503 get_builtin_sync_mode (int fcode_diff)
5505 /* The size is not negotiable, so ask not to get BLKmode in return
5506 if the target indicates that a smaller size would be better. */
5507 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5510 /* Expand the memory expression LOC and return the appropriate memory operand
5511 for the builtin_sync operations. */
5513 static rtx
5514 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5516 rtx addr, mem;
5518 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5520 /* Note that we explicitly do not want any alias information for this
5521 memory, so that we kill all other live memories. Otherwise we don't
5522 satisfy the full barrier semantics of the intrinsic. */
5523 mem = validize_mem (gen_rtx_MEM (mode, addr));
5525 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5526 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5527 MEM_VOLATILE_P (mem) = 1;
5529 return mem;
5532 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5533 ARGLIST is the operands list to the function. CODE is the rtx code
5534 that corresponds to the arithmetic or logical operation from the name;
5535 an exception here is that NOT actually means NAND. TARGET is an optional
5536 place for us to store the results; AFTER is true if this is the
5537 fetch_and_xxx form. IGNORE is true if we don't actually care about
5538 the result of the operation at all. */
5540 static rtx
5541 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5542 enum rtx_code code, bool after,
5543 rtx target, bool ignore)
5545 rtx val, mem;
5547 /* Expand the operands. */
5548 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5550 arglist = TREE_CHAIN (arglist);
5551 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5552 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5553 val = convert_to_mode (mode, val, 1);
5555 if (ignore)
5556 return expand_sync_operation (mem, val, code);
5557 else
5558 return expand_sync_fetch_operation (mem, val, code, after, target);
5561 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5562 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5563 true if this is the boolean form. TARGET is a place for us to store the
5564 results; this is NOT optional if IS_BOOL is true. */
5566 static rtx
5567 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5568 bool is_bool, rtx target)
5570 rtx old_val, new_val, mem;
5572 /* Expand the operands. */
5573 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5575 arglist = TREE_CHAIN (arglist);
5576 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5577 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5578 old_val = convert_to_mode (mode, old_val, 1);
5580 arglist = TREE_CHAIN (arglist);
5581 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5582 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5583 new_val = convert_to_mode (mode, new_val, 1);
5585 if (is_bool)
5586 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5587 else
5588 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5591 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5592 general form is actually an atomic exchange, and some targets only
5593 support a reduced form with the second argument being a constant 1.
5594 ARGLIST is the operands list to the function; TARGET is an optional
5595 place for us to store the results. */
5597 static rtx
5598 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5599 rtx target)
5601 rtx val, mem;
5603 /* Expand the operands. */
5604 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5606 arglist = TREE_CHAIN (arglist);
5607 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5608 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5609 val = convert_to_mode (mode, val, 1);
5611 return expand_sync_lock_test_and_set (mem, val, target);
5614 /* Expand the __sync_synchronize intrinsic. */
5616 static void
5617 expand_builtin_synchronize (void)
5619 tree x;
5621 #ifdef HAVE_memory_barrier
5622 if (HAVE_memory_barrier)
5624 emit_insn (gen_memory_barrier ());
5625 return;
5627 #endif
5629 /* If no explicit memory barrier instruction is available, create an
5630 empty asm stmt with a memory clobber. */
5631 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5632 tree_cons (NULL, build_string (6, "memory"), NULL));
5633 ASM_VOLATILE_P (x) = 1;
5634 expand_asm_expr (x);
5637 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5638 to the function. */
5640 static void
5641 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5643 enum insn_code icode;
5644 rtx mem, insn;
5645 rtx val = const0_rtx;
5647 /* Expand the operands. */
5648 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5650 /* If there is an explicit operation in the md file, use it. */
5651 icode = sync_lock_release[mode];
5652 if (icode != CODE_FOR_nothing)
5654 if (!insn_data[icode].operand[1].predicate (val, mode))
5655 val = force_reg (mode, val);
5657 insn = GEN_FCN (icode) (mem, val);
5658 if (insn)
5660 emit_insn (insn);
5661 return;
5665 /* Otherwise we can implement this operation by emitting a barrier
5666 followed by a store of zero. */
5667 expand_builtin_synchronize ();
5668 emit_move_insn (mem, val);
5671 /* Expand an expression EXP that calls a built-in function,
5672 with result going to TARGET if that's convenient
5673 (and in mode MODE if that's convenient).
5674 SUBTARGET may be used as the target for computing one of EXP's operands.
5675 IGNORE is nonzero if the value is to be ignored. */
5678 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5679 int ignore)
5681 tree fndecl = get_callee_fndecl (exp);
5682 tree arglist = TREE_OPERAND (exp, 1);
5683 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5684 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5686 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5687 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5689 /* When not optimizing, generate calls to library functions for a certain
5690 set of builtins. */
5691 if (!optimize
5692 && !called_as_built_in (fndecl)
5693 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5694 && fcode != BUILT_IN_ALLOCA)
5695 return expand_call (exp, target, ignore);
5697 /* The built-in function expanders test for target == const0_rtx
5698 to determine whether the function's result will be ignored. */
5699 if (ignore)
5700 target = const0_rtx;
5702 /* If the result of a pure or const built-in function is ignored, and
5703 none of its arguments are volatile, we can avoid expanding the
5704 built-in call and just evaluate the arguments for side-effects. */
5705 if (target == const0_rtx
5706 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5708 bool volatilep = false;
5709 tree arg;
5711 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5712 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5714 volatilep = true;
5715 break;
5718 if (! volatilep)
5720 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5721 expand_expr (TREE_VALUE (arg), const0_rtx,
5722 VOIDmode, EXPAND_NORMAL);
5723 return const0_rtx;
5727 switch (fcode)
5729 case BUILT_IN_FABS:
5730 case BUILT_IN_FABSF:
5731 case BUILT_IN_FABSL:
5732 target = expand_builtin_fabs (arglist, target, subtarget);
5733 if (target)
5734 return target;
5735 break;
5737 case BUILT_IN_COPYSIGN:
5738 case BUILT_IN_COPYSIGNF:
5739 case BUILT_IN_COPYSIGNL:
5740 target = expand_builtin_copysign (arglist, target, subtarget);
5741 if (target)
5742 return target;
5743 break;
5745 /* Just do a normal library call if we were unable to fold
5746 the values. */
5747 case BUILT_IN_CABS:
5748 case BUILT_IN_CABSF:
5749 case BUILT_IN_CABSL:
5750 break;
5752 case BUILT_IN_EXP:
5753 case BUILT_IN_EXPF:
5754 case BUILT_IN_EXPL:
5755 case BUILT_IN_EXP10:
5756 case BUILT_IN_EXP10F:
5757 case BUILT_IN_EXP10L:
5758 case BUILT_IN_POW10:
5759 case BUILT_IN_POW10F:
5760 case BUILT_IN_POW10L:
5761 case BUILT_IN_EXP2:
5762 case BUILT_IN_EXP2F:
5763 case BUILT_IN_EXP2L:
5764 case BUILT_IN_EXPM1:
5765 case BUILT_IN_EXPM1F:
5766 case BUILT_IN_EXPM1L:
5767 case BUILT_IN_LOGB:
5768 case BUILT_IN_LOGBF:
5769 case BUILT_IN_LOGBL:
5770 case BUILT_IN_ILOGB:
5771 case BUILT_IN_ILOGBF:
5772 case BUILT_IN_ILOGBL:
5773 case BUILT_IN_LOG:
5774 case BUILT_IN_LOGF:
5775 case BUILT_IN_LOGL:
5776 case BUILT_IN_LOG10:
5777 case BUILT_IN_LOG10F:
5778 case BUILT_IN_LOG10L:
5779 case BUILT_IN_LOG2:
5780 case BUILT_IN_LOG2F:
5781 case BUILT_IN_LOG2L:
5782 case BUILT_IN_LOG1P:
5783 case BUILT_IN_LOG1PF:
5784 case BUILT_IN_LOG1PL:
5785 case BUILT_IN_TAN:
5786 case BUILT_IN_TANF:
5787 case BUILT_IN_TANL:
5788 case BUILT_IN_ASIN:
5789 case BUILT_IN_ASINF:
5790 case BUILT_IN_ASINL:
5791 case BUILT_IN_ACOS:
5792 case BUILT_IN_ACOSF:
5793 case BUILT_IN_ACOSL:
5794 case BUILT_IN_ATAN:
5795 case BUILT_IN_ATANF:
5796 case BUILT_IN_ATANL:
5797 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5798 because of possible accuracy problems. */
5799 if (! flag_unsafe_math_optimizations)
5800 break;
5801 case BUILT_IN_SQRT:
5802 case BUILT_IN_SQRTF:
5803 case BUILT_IN_SQRTL:
5804 case BUILT_IN_FLOOR:
5805 case BUILT_IN_FLOORF:
5806 case BUILT_IN_FLOORL:
5807 case BUILT_IN_CEIL:
5808 case BUILT_IN_CEILF:
5809 case BUILT_IN_CEILL:
5810 case BUILT_IN_TRUNC:
5811 case BUILT_IN_TRUNCF:
5812 case BUILT_IN_TRUNCL:
5813 case BUILT_IN_ROUND:
5814 case BUILT_IN_ROUNDF:
5815 case BUILT_IN_ROUNDL:
5816 case BUILT_IN_NEARBYINT:
5817 case BUILT_IN_NEARBYINTF:
5818 case BUILT_IN_NEARBYINTL:
5819 case BUILT_IN_RINT:
5820 case BUILT_IN_RINTF:
5821 case BUILT_IN_RINTL:
5822 case BUILT_IN_LRINT:
5823 case BUILT_IN_LRINTF:
5824 case BUILT_IN_LRINTL:
5825 case BUILT_IN_LLRINT:
5826 case BUILT_IN_LLRINTF:
5827 case BUILT_IN_LLRINTL:
5828 target = expand_builtin_mathfn (exp, target, subtarget);
5829 if (target)
5830 return target;
5831 break;
5833 case BUILT_IN_LCEIL:
5834 case BUILT_IN_LCEILF:
5835 case BUILT_IN_LCEILL:
5836 case BUILT_IN_LLCEIL:
5837 case BUILT_IN_LLCEILF:
5838 case BUILT_IN_LLCEILL:
5839 case BUILT_IN_LFLOOR:
5840 case BUILT_IN_LFLOORF:
5841 case BUILT_IN_LFLOORL:
5842 case BUILT_IN_LLFLOOR:
5843 case BUILT_IN_LLFLOORF:
5844 case BUILT_IN_LLFLOORL:
5845 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5846 if (target)
5847 return target;
5848 break;
5850 case BUILT_IN_POW:
5851 case BUILT_IN_POWF:
5852 case BUILT_IN_POWL:
5853 target = expand_builtin_pow (exp, target, subtarget);
5854 if (target)
5855 return target;
5856 break;
5858 case BUILT_IN_POWI:
5859 case BUILT_IN_POWIF:
5860 case BUILT_IN_POWIL:
5861 target = expand_builtin_powi (exp, target, subtarget);
5862 if (target)
5863 return target;
5864 break;
5866 case BUILT_IN_ATAN2:
5867 case BUILT_IN_ATAN2F:
5868 case BUILT_IN_ATAN2L:
5869 case BUILT_IN_LDEXP:
5870 case BUILT_IN_LDEXPF:
5871 case BUILT_IN_LDEXPL:
5872 case BUILT_IN_FMOD:
5873 case BUILT_IN_FMODF:
5874 case BUILT_IN_FMODL:
5875 case BUILT_IN_DREM:
5876 case BUILT_IN_DREMF:
5877 case BUILT_IN_DREML:
5878 if (! flag_unsafe_math_optimizations)
5879 break;
5880 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5881 if (target)
5882 return target;
5883 break;
5885 case BUILT_IN_SIN:
5886 case BUILT_IN_SINF:
5887 case BUILT_IN_SINL:
5888 case BUILT_IN_COS:
5889 case BUILT_IN_COSF:
5890 case BUILT_IN_COSL:
5891 if (! flag_unsafe_math_optimizations)
5892 break;
5893 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5894 if (target)
5895 return target;
5896 break;
5898 case BUILT_IN_APPLY_ARGS:
5899 return expand_builtin_apply_args ();
5901 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5902 FUNCTION with a copy of the parameters described by
5903 ARGUMENTS, and ARGSIZE. It returns a block of memory
5904 allocated on the stack into which is stored all the registers
5905 that might possibly be used for returning the result of a
5906 function. ARGUMENTS is the value returned by
5907 __builtin_apply_args. ARGSIZE is the number of bytes of
5908 arguments that must be copied. ??? How should this value be
5909 computed? We'll also need a safe worst case value for varargs
5910 functions. */
5911 case BUILT_IN_APPLY:
5912 if (!validate_arglist (arglist, POINTER_TYPE,
5913 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5914 && !validate_arglist (arglist, REFERENCE_TYPE,
5915 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5916 return const0_rtx;
5917 else
5919 int i;
5920 tree t;
5921 rtx ops[3];
5923 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5924 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5926 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5929 /* __builtin_return (RESULT) causes the function to return the
5930 value described by RESULT. RESULT is address of the block of
5931 memory returned by __builtin_apply. */
5932 case BUILT_IN_RETURN:
5933 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5934 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5935 NULL_RTX, VOIDmode, 0));
5936 return const0_rtx;
5938 case BUILT_IN_SAVEREGS:
5939 return expand_builtin_saveregs ();
5941 case BUILT_IN_ARGS_INFO:
5942 return expand_builtin_args_info (arglist);
5944 /* Return the address of the first anonymous stack arg. */
5945 case BUILT_IN_NEXT_ARG:
5946 if (fold_builtin_next_arg (arglist))
5947 return const0_rtx;
5948 return expand_builtin_next_arg ();
5950 case BUILT_IN_CLASSIFY_TYPE:
5951 return expand_builtin_classify_type (arglist);
5953 case BUILT_IN_CONSTANT_P:
5954 return const0_rtx;
5956 case BUILT_IN_FRAME_ADDRESS:
5957 case BUILT_IN_RETURN_ADDRESS:
5958 return expand_builtin_frame_address (fndecl, arglist);
5960 /* Returns the address of the area where the structure is returned.
5961 0 otherwise. */
5962 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5963 if (arglist != 0
5964 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5965 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5966 return const0_rtx;
5967 else
5968 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5970 case BUILT_IN_ALLOCA:
5971 target = expand_builtin_alloca (arglist, target);
5972 if (target)
5973 return target;
5974 break;
5976 case BUILT_IN_STACK_SAVE:
5977 return expand_stack_save ();
5979 case BUILT_IN_STACK_RESTORE:
5980 expand_stack_restore (TREE_VALUE (arglist));
5981 return const0_rtx;
5983 case BUILT_IN_FFS:
5984 case BUILT_IN_FFSL:
5985 case BUILT_IN_FFSLL:
5986 case BUILT_IN_FFSIMAX:
5987 target = expand_builtin_unop (target_mode, arglist, target,
5988 subtarget, ffs_optab);
5989 if (target)
5990 return target;
5991 break;
5993 case BUILT_IN_CLZ:
5994 case BUILT_IN_CLZL:
5995 case BUILT_IN_CLZLL:
5996 case BUILT_IN_CLZIMAX:
5997 target = expand_builtin_unop (target_mode, arglist, target,
5998 subtarget, clz_optab);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_CTZ:
6004 case BUILT_IN_CTZL:
6005 case BUILT_IN_CTZLL:
6006 case BUILT_IN_CTZIMAX:
6007 target = expand_builtin_unop (target_mode, arglist, target,
6008 subtarget, ctz_optab);
6009 if (target)
6010 return target;
6011 break;
6013 case BUILT_IN_POPCOUNT:
6014 case BUILT_IN_POPCOUNTL:
6015 case BUILT_IN_POPCOUNTLL:
6016 case BUILT_IN_POPCOUNTIMAX:
6017 target = expand_builtin_unop (target_mode, arglist, target,
6018 subtarget, popcount_optab);
6019 if (target)
6020 return target;
6021 break;
6023 case BUILT_IN_PARITY:
6024 case BUILT_IN_PARITYL:
6025 case BUILT_IN_PARITYLL:
6026 case BUILT_IN_PARITYIMAX:
6027 target = expand_builtin_unop (target_mode, arglist, target,
6028 subtarget, parity_optab);
6029 if (target)
6030 return target;
6031 break;
6033 case BUILT_IN_STRLEN:
6034 target = expand_builtin_strlen (arglist, target, target_mode);
6035 if (target)
6036 return target;
6037 break;
6039 case BUILT_IN_STRCPY:
6040 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
6041 if (target)
6042 return target;
6043 break;
6045 case BUILT_IN_STRNCPY:
6046 target = expand_builtin_strncpy (exp, target, mode);
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_STPCPY:
6052 target = expand_builtin_stpcpy (exp, target, mode);
6053 if (target)
6054 return target;
6055 break;
6057 case BUILT_IN_STRCAT:
6058 target = expand_builtin_strcat (fndecl, arglist, target, mode);
6059 if (target)
6060 return target;
6061 break;
6063 case BUILT_IN_STRNCAT:
6064 target = expand_builtin_strncat (arglist, target, mode);
6065 if (target)
6066 return target;
6067 break;
6069 case BUILT_IN_STRSPN:
6070 target = expand_builtin_strspn (arglist, target, mode);
6071 if (target)
6072 return target;
6073 break;
6075 case BUILT_IN_STRCSPN:
6076 target = expand_builtin_strcspn (arglist, target, mode);
6077 if (target)
6078 return target;
6079 break;
6081 case BUILT_IN_STRSTR:
6082 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6083 if (target)
6084 return target;
6085 break;
6087 case BUILT_IN_STRPBRK:
6088 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6089 if (target)
6090 return target;
6091 break;
6093 case BUILT_IN_INDEX:
6094 case BUILT_IN_STRCHR:
6095 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6096 if (target)
6097 return target;
6098 break;
6100 case BUILT_IN_RINDEX:
6101 case BUILT_IN_STRRCHR:
6102 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6103 if (target)
6104 return target;
6105 break;
6107 case BUILT_IN_MEMCPY:
6108 target = expand_builtin_memcpy (exp, target, mode);
6109 if (target)
6110 return target;
6111 break;
6113 case BUILT_IN_MEMPCPY:
6114 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6115 if (target)
6116 return target;
6117 break;
6119 case BUILT_IN_MEMMOVE:
6120 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6121 mode, exp);
6122 if (target)
6123 return target;
6124 break;
6126 case BUILT_IN_BCOPY:
6127 target = expand_builtin_bcopy (exp);
6128 if (target)
6129 return target;
6130 break;
6132 case BUILT_IN_MEMSET:
6133 target = expand_builtin_memset (arglist, target, mode, exp);
6134 if (target)
6135 return target;
6136 break;
6138 case BUILT_IN_BZERO:
6139 target = expand_builtin_bzero (exp);
6140 if (target)
6141 return target;
6142 break;
6144 case BUILT_IN_STRCMP:
6145 target = expand_builtin_strcmp (exp, target, mode);
6146 if (target)
6147 return target;
6148 break;
6150 case BUILT_IN_STRNCMP:
6151 target = expand_builtin_strncmp (exp, target, mode);
6152 if (target)
6153 return target;
6154 break;
6156 case BUILT_IN_BCMP:
6157 case BUILT_IN_MEMCMP:
6158 target = expand_builtin_memcmp (exp, arglist, target, mode);
6159 if (target)
6160 return target;
6161 break;
6163 case BUILT_IN_SETJMP:
6164 target = expand_builtin_setjmp (arglist, target);
6165 if (target)
6166 return target;
6167 break;
6169 /* __builtin_longjmp is passed a pointer to an array of five words.
6170 It's similar to the C library longjmp function but works with
6171 __builtin_setjmp above. */
6172 case BUILT_IN_LONGJMP:
6173 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6174 break;
6175 else
6177 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6178 VOIDmode, 0);
6179 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6180 NULL_RTX, VOIDmode, 0);
6182 if (value != const1_rtx)
6184 error ("%<__builtin_longjmp%> second argument must be 1");
6185 return const0_rtx;
6188 expand_builtin_longjmp (buf_addr, value);
6189 return const0_rtx;
6192 case BUILT_IN_NONLOCAL_GOTO:
6193 target = expand_builtin_nonlocal_goto (arglist);
6194 if (target)
6195 return target;
6196 break;
6198 /* This updates the setjmp buffer that is its argument with the value
6199 of the current stack pointer. */
6200 case BUILT_IN_UPDATE_SETJMP_BUF:
6201 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6203 rtx buf_addr
6204 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6206 expand_builtin_update_setjmp_buf (buf_addr);
6207 return const0_rtx;
6209 break;
6211 case BUILT_IN_TRAP:
6212 expand_builtin_trap ();
6213 return const0_rtx;
6215 case BUILT_IN_PRINTF:
6216 target = expand_builtin_printf (exp, target, mode, false);
6217 if (target)
6218 return target;
6219 break;
6221 case BUILT_IN_PRINTF_UNLOCKED:
6222 target = expand_builtin_printf (exp, target, mode, true);
6223 if (target)
6224 return target;
6225 break;
6227 case BUILT_IN_FPUTS:
6228 target = expand_builtin_fputs (arglist, target, false);
6229 if (target)
6230 return target;
6231 break;
6232 case BUILT_IN_FPUTS_UNLOCKED:
6233 target = expand_builtin_fputs (arglist, target, true);
6234 if (target)
6235 return target;
6236 break;
6238 case BUILT_IN_FPRINTF:
6239 target = expand_builtin_fprintf (exp, target, mode, false);
6240 if (target)
6241 return target;
6242 break;
6244 case BUILT_IN_FPRINTF_UNLOCKED:
6245 target = expand_builtin_fprintf (exp, target, mode, true);
6246 if (target)
6247 return target;
6248 break;
6250 case BUILT_IN_SPRINTF:
6251 target = expand_builtin_sprintf (arglist, target, mode);
6252 if (target)
6253 return target;
6254 break;
6256 case BUILT_IN_SIGNBIT:
6257 case BUILT_IN_SIGNBITF:
6258 case BUILT_IN_SIGNBITL:
6259 target = expand_builtin_signbit (exp, target);
6260 if (target)
6261 return target;
6262 break;
6264 /* Various hooks for the DWARF 2 __throw routine. */
6265 case BUILT_IN_UNWIND_INIT:
6266 expand_builtin_unwind_init ();
6267 return const0_rtx;
6268 case BUILT_IN_DWARF_CFA:
6269 return virtual_cfa_rtx;
6270 #ifdef DWARF2_UNWIND_INFO
6271 case BUILT_IN_DWARF_SP_COLUMN:
6272 return expand_builtin_dwarf_sp_column ();
6273 case BUILT_IN_INIT_DWARF_REG_SIZES:
6274 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6275 return const0_rtx;
6276 #endif
6277 case BUILT_IN_FROB_RETURN_ADDR:
6278 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6279 case BUILT_IN_EXTRACT_RETURN_ADDR:
6280 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6281 case BUILT_IN_EH_RETURN:
6282 expand_builtin_eh_return (TREE_VALUE (arglist),
6283 TREE_VALUE (TREE_CHAIN (arglist)));
6284 return const0_rtx;
6285 #ifdef EH_RETURN_DATA_REGNO
6286 case BUILT_IN_EH_RETURN_DATA_REGNO:
6287 return expand_builtin_eh_return_data_regno (arglist);
6288 #endif
6289 case BUILT_IN_EXTEND_POINTER:
6290 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6292 case BUILT_IN_VA_START:
6293 case BUILT_IN_STDARG_START:
6294 return expand_builtin_va_start (arglist);
6295 case BUILT_IN_VA_END:
6296 return expand_builtin_va_end (arglist);
6297 case BUILT_IN_VA_COPY:
6298 return expand_builtin_va_copy (arglist);
6299 case BUILT_IN_EXPECT:
6300 return expand_builtin_expect (arglist, target);
6301 case BUILT_IN_PREFETCH:
6302 expand_builtin_prefetch (arglist);
6303 return const0_rtx;
6305 case BUILT_IN_PROFILE_FUNC_ENTER:
6306 return expand_builtin_profile_func (false);
6307 case BUILT_IN_PROFILE_FUNC_EXIT:
6308 return expand_builtin_profile_func (true);
6310 case BUILT_IN_INIT_TRAMPOLINE:
6311 return expand_builtin_init_trampoline (arglist);
6312 case BUILT_IN_ADJUST_TRAMPOLINE:
6313 return expand_builtin_adjust_trampoline (arglist);
6315 case BUILT_IN_FORK:
6316 case BUILT_IN_EXECL:
6317 case BUILT_IN_EXECV:
6318 case BUILT_IN_EXECLP:
6319 case BUILT_IN_EXECLE:
6320 case BUILT_IN_EXECVP:
6321 case BUILT_IN_EXECVE:
6322 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6323 if (target)
6324 return target;
6325 break;
6327 case BUILT_IN_FETCH_AND_ADD_1:
6328 case BUILT_IN_FETCH_AND_ADD_2:
6329 case BUILT_IN_FETCH_AND_ADD_4:
6330 case BUILT_IN_FETCH_AND_ADD_8:
6331 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6332 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6333 false, target, ignore);
6334 if (target)
6335 return target;
6336 break;
6338 case BUILT_IN_FETCH_AND_SUB_1:
6339 case BUILT_IN_FETCH_AND_SUB_2:
6340 case BUILT_IN_FETCH_AND_SUB_4:
6341 case BUILT_IN_FETCH_AND_SUB_8:
6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6343 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6344 false, target, ignore);
6345 if (target)
6346 return target;
6347 break;
6349 case BUILT_IN_FETCH_AND_OR_1:
6350 case BUILT_IN_FETCH_AND_OR_2:
6351 case BUILT_IN_FETCH_AND_OR_4:
6352 case BUILT_IN_FETCH_AND_OR_8:
6353 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6354 target = expand_builtin_sync_operation (mode, arglist, IOR,
6355 false, target, ignore);
6356 if (target)
6357 return target;
6358 break;
6360 case BUILT_IN_FETCH_AND_AND_1:
6361 case BUILT_IN_FETCH_AND_AND_2:
6362 case BUILT_IN_FETCH_AND_AND_4:
6363 case BUILT_IN_FETCH_AND_AND_8:
6364 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6365 target = expand_builtin_sync_operation (mode, arglist, AND,
6366 false, target, ignore);
6367 if (target)
6368 return target;
6369 break;
6371 case BUILT_IN_FETCH_AND_XOR_1:
6372 case BUILT_IN_FETCH_AND_XOR_2:
6373 case BUILT_IN_FETCH_AND_XOR_4:
6374 case BUILT_IN_FETCH_AND_XOR_8:
6375 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6376 target = expand_builtin_sync_operation (mode, arglist, XOR,
6377 false, target, ignore);
6378 if (target)
6379 return target;
6380 break;
6382 case BUILT_IN_FETCH_AND_NAND_1:
6383 case BUILT_IN_FETCH_AND_NAND_2:
6384 case BUILT_IN_FETCH_AND_NAND_4:
6385 case BUILT_IN_FETCH_AND_NAND_8:
6386 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6387 target = expand_builtin_sync_operation (mode, arglist, NOT,
6388 false, target, ignore);
6389 if (target)
6390 return target;
6391 break;
6393 case BUILT_IN_ADD_AND_FETCH_1:
6394 case BUILT_IN_ADD_AND_FETCH_2:
6395 case BUILT_IN_ADD_AND_FETCH_4:
6396 case BUILT_IN_ADD_AND_FETCH_8:
6397 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6398 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6399 true, target, ignore);
6400 if (target)
6401 return target;
6402 break;
6404 case BUILT_IN_SUB_AND_FETCH_1:
6405 case BUILT_IN_SUB_AND_FETCH_2:
6406 case BUILT_IN_SUB_AND_FETCH_4:
6407 case BUILT_IN_SUB_AND_FETCH_8:
6408 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6409 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6410 true, target, ignore);
6411 if (target)
6412 return target;
6413 break;
6415 case BUILT_IN_OR_AND_FETCH_1:
6416 case BUILT_IN_OR_AND_FETCH_2:
6417 case BUILT_IN_OR_AND_FETCH_4:
6418 case BUILT_IN_OR_AND_FETCH_8:
6419 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6420 target = expand_builtin_sync_operation (mode, arglist, IOR,
6421 true, target, ignore);
6422 if (target)
6423 return target;
6424 break;
6426 case BUILT_IN_AND_AND_FETCH_1:
6427 case BUILT_IN_AND_AND_FETCH_2:
6428 case BUILT_IN_AND_AND_FETCH_4:
6429 case BUILT_IN_AND_AND_FETCH_8:
6430 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6431 target = expand_builtin_sync_operation (mode, arglist, AND,
6432 true, target, ignore);
6433 if (target)
6434 return target;
6435 break;
6437 case BUILT_IN_XOR_AND_FETCH_1:
6438 case BUILT_IN_XOR_AND_FETCH_2:
6439 case BUILT_IN_XOR_AND_FETCH_4:
6440 case BUILT_IN_XOR_AND_FETCH_8:
6441 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6442 target = expand_builtin_sync_operation (mode, arglist, XOR,
6443 true, target, ignore);
6444 if (target)
6445 return target;
6446 break;
6448 case BUILT_IN_NAND_AND_FETCH_1:
6449 case BUILT_IN_NAND_AND_FETCH_2:
6450 case BUILT_IN_NAND_AND_FETCH_4:
6451 case BUILT_IN_NAND_AND_FETCH_8:
6452 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6453 target = expand_builtin_sync_operation (mode, arglist, NOT,
6454 true, target, ignore);
6455 if (target)
6456 return target;
6457 break;
6459 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6460 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6461 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6462 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6463 if (mode == VOIDmode)
6464 mode = TYPE_MODE (boolean_type_node);
6465 if (!target || !register_operand (target, mode))
6466 target = gen_reg_rtx (mode);
6468 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6469 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6470 if (target)
6471 return target;
6472 break;
6474 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6475 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6476 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6477 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6478 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6479 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6480 if (target)
6481 return target;
6482 break;
6484 case BUILT_IN_LOCK_TEST_AND_SET_1:
6485 case BUILT_IN_LOCK_TEST_AND_SET_2:
6486 case BUILT_IN_LOCK_TEST_AND_SET_4:
6487 case BUILT_IN_LOCK_TEST_AND_SET_8:
6488 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6489 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6490 if (target)
6491 return target;
6492 break;
6494 case BUILT_IN_LOCK_RELEASE_1:
6495 case BUILT_IN_LOCK_RELEASE_2:
6496 case BUILT_IN_LOCK_RELEASE_4:
6497 case BUILT_IN_LOCK_RELEASE_8:
6498 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6499 expand_builtin_lock_release (mode, arglist);
6500 return const0_rtx;
6502 case BUILT_IN_SYNCHRONIZE:
6503 expand_builtin_synchronize ();
6504 return const0_rtx;
6506 case BUILT_IN_OBJECT_SIZE:
6507 return expand_builtin_object_size (exp);
6509 case BUILT_IN_MEMCPY_CHK:
6510 case BUILT_IN_MEMPCPY_CHK:
6511 case BUILT_IN_MEMMOVE_CHK:
6512 case BUILT_IN_MEMSET_CHK:
6513 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6514 if (target)
6515 return target;
6516 break;
6518 case BUILT_IN_STRCPY_CHK:
6519 case BUILT_IN_STPCPY_CHK:
6520 case BUILT_IN_STRNCPY_CHK:
6521 case BUILT_IN_STRCAT_CHK:
6522 case BUILT_IN_SNPRINTF_CHK:
6523 case BUILT_IN_VSNPRINTF_CHK:
6524 maybe_emit_chk_warning (exp, fcode);
6525 break;
6527 case BUILT_IN_SPRINTF_CHK:
6528 case BUILT_IN_VSPRINTF_CHK:
6529 maybe_emit_sprintf_chk_warning (exp, fcode);
6530 break;
6532 default: /* just do library call, if unknown builtin */
6533 break;
6536 /* The switch statement above can drop through to cause the function
6537 to be called normally. */
6538 return expand_call (exp, target, ignore);
6541 /* Determine whether a tree node represents a call to a built-in
6542 function. If the tree T is a call to a built-in function with
6543 the right number of arguments of the appropriate types, return
6544 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6545 Otherwise the return value is END_BUILTINS. */
6547 enum built_in_function
6548 builtin_mathfn_code (tree t)
6550 tree fndecl, arglist, parmlist;
6551 tree argtype, parmtype;
6553 if (TREE_CODE (t) != CALL_EXPR
6554 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6555 return END_BUILTINS;
6557 fndecl = get_callee_fndecl (t);
6558 if (fndecl == NULL_TREE
6559 || TREE_CODE (fndecl) != FUNCTION_DECL
6560 || ! DECL_BUILT_IN (fndecl)
6561 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6562 return END_BUILTINS;
6564 arglist = TREE_OPERAND (t, 1);
6565 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6566 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6568 /* If a function doesn't take a variable number of arguments,
6569 the last element in the list will have type `void'. */
6570 parmtype = TREE_VALUE (parmlist);
6571 if (VOID_TYPE_P (parmtype))
6573 if (arglist)
6574 return END_BUILTINS;
6575 return DECL_FUNCTION_CODE (fndecl);
6578 if (! arglist)
6579 return END_BUILTINS;
6581 argtype = TREE_TYPE (TREE_VALUE (arglist));
6583 if (SCALAR_FLOAT_TYPE_P (parmtype))
6585 if (! SCALAR_FLOAT_TYPE_P (argtype))
6586 return END_BUILTINS;
6588 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6590 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6591 return END_BUILTINS;
6593 else if (POINTER_TYPE_P (parmtype))
6595 if (! POINTER_TYPE_P (argtype))
6596 return END_BUILTINS;
6598 else if (INTEGRAL_TYPE_P (parmtype))
6600 if (! INTEGRAL_TYPE_P (argtype))
6601 return END_BUILTINS;
6603 else
6604 return END_BUILTINS;
6606 arglist = TREE_CHAIN (arglist);
6609 /* Variable-length argument list. */
6610 return DECL_FUNCTION_CODE (fndecl);
6613 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6614 constant. ARGLIST is the argument list of the call. */
6616 static tree
6617 fold_builtin_constant_p (tree arglist)
6619 if (arglist == 0)
6620 return 0;
6622 arglist = TREE_VALUE (arglist);
6624 /* We return 1 for a numeric type that's known to be a constant
6625 value at compile-time or for an aggregate type that's a
6626 literal constant. */
6627 STRIP_NOPS (arglist);
6629 /* If we know this is a constant, emit the constant of one. */
6630 if (CONSTANT_CLASS_P (arglist)
6631 || (TREE_CODE (arglist) == CONSTRUCTOR
6632 && TREE_CONSTANT (arglist)))
6633 return integer_one_node;
6634 if (TREE_CODE (arglist) == ADDR_EXPR)
6636 tree op = TREE_OPERAND (arglist, 0);
6637 if (TREE_CODE (op) == STRING_CST
6638 || (TREE_CODE (op) == ARRAY_REF
6639 && integer_zerop (TREE_OPERAND (op, 1))
6640 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6641 return integer_one_node;
6644 /* If this expression has side effects, show we don't know it to be a
6645 constant. Likewise if it's a pointer or aggregate type since in
6646 those case we only want literals, since those are only optimized
6647 when generating RTL, not later.
6648 And finally, if we are compiling an initializer, not code, we
6649 need to return a definite result now; there's not going to be any
6650 more optimization done. */
6651 if (TREE_SIDE_EFFECTS (arglist)
6652 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6653 || POINTER_TYPE_P (TREE_TYPE (arglist))
6654 || cfun == 0)
6655 return integer_zero_node;
6657 return 0;
6660 /* Fold a call to __builtin_expect, if we expect that a comparison against
6661 the argument will fold to a constant. In practice, this means a true
6662 constant or the address of a non-weak symbol. ARGLIST is the argument
6663 list of the call. */
6665 static tree
6666 fold_builtin_expect (tree arglist)
6668 tree arg, inner;
6670 if (arglist == 0)
6671 return 0;
6673 arg = TREE_VALUE (arglist);
6675 /* If the argument isn't invariant, then there's nothing we can do. */
6676 if (!TREE_INVARIANT (arg))
6677 return 0;
6679 /* If we're looking at an address of a weak decl, then do not fold. */
6680 inner = arg;
6681 STRIP_NOPS (inner);
6682 if (TREE_CODE (inner) == ADDR_EXPR)
6686 inner = TREE_OPERAND (inner, 0);
6688 while (TREE_CODE (inner) == COMPONENT_REF
6689 || TREE_CODE (inner) == ARRAY_REF);
6690 if (DECL_P (inner) && DECL_WEAK (inner))
6691 return 0;
6694 /* Otherwise, ARG already has the proper type for the return value. */
6695 return arg;
6698 /* Fold a call to __builtin_classify_type. */
6700 static tree
6701 fold_builtin_classify_type (tree arglist)
6703 if (arglist == 0)
6704 return build_int_cst (NULL_TREE, no_type_class);
6706 return build_int_cst (NULL_TREE,
6707 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6710 /* Fold a call to __builtin_strlen. */
6712 static tree
6713 fold_builtin_strlen (tree arglist)
6715 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6716 return NULL_TREE;
6717 else
6719 tree len = c_strlen (TREE_VALUE (arglist), 0);
6721 if (len)
6723 /* Convert from the internal "sizetype" type to "size_t". */
6724 if (size_type_node)
6725 len = fold_convert (size_type_node, len);
6726 return len;
6729 return NULL_TREE;
6733 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6735 static tree
6736 fold_builtin_inf (tree type, int warn)
6738 REAL_VALUE_TYPE real;
6740 /* __builtin_inff is intended to be usable to define INFINITY on all
6741 targets. If an infinity is not available, INFINITY expands "to a
6742 positive constant of type float that overflows at translation
6743 time", footnote "In this case, using INFINITY will violate the
6744 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6745 Thus we pedwarn to ensure this constraint violation is
6746 diagnosed. */
6747 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6748 pedwarn ("target format does not support infinity");
6750 real_inf (&real);
6751 return build_real (type, real);
6754 /* Fold a call to __builtin_nan or __builtin_nans. */
6756 static tree
6757 fold_builtin_nan (tree arglist, tree type, int quiet)
6759 REAL_VALUE_TYPE real;
6760 const char *str;
6762 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6763 return 0;
6764 str = c_getstr (TREE_VALUE (arglist));
6765 if (!str)
6766 return 0;
6768 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6769 return 0;
6771 return build_real (type, real);
6774 /* Return true if the floating point expression T has an integer value.
6775 We also allow +Inf, -Inf and NaN to be considered integer values. */
6777 static bool
6778 integer_valued_real_p (tree t)
6780 switch (TREE_CODE (t))
6782 case FLOAT_EXPR:
6783 return true;
6785 case ABS_EXPR:
6786 case SAVE_EXPR:
6787 case NON_LVALUE_EXPR:
6788 return integer_valued_real_p (TREE_OPERAND (t, 0));
6790 case COMPOUND_EXPR:
6791 case MODIFY_EXPR:
6792 case BIND_EXPR:
6793 return integer_valued_real_p (TREE_OPERAND (t, 1));
6795 case PLUS_EXPR:
6796 case MINUS_EXPR:
6797 case MULT_EXPR:
6798 case MIN_EXPR:
6799 case MAX_EXPR:
6800 return integer_valued_real_p (TREE_OPERAND (t, 0))
6801 && integer_valued_real_p (TREE_OPERAND (t, 1));
6803 case COND_EXPR:
6804 return integer_valued_real_p (TREE_OPERAND (t, 1))
6805 && integer_valued_real_p (TREE_OPERAND (t, 2));
6807 case REAL_CST:
6808 if (! TREE_CONSTANT_OVERFLOW (t))
6810 REAL_VALUE_TYPE c, cint;
6812 c = TREE_REAL_CST (t);
6813 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6814 return real_identical (&c, &cint);
6816 break;
6818 case NOP_EXPR:
6820 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6821 if (TREE_CODE (type) == INTEGER_TYPE)
6822 return true;
6823 if (TREE_CODE (type) == REAL_TYPE)
6824 return integer_valued_real_p (TREE_OPERAND (t, 0));
6825 break;
6828 case CALL_EXPR:
6829 switch (builtin_mathfn_code (t))
6831 case BUILT_IN_CEIL:
6832 case BUILT_IN_CEILF:
6833 case BUILT_IN_CEILL:
6834 case BUILT_IN_FLOOR:
6835 case BUILT_IN_FLOORF:
6836 case BUILT_IN_FLOORL:
6837 case BUILT_IN_NEARBYINT:
6838 case BUILT_IN_NEARBYINTF:
6839 case BUILT_IN_NEARBYINTL:
6840 case BUILT_IN_RINT:
6841 case BUILT_IN_RINTF:
6842 case BUILT_IN_RINTL:
6843 case BUILT_IN_ROUND:
6844 case BUILT_IN_ROUNDF:
6845 case BUILT_IN_ROUNDL:
6846 case BUILT_IN_TRUNC:
6847 case BUILT_IN_TRUNCF:
6848 case BUILT_IN_TRUNCL:
6849 return true;
6851 default:
6852 break;
6854 break;
6856 default:
6857 break;
6859 return false;
6862 /* EXP is assumed to be builtin call where truncation can be propagated
6863 across (for instance floor((double)f) == (double)floorf (f).
6864 Do the transformation. */
6866 static tree
6867 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6869 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6870 tree arg;
6872 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6873 return 0;
6875 arg = TREE_VALUE (arglist);
6876 /* Integer rounding functions are idempotent. */
6877 if (fcode == builtin_mathfn_code (arg))
6878 return arg;
6880 /* If argument is already integer valued, and we don't need to worry
6881 about setting errno, there's no need to perform rounding. */
6882 if (! flag_errno_math && integer_valued_real_p (arg))
6883 return arg;
6885 if (optimize)
6887 tree arg0 = strip_float_extensions (arg);
6888 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6889 tree newtype = TREE_TYPE (arg0);
6890 tree decl;
6892 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6893 && (decl = mathfn_built_in (newtype, fcode)))
6895 arglist =
6896 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6897 return fold_convert (ftype,
6898 build_function_call_expr (decl, arglist));
6901 return 0;
6904 /* EXP is assumed to be builtin call which can narrow the FP type of
6905 the argument, for instance lround((double)f) -> lroundf (f). */
6907 static tree
6908 fold_fixed_mathfn (tree fndecl, tree arglist)
6910 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6911 tree arg;
6913 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6914 return 0;
6916 arg = TREE_VALUE (arglist);
6918 /* If argument is already integer valued, and we don't need to worry
6919 about setting errno, there's no need to perform rounding. */
6920 if (! flag_errno_math && integer_valued_real_p (arg))
6921 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6923 if (optimize)
6925 tree ftype = TREE_TYPE (arg);
6926 tree arg0 = strip_float_extensions (arg);
6927 tree newtype = TREE_TYPE (arg0);
6928 tree decl;
6930 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6931 && (decl = mathfn_built_in (newtype, fcode)))
6933 arglist =
6934 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6935 return build_function_call_expr (decl, arglist);
6939 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6940 sizeof (long long) == sizeof (long). */
6941 if (TYPE_PRECISION (long_long_integer_type_node)
6942 == TYPE_PRECISION (long_integer_type_node))
6944 tree newfn = NULL_TREE;
6945 switch (fcode)
6947 case BUILT_IN_LLCEIL:
6948 case BUILT_IN_LLCEILF:
6949 case BUILT_IN_LLCEILL:
6950 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6951 break;
6953 case BUILT_IN_LLFLOOR:
6954 case BUILT_IN_LLFLOORF:
6955 case BUILT_IN_LLFLOORL:
6956 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6957 break;
6959 case BUILT_IN_LLROUND:
6960 case BUILT_IN_LLROUNDF:
6961 case BUILT_IN_LLROUNDL:
6962 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6963 break;
6965 case BUILT_IN_LLRINT:
6966 case BUILT_IN_LLRINTF:
6967 case BUILT_IN_LLRINTL:
6968 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6969 break;
6971 default:
6972 break;
6975 if (newfn)
6977 tree newcall = build_function_call_expr (newfn, arglist);
6978 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6982 return 0;
6985 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6986 is the argument list and TYPE is the return type. Return
6987 NULL_TREE if no if no simplification can be made. */
6989 static tree
6990 fold_builtin_cabs (tree arglist, tree type)
6992 tree arg;
6994 if (!arglist || TREE_CHAIN (arglist))
6995 return NULL_TREE;
6997 arg = TREE_VALUE (arglist);
6998 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6999 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7000 return NULL_TREE;
7002 /* Evaluate cabs of a constant at compile-time. */
7003 if (flag_unsafe_math_optimizations
7004 && TREE_CODE (arg) == COMPLEX_CST
7005 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
7006 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
7007 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
7008 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
7010 REAL_VALUE_TYPE r, i;
7012 r = TREE_REAL_CST (TREE_REALPART (arg));
7013 i = TREE_REAL_CST (TREE_IMAGPART (arg));
7015 real_arithmetic (&r, MULT_EXPR, &r, &r);
7016 real_arithmetic (&i, MULT_EXPR, &i, &i);
7017 real_arithmetic (&r, PLUS_EXPR, &r, &i);
7018 if (real_sqrt (&r, TYPE_MODE (type), &r)
7019 || ! flag_trapping_math)
7020 return build_real (type, r);
7023 /* If either part is zero, cabs is fabs of the other. */
7024 if (TREE_CODE (arg) == COMPLEX_EXPR
7025 && real_zerop (TREE_OPERAND (arg, 0)))
7026 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
7027 if (TREE_CODE (arg) == COMPLEX_EXPR
7028 && real_zerop (TREE_OPERAND (arg, 1)))
7029 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
7031 /* Don't do this when optimizing for size. */
7032 if (flag_unsafe_math_optimizations
7033 && optimize && !optimize_size)
7035 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7037 if (sqrtfn != NULL_TREE)
7039 tree rpart, ipart, result, arglist;
7041 arg = builtin_save_expr (arg);
7043 rpart = fold_build1 (REALPART_EXPR, type, arg);
7044 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7046 rpart = builtin_save_expr (rpart);
7047 ipart = builtin_save_expr (ipart);
7049 result = fold_build2 (PLUS_EXPR, type,
7050 fold_build2 (MULT_EXPR, type,
7051 rpart, rpart),
7052 fold_build2 (MULT_EXPR, type,
7053 ipart, ipart));
7055 arglist = build_tree_list (NULL_TREE, result);
7056 return build_function_call_expr (sqrtfn, arglist);
7060 return NULL_TREE;
7063 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7064 NULL_TREE if no simplification can be made. */
7066 static tree
7067 fold_builtin_sqrt (tree arglist, tree type)
7070 enum built_in_function fcode;
7071 tree arg = TREE_VALUE (arglist);
7073 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7074 return NULL_TREE;
7076 /* Optimize sqrt of constant value. */
7077 if (TREE_CODE (arg) == REAL_CST
7078 && ! TREE_CONSTANT_OVERFLOW (arg))
7080 REAL_VALUE_TYPE r, x;
7082 x = TREE_REAL_CST (arg);
7083 if (real_sqrt (&r, TYPE_MODE (type), &x)
7084 || (!flag_trapping_math && !flag_errno_math))
7085 return build_real (type, r);
7088 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7089 fcode = builtin_mathfn_code (arg);
7090 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7092 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7093 arg = fold_build2 (MULT_EXPR, type,
7094 TREE_VALUE (TREE_OPERAND (arg, 1)),
7095 build_real (type, dconsthalf));
7096 arglist = build_tree_list (NULL_TREE, arg);
7097 return build_function_call_expr (expfn, arglist);
7100 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7101 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7103 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7105 if (powfn)
7107 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7108 tree tree_root;
7109 /* The inner root was either sqrt or cbrt. */
7110 REAL_VALUE_TYPE dconstroot =
7111 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7113 /* Adjust for the outer root. */
7114 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7115 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7116 tree_root = build_real (type, dconstroot);
7117 arglist = tree_cons (NULL_TREE, arg0,
7118 build_tree_list (NULL_TREE, tree_root));
7119 return build_function_call_expr (powfn, arglist);
7123 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7124 if (flag_unsafe_math_optimizations
7125 && (fcode == BUILT_IN_POW
7126 || fcode == BUILT_IN_POWF
7127 || fcode == BUILT_IN_POWL))
7129 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7130 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7131 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7132 tree narg1;
7133 if (!tree_expr_nonnegative_p (arg0))
7134 arg0 = build1 (ABS_EXPR, type, arg0);
7135 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7136 build_real (type, dconsthalf));
7137 arglist = tree_cons (NULL_TREE, arg0,
7138 build_tree_list (NULL_TREE, narg1));
7139 return build_function_call_expr (powfn, arglist);
7142 return NULL_TREE;
7145 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7146 NULL_TREE if no simplification can be made. */
7147 static tree
7148 fold_builtin_cbrt (tree arglist, tree type)
7150 tree arg = TREE_VALUE (arglist);
7151 const enum built_in_function fcode = builtin_mathfn_code (arg);
7153 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7154 return NULL_TREE;
7156 /* Optimize cbrt of constant value. */
7157 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7158 return arg;
7160 if (flag_unsafe_math_optimizations)
7162 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7163 if (BUILTIN_EXPONENT_P (fcode))
7165 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7166 const REAL_VALUE_TYPE third_trunc =
7167 real_value_truncate (TYPE_MODE (type), dconstthird);
7168 arg = fold_build2 (MULT_EXPR, type,
7169 TREE_VALUE (TREE_OPERAND (arg, 1)),
7170 build_real (type, third_trunc));
7171 arglist = build_tree_list (NULL_TREE, arg);
7172 return build_function_call_expr (expfn, arglist);
7175 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7176 if (BUILTIN_SQRT_P (fcode))
7178 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7180 if (powfn)
7182 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7183 tree tree_root;
7184 REAL_VALUE_TYPE dconstroot = dconstthird;
7186 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7187 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7188 tree_root = build_real (type, dconstroot);
7189 arglist = tree_cons (NULL_TREE, arg0,
7190 build_tree_list (NULL_TREE, tree_root));
7191 return build_function_call_expr (powfn, arglist);
7195 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7196 if (BUILTIN_CBRT_P (fcode))
7198 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7199 if (tree_expr_nonnegative_p (arg0))
7201 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7203 if (powfn)
7205 tree tree_root;
7206 REAL_VALUE_TYPE dconstroot;
7208 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7209 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7210 tree_root = build_real (type, dconstroot);
7211 arglist = tree_cons (NULL_TREE, arg0,
7212 build_tree_list (NULL_TREE, tree_root));
7213 return build_function_call_expr (powfn, arglist);
7218 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7219 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7220 || fcode == BUILT_IN_POWL)
7222 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7223 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7224 if (tree_expr_nonnegative_p (arg00))
7226 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7227 const REAL_VALUE_TYPE dconstroot
7228 = real_value_truncate (TYPE_MODE (type), dconstthird);
7229 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7230 build_real (type, dconstroot));
7231 arglist = tree_cons (NULL_TREE, arg00,
7232 build_tree_list (NULL_TREE, narg01));
7233 return build_function_call_expr (powfn, arglist);
7237 return NULL_TREE;
7240 /* Fold function call to builtin sin, sinf, or sinl. Return
7241 NULL_TREE if no simplification can be made. */
7242 static tree
7243 fold_builtin_sin (tree arglist)
7245 tree arg = TREE_VALUE (arglist);
7247 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7248 return NULL_TREE;
7250 /* Optimize sin (0.0) = 0.0. */
7251 if (real_zerop (arg))
7252 return arg;
7254 return NULL_TREE;
7257 /* Fold function call to builtin cos, cosf, or cosl. Return
7258 NULL_TREE if no simplification can be made. */
7259 static tree
7260 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7262 tree arg = TREE_VALUE (arglist);
7264 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7265 return NULL_TREE;
7267 /* Optimize cos (0.0) = 1.0. */
7268 if (real_zerop (arg))
7269 return build_real (type, dconst1);
7271 /* Optimize cos(-x) into cos (x). */
7272 if (TREE_CODE (arg) == NEGATE_EXPR)
7274 tree args = build_tree_list (NULL_TREE,
7275 TREE_OPERAND (arg, 0));
7276 return build_function_call_expr (fndecl, args);
7279 return NULL_TREE;
7282 /* Fold function call to builtin tan, tanf, or tanl. Return
7283 NULL_TREE if no simplification can be made. */
7284 static tree
7285 fold_builtin_tan (tree arglist)
7287 enum built_in_function fcode;
7288 tree arg = TREE_VALUE (arglist);
7290 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7291 return NULL_TREE;
7293 /* Optimize tan(0.0) = 0.0. */
7294 if (real_zerop (arg))
7295 return arg;
7297 /* Optimize tan(atan(x)) = x. */
7298 fcode = builtin_mathfn_code (arg);
7299 if (flag_unsafe_math_optimizations
7300 && (fcode == BUILT_IN_ATAN
7301 || fcode == BUILT_IN_ATANF
7302 || fcode == BUILT_IN_ATANL))
7303 return TREE_VALUE (TREE_OPERAND (arg, 1));
7305 return NULL_TREE;
7308 /* Fold function call to builtin atan, atanf, or atanl. Return
7309 NULL_TREE if no simplification can be made. */
7311 static tree
7312 fold_builtin_atan (tree arglist, tree type)
7315 tree arg = TREE_VALUE (arglist);
7317 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7318 return NULL_TREE;
7320 /* Optimize atan(0.0) = 0.0. */
7321 if (real_zerop (arg))
7322 return arg;
7324 /* Optimize atan(1.0) = pi/4. */
7325 if (real_onep (arg))
7327 REAL_VALUE_TYPE cst;
7329 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7330 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7331 return build_real (type, cst);
7334 return NULL_TREE;
7337 /* Fold function call to builtin trunc, truncf or truncl. Return
7338 NULL_TREE if no simplification can be made. */
7340 static tree
7341 fold_builtin_trunc (tree fndecl, tree arglist)
7343 tree arg;
7345 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7346 return 0;
7348 /* Optimize trunc of constant value. */
7349 arg = TREE_VALUE (arglist);
7350 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7352 REAL_VALUE_TYPE r, x;
7353 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7355 x = TREE_REAL_CST (arg);
7356 real_trunc (&r, TYPE_MODE (type), &x);
7357 return build_real (type, r);
7360 return fold_trunc_transparent_mathfn (fndecl, arglist);
7363 /* Fold function call to builtin floor, floorf or floorl. Return
7364 NULL_TREE if no simplification can be made. */
7366 static tree
7367 fold_builtin_floor (tree fndecl, tree arglist)
7369 tree arg;
7371 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7372 return 0;
7374 /* Optimize floor of constant value. */
7375 arg = TREE_VALUE (arglist);
7376 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7378 REAL_VALUE_TYPE x;
7380 x = TREE_REAL_CST (arg);
7381 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7383 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7384 REAL_VALUE_TYPE r;
7386 real_floor (&r, TYPE_MODE (type), &x);
7387 return build_real (type, r);
7391 return fold_trunc_transparent_mathfn (fndecl, arglist);
7394 /* Fold function call to builtin ceil, ceilf or ceill. Return
7395 NULL_TREE if no simplification can be made. */
7397 static tree
7398 fold_builtin_ceil (tree fndecl, tree arglist)
7400 tree arg;
7402 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7403 return 0;
7405 /* Optimize ceil of constant value. */
7406 arg = TREE_VALUE (arglist);
7407 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7409 REAL_VALUE_TYPE x;
7411 x = TREE_REAL_CST (arg);
7412 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7414 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7415 REAL_VALUE_TYPE r;
7417 real_ceil (&r, TYPE_MODE (type), &x);
7418 return build_real (type, r);
7422 return fold_trunc_transparent_mathfn (fndecl, arglist);
7425 /* Fold function call to builtin round, roundf or roundl. Return
7426 NULL_TREE if no simplification can be made. */
7428 static tree
7429 fold_builtin_round (tree fndecl, tree arglist)
7431 tree arg;
7433 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7434 return 0;
7436 /* Optimize round of constant value. */
7437 arg = TREE_VALUE (arglist);
7438 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7440 REAL_VALUE_TYPE x;
7442 x = TREE_REAL_CST (arg);
7443 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7445 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7446 REAL_VALUE_TYPE r;
7448 real_round (&r, TYPE_MODE (type), &x);
7449 return build_real (type, r);
7453 return fold_trunc_transparent_mathfn (fndecl, arglist);
7456 /* Fold function call to builtin lround, lroundf or lroundl (or the
7457 corresponding long long versions) and other rounding functions.
7458 Return NULL_TREE if no simplification can be made. */
7460 static tree
7461 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7463 tree arg;
7465 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7466 return 0;
7468 /* Optimize lround of constant value. */
7469 arg = TREE_VALUE (arglist);
7470 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7472 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7474 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7476 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7477 tree ftype = TREE_TYPE (arg), result;
7478 HOST_WIDE_INT hi, lo;
7479 REAL_VALUE_TYPE r;
7481 switch (DECL_FUNCTION_CODE (fndecl))
7483 case BUILT_IN_LFLOOR:
7484 case BUILT_IN_LFLOORF:
7485 case BUILT_IN_LFLOORL:
7486 case BUILT_IN_LLFLOOR:
7487 case BUILT_IN_LLFLOORF:
7488 case BUILT_IN_LLFLOORL:
7489 real_floor (&r, TYPE_MODE (ftype), &x);
7490 break;
7492 case BUILT_IN_LCEIL:
7493 case BUILT_IN_LCEILF:
7494 case BUILT_IN_LCEILL:
7495 case BUILT_IN_LLCEIL:
7496 case BUILT_IN_LLCEILF:
7497 case BUILT_IN_LLCEILL:
7498 real_ceil (&r, TYPE_MODE (ftype), &x);
7499 break;
7501 case BUILT_IN_LROUND:
7502 case BUILT_IN_LROUNDF:
7503 case BUILT_IN_LROUNDL:
7504 case BUILT_IN_LLROUND:
7505 case BUILT_IN_LLROUNDF:
7506 case BUILT_IN_LLROUNDL:
7507 real_round (&r, TYPE_MODE (ftype), &x);
7508 break;
7510 default:
7511 gcc_unreachable ();
7514 REAL_VALUE_TO_INT (&lo, &hi, r);
7515 result = build_int_cst_wide (NULL_TREE, lo, hi);
7516 if (int_fits_type_p (result, itype))
7517 return fold_convert (itype, result);
7521 return fold_fixed_mathfn (fndecl, arglist);
7524 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7525 and their long and long long variants (i.e. ffsl and ffsll).
7526 Return NULL_TREE if no simplification can be made. */
7528 static tree
7529 fold_builtin_bitop (tree fndecl, tree arglist)
7531 tree arg;
7533 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7534 return NULL_TREE;
7536 /* Optimize for constant argument. */
7537 arg = TREE_VALUE (arglist);
7538 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7540 HOST_WIDE_INT hi, width, result;
7541 unsigned HOST_WIDE_INT lo;
7542 tree type;
7544 type = TREE_TYPE (arg);
7545 width = TYPE_PRECISION (type);
7546 lo = TREE_INT_CST_LOW (arg);
7548 /* Clear all the bits that are beyond the type's precision. */
7549 if (width > HOST_BITS_PER_WIDE_INT)
7551 hi = TREE_INT_CST_HIGH (arg);
7552 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7553 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7555 else
7557 hi = 0;
7558 if (width < HOST_BITS_PER_WIDE_INT)
7559 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7562 switch (DECL_FUNCTION_CODE (fndecl))
7564 case BUILT_IN_FFS:
7565 case BUILT_IN_FFSL:
7566 case BUILT_IN_FFSLL:
7567 if (lo != 0)
7568 result = exact_log2 (lo & -lo) + 1;
7569 else if (hi != 0)
7570 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7571 else
7572 result = 0;
7573 break;
7575 case BUILT_IN_CLZ:
7576 case BUILT_IN_CLZL:
7577 case BUILT_IN_CLZLL:
7578 if (hi != 0)
7579 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7580 else if (lo != 0)
7581 result = width - floor_log2 (lo) - 1;
7582 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7583 result = width;
7584 break;
7586 case BUILT_IN_CTZ:
7587 case BUILT_IN_CTZL:
7588 case BUILT_IN_CTZLL:
7589 if (lo != 0)
7590 result = exact_log2 (lo & -lo);
7591 else if (hi != 0)
7592 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7593 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7594 result = width;
7595 break;
7597 case BUILT_IN_POPCOUNT:
7598 case BUILT_IN_POPCOUNTL:
7599 case BUILT_IN_POPCOUNTLL:
7600 result = 0;
7601 while (lo)
7602 result++, lo &= lo - 1;
7603 while (hi)
7604 result++, hi &= hi - 1;
7605 break;
7607 case BUILT_IN_PARITY:
7608 case BUILT_IN_PARITYL:
7609 case BUILT_IN_PARITYLL:
7610 result = 0;
7611 while (lo)
7612 result++, lo &= lo - 1;
7613 while (hi)
7614 result++, hi &= hi - 1;
7615 result &= 1;
7616 break;
7618 default:
7619 gcc_unreachable ();
7622 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7625 return NULL_TREE;
7628 /* Return true if EXPR is the real constant contained in VALUE. */
7630 static bool
7631 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7633 STRIP_NOPS (expr);
7635 return ((TREE_CODE (expr) == REAL_CST
7636 && ! TREE_CONSTANT_OVERFLOW (expr)
7637 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7638 || (TREE_CODE (expr) == COMPLEX_CST
7639 && real_dconstp (TREE_REALPART (expr), value)
7640 && real_zerop (TREE_IMAGPART (expr))));
7643 /* A subroutine of fold_builtin to fold the various logarithmic
7644 functions. EXP is the CALL_EXPR of a call to a builtin logN
7645 function. VALUE is the base of the logN function. */
7647 static tree
7648 fold_builtin_logarithm (tree fndecl, tree arglist,
7649 const REAL_VALUE_TYPE *value)
7651 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7653 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7654 tree arg = TREE_VALUE (arglist);
7655 const enum built_in_function fcode = builtin_mathfn_code (arg);
7657 /* Optimize logN(1.0) = 0.0. */
7658 if (real_onep (arg))
7659 return build_real (type, dconst0);
7661 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7662 exactly, then only do this if flag_unsafe_math_optimizations. */
7663 if (exact_real_truncate (TYPE_MODE (type), value)
7664 || flag_unsafe_math_optimizations)
7666 const REAL_VALUE_TYPE value_truncate =
7667 real_value_truncate (TYPE_MODE (type), *value);
7668 if (real_dconstp (arg, &value_truncate))
7669 return build_real (type, dconst1);
7672 /* Special case, optimize logN(expN(x)) = x. */
7673 if (flag_unsafe_math_optimizations
7674 && ((value == &dconste
7675 && (fcode == BUILT_IN_EXP
7676 || fcode == BUILT_IN_EXPF
7677 || fcode == BUILT_IN_EXPL))
7678 || (value == &dconst2
7679 && (fcode == BUILT_IN_EXP2
7680 || fcode == BUILT_IN_EXP2F
7681 || fcode == BUILT_IN_EXP2L))
7682 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7683 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7685 /* Optimize logN(func()) for various exponential functions. We
7686 want to determine the value "x" and the power "exponent" in
7687 order to transform logN(x**exponent) into exponent*logN(x). */
7688 if (flag_unsafe_math_optimizations)
7690 tree exponent = 0, x = 0;
7692 switch (fcode)
7694 case BUILT_IN_EXP:
7695 case BUILT_IN_EXPF:
7696 case BUILT_IN_EXPL:
7697 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7698 x = build_real (type,
7699 real_value_truncate (TYPE_MODE (type), dconste));
7700 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7701 break;
7702 case BUILT_IN_EXP2:
7703 case BUILT_IN_EXP2F:
7704 case BUILT_IN_EXP2L:
7705 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7706 x = build_real (type, dconst2);
7707 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7708 break;
7709 case BUILT_IN_EXP10:
7710 case BUILT_IN_EXP10F:
7711 case BUILT_IN_EXP10L:
7712 case BUILT_IN_POW10:
7713 case BUILT_IN_POW10F:
7714 case BUILT_IN_POW10L:
7715 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7716 x = build_real (type, dconst10);
7717 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7718 break;
7719 case BUILT_IN_SQRT:
7720 case BUILT_IN_SQRTF:
7721 case BUILT_IN_SQRTL:
7722 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7723 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7724 exponent = build_real (type, dconsthalf);
7725 break;
7726 case BUILT_IN_CBRT:
7727 case BUILT_IN_CBRTF:
7728 case BUILT_IN_CBRTL:
7729 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7730 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7731 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7732 dconstthird));
7733 break;
7734 case BUILT_IN_POW:
7735 case BUILT_IN_POWF:
7736 case BUILT_IN_POWL:
7737 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7738 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7739 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7740 break;
7741 default:
7742 break;
7745 /* Now perform the optimization. */
7746 if (x && exponent)
7748 tree logfn;
7749 arglist = build_tree_list (NULL_TREE, x);
7750 logfn = build_function_call_expr (fndecl, arglist);
7751 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7756 return 0;
7759 /* Fold a builtin function call to pow, powf, or powl. Return
7760 NULL_TREE if no simplification can be made. */
7761 static tree
7762 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7764 tree arg0 = TREE_VALUE (arglist);
7765 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7767 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7768 return NULL_TREE;
7770 /* Optimize pow(1.0,y) = 1.0. */
7771 if (real_onep (arg0))
7772 return omit_one_operand (type, build_real (type, dconst1), arg1);
7774 if (TREE_CODE (arg1) == REAL_CST
7775 && ! TREE_CONSTANT_OVERFLOW (arg1))
7777 REAL_VALUE_TYPE cint;
7778 REAL_VALUE_TYPE c;
7779 HOST_WIDE_INT n;
7781 c = TREE_REAL_CST (arg1);
7783 /* Optimize pow(x,0.0) = 1.0. */
7784 if (REAL_VALUES_EQUAL (c, dconst0))
7785 return omit_one_operand (type, build_real (type, dconst1),
7786 arg0);
7788 /* Optimize pow(x,1.0) = x. */
7789 if (REAL_VALUES_EQUAL (c, dconst1))
7790 return arg0;
7792 /* Optimize pow(x,-1.0) = 1.0/x. */
7793 if (REAL_VALUES_EQUAL (c, dconstm1))
7794 return fold_build2 (RDIV_EXPR, type,
7795 build_real (type, dconst1), arg0);
7797 /* Optimize pow(x,0.5) = sqrt(x). */
7798 if (flag_unsafe_math_optimizations
7799 && REAL_VALUES_EQUAL (c, dconsthalf))
7801 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7803 if (sqrtfn != NULL_TREE)
7805 tree arglist = build_tree_list (NULL_TREE, arg0);
7806 return build_function_call_expr (sqrtfn, arglist);
7810 /* Check for an integer exponent. */
7811 n = real_to_integer (&c);
7812 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7813 if (real_identical (&c, &cint))
7815 /* Attempt to evaluate pow at compile-time. */
7816 if (TREE_CODE (arg0) == REAL_CST
7817 && ! TREE_CONSTANT_OVERFLOW (arg0))
7819 REAL_VALUE_TYPE x;
7820 bool inexact;
7822 x = TREE_REAL_CST (arg0);
7823 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7824 if (flag_unsafe_math_optimizations || !inexact)
7825 return build_real (type, x);
7828 /* Strip sign ops from even integer powers. */
7829 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7831 tree narg0 = fold_strip_sign_ops (arg0);
7832 if (narg0)
7834 arglist = build_tree_list (NULL_TREE, arg1);
7835 arglist = tree_cons (NULL_TREE, narg0, arglist);
7836 return build_function_call_expr (fndecl, arglist);
7842 if (flag_unsafe_math_optimizations)
7844 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7846 /* Optimize pow(expN(x),y) = expN(x*y). */
7847 if (BUILTIN_EXPONENT_P (fcode))
7849 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7850 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7851 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7852 arglist = build_tree_list (NULL_TREE, arg);
7853 return build_function_call_expr (expfn, arglist);
7856 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7857 if (BUILTIN_SQRT_P (fcode))
7859 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7860 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7861 build_real (type, dconsthalf));
7863 arglist = tree_cons (NULL_TREE, narg0,
7864 build_tree_list (NULL_TREE, narg1));
7865 return build_function_call_expr (fndecl, arglist);
7868 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7869 if (BUILTIN_CBRT_P (fcode))
7871 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7872 if (tree_expr_nonnegative_p (arg))
7874 const REAL_VALUE_TYPE dconstroot
7875 = real_value_truncate (TYPE_MODE (type), dconstthird);
7876 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7877 build_real (type, dconstroot));
7878 arglist = tree_cons (NULL_TREE, arg,
7879 build_tree_list (NULL_TREE, narg1));
7880 return build_function_call_expr (fndecl, arglist);
7884 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7885 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7886 || fcode == BUILT_IN_POWL)
7888 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7889 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7890 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7891 arglist = tree_cons (NULL_TREE, arg00,
7892 build_tree_list (NULL_TREE, narg1));
7893 return build_function_call_expr (fndecl, arglist);
7897 return NULL_TREE;
7900 /* Fold a builtin function call to powi, powif, or powil. Return
7901 NULL_TREE if no simplification can be made. */
7902 static tree
7903 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7905 tree arg0 = TREE_VALUE (arglist);
7906 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7908 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7909 return NULL_TREE;
7911 /* Optimize pow(1.0,y) = 1.0. */
7912 if (real_onep (arg0))
7913 return omit_one_operand (type, build_real (type, dconst1), arg1);
7915 if (host_integerp (arg1, 0))
7917 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7919 /* Evaluate powi at compile-time. */
7920 if (TREE_CODE (arg0) == REAL_CST
7921 && ! TREE_CONSTANT_OVERFLOW (arg0))
7923 REAL_VALUE_TYPE x;
7924 x = TREE_REAL_CST (arg0);
7925 real_powi (&x, TYPE_MODE (type), &x, c);
7926 return build_real (type, x);
7929 /* Optimize pow(x,0) = 1.0. */
7930 if (c == 0)
7931 return omit_one_operand (type, build_real (type, dconst1),
7932 arg0);
7934 /* Optimize pow(x,1) = x. */
7935 if (c == 1)
7936 return arg0;
7938 /* Optimize pow(x,-1) = 1.0/x. */
7939 if (c == -1)
7940 return fold_build2 (RDIV_EXPR, type,
7941 build_real (type, dconst1), arg0);
7944 return NULL_TREE;
7947 /* A subroutine of fold_builtin to fold the various exponent
7948 functions. EXP is the CALL_EXPR of a call to a builtin function.
7949 VALUE is the value which will be raised to a power. */
7951 static tree
7952 fold_builtin_exponent (tree fndecl, tree arglist,
7953 const REAL_VALUE_TYPE *value)
7955 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7957 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7958 tree arg = TREE_VALUE (arglist);
7960 /* Optimize exp*(0.0) = 1.0. */
7961 if (real_zerop (arg))
7962 return build_real (type, dconst1);
7964 /* Optimize expN(1.0) = N. */
7965 if (real_onep (arg))
7967 REAL_VALUE_TYPE cst;
7969 real_convert (&cst, TYPE_MODE (type), value);
7970 return build_real (type, cst);
7973 /* Attempt to evaluate expN(integer) at compile-time. */
7974 if (flag_unsafe_math_optimizations
7975 && TREE_CODE (arg) == REAL_CST
7976 && ! TREE_CONSTANT_OVERFLOW (arg))
7978 REAL_VALUE_TYPE cint;
7979 REAL_VALUE_TYPE c;
7980 HOST_WIDE_INT n;
7982 c = TREE_REAL_CST (arg);
7983 n = real_to_integer (&c);
7984 real_from_integer (&cint, VOIDmode, n,
7985 n < 0 ? -1 : 0, 0);
7986 if (real_identical (&c, &cint))
7988 REAL_VALUE_TYPE x;
7990 real_powi (&x, TYPE_MODE (type), value, n);
7991 return build_real (type, x);
7995 /* Optimize expN(logN(x)) = x. */
7996 if (flag_unsafe_math_optimizations)
7998 const enum built_in_function fcode = builtin_mathfn_code (arg);
8000 if ((value == &dconste
8001 && (fcode == BUILT_IN_LOG
8002 || fcode == BUILT_IN_LOGF
8003 || fcode == BUILT_IN_LOGL))
8004 || (value == &dconst2
8005 && (fcode == BUILT_IN_LOG2
8006 || fcode == BUILT_IN_LOG2F
8007 || fcode == BUILT_IN_LOG2L))
8008 || (value == &dconst10
8009 && (fcode == BUILT_IN_LOG10
8010 || fcode == BUILT_IN_LOG10F
8011 || fcode == BUILT_IN_LOG10L)))
8012 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8016 return 0;
8019 /* Fold function call to builtin memcpy. Return
8020 NULL_TREE if no simplification can be made. */
8022 static tree
8023 fold_builtin_memcpy (tree fndecl, tree arglist)
8025 tree dest, src, len;
8027 if (!validate_arglist (arglist,
8028 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8029 return 0;
8031 dest = TREE_VALUE (arglist);
8032 src = TREE_VALUE (TREE_CHAIN (arglist));
8033 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8035 /* If the LEN parameter is zero, return DEST. */
8036 if (integer_zerop (len))
8037 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8039 /* If SRC and DEST are the same (and not volatile), return DEST. */
8040 if (operand_equal_p (src, dest, 0))
8041 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
8043 return 0;
8046 /* Fold function call to builtin mempcpy. Return
8047 NULL_TREE if no simplification can be made. */
8049 static tree
8050 fold_builtin_mempcpy (tree arglist, tree type, int endp)
8052 if (validate_arglist (arglist,
8053 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8055 tree dest = TREE_VALUE (arglist);
8056 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8057 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8059 /* If the LEN parameter is zero, return DEST. */
8060 if (integer_zerop (len))
8061 return omit_one_operand (type, dest, src);
8063 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
8064 if (operand_equal_p (src, dest, 0))
8066 if (endp == 0)
8067 return omit_one_operand (type, dest, len);
8069 if (endp == 2)
8070 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8071 ssize_int (1));
8073 len = fold_convert (TREE_TYPE (dest), len);
8074 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8075 return fold_convert (type, len);
8078 return 0;
8081 /* Fold function call to builtin memmove. Return
8082 NULL_TREE if no simplification can be made. */
8084 static tree
8085 fold_builtin_memmove (tree arglist, tree type)
8087 tree dest, src, len;
8089 if (!validate_arglist (arglist,
8090 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8091 return 0;
8093 dest = TREE_VALUE (arglist);
8094 src = TREE_VALUE (TREE_CHAIN (arglist));
8095 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8097 /* If the LEN parameter is zero, return DEST. */
8098 if (integer_zerop (len))
8099 return omit_one_operand (type, dest, src);
8101 /* If SRC and DEST are the same (and not volatile), return DEST. */
8102 if (operand_equal_p (src, dest, 0))
8103 return omit_one_operand (type, dest, len);
8105 return 0;
8108 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8109 the length of the string to be copied. Return NULL_TREE if no
8110 simplification can be made. */
8112 tree
8113 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8115 tree dest, src, fn;
8117 if (!validate_arglist (arglist,
8118 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8119 return 0;
8121 dest = TREE_VALUE (arglist);
8122 src = TREE_VALUE (TREE_CHAIN (arglist));
8124 /* If SRC and DEST are the same (and not volatile), return DEST. */
8125 if (operand_equal_p (src, dest, 0))
8126 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8128 if (optimize_size)
8129 return 0;
8131 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8132 if (!fn)
8133 return 0;
8135 if (!len)
8137 len = c_strlen (src, 1);
8138 if (! len || TREE_SIDE_EFFECTS (len))
8139 return 0;
8142 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8143 arglist = build_tree_list (NULL_TREE, len);
8144 arglist = tree_cons (NULL_TREE, src, arglist);
8145 arglist = tree_cons (NULL_TREE, dest, arglist);
8146 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8147 build_function_call_expr (fn, arglist));
8150 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8151 the length of the source string. Return NULL_TREE if no simplification
8152 can be made. */
8154 tree
8155 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8157 tree dest, src, len, fn;
8159 if (!validate_arglist (arglist,
8160 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8161 return 0;
8163 dest = TREE_VALUE (arglist);
8164 src = TREE_VALUE (TREE_CHAIN (arglist));
8165 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8167 /* If the LEN parameter is zero, return DEST. */
8168 if (integer_zerop (len))
8169 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8171 /* We can't compare slen with len as constants below if len is not a
8172 constant. */
8173 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8174 return 0;
8176 if (!slen)
8177 slen = c_strlen (src, 1);
8179 /* Now, we must be passed a constant src ptr parameter. */
8180 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8181 return 0;
8183 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8185 /* We do not support simplification of this case, though we do
8186 support it when expanding trees into RTL. */
8187 /* FIXME: generate a call to __builtin_memset. */
8188 if (tree_int_cst_lt (slen, len))
8189 return 0;
8191 /* OK transform into builtin memcpy. */
8192 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8193 if (!fn)
8194 return 0;
8195 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8196 build_function_call_expr (fn, arglist));
8199 /* Fold function call to builtin memcmp. Return
8200 NULL_TREE if no simplification can be made. */
8202 static tree
8203 fold_builtin_memcmp (tree arglist)
8205 tree arg1, arg2, len;
8206 const char *p1, *p2;
8208 if (!validate_arglist (arglist,
8209 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8210 return 0;
8212 arg1 = TREE_VALUE (arglist);
8213 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8214 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8216 /* If the LEN parameter is zero, return zero. */
8217 if (integer_zerop (len))
8218 return omit_two_operands (integer_type_node, integer_zero_node,
8219 arg1, arg2);
8221 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8222 if (operand_equal_p (arg1, arg2, 0))
8223 return omit_one_operand (integer_type_node, integer_zero_node, len);
8225 p1 = c_getstr (arg1);
8226 p2 = c_getstr (arg2);
8228 /* If all arguments are constant, and the value of len is not greater
8229 than the lengths of arg1 and arg2, evaluate at compile-time. */
8230 if (host_integerp (len, 1) && p1 && p2
8231 && compare_tree_int (len, strlen (p1) + 1) <= 0
8232 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8234 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8236 if (r > 0)
8237 return integer_one_node;
8238 else if (r < 0)
8239 return integer_minus_one_node;
8240 else
8241 return integer_zero_node;
8244 /* If len parameter is one, return an expression corresponding to
8245 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8246 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8248 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8249 tree cst_uchar_ptr_node
8250 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8252 tree ind1 = fold_convert (integer_type_node,
8253 build1 (INDIRECT_REF, cst_uchar_node,
8254 fold_convert (cst_uchar_ptr_node,
8255 arg1)));
8256 tree ind2 = fold_convert (integer_type_node,
8257 build1 (INDIRECT_REF, cst_uchar_node,
8258 fold_convert (cst_uchar_ptr_node,
8259 arg2)));
8260 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8263 return 0;
8266 /* Fold function call to builtin strcmp. Return
8267 NULL_TREE if no simplification can be made. */
8269 static tree
8270 fold_builtin_strcmp (tree arglist)
8272 tree arg1, arg2;
8273 const char *p1, *p2;
8275 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8276 return 0;
8278 arg1 = TREE_VALUE (arglist);
8279 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8281 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8282 if (operand_equal_p (arg1, arg2, 0))
8283 return integer_zero_node;
8285 p1 = c_getstr (arg1);
8286 p2 = c_getstr (arg2);
8288 if (p1 && p2)
8290 const int i = strcmp (p1, p2);
8291 if (i < 0)
8292 return integer_minus_one_node;
8293 else if (i > 0)
8294 return integer_one_node;
8295 else
8296 return integer_zero_node;
8299 /* If the second arg is "", return *(const unsigned char*)arg1. */
8300 if (p2 && *p2 == '\0')
8302 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8303 tree cst_uchar_ptr_node
8304 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8306 return fold_convert (integer_type_node,
8307 build1 (INDIRECT_REF, cst_uchar_node,
8308 fold_convert (cst_uchar_ptr_node,
8309 arg1)));
8312 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8313 if (p1 && *p1 == '\0')
8315 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8316 tree cst_uchar_ptr_node
8317 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8319 tree temp = fold_convert (integer_type_node,
8320 build1 (INDIRECT_REF, cst_uchar_node,
8321 fold_convert (cst_uchar_ptr_node,
8322 arg2)));
8323 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8326 return 0;
8329 /* Fold function call to builtin strncmp. Return
8330 NULL_TREE if no simplification can be made. */
8332 static tree
8333 fold_builtin_strncmp (tree arglist)
8335 tree arg1, arg2, len;
8336 const char *p1, *p2;
8338 if (!validate_arglist (arglist,
8339 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8340 return 0;
8342 arg1 = TREE_VALUE (arglist);
8343 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8344 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8346 /* If the LEN parameter is zero, return zero. */
8347 if (integer_zerop (len))
8348 return omit_two_operands (integer_type_node, integer_zero_node,
8349 arg1, arg2);
8351 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8352 if (operand_equal_p (arg1, arg2, 0))
8353 return omit_one_operand (integer_type_node, integer_zero_node, len);
8355 p1 = c_getstr (arg1);
8356 p2 = c_getstr (arg2);
8358 if (host_integerp (len, 1) && p1 && p2)
8360 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8361 if (i > 0)
8362 return integer_one_node;
8363 else if (i < 0)
8364 return integer_minus_one_node;
8365 else
8366 return integer_zero_node;
8369 /* If the second arg is "", and the length is greater than zero,
8370 return *(const unsigned char*)arg1. */
8371 if (p2 && *p2 == '\0'
8372 && TREE_CODE (len) == INTEGER_CST
8373 && tree_int_cst_sgn (len) == 1)
8375 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8376 tree cst_uchar_ptr_node
8377 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8379 return fold_convert (integer_type_node,
8380 build1 (INDIRECT_REF, cst_uchar_node,
8381 fold_convert (cst_uchar_ptr_node,
8382 arg1)));
8385 /* If the first arg is "", and the length is greater than zero,
8386 return -*(const unsigned char*)arg2. */
8387 if (p1 && *p1 == '\0'
8388 && TREE_CODE (len) == INTEGER_CST
8389 && tree_int_cst_sgn (len) == 1)
8391 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8392 tree cst_uchar_ptr_node
8393 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8395 tree temp = fold_convert (integer_type_node,
8396 build1 (INDIRECT_REF, cst_uchar_node,
8397 fold_convert (cst_uchar_ptr_node,
8398 arg2)));
8399 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8402 /* If len parameter is one, return an expression corresponding to
8403 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8404 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8406 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8407 tree cst_uchar_ptr_node
8408 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8410 tree ind1 = fold_convert (integer_type_node,
8411 build1 (INDIRECT_REF, cst_uchar_node,
8412 fold_convert (cst_uchar_ptr_node,
8413 arg1)));
8414 tree ind2 = fold_convert (integer_type_node,
8415 build1 (INDIRECT_REF, cst_uchar_node,
8416 fold_convert (cst_uchar_ptr_node,
8417 arg2)));
8418 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8421 return 0;
8424 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8425 NULL_TREE if no simplification can be made. */
8427 static tree
8428 fold_builtin_signbit (tree fndecl, tree arglist)
8430 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8431 tree arg, temp;
8433 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8434 return NULL_TREE;
8436 arg = TREE_VALUE (arglist);
8438 /* If ARG is a compile-time constant, determine the result. */
8439 if (TREE_CODE (arg) == REAL_CST
8440 && !TREE_CONSTANT_OVERFLOW (arg))
8442 REAL_VALUE_TYPE c;
8444 c = TREE_REAL_CST (arg);
8445 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8446 return fold_convert (type, temp);
8449 /* If ARG is non-negative, the result is always zero. */
8450 if (tree_expr_nonnegative_p (arg))
8451 return omit_one_operand (type, integer_zero_node, arg);
8453 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8454 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8455 return fold_build2 (LT_EXPR, type, arg,
8456 build_real (TREE_TYPE (arg), dconst0));
8458 return NULL_TREE;
8461 /* Fold function call to builtin copysign, copysignf or copysignl.
8462 Return NULL_TREE if no simplification can be made. */
8464 static tree
8465 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8467 tree arg1, arg2, tem;
8469 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8470 return NULL_TREE;
8472 arg1 = TREE_VALUE (arglist);
8473 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8475 /* copysign(X,X) is X. */
8476 if (operand_equal_p (arg1, arg2, 0))
8477 return fold_convert (type, arg1);
8479 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8480 if (TREE_CODE (arg1) == REAL_CST
8481 && TREE_CODE (arg2) == REAL_CST
8482 && !TREE_CONSTANT_OVERFLOW (arg1)
8483 && !TREE_CONSTANT_OVERFLOW (arg2))
8485 REAL_VALUE_TYPE c1, c2;
8487 c1 = TREE_REAL_CST (arg1);
8488 c2 = TREE_REAL_CST (arg2);
8489 real_copysign (&c1, &c2);
8490 return build_real (type, c1);
8491 c1.sign = c2.sign;
8494 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8495 Remember to evaluate Y for side-effects. */
8496 if (tree_expr_nonnegative_p (arg2))
8497 return omit_one_operand (type,
8498 fold_build1 (ABS_EXPR, type, arg1),
8499 arg2);
8501 /* Strip sign changing operations for the first argument. */
8502 tem = fold_strip_sign_ops (arg1);
8503 if (tem)
8505 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8506 return build_function_call_expr (fndecl, arglist);
8509 return NULL_TREE;
8512 /* Fold a call to builtin isascii. */
8514 static tree
8515 fold_builtin_isascii (tree arglist)
8517 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8518 return 0;
8519 else
8521 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8522 tree arg = TREE_VALUE (arglist);
8524 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8525 build_int_cst (NULL_TREE,
8526 ~ (unsigned HOST_WIDE_INT) 0x7f));
8527 arg = fold_build2 (EQ_EXPR, integer_type_node,
8528 arg, integer_zero_node);
8530 if (in_gimple_form && !TREE_CONSTANT (arg))
8531 return NULL_TREE;
8532 else
8533 return arg;
8537 /* Fold a call to builtin toascii. */
8539 static tree
8540 fold_builtin_toascii (tree arglist)
8542 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8543 return 0;
8544 else
8546 /* Transform toascii(c) -> (c & 0x7f). */
8547 tree arg = TREE_VALUE (arglist);
8549 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8550 build_int_cst (NULL_TREE, 0x7f));
8554 /* Fold a call to builtin isdigit. */
8556 static tree
8557 fold_builtin_isdigit (tree arglist)
8559 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8560 return 0;
8561 else
8563 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8564 /* According to the C standard, isdigit is unaffected by locale.
8565 However, it definitely is affected by the target character set. */
8566 tree arg;
8567 unsigned HOST_WIDE_INT target_digit0
8568 = lang_hooks.to_target_charset ('0');
8570 if (target_digit0 == 0)
8571 return NULL_TREE;
8573 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8574 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8575 build_int_cst (unsigned_type_node, target_digit0));
8576 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8577 build_int_cst (unsigned_type_node, 9));
8578 if (in_gimple_form && !TREE_CONSTANT (arg))
8579 return NULL_TREE;
8580 else
8581 return arg;
8585 /* Fold a call to fabs, fabsf or fabsl. */
8587 static tree
8588 fold_builtin_fabs (tree arglist, tree type)
8590 tree arg;
8592 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8593 return 0;
8595 arg = TREE_VALUE (arglist);
8596 arg = fold_convert (type, arg);
8597 if (TREE_CODE (arg) == REAL_CST)
8598 return fold_abs_const (arg, type);
8599 return fold_build1 (ABS_EXPR, type, arg);
8602 /* Fold a call to abs, labs, llabs or imaxabs. */
8604 static tree
8605 fold_builtin_abs (tree arglist, tree type)
8607 tree arg;
8609 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8610 return 0;
8612 arg = TREE_VALUE (arglist);
8613 arg = fold_convert (type, arg);
8614 if (TREE_CODE (arg) == INTEGER_CST)
8615 return fold_abs_const (arg, type);
8616 return fold_build1 (ABS_EXPR, type, arg);
8619 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8620 EXP is the CALL_EXPR for the call. */
8622 static tree
8623 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8625 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8626 tree arg;
8627 REAL_VALUE_TYPE r;
8629 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8631 /* Check that we have exactly one argument. */
8632 if (arglist == 0)
8634 error ("too few arguments to function %qs",
8635 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8636 return error_mark_node;
8638 else if (TREE_CHAIN (arglist) != 0)
8640 error ("too many arguments to function %qs",
8641 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8642 return error_mark_node;
8644 else
8646 error ("non-floating-point argument to function %qs",
8647 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8648 return error_mark_node;
8652 arg = TREE_VALUE (arglist);
8653 switch (builtin_index)
8655 case BUILT_IN_ISINF:
8656 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8657 return omit_one_operand (type, integer_zero_node, arg);
8659 if (TREE_CODE (arg) == REAL_CST)
8661 r = TREE_REAL_CST (arg);
8662 if (real_isinf (&r))
8663 return real_compare (GT_EXPR, &r, &dconst0)
8664 ? integer_one_node : integer_minus_one_node;
8665 else
8666 return integer_zero_node;
8669 return NULL_TREE;
8671 case BUILT_IN_FINITE:
8672 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8673 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8674 return omit_one_operand (type, integer_zero_node, arg);
8676 if (TREE_CODE (arg) == REAL_CST)
8678 r = TREE_REAL_CST (arg);
8679 return real_isinf (&r) || real_isnan (&r)
8680 ? integer_zero_node : integer_one_node;
8683 return NULL_TREE;
8685 case BUILT_IN_ISNAN:
8686 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8687 return omit_one_operand (type, integer_zero_node, arg);
8689 if (TREE_CODE (arg) == REAL_CST)
8691 r = TREE_REAL_CST (arg);
8692 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8695 arg = builtin_save_expr (arg);
8696 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8698 default:
8699 gcc_unreachable ();
8703 /* Fold a call to an unordered comparison function such as
8704 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8705 being called and ARGLIST is the argument list for the call.
8706 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8707 the opposite of the desired result. UNORDERED_CODE is used
8708 for modes that can hold NaNs and ORDERED_CODE is used for
8709 the rest. */
8711 static tree
8712 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8713 enum tree_code unordered_code,
8714 enum tree_code ordered_code)
8716 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8717 enum tree_code code;
8718 tree arg0, arg1;
8719 tree type0, type1;
8720 enum tree_code code0, code1;
8721 tree cmp_type = NULL_TREE;
8723 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8725 /* Check that we have exactly two arguments. */
8726 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8728 error ("too few arguments to function %qs",
8729 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8730 return error_mark_node;
8732 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8734 error ("too many arguments to function %qs",
8735 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8736 return error_mark_node;
8740 arg0 = TREE_VALUE (arglist);
8741 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8743 type0 = TREE_TYPE (arg0);
8744 type1 = TREE_TYPE (arg1);
8746 code0 = TREE_CODE (type0);
8747 code1 = TREE_CODE (type1);
8749 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8750 /* Choose the wider of two real types. */
8751 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8752 ? type0 : type1;
8753 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8754 cmp_type = type0;
8755 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8756 cmp_type = type1;
8757 else
8759 error ("non-floating-point argument to function %qs",
8760 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8761 return error_mark_node;
8764 arg0 = fold_convert (cmp_type, arg0);
8765 arg1 = fold_convert (cmp_type, arg1);
8767 if (unordered_code == UNORDERED_EXPR)
8769 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8770 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8771 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8774 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8775 : ordered_code;
8776 return fold_build1 (TRUTH_NOT_EXPR, type,
8777 fold_build2 (code, type, arg0, arg1));
8780 /* Used by constant folding to simplify calls to builtin functions. EXP is
8781 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8782 result of the function call is ignored. This function returns NULL_TREE
8783 if no simplification was possible. */
8785 static tree
8786 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8788 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8789 enum built_in_function fcode;
8791 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8792 return targetm.fold_builtin (fndecl, arglist, ignore);
8794 fcode = DECL_FUNCTION_CODE (fndecl);
8795 switch (fcode)
8797 case BUILT_IN_FPUTS:
8798 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8800 case BUILT_IN_FPUTS_UNLOCKED:
8801 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8803 case BUILT_IN_STRSTR:
8804 return fold_builtin_strstr (arglist, type);
8806 case BUILT_IN_STRCAT:
8807 return fold_builtin_strcat (arglist);
8809 case BUILT_IN_STRNCAT:
8810 return fold_builtin_strncat (arglist);
8812 case BUILT_IN_STRSPN:
8813 return fold_builtin_strspn (arglist);
8815 case BUILT_IN_STRCSPN:
8816 return fold_builtin_strcspn (arglist);
8818 case BUILT_IN_STRCHR:
8819 case BUILT_IN_INDEX:
8820 return fold_builtin_strchr (arglist, type);
8822 case BUILT_IN_STRRCHR:
8823 case BUILT_IN_RINDEX:
8824 return fold_builtin_strrchr (arglist, type);
8826 case BUILT_IN_STRCPY:
8827 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8829 case BUILT_IN_STRNCPY:
8830 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8832 case BUILT_IN_STRCMP:
8833 return fold_builtin_strcmp (arglist);
8835 case BUILT_IN_STRNCMP:
8836 return fold_builtin_strncmp (arglist);
8838 case BUILT_IN_STRPBRK:
8839 return fold_builtin_strpbrk (arglist, type);
8841 case BUILT_IN_BCMP:
8842 case BUILT_IN_MEMCMP:
8843 return fold_builtin_memcmp (arglist);
8845 case BUILT_IN_SPRINTF:
8846 return fold_builtin_sprintf (arglist, ignore);
8848 case BUILT_IN_CONSTANT_P:
8850 tree val;
8852 val = fold_builtin_constant_p (arglist);
8853 /* Gimplification will pull the CALL_EXPR for the builtin out of
8854 an if condition. When not optimizing, we'll not CSE it back.
8855 To avoid link error types of regressions, return false now. */
8856 if (!val && !optimize)
8857 val = integer_zero_node;
8859 return val;
8862 case BUILT_IN_EXPECT:
8863 return fold_builtin_expect (arglist);
8865 case BUILT_IN_CLASSIFY_TYPE:
8866 return fold_builtin_classify_type (arglist);
8868 case BUILT_IN_STRLEN:
8869 return fold_builtin_strlen (arglist);
8871 case BUILT_IN_FABS:
8872 case BUILT_IN_FABSF:
8873 case BUILT_IN_FABSL:
8874 return fold_builtin_fabs (arglist, type);
8876 case BUILT_IN_ABS:
8877 case BUILT_IN_LABS:
8878 case BUILT_IN_LLABS:
8879 case BUILT_IN_IMAXABS:
8880 return fold_builtin_abs (arglist, type);
8882 case BUILT_IN_CONJ:
8883 case BUILT_IN_CONJF:
8884 case BUILT_IN_CONJL:
8885 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8886 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8887 break;
8889 case BUILT_IN_CREAL:
8890 case BUILT_IN_CREALF:
8891 case BUILT_IN_CREALL:
8892 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8893 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8894 TREE_VALUE (arglist)));
8895 break;
8897 case BUILT_IN_CIMAG:
8898 case BUILT_IN_CIMAGF:
8899 case BUILT_IN_CIMAGL:
8900 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8901 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8902 TREE_VALUE (arglist)));
8903 break;
8905 case BUILT_IN_CABS:
8906 case BUILT_IN_CABSF:
8907 case BUILT_IN_CABSL:
8908 return fold_builtin_cabs (arglist, type);
8910 case BUILT_IN_SQRT:
8911 case BUILT_IN_SQRTF:
8912 case BUILT_IN_SQRTL:
8913 return fold_builtin_sqrt (arglist, type);
8915 case BUILT_IN_CBRT:
8916 case BUILT_IN_CBRTF:
8917 case BUILT_IN_CBRTL:
8918 return fold_builtin_cbrt (arglist, type);
8920 case BUILT_IN_SIN:
8921 case BUILT_IN_SINF:
8922 case BUILT_IN_SINL:
8923 return fold_builtin_sin (arglist);
8925 case BUILT_IN_COS:
8926 case BUILT_IN_COSF:
8927 case BUILT_IN_COSL:
8928 return fold_builtin_cos (arglist, type, fndecl);
8930 case BUILT_IN_EXP:
8931 case BUILT_IN_EXPF:
8932 case BUILT_IN_EXPL:
8933 return fold_builtin_exponent (fndecl, arglist, &dconste);
8935 case BUILT_IN_EXP2:
8936 case BUILT_IN_EXP2F:
8937 case BUILT_IN_EXP2L:
8938 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8940 case BUILT_IN_EXP10:
8941 case BUILT_IN_EXP10F:
8942 case BUILT_IN_EXP10L:
8943 case BUILT_IN_POW10:
8944 case BUILT_IN_POW10F:
8945 case BUILT_IN_POW10L:
8946 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8948 case BUILT_IN_LOG:
8949 case BUILT_IN_LOGF:
8950 case BUILT_IN_LOGL:
8951 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8953 case BUILT_IN_LOG2:
8954 case BUILT_IN_LOG2F:
8955 case BUILT_IN_LOG2L:
8956 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8958 case BUILT_IN_LOG10:
8959 case BUILT_IN_LOG10F:
8960 case BUILT_IN_LOG10L:
8961 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8963 case BUILT_IN_TAN:
8964 case BUILT_IN_TANF:
8965 case BUILT_IN_TANL:
8966 return fold_builtin_tan (arglist);
8968 case BUILT_IN_ATAN:
8969 case BUILT_IN_ATANF:
8970 case BUILT_IN_ATANL:
8971 return fold_builtin_atan (arglist, type);
8973 case BUILT_IN_POW:
8974 case BUILT_IN_POWF:
8975 case BUILT_IN_POWL:
8976 return fold_builtin_pow (fndecl, arglist, type);
8978 case BUILT_IN_POWI:
8979 case BUILT_IN_POWIF:
8980 case BUILT_IN_POWIL:
8981 return fold_builtin_powi (fndecl, arglist, type);
8983 case BUILT_IN_INF:
8984 case BUILT_IN_INFF:
8985 case BUILT_IN_INFL:
8986 return fold_builtin_inf (type, true);
8988 case BUILT_IN_HUGE_VAL:
8989 case BUILT_IN_HUGE_VALF:
8990 case BUILT_IN_HUGE_VALL:
8991 return fold_builtin_inf (type, false);
8993 case BUILT_IN_NAN:
8994 case BUILT_IN_NANF:
8995 case BUILT_IN_NANL:
8996 return fold_builtin_nan (arglist, type, true);
8998 case BUILT_IN_NANS:
8999 case BUILT_IN_NANSF:
9000 case BUILT_IN_NANSL:
9001 return fold_builtin_nan (arglist, type, false);
9003 case BUILT_IN_FLOOR:
9004 case BUILT_IN_FLOORF:
9005 case BUILT_IN_FLOORL:
9006 return fold_builtin_floor (fndecl, arglist);
9008 case BUILT_IN_CEIL:
9009 case BUILT_IN_CEILF:
9010 case BUILT_IN_CEILL:
9011 return fold_builtin_ceil (fndecl, arglist);
9013 case BUILT_IN_TRUNC:
9014 case BUILT_IN_TRUNCF:
9015 case BUILT_IN_TRUNCL:
9016 return fold_builtin_trunc (fndecl, arglist);
9018 case BUILT_IN_ROUND:
9019 case BUILT_IN_ROUNDF:
9020 case BUILT_IN_ROUNDL:
9021 return fold_builtin_round (fndecl, arglist);
9023 case BUILT_IN_NEARBYINT:
9024 case BUILT_IN_NEARBYINTF:
9025 case BUILT_IN_NEARBYINTL:
9026 case BUILT_IN_RINT:
9027 case BUILT_IN_RINTF:
9028 case BUILT_IN_RINTL:
9029 return fold_trunc_transparent_mathfn (fndecl, arglist);
9031 case BUILT_IN_LCEIL:
9032 case BUILT_IN_LCEILF:
9033 case BUILT_IN_LCEILL:
9034 case BUILT_IN_LLCEIL:
9035 case BUILT_IN_LLCEILF:
9036 case BUILT_IN_LLCEILL:
9037 case BUILT_IN_LFLOOR:
9038 case BUILT_IN_LFLOORF:
9039 case BUILT_IN_LFLOORL:
9040 case BUILT_IN_LLFLOOR:
9041 case BUILT_IN_LLFLOORF:
9042 case BUILT_IN_LLFLOORL:
9043 case BUILT_IN_LROUND:
9044 case BUILT_IN_LROUNDF:
9045 case BUILT_IN_LROUNDL:
9046 case BUILT_IN_LLROUND:
9047 case BUILT_IN_LLROUNDF:
9048 case BUILT_IN_LLROUNDL:
9049 return fold_builtin_int_roundingfn (fndecl, arglist);
9051 case BUILT_IN_LRINT:
9052 case BUILT_IN_LRINTF:
9053 case BUILT_IN_LRINTL:
9054 case BUILT_IN_LLRINT:
9055 case BUILT_IN_LLRINTF:
9056 case BUILT_IN_LLRINTL:
9057 return fold_fixed_mathfn (fndecl, arglist);
9059 case BUILT_IN_FFS:
9060 case BUILT_IN_FFSL:
9061 case BUILT_IN_FFSLL:
9062 case BUILT_IN_CLZ:
9063 case BUILT_IN_CLZL:
9064 case BUILT_IN_CLZLL:
9065 case BUILT_IN_CTZ:
9066 case BUILT_IN_CTZL:
9067 case BUILT_IN_CTZLL:
9068 case BUILT_IN_POPCOUNT:
9069 case BUILT_IN_POPCOUNTL:
9070 case BUILT_IN_POPCOUNTLL:
9071 case BUILT_IN_PARITY:
9072 case BUILT_IN_PARITYL:
9073 case BUILT_IN_PARITYLL:
9074 return fold_builtin_bitop (fndecl, arglist);
9076 case BUILT_IN_MEMCPY:
9077 return fold_builtin_memcpy (fndecl, arglist);
9079 case BUILT_IN_MEMPCPY:
9080 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
9082 case BUILT_IN_MEMMOVE:
9083 return fold_builtin_memmove (arglist, type);
9085 case BUILT_IN_SIGNBIT:
9086 case BUILT_IN_SIGNBITF:
9087 case BUILT_IN_SIGNBITL:
9088 return fold_builtin_signbit (fndecl, arglist);
9090 case BUILT_IN_ISASCII:
9091 return fold_builtin_isascii (arglist);
9093 case BUILT_IN_TOASCII:
9094 return fold_builtin_toascii (arglist);
9096 case BUILT_IN_ISDIGIT:
9097 return fold_builtin_isdigit (arglist);
9099 case BUILT_IN_COPYSIGN:
9100 case BUILT_IN_COPYSIGNF:
9101 case BUILT_IN_COPYSIGNL:
9102 return fold_builtin_copysign (fndecl, arglist, type);
9104 case BUILT_IN_FINITE:
9105 case BUILT_IN_FINITEF:
9106 case BUILT_IN_FINITEL:
9107 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9109 case BUILT_IN_ISINF:
9110 case BUILT_IN_ISINFF:
9111 case BUILT_IN_ISINFL:
9112 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9114 case BUILT_IN_ISNAN:
9115 case BUILT_IN_ISNANF:
9116 case BUILT_IN_ISNANL:
9117 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9119 case BUILT_IN_ISGREATER:
9120 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9121 case BUILT_IN_ISGREATEREQUAL:
9122 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9123 case BUILT_IN_ISLESS:
9124 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9125 case BUILT_IN_ISLESSEQUAL:
9126 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9127 case BUILT_IN_ISLESSGREATER:
9128 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9129 case BUILT_IN_ISUNORDERED:
9130 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9131 NOP_EXPR);
9133 /* We do the folding for va_start in the expander. */
9134 case BUILT_IN_VA_START:
9135 break;
9137 case BUILT_IN_OBJECT_SIZE:
9138 return fold_builtin_object_size (arglist);
9139 case BUILT_IN_MEMCPY_CHK:
9140 case BUILT_IN_MEMPCPY_CHK:
9141 case BUILT_IN_MEMMOVE_CHK:
9142 case BUILT_IN_MEMSET_CHK:
9143 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9144 DECL_FUNCTION_CODE (fndecl));
9145 case BUILT_IN_STRCPY_CHK:
9146 case BUILT_IN_STPCPY_CHK:
9147 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9148 DECL_FUNCTION_CODE (fndecl));
9149 case BUILT_IN_STRNCPY_CHK:
9150 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9151 case BUILT_IN_STRCAT_CHK:
9152 return fold_builtin_strcat_chk (fndecl, arglist);
9153 case BUILT_IN_STRNCAT_CHK:
9154 return fold_builtin_strncat_chk (fndecl, arglist);
9155 case BUILT_IN_SPRINTF_CHK:
9156 case BUILT_IN_VSPRINTF_CHK:
9157 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9158 case BUILT_IN_SNPRINTF_CHK:
9159 case BUILT_IN_VSNPRINTF_CHK:
9160 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9161 DECL_FUNCTION_CODE (fndecl));
9163 case BUILT_IN_PRINTF:
9164 case BUILT_IN_PRINTF_UNLOCKED:
9165 case BUILT_IN_VPRINTF:
9166 case BUILT_IN_PRINTF_CHK:
9167 case BUILT_IN_VPRINTF_CHK:
9168 return fold_builtin_printf (fndecl, arglist, ignore,
9169 DECL_FUNCTION_CODE (fndecl));
9171 case BUILT_IN_FPRINTF:
9172 case BUILT_IN_FPRINTF_UNLOCKED:
9173 case BUILT_IN_VFPRINTF:
9174 case BUILT_IN_FPRINTF_CHK:
9175 case BUILT_IN_VFPRINTF_CHK:
9176 return fold_builtin_fprintf (fndecl, arglist, ignore,
9177 DECL_FUNCTION_CODE (fndecl));
9179 default:
9180 break;
9183 return 0;
9186 /* A wrapper function for builtin folding that prevents warnings for
9187 "statement without effect" and the like, caused by removing the
9188 call node earlier than the warning is generated. */
9190 tree
9191 fold_builtin (tree fndecl, tree arglist, bool ignore)
9193 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9194 if (exp)
9196 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9197 TREE_NO_WARNING (exp) = 1;
9200 return exp;
9203 /* Conveniently construct a function call expression. */
9205 tree
9206 build_function_call_expr (tree fn, tree arglist)
9208 tree call_expr;
9210 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9211 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9212 call_expr, arglist, NULL_TREE);
9215 /* This function validates the types of a function call argument list
9216 represented as a tree chain of parameters against a specified list
9217 of tree_codes. If the last specifier is a 0, that represents an
9218 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9220 static int
9221 validate_arglist (tree arglist, ...)
9223 enum tree_code code;
9224 int res = 0;
9225 va_list ap;
9227 va_start (ap, arglist);
9231 code = va_arg (ap, enum tree_code);
9232 switch (code)
9234 case 0:
9235 /* This signifies an ellipses, any further arguments are all ok. */
9236 res = 1;
9237 goto end;
9238 case VOID_TYPE:
9239 /* This signifies an endlink, if no arguments remain, return
9240 true, otherwise return false. */
9241 res = arglist == 0;
9242 goto end;
9243 default:
9244 /* If no parameters remain or the parameter's code does not
9245 match the specified code, return false. Otherwise continue
9246 checking any remaining arguments. */
9247 if (arglist == 0)
9248 goto end;
9249 if (code == POINTER_TYPE)
9251 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9252 goto end;
9254 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9255 goto end;
9256 break;
9258 arglist = TREE_CHAIN (arglist);
9260 while (1);
9262 /* We need gotos here since we can only have one VA_CLOSE in a
9263 function. */
9264 end: ;
9265 va_end (ap);
9267 return res;
9270 /* Default target-specific builtin expander that does nothing. */
9273 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9274 rtx target ATTRIBUTE_UNUSED,
9275 rtx subtarget ATTRIBUTE_UNUSED,
9276 enum machine_mode mode ATTRIBUTE_UNUSED,
9277 int ignore ATTRIBUTE_UNUSED)
9279 return NULL_RTX;
9282 /* Returns true is EXP represents data that would potentially reside
9283 in a readonly section. */
9285 static bool
9286 readonly_data_expr (tree exp)
9288 STRIP_NOPS (exp);
9290 if (TREE_CODE (exp) != ADDR_EXPR)
9291 return false;
9293 exp = get_base_address (TREE_OPERAND (exp, 0));
9294 if (!exp)
9295 return false;
9297 /* Make sure we call decl_readonly_section only for trees it
9298 can handle (since it returns true for everything it doesn't
9299 understand). */
9300 if (TREE_CODE (exp) == STRING_CST
9301 || TREE_CODE (exp) == CONSTRUCTOR
9302 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9303 return decl_readonly_section (exp, 0);
9304 else
9305 return false;
9308 /* Simplify a call to the strstr builtin.
9310 Return 0 if no simplification was possible, otherwise return the
9311 simplified form of the call as a tree.
9313 The simplified form may be a constant or other expression which
9314 computes the same value, but in a more efficient manner (including
9315 calls to other builtin functions).
9317 The call may contain arguments which need to be evaluated, but
9318 which are not useful to determine the result of the call. In
9319 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9320 COMPOUND_EXPR will be an argument which must be evaluated.
9321 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9322 COMPOUND_EXPR in the chain will contain the tree for the simplified
9323 form of the builtin function call. */
9325 static tree
9326 fold_builtin_strstr (tree arglist, tree type)
9328 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9329 return 0;
9330 else
9332 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9333 tree fn;
9334 const char *p1, *p2;
9336 p2 = c_getstr (s2);
9337 if (p2 == NULL)
9338 return 0;
9340 p1 = c_getstr (s1);
9341 if (p1 != NULL)
9343 const char *r = strstr (p1, p2);
9344 tree tem;
9346 if (r == NULL)
9347 return build_int_cst (TREE_TYPE (s1), 0);
9349 /* Return an offset into the constant string argument. */
9350 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9351 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9352 return fold_convert (type, tem);
9355 /* The argument is const char *, and the result is char *, so we need
9356 a type conversion here to avoid a warning. */
9357 if (p2[0] == '\0')
9358 return fold_convert (type, s1);
9360 if (p2[1] != '\0')
9361 return 0;
9363 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9364 if (!fn)
9365 return 0;
9367 /* New argument list transforming strstr(s1, s2) to
9368 strchr(s1, s2[0]). */
9369 arglist = build_tree_list (NULL_TREE,
9370 build_int_cst (NULL_TREE, p2[0]));
9371 arglist = tree_cons (NULL_TREE, s1, arglist);
9372 return build_function_call_expr (fn, arglist);
9376 /* Simplify a call to the strchr builtin.
9378 Return 0 if no simplification was possible, otherwise return the
9379 simplified form of the call as a tree.
9381 The simplified form may be a constant or other expression which
9382 computes the same value, but in a more efficient manner (including
9383 calls to other builtin functions).
9385 The call may contain arguments which need to be evaluated, but
9386 which are not useful to determine the result of the call. In
9387 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9388 COMPOUND_EXPR will be an argument which must be evaluated.
9389 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9390 COMPOUND_EXPR in the chain will contain the tree for the simplified
9391 form of the builtin function call. */
9393 static tree
9394 fold_builtin_strchr (tree arglist, tree type)
9396 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9397 return 0;
9398 else
9400 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9401 const char *p1;
9403 if (TREE_CODE (s2) != INTEGER_CST)
9404 return 0;
9406 p1 = c_getstr (s1);
9407 if (p1 != NULL)
9409 char c;
9410 const char *r;
9411 tree tem;
9413 if (target_char_cast (s2, &c))
9414 return 0;
9416 r = strchr (p1, c);
9418 if (r == NULL)
9419 return build_int_cst (TREE_TYPE (s1), 0);
9421 /* Return an offset into the constant string argument. */
9422 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9423 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9424 return fold_convert (type, tem);
9426 return 0;
9430 /* Simplify a call to the strrchr builtin.
9432 Return 0 if no simplification was possible, otherwise return the
9433 simplified form of the call as a tree.
9435 The simplified form may be a constant or other expression which
9436 computes the same value, but in a more efficient manner (including
9437 calls to other builtin functions).
9439 The call may contain arguments which need to be evaluated, but
9440 which are not useful to determine the result of the call. In
9441 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9442 COMPOUND_EXPR will be an argument which must be evaluated.
9443 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9444 COMPOUND_EXPR in the chain will contain the tree for the simplified
9445 form of the builtin function call. */
9447 static tree
9448 fold_builtin_strrchr (tree arglist, tree type)
9450 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9451 return 0;
9452 else
9454 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9455 tree fn;
9456 const char *p1;
9458 if (TREE_CODE (s2) != INTEGER_CST)
9459 return 0;
9461 p1 = c_getstr (s1);
9462 if (p1 != NULL)
9464 char c;
9465 const char *r;
9466 tree tem;
9468 if (target_char_cast (s2, &c))
9469 return 0;
9471 r = strrchr (p1, c);
9473 if (r == NULL)
9474 return build_int_cst (TREE_TYPE (s1), 0);
9476 /* Return an offset into the constant string argument. */
9477 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9478 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9479 return fold_convert (type, tem);
9482 if (! integer_zerop (s2))
9483 return 0;
9485 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9486 if (!fn)
9487 return 0;
9489 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9490 return build_function_call_expr (fn, arglist);
9494 /* Simplify a call to the strpbrk builtin.
9496 Return 0 if no simplification was possible, otherwise return the
9497 simplified form of the call as a tree.
9499 The simplified form may be a constant or other expression which
9500 computes the same value, but in a more efficient manner (including
9501 calls to other builtin functions).
9503 The call may contain arguments which need to be evaluated, but
9504 which are not useful to determine the result of the call. In
9505 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9506 COMPOUND_EXPR will be an argument which must be evaluated.
9507 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9508 COMPOUND_EXPR in the chain will contain the tree for the simplified
9509 form of the builtin function call. */
9511 static tree
9512 fold_builtin_strpbrk (tree arglist, tree type)
9514 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9515 return 0;
9516 else
9518 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9519 tree fn;
9520 const char *p1, *p2;
9522 p2 = c_getstr (s2);
9523 if (p2 == NULL)
9524 return 0;
9526 p1 = c_getstr (s1);
9527 if (p1 != NULL)
9529 const char *r = strpbrk (p1, p2);
9530 tree tem;
9532 if (r == NULL)
9533 return build_int_cst (TREE_TYPE (s1), 0);
9535 /* Return an offset into the constant string argument. */
9536 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9537 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9538 return fold_convert (type, tem);
9541 if (p2[0] == '\0')
9542 /* strpbrk(x, "") == NULL.
9543 Evaluate and ignore s1 in case it had side-effects. */
9544 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9546 if (p2[1] != '\0')
9547 return 0; /* Really call strpbrk. */
9549 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9550 if (!fn)
9551 return 0;
9553 /* New argument list transforming strpbrk(s1, s2) to
9554 strchr(s1, s2[0]). */
9555 arglist = build_tree_list (NULL_TREE,
9556 build_int_cst (NULL_TREE, p2[0]));
9557 arglist = tree_cons (NULL_TREE, s1, arglist);
9558 return build_function_call_expr (fn, arglist);
9562 /* Simplify a call to the strcat builtin.
9564 Return 0 if no simplification was possible, otherwise return the
9565 simplified form of the call as a tree.
9567 The simplified form may be a constant or other expression which
9568 computes the same value, but in a more efficient manner (including
9569 calls to other builtin functions).
9571 The call may contain arguments which need to be evaluated, but
9572 which are not useful to determine the result of the call. In
9573 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9574 COMPOUND_EXPR will be an argument which must be evaluated.
9575 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9576 COMPOUND_EXPR in the chain will contain the tree for the simplified
9577 form of the builtin function call. */
9579 static tree
9580 fold_builtin_strcat (tree arglist)
9582 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9583 return 0;
9584 else
9586 tree dst = TREE_VALUE (arglist),
9587 src = TREE_VALUE (TREE_CHAIN (arglist));
9588 const char *p = c_getstr (src);
9590 /* If the string length is zero, return the dst parameter. */
9591 if (p && *p == '\0')
9592 return dst;
9594 return 0;
9598 /* Simplify a call to the strncat builtin.
9600 Return 0 if no simplification was possible, otherwise return the
9601 simplified form of the call as a tree.
9603 The simplified form may be a constant or other expression which
9604 computes the same value, but in a more efficient manner (including
9605 calls to other builtin functions).
9607 The call may contain arguments which need to be evaluated, but
9608 which are not useful to determine the result of the call. In
9609 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9610 COMPOUND_EXPR will be an argument which must be evaluated.
9611 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9612 COMPOUND_EXPR in the chain will contain the tree for the simplified
9613 form of the builtin function call. */
9615 static tree
9616 fold_builtin_strncat (tree arglist)
9618 if (!validate_arglist (arglist,
9619 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9620 return 0;
9621 else
9623 tree dst = TREE_VALUE (arglist);
9624 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9625 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9626 const char *p = c_getstr (src);
9628 /* If the requested length is zero, or the src parameter string
9629 length is zero, return the dst parameter. */
9630 if (integer_zerop (len) || (p && *p == '\0'))
9631 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9633 /* If the requested len is greater than or equal to the string
9634 length, call strcat. */
9635 if (TREE_CODE (len) == INTEGER_CST && p
9636 && compare_tree_int (len, strlen (p)) >= 0)
9638 tree newarglist
9639 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9640 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9642 /* If the replacement _DECL isn't initialized, don't do the
9643 transformation. */
9644 if (!fn)
9645 return 0;
9647 return build_function_call_expr (fn, newarglist);
9649 return 0;
9653 /* Simplify a call to the strspn builtin.
9655 Return 0 if no simplification was possible, otherwise return the
9656 simplified form of the call as a tree.
9658 The simplified form may be a constant or other expression which
9659 computes the same value, but in a more efficient manner (including
9660 calls to other builtin functions).
9662 The call may contain arguments which need to be evaluated, but
9663 which are not useful to determine the result of the call. In
9664 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9665 COMPOUND_EXPR will be an argument which must be evaluated.
9666 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9667 COMPOUND_EXPR in the chain will contain the tree for the simplified
9668 form of the builtin function call. */
9670 static tree
9671 fold_builtin_strspn (tree arglist)
9673 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9674 return 0;
9675 else
9677 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9678 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9680 /* If both arguments are constants, evaluate at compile-time. */
9681 if (p1 && p2)
9683 const size_t r = strspn (p1, p2);
9684 return size_int (r);
9687 /* If either argument is "", return 0. */
9688 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9689 /* Evaluate and ignore both arguments in case either one has
9690 side-effects. */
9691 return omit_two_operands (integer_type_node, integer_zero_node,
9692 s1, s2);
9693 return 0;
9697 /* Simplify a call to the strcspn builtin.
9699 Return 0 if no simplification was possible, otherwise return the
9700 simplified form of the call as a tree.
9702 The simplified form may be a constant or other expression which
9703 computes the same value, but in a more efficient manner (including
9704 calls to other builtin functions).
9706 The call may contain arguments which need to be evaluated, but
9707 which are not useful to determine the result of the call. In
9708 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9709 COMPOUND_EXPR will be an argument which must be evaluated.
9710 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9711 COMPOUND_EXPR in the chain will contain the tree for the simplified
9712 form of the builtin function call. */
9714 static tree
9715 fold_builtin_strcspn (tree arglist)
9717 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9718 return 0;
9719 else
9721 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9722 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9724 /* If both arguments are constants, evaluate at compile-time. */
9725 if (p1 && p2)
9727 const size_t r = strcspn (p1, p2);
9728 return size_int (r);
9731 /* If the first argument is "", return 0. */
9732 if (p1 && *p1 == '\0')
9734 /* Evaluate and ignore argument s2 in case it has
9735 side-effects. */
9736 return omit_one_operand (integer_type_node,
9737 integer_zero_node, s2);
9740 /* If the second argument is "", return __builtin_strlen(s1). */
9741 if (p2 && *p2 == '\0')
9743 tree newarglist = build_tree_list (NULL_TREE, s1),
9744 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9746 /* If the replacement _DECL isn't initialized, don't do the
9747 transformation. */
9748 if (!fn)
9749 return 0;
9751 return build_function_call_expr (fn, newarglist);
9753 return 0;
9757 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9758 by the builtin will be ignored. UNLOCKED is true is true if this
9759 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9760 the known length of the string. Return NULL_TREE if no simplification
9761 was possible. */
9763 tree
9764 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9766 tree fn;
9767 /* If we're using an unlocked function, assume the other unlocked
9768 functions exist explicitly. */
9769 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9770 : implicit_built_in_decls[BUILT_IN_FPUTC];
9771 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9772 : implicit_built_in_decls[BUILT_IN_FWRITE];
9774 /* If the return value is used, don't do the transformation. */
9775 if (!ignore)
9776 return 0;
9778 /* Verify the arguments in the original call. */
9779 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9780 return 0;
9782 if (! len)
9783 len = c_strlen (TREE_VALUE (arglist), 0);
9785 /* Get the length of the string passed to fputs. If the length
9786 can't be determined, punt. */
9787 if (!len
9788 || TREE_CODE (len) != INTEGER_CST)
9789 return 0;
9791 switch (compare_tree_int (len, 1))
9793 case -1: /* length is 0, delete the call entirely . */
9794 return omit_one_operand (integer_type_node, integer_zero_node,
9795 TREE_VALUE (TREE_CHAIN (arglist)));
9797 case 0: /* length is 1, call fputc. */
9799 const char *p = c_getstr (TREE_VALUE (arglist));
9801 if (p != NULL)
9803 /* New argument list transforming fputs(string, stream) to
9804 fputc(string[0], stream). */
9805 arglist = build_tree_list (NULL_TREE,
9806 TREE_VALUE (TREE_CHAIN (arglist)));
9807 arglist = tree_cons (NULL_TREE,
9808 build_int_cst (NULL_TREE, p[0]),
9809 arglist);
9810 fn = fn_fputc;
9811 break;
9814 /* FALLTHROUGH */
9815 case 1: /* length is greater than 1, call fwrite. */
9817 tree string_arg;
9819 /* If optimizing for size keep fputs. */
9820 if (optimize_size)
9821 return 0;
9822 string_arg = TREE_VALUE (arglist);
9823 /* New argument list transforming fputs(string, stream) to
9824 fwrite(string, 1, len, stream). */
9825 arglist = build_tree_list (NULL_TREE,
9826 TREE_VALUE (TREE_CHAIN (arglist)));
9827 arglist = tree_cons (NULL_TREE, len, arglist);
9828 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9829 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9830 fn = fn_fwrite;
9831 break;
9833 default:
9834 gcc_unreachable ();
9837 /* If the replacement _DECL isn't initialized, don't do the
9838 transformation. */
9839 if (!fn)
9840 return 0;
9842 /* These optimizations are only performed when the result is ignored,
9843 hence there's no need to cast the result to integer_type_node. */
9844 return build_function_call_expr (fn, arglist);
9847 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9848 produced. False otherwise. This is done so that we don't output the error
9849 or warning twice or three times. */
9850 bool
9851 fold_builtin_next_arg (tree arglist)
9853 tree fntype = TREE_TYPE (current_function_decl);
9855 if (TYPE_ARG_TYPES (fntype) == 0
9856 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9857 == void_type_node))
9859 error ("%<va_start%> used in function with fixed args");
9860 return true;
9862 else if (!arglist)
9864 /* Evidently an out of date version of <stdarg.h>; can't validate
9865 va_start's second argument, but can still work as intended. */
9866 warning (0, "%<__builtin_next_arg%> called without an argument");
9867 return true;
9869 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9870 when we checked the arguments and if needed issued a warning. */
9871 else if (!TREE_CHAIN (arglist)
9872 || !integer_zerop (TREE_VALUE (arglist))
9873 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9874 || TREE_CHAIN (TREE_CHAIN (arglist)))
9876 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9877 tree arg = TREE_VALUE (arglist);
9879 if (TREE_CHAIN (arglist))
9881 error ("%<va_start%> used with too many arguments");
9882 return true;
9885 /* Strip off all nops for the sake of the comparison. This
9886 is not quite the same as STRIP_NOPS. It does more.
9887 We must also strip off INDIRECT_EXPR for C++ reference
9888 parameters. */
9889 while (TREE_CODE (arg) == NOP_EXPR
9890 || TREE_CODE (arg) == CONVERT_EXPR
9891 || TREE_CODE (arg) == NON_LVALUE_EXPR
9892 || TREE_CODE (arg) == INDIRECT_REF)
9893 arg = TREE_OPERAND (arg, 0);
9894 if (arg != last_parm)
9896 /* FIXME: Sometimes with the tree optimizers we can get the
9897 not the last argument even though the user used the last
9898 argument. We just warn and set the arg to be the last
9899 argument so that we will get wrong-code because of
9900 it. */
9901 warning (0, "second parameter of %<va_start%> not last named argument");
9903 /* We want to verify the second parameter just once before the tree
9904 optimizers are run and then avoid keeping it in the tree,
9905 as otherwise we could warn even for correct code like:
9906 void foo (int i, ...)
9907 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9908 TREE_VALUE (arglist) = integer_zero_node;
9909 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9911 return false;
9915 /* Simplify a call to the sprintf builtin.
9917 Return 0 if no simplification was possible, otherwise return the
9918 simplified form of the call as a tree. If IGNORED is true, it means that
9919 the caller does not use the returned value of the function. */
9921 static tree
9922 fold_builtin_sprintf (tree arglist, int ignored)
9924 tree call, retval, dest, fmt;
9925 const char *fmt_str = NULL;
9927 /* Verify the required arguments in the original call. We deal with two
9928 types of sprintf() calls: 'sprintf (str, fmt)' and
9929 'sprintf (dest, "%s", orig)'. */
9930 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9931 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9932 VOID_TYPE))
9933 return NULL_TREE;
9935 /* Get the destination string and the format specifier. */
9936 dest = TREE_VALUE (arglist);
9937 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9939 /* Check whether the format is a literal string constant. */
9940 fmt_str = c_getstr (fmt);
9941 if (fmt_str == NULL)
9942 return NULL_TREE;
9944 call = NULL_TREE;
9945 retval = NULL_TREE;
9947 if (!init_target_chars())
9948 return 0;
9950 /* If the format doesn't contain % args or %%, use strcpy. */
9951 if (strchr (fmt_str, target_percent) == NULL)
9953 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9955 if (!fn)
9956 return NULL_TREE;
9958 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9959 'format' is known to contain no % formats. */
9960 arglist = build_tree_list (NULL_TREE, fmt);
9961 arglist = tree_cons (NULL_TREE, dest, arglist);
9962 call = build_function_call_expr (fn, arglist);
9963 if (!ignored)
9964 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9967 /* If the format is "%s", use strcpy if the result isn't used. */
9968 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9970 tree fn, orig;
9971 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9973 if (!fn)
9974 return NULL_TREE;
9976 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9977 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9978 arglist = build_tree_list (NULL_TREE, orig);
9979 arglist = tree_cons (NULL_TREE, dest, arglist);
9980 if (!ignored)
9982 retval = c_strlen (orig, 1);
9983 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9984 return NULL_TREE;
9986 call = build_function_call_expr (fn, arglist);
9989 if (call && retval)
9991 retval = convert
9992 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9993 retval);
9994 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9996 else
9997 return call;
10000 /* Expand a call to __builtin_object_size. */
10003 expand_builtin_object_size (tree exp)
10005 tree ost;
10006 int object_size_type;
10007 tree fndecl = get_callee_fndecl (exp);
10008 tree arglist = TREE_OPERAND (exp, 1);
10009 location_t locus = EXPR_LOCATION (exp);
10011 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10013 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10014 &locus, fndecl);
10015 expand_builtin_trap ();
10016 return const0_rtx;
10019 ost = TREE_VALUE (TREE_CHAIN (arglist));
10020 STRIP_NOPS (ost);
10022 if (TREE_CODE (ost) != INTEGER_CST
10023 || tree_int_cst_sgn (ost) < 0
10024 || compare_tree_int (ost, 3) > 0)
10026 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10027 &locus, fndecl);
10028 expand_builtin_trap ();
10029 return const0_rtx;
10032 object_size_type = tree_low_cst (ost, 0);
10034 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10037 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10038 FCODE is the BUILT_IN_* to use.
10039 Return 0 if we failed; the caller should emit a normal call,
10040 otherwise try to get the result in TARGET, if convenient (and in
10041 mode MODE if that's convenient). */
10043 static rtx
10044 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10045 enum built_in_function fcode)
10047 tree arglist = TREE_OPERAND (exp, 1);
10048 tree dest, src, len, size;
10050 if (!validate_arglist (arglist,
10051 POINTER_TYPE,
10052 fcode == BUILT_IN_MEMSET_CHK
10053 ? INTEGER_TYPE : POINTER_TYPE,
10054 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10055 return 0;
10057 dest = TREE_VALUE (arglist);
10058 src = TREE_VALUE (TREE_CHAIN (arglist));
10059 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10060 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10062 if (! host_integerp (size, 1))
10063 return 0;
10065 if (host_integerp (len, 1) || integer_all_onesp (size))
10067 tree fn;
10069 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10071 location_t locus = EXPR_LOCATION (exp);
10072 warning (0, "%Hcall to %D will always overflow destination buffer",
10073 &locus, get_callee_fndecl (exp));
10074 return 0;
10077 arglist = build_tree_list (NULL_TREE, len);
10078 arglist = tree_cons (NULL_TREE, src, arglist);
10079 arglist = tree_cons (NULL_TREE, dest, arglist);
10081 fn = NULL_TREE;
10082 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10083 mem{cpy,pcpy,move,set} is available. */
10084 switch (fcode)
10086 case BUILT_IN_MEMCPY_CHK:
10087 fn = built_in_decls[BUILT_IN_MEMCPY];
10088 break;
10089 case BUILT_IN_MEMPCPY_CHK:
10090 fn = built_in_decls[BUILT_IN_MEMPCPY];
10091 break;
10092 case BUILT_IN_MEMMOVE_CHK:
10093 fn = built_in_decls[BUILT_IN_MEMMOVE];
10094 break;
10095 case BUILT_IN_MEMSET_CHK:
10096 fn = built_in_decls[BUILT_IN_MEMSET];
10097 break;
10098 default:
10099 break;
10102 if (! fn)
10103 return 0;
10105 fn = build_function_call_expr (fn, arglist);
10106 if (TREE_CODE (fn) == CALL_EXPR)
10107 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10108 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10110 else if (fcode == BUILT_IN_MEMSET_CHK)
10111 return 0;
10112 else
10114 unsigned int dest_align
10115 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10117 /* If DEST is not a pointer type, call the normal function. */
10118 if (dest_align == 0)
10119 return 0;
10121 /* If SRC and DEST are the same (and not volatile), do nothing. */
10122 if (operand_equal_p (src, dest, 0))
10124 tree expr;
10126 if (fcode != BUILT_IN_MEMPCPY_CHK)
10128 /* Evaluate and ignore LEN in case it has side-effects. */
10129 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10130 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10133 len = fold_convert (TREE_TYPE (dest), len);
10134 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10135 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10138 /* __memmove_chk special case. */
10139 if (fcode == BUILT_IN_MEMMOVE_CHK)
10141 unsigned int src_align
10142 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10144 if (src_align == 0)
10145 return 0;
10147 /* If src is categorized for a readonly section we can use
10148 normal __memcpy_chk. */
10149 if (readonly_data_expr (src))
10151 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10152 if (!fn)
10153 return 0;
10154 fn = build_function_call_expr (fn, arglist);
10155 if (TREE_CODE (fn) == CALL_EXPR)
10156 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10157 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10160 return 0;
10164 /* Emit warning if a buffer overflow is detected at compile time. */
10166 static void
10167 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10169 int arg_mask, is_strlen = 0;
10170 tree arglist = TREE_OPERAND (exp, 1), a;
10171 tree len, size;
10172 location_t locus;
10174 switch (fcode)
10176 case BUILT_IN_STRCPY_CHK:
10177 case BUILT_IN_STPCPY_CHK:
10178 /* For __strcat_chk the warning will be emitted only if overflowing
10179 by at least strlen (dest) + 1 bytes. */
10180 case BUILT_IN_STRCAT_CHK:
10181 arg_mask = 6;
10182 is_strlen = 1;
10183 break;
10184 case BUILT_IN_STRNCPY_CHK:
10185 arg_mask = 12;
10186 break;
10187 case BUILT_IN_SNPRINTF_CHK:
10188 case BUILT_IN_VSNPRINTF_CHK:
10189 arg_mask = 10;
10190 break;
10191 default:
10192 gcc_unreachable ();
10195 len = NULL_TREE;
10196 size = NULL_TREE;
10197 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10198 if (arg_mask & 1)
10200 if (len)
10201 size = a;
10202 else
10203 len = a;
10206 if (!len || !size)
10207 return;
10209 len = TREE_VALUE (len);
10210 size = TREE_VALUE (size);
10212 if (! host_integerp (size, 1) || integer_all_onesp (size))
10213 return;
10215 if (is_strlen)
10217 len = c_strlen (len, 1);
10218 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10219 return;
10221 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10222 return;
10224 locus = EXPR_LOCATION (exp);
10225 warning (0, "%Hcall to %D will always overflow destination buffer",
10226 &locus, get_callee_fndecl (exp));
10229 /* Emit warning if a buffer overflow is detected at compile time
10230 in __sprintf_chk/__vsprintf_chk calls. */
10232 static void
10233 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10235 tree arglist = TREE_OPERAND (exp, 1);
10236 tree dest, size, len, fmt, flag;
10237 const char *fmt_str;
10239 /* Verify the required arguments in the original call. */
10240 if (! arglist)
10241 return;
10242 dest = TREE_VALUE (arglist);
10243 arglist = TREE_CHAIN (arglist);
10244 if (! arglist)
10245 return;
10246 flag = TREE_VALUE (arglist);
10247 arglist = TREE_CHAIN (arglist);
10248 if (! arglist)
10249 return;
10250 size = TREE_VALUE (arglist);
10251 arglist = TREE_CHAIN (arglist);
10252 if (! arglist)
10253 return;
10254 fmt = TREE_VALUE (arglist);
10255 arglist = TREE_CHAIN (arglist);
10257 if (! host_integerp (size, 1) || integer_all_onesp (size))
10258 return;
10260 /* Check whether the format is a literal string constant. */
10261 fmt_str = c_getstr (fmt);
10262 if (fmt_str == NULL)
10263 return;
10265 if (!init_target_chars())
10266 return;
10268 /* If the format doesn't contain % args or %%, we know its size. */
10269 if (strchr (fmt_str, target_percent) == 0)
10270 len = build_int_cstu (size_type_node, strlen (fmt_str));
10271 /* If the format is "%s" and first ... argument is a string literal,
10272 we know it too. */
10273 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10275 tree arg;
10277 if (! arglist)
10278 return;
10279 arg = TREE_VALUE (arglist);
10280 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10281 return;
10283 len = c_strlen (arg, 1);
10284 if (!len || ! host_integerp (len, 1))
10285 return;
10287 else
10288 return;
10290 if (! tree_int_cst_lt (len, size))
10292 location_t locus = EXPR_LOCATION (exp);
10293 warning (0, "%Hcall to %D will always overflow destination buffer",
10294 &locus, get_callee_fndecl (exp));
10298 /* Fold a call to __builtin_object_size, if possible. */
10300 tree
10301 fold_builtin_object_size (tree arglist)
10303 tree ptr, ost, ret = 0;
10304 int object_size_type;
10306 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10307 return 0;
10309 ptr = TREE_VALUE (arglist);
10310 ost = TREE_VALUE (TREE_CHAIN (arglist));
10311 STRIP_NOPS (ost);
10313 if (TREE_CODE (ost) != INTEGER_CST
10314 || tree_int_cst_sgn (ost) < 0
10315 || compare_tree_int (ost, 3) > 0)
10316 return 0;
10318 object_size_type = tree_low_cst (ost, 0);
10320 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10321 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10322 and (size_t) 0 for types 2 and 3. */
10323 if (TREE_SIDE_EFFECTS (ptr))
10324 return fold_convert (size_type_node,
10325 object_size_type < 2
10326 ? integer_minus_one_node : integer_zero_node);
10328 if (TREE_CODE (ptr) == ADDR_EXPR)
10329 ret = build_int_cstu (size_type_node,
10330 compute_builtin_object_size (ptr, object_size_type));
10332 else if (TREE_CODE (ptr) == SSA_NAME)
10334 unsigned HOST_WIDE_INT bytes;
10336 /* If object size is not known yet, delay folding until
10337 later. Maybe subsequent passes will help determining
10338 it. */
10339 bytes = compute_builtin_object_size (ptr, object_size_type);
10340 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10341 ? -1 : 0))
10342 ret = build_int_cstu (size_type_node, bytes);
10345 if (ret)
10347 ret = force_fit_type (ret, -1, false, false);
10348 if (TREE_CONSTANT_OVERFLOW (ret))
10349 ret = 0;
10352 return ret;
10355 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10356 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10357 code of the builtin. If MAXLEN is not NULL, it is maximum length
10358 passed as third argument. */
10360 tree
10361 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10362 enum built_in_function fcode)
10364 tree dest, src, len, size, fn;
10366 if (!validate_arglist (arglist,
10367 POINTER_TYPE,
10368 fcode == BUILT_IN_MEMSET_CHK
10369 ? INTEGER_TYPE : POINTER_TYPE,
10370 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10371 return 0;
10373 dest = TREE_VALUE (arglist);
10374 /* Actually val for __memset_chk, but it doesn't matter. */
10375 src = TREE_VALUE (TREE_CHAIN (arglist));
10376 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10377 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10379 /* If SRC and DEST are the same (and not volatile), return DEST
10380 (resp. DEST+LEN for __mempcpy_chk). */
10381 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10383 if (fcode != BUILT_IN_MEMPCPY_CHK)
10384 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10385 else
10387 tree temp = fold_convert (TREE_TYPE (dest), len);
10388 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10389 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10393 if (! host_integerp (size, 1))
10394 return 0;
10396 if (! integer_all_onesp (size))
10398 if (! host_integerp (len, 1))
10400 /* If LEN is not constant, try MAXLEN too.
10401 For MAXLEN only allow optimizing into non-_ocs function
10402 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10403 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10405 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10407 /* (void) __mempcpy_chk () can be optimized into
10408 (void) __memcpy_chk (). */
10409 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10410 if (!fn)
10411 return 0;
10413 return build_function_call_expr (fn, arglist);
10415 return 0;
10418 else
10419 maxlen = len;
10421 if (tree_int_cst_lt (size, maxlen))
10422 return 0;
10425 arglist = build_tree_list (NULL_TREE, len);
10426 arglist = tree_cons (NULL_TREE, src, arglist);
10427 arglist = tree_cons (NULL_TREE, dest, arglist);
10429 fn = NULL_TREE;
10430 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10431 mem{cpy,pcpy,move,set} is available. */
10432 switch (fcode)
10434 case BUILT_IN_MEMCPY_CHK:
10435 fn = built_in_decls[BUILT_IN_MEMCPY];
10436 break;
10437 case BUILT_IN_MEMPCPY_CHK:
10438 fn = built_in_decls[BUILT_IN_MEMPCPY];
10439 break;
10440 case BUILT_IN_MEMMOVE_CHK:
10441 fn = built_in_decls[BUILT_IN_MEMMOVE];
10442 break;
10443 case BUILT_IN_MEMSET_CHK:
10444 fn = built_in_decls[BUILT_IN_MEMSET];
10445 break;
10446 default:
10447 break;
10450 if (!fn)
10451 return 0;
10453 return build_function_call_expr (fn, arglist);
10456 /* Fold a call to the __st[rp]cpy_chk builtin.
10457 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10458 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10459 strings passed as second argument. */
10461 tree
10462 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10463 enum built_in_function fcode)
10465 tree dest, src, size, len, fn;
10467 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10468 VOID_TYPE))
10469 return 0;
10471 dest = TREE_VALUE (arglist);
10472 src = TREE_VALUE (TREE_CHAIN (arglist));
10473 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10475 /* If SRC and DEST are the same (and not volatile), return DEST. */
10476 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10477 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10479 if (! host_integerp (size, 1))
10480 return 0;
10482 if (! integer_all_onesp (size))
10484 len = c_strlen (src, 1);
10485 if (! len || ! host_integerp (len, 1))
10487 /* If LEN is not constant, try MAXLEN too.
10488 For MAXLEN only allow optimizing into non-_ocs function
10489 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10490 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10492 if (fcode == BUILT_IN_STPCPY_CHK)
10494 if (! ignore)
10495 return 0;
10497 /* If return value of __stpcpy_chk is ignored,
10498 optimize into __strcpy_chk. */
10499 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10500 if (!fn)
10501 return 0;
10503 return build_function_call_expr (fn, arglist);
10506 if (! len || TREE_SIDE_EFFECTS (len))
10507 return 0;
10509 /* If c_strlen returned something, but not a constant,
10510 transform __strcpy_chk into __memcpy_chk. */
10511 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10512 if (!fn)
10513 return 0;
10515 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10516 arglist = build_tree_list (NULL_TREE, size);
10517 arglist = tree_cons (NULL_TREE, len, arglist);
10518 arglist = tree_cons (NULL_TREE, src, arglist);
10519 arglist = tree_cons (NULL_TREE, dest, arglist);
10520 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10521 build_function_call_expr (fn, arglist));
10524 else
10525 maxlen = len;
10527 if (! tree_int_cst_lt (maxlen, size))
10528 return 0;
10531 arglist = build_tree_list (NULL_TREE, src);
10532 arglist = tree_cons (NULL_TREE, dest, arglist);
10534 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10535 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10536 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10537 if (!fn)
10538 return 0;
10540 return build_function_call_expr (fn, arglist);
10543 /* Fold a call to the __strncpy_chk builtin.
10544 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10546 tree
10547 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10549 tree dest, src, size, len, fn;
10551 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10552 INTEGER_TYPE, VOID_TYPE))
10553 return 0;
10555 dest = TREE_VALUE (arglist);
10556 src = TREE_VALUE (TREE_CHAIN (arglist));
10557 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10558 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10560 if (! host_integerp (size, 1))
10561 return 0;
10563 if (! integer_all_onesp (size))
10565 if (! host_integerp (len, 1))
10567 /* If LEN is not constant, try MAXLEN too.
10568 For MAXLEN only allow optimizing into non-_ocs function
10569 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10570 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10571 return 0;
10573 else
10574 maxlen = len;
10576 if (tree_int_cst_lt (size, maxlen))
10577 return 0;
10580 arglist = build_tree_list (NULL_TREE, len);
10581 arglist = tree_cons (NULL_TREE, src, arglist);
10582 arglist = tree_cons (NULL_TREE, dest, arglist);
10584 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10585 fn = built_in_decls[BUILT_IN_STRNCPY];
10586 if (!fn)
10587 return 0;
10589 return build_function_call_expr (fn, arglist);
10592 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10594 static tree
10595 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10597 tree dest, src, size, fn;
10598 const char *p;
10600 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10601 VOID_TYPE))
10602 return 0;
10604 dest = TREE_VALUE (arglist);
10605 src = TREE_VALUE (TREE_CHAIN (arglist));
10606 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10608 p = c_getstr (src);
10609 /* If the SRC parameter is "", return DEST. */
10610 if (p && *p == '\0')
10611 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10613 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10614 return 0;
10616 arglist = build_tree_list (NULL_TREE, src);
10617 arglist = tree_cons (NULL_TREE, dest, arglist);
10619 /* If __builtin_strcat_chk is used, assume strcat is available. */
10620 fn = built_in_decls[BUILT_IN_STRCAT];
10621 if (!fn)
10622 return 0;
10624 return build_function_call_expr (fn, arglist);
10627 /* Fold a call to the __strncat_chk builtin EXP. */
10629 static tree
10630 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10632 tree dest, src, size, len, fn;
10633 const char *p;
10635 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10636 INTEGER_TYPE, VOID_TYPE))
10637 return 0;
10639 dest = TREE_VALUE (arglist);
10640 src = TREE_VALUE (TREE_CHAIN (arglist));
10641 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10642 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10644 p = c_getstr (src);
10645 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10646 if (p && *p == '\0')
10647 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10648 else if (integer_zerop (len))
10649 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10651 if (! host_integerp (size, 1))
10652 return 0;
10654 if (! integer_all_onesp (size))
10656 tree src_len = c_strlen (src, 1);
10657 if (src_len
10658 && host_integerp (src_len, 1)
10659 && host_integerp (len, 1)
10660 && ! tree_int_cst_lt (len, src_len))
10662 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10663 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10664 if (!fn)
10665 return 0;
10667 arglist = build_tree_list (NULL_TREE, size);
10668 arglist = tree_cons (NULL_TREE, src, arglist);
10669 arglist = tree_cons (NULL_TREE, dest, arglist);
10670 return build_function_call_expr (fn, arglist);
10672 return 0;
10675 arglist = build_tree_list (NULL_TREE, len);
10676 arglist = tree_cons (NULL_TREE, src, arglist);
10677 arglist = tree_cons (NULL_TREE, dest, arglist);
10679 /* If __builtin_strncat_chk is used, assume strncat is available. */
10680 fn = built_in_decls[BUILT_IN_STRNCAT];
10681 if (!fn)
10682 return 0;
10684 return build_function_call_expr (fn, arglist);
10687 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10688 a normal call should be emitted rather than expanding the function
10689 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10691 static tree
10692 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10694 tree dest, size, len, fn, fmt, flag;
10695 const char *fmt_str;
10697 /* Verify the required arguments in the original call. */
10698 if (! arglist)
10699 return 0;
10700 dest = TREE_VALUE (arglist);
10701 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10702 return 0;
10703 arglist = TREE_CHAIN (arglist);
10704 if (! arglist)
10705 return 0;
10706 flag = TREE_VALUE (arglist);
10707 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10708 return 0;
10709 arglist = TREE_CHAIN (arglist);
10710 if (! arglist)
10711 return 0;
10712 size = TREE_VALUE (arglist);
10713 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10714 return 0;
10715 arglist = TREE_CHAIN (arglist);
10716 if (! arglist)
10717 return 0;
10718 fmt = TREE_VALUE (arglist);
10719 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10720 return 0;
10721 arglist = TREE_CHAIN (arglist);
10723 if (! host_integerp (size, 1))
10724 return 0;
10726 len = NULL_TREE;
10728 if (!init_target_chars())
10729 return 0;
10731 /* Check whether the format is a literal string constant. */
10732 fmt_str = c_getstr (fmt);
10733 if (fmt_str != NULL)
10735 /* If the format doesn't contain % args or %%, we know the size. */
10736 if (strchr (fmt_str, target_percent) == 0)
10738 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10739 len = build_int_cstu (size_type_node, strlen (fmt_str));
10741 /* If the format is "%s" and first ... argument is a string literal,
10742 we know the size too. */
10743 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10745 tree arg;
10747 if (arglist && !TREE_CHAIN (arglist))
10749 arg = TREE_VALUE (arglist);
10750 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10752 len = c_strlen (arg, 1);
10753 if (! len || ! host_integerp (len, 1))
10754 len = NULL_TREE;
10760 if (! integer_all_onesp (size))
10762 if (! len || ! tree_int_cst_lt (len, size))
10763 return 0;
10766 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10767 or if format doesn't contain % chars or is "%s". */
10768 if (! integer_zerop (flag))
10770 if (fmt_str == NULL)
10771 return 0;
10772 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10773 return 0;
10776 arglist = tree_cons (NULL_TREE, fmt, arglist);
10777 arglist = tree_cons (NULL_TREE, dest, arglist);
10779 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10780 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10781 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10782 if (!fn)
10783 return 0;
10785 return build_function_call_expr (fn, arglist);
10788 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10789 a normal call should be emitted rather than expanding the function
10790 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10791 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10792 passed as second argument. */
10794 tree
10795 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10796 enum built_in_function fcode)
10798 tree dest, size, len, fn, fmt, flag;
10799 const char *fmt_str;
10801 /* Verify the required arguments in the original call. */
10802 if (! arglist)
10803 return 0;
10804 dest = TREE_VALUE (arglist);
10805 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10806 return 0;
10807 arglist = TREE_CHAIN (arglist);
10808 if (! arglist)
10809 return 0;
10810 len = TREE_VALUE (arglist);
10811 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10812 return 0;
10813 arglist = TREE_CHAIN (arglist);
10814 if (! arglist)
10815 return 0;
10816 flag = TREE_VALUE (arglist);
10817 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10818 return 0;
10819 arglist = TREE_CHAIN (arglist);
10820 if (! arglist)
10821 return 0;
10822 size = TREE_VALUE (arglist);
10823 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10824 return 0;
10825 arglist = TREE_CHAIN (arglist);
10826 if (! arglist)
10827 return 0;
10828 fmt = TREE_VALUE (arglist);
10829 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10830 return 0;
10831 arglist = TREE_CHAIN (arglist);
10833 if (! host_integerp (size, 1))
10834 return 0;
10836 if (! integer_all_onesp (size))
10838 if (! host_integerp (len, 1))
10840 /* If LEN is not constant, try MAXLEN too.
10841 For MAXLEN only allow optimizing into non-_ocs function
10842 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10843 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10844 return 0;
10846 else
10847 maxlen = len;
10849 if (tree_int_cst_lt (size, maxlen))
10850 return 0;
10853 if (!init_target_chars())
10854 return 0;
10856 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10857 or if format doesn't contain % chars or is "%s". */
10858 if (! integer_zerop (flag))
10860 fmt_str = c_getstr (fmt);
10861 if (fmt_str == NULL)
10862 return 0;
10863 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10864 return 0;
10867 arglist = tree_cons (NULL_TREE, fmt, arglist);
10868 arglist = tree_cons (NULL_TREE, len, arglist);
10869 arglist = tree_cons (NULL_TREE, dest, arglist);
10871 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10872 available. */
10873 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10874 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10875 if (!fn)
10876 return 0;
10878 return build_function_call_expr (fn, arglist);
10881 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10883 Return 0 if no simplification was possible, otherwise return the
10884 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10885 code of the function to be simplified. */
10887 static tree
10888 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10889 enum built_in_function fcode)
10891 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10892 const char *fmt_str = NULL;
10894 /* If the return value is used, don't do the transformation. */
10895 if (! ignore)
10896 return 0;
10898 /* Verify the required arguments in the original call. */
10899 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10901 tree flag;
10903 if (! arglist)
10904 return 0;
10905 flag = TREE_VALUE (arglist);
10906 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10907 || TREE_SIDE_EFFECTS (flag))
10908 return 0;
10909 arglist = TREE_CHAIN (arglist);
10912 if (! arglist)
10913 return 0;
10914 fmt = TREE_VALUE (arglist);
10915 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10916 return 0;
10917 arglist = TREE_CHAIN (arglist);
10919 /* Check whether the format is a literal string constant. */
10920 fmt_str = c_getstr (fmt);
10921 if (fmt_str == NULL)
10922 return NULL_TREE;
10924 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10926 /* If we're using an unlocked function, assume the other
10927 unlocked functions exist explicitly. */
10928 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10929 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10931 else
10933 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10934 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10937 if (!init_target_chars())
10938 return 0;
10940 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10942 const char *str;
10944 if (strcmp (fmt_str, target_percent_s) == 0)
10946 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10947 return 0;
10949 if (! arglist
10950 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10951 || TREE_CHAIN (arglist))
10952 return 0;
10954 str = c_getstr (TREE_VALUE (arglist));
10955 if (str == NULL)
10956 return 0;
10958 else
10960 /* The format specifier doesn't contain any '%' characters. */
10961 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10962 && arglist)
10963 return 0;
10964 str = fmt_str;
10967 /* If the string was "", printf does nothing. */
10968 if (str[0] == '\0')
10969 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10971 /* If the string has length of 1, call putchar. */
10972 if (str[1] == '\0')
10974 /* Given printf("c"), (where c is any one character,)
10975 convert "c"[0] to an int and pass that to the replacement
10976 function. */
10977 arg = build_int_cst (NULL_TREE, str[0]);
10978 arglist = build_tree_list (NULL_TREE, arg);
10979 fn = fn_putchar;
10981 else
10983 /* If the string was "string\n", call puts("string"). */
10984 size_t len = strlen (str);
10985 if ((unsigned char)str[len - 1] == target_newline)
10987 /* Create a NUL-terminated string that's one char shorter
10988 than the original, stripping off the trailing '\n'. */
10989 char *newstr = alloca (len);
10990 memcpy (newstr, str, len - 1);
10991 newstr[len - 1] = 0;
10993 arg = build_string_literal (len, newstr);
10994 arglist = build_tree_list (NULL_TREE, arg);
10995 fn = fn_puts;
10997 else
10998 /* We'd like to arrange to call fputs(string,stdout) here,
10999 but we need stdout and don't have a way to get it yet. */
11000 return 0;
11004 /* The other optimizations can be done only on the non-va_list variants. */
11005 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11006 return 0;
11008 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11009 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11011 if (! arglist
11012 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11013 || TREE_CHAIN (arglist))
11014 return 0;
11015 fn = fn_puts;
11018 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11019 else if (strcmp (fmt_str, target_percent_c) == 0)
11021 if (! arglist
11022 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11023 || TREE_CHAIN (arglist))
11024 return 0;
11025 fn = fn_putchar;
11028 if (!fn)
11029 return 0;
11031 call = build_function_call_expr (fn, arglist);
11032 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11035 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11037 Return 0 if no simplification was possible, otherwise return the
11038 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11039 code of the function to be simplified. */
11041 static tree
11042 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11043 enum built_in_function fcode)
11045 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11046 const char *fmt_str = NULL;
11048 /* If the return value is used, don't do the transformation. */
11049 if (! ignore)
11050 return 0;
11052 /* Verify the required arguments in the original call. */
11053 if (! arglist)
11054 return 0;
11055 fp = TREE_VALUE (arglist);
11056 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11057 return 0;
11058 arglist = TREE_CHAIN (arglist);
11060 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11062 tree flag;
11064 if (! arglist)
11065 return 0;
11066 flag = TREE_VALUE (arglist);
11067 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11068 || TREE_SIDE_EFFECTS (flag))
11069 return 0;
11070 arglist = TREE_CHAIN (arglist);
11073 if (! arglist)
11074 return 0;
11075 fmt = TREE_VALUE (arglist);
11076 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11077 return 0;
11078 arglist = TREE_CHAIN (arglist);
11080 /* Check whether the format is a literal string constant. */
11081 fmt_str = c_getstr (fmt);
11082 if (fmt_str == NULL)
11083 return NULL_TREE;
11085 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11087 /* If we're using an unlocked function, assume the other
11088 unlocked functions exist explicitly. */
11089 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11090 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11092 else
11094 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11095 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11098 if (!init_target_chars())
11099 return 0;
11101 /* If the format doesn't contain % args or %%, use strcpy. */
11102 if (strchr (fmt_str, target_percent) == NULL)
11104 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11105 && arglist)
11106 return 0;
11108 /* If the format specifier was "", fprintf does nothing. */
11109 if (fmt_str[0] == '\0')
11111 /* If FP has side-effects, just wait until gimplification is
11112 done. */
11113 if (TREE_SIDE_EFFECTS (fp))
11114 return 0;
11116 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11119 /* When "string" doesn't contain %, replace all cases of
11120 fprintf (fp, string) with fputs (string, fp). The fputs
11121 builtin will take care of special cases like length == 1. */
11122 arglist = build_tree_list (NULL_TREE, fp);
11123 arglist = tree_cons (NULL_TREE, fmt, arglist);
11124 fn = fn_fputs;
11127 /* The other optimizations can be done only on the non-va_list variants. */
11128 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11129 return 0;
11131 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11132 else if (strcmp (fmt_str, target_percent_s) == 0)
11134 if (! arglist
11135 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11136 || TREE_CHAIN (arglist))
11137 return 0;
11138 arg = TREE_VALUE (arglist);
11139 arglist = build_tree_list (NULL_TREE, fp);
11140 arglist = tree_cons (NULL_TREE, arg, arglist);
11141 fn = fn_fputs;
11144 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11145 else if (strcmp (fmt_str, target_percent_c) == 0)
11147 if (! arglist
11148 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11149 || TREE_CHAIN (arglist))
11150 return 0;
11151 arg = TREE_VALUE (arglist);
11152 arglist = build_tree_list (NULL_TREE, fp);
11153 arglist = tree_cons (NULL_TREE, arg, arglist);
11154 fn = fn_fputc;
11157 if (!fn)
11158 return 0;
11160 call = build_function_call_expr (fn, arglist);
11161 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11164 /* Initialize format string characters in the target charset. */
11166 static bool
11167 init_target_chars (void)
11169 static bool init;
11170 if (!init)
11172 target_newline = lang_hooks.to_target_charset ('\n');
11173 target_percent = lang_hooks.to_target_charset ('%');
11174 target_c = lang_hooks.to_target_charset ('c');
11175 target_s = lang_hooks.to_target_charset ('s');
11176 if (target_newline == 0 || target_percent == 0 || target_c == 0
11177 || target_s == 0)
11178 return false;
11180 target_percent_c[0] = target_percent;
11181 target_percent_c[1] = target_c;
11182 target_percent_c[2] = '\0';
11184 target_percent_s[0] = target_percent;
11185 target_percent_s[1] = target_s;
11186 target_percent_s[2] = '\0';
11188 target_percent_s_newline[0] = target_percent;
11189 target_percent_s_newline[1] = target_s;
11190 target_percent_s_newline[2] = target_newline;
11191 target_percent_s_newline[3] = '\0';
11193 init = true;
11195 return true;