r113612@merlin: rearnsha | 2006-05-07 00:19:18 +0100
[official-gcc.git] / gcc / builtins.c
blob085c1fae3ca805cd0c281b9664e3ce3f9f3dfc42
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_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 while (handled_component_p (exp))
281 /* Fields in a structure can be packed, honor DECL_ALIGN
282 of the FIELD_DECL. For all other references the conservative
283 alignment is the element type alignment. */
284 if (TREE_CODE (exp) == COMPONENT_REF)
285 inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
286 else
287 inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
288 exp = TREE_OPERAND (exp, 0);
290 if (TREE_CODE (exp) == FUNCTION_DECL)
291 align = FUNCTION_BOUNDARY;
292 else if (DECL_P (exp))
293 align = MIN (inner, DECL_ALIGN (exp));
294 #ifdef CONSTANT_ALIGNMENT
295 else if (CONSTANT_CLASS_P (exp))
296 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
297 #endif
298 else
299 align = MIN (align, inner);
300 return MIN (align, max_align);
302 default:
303 return align;
308 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
309 way, because it could contain a zero byte in the middle.
310 TREE_STRING_LENGTH is the size of the character array, not the string.
312 ONLY_VALUE should be nonzero if the result is not going to be emitted
313 into the instruction stream and zero if it is going to be expanded.
314 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
315 is returned, otherwise NULL, since
316 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
317 evaluate the side-effects.
319 The value returned is of type `ssizetype'.
321 Unfortunately, string_constant can't access the values of const char
322 arrays with initializers, so neither can we do so here. */
324 tree
325 c_strlen (tree src, int only_value)
327 tree offset_node;
328 HOST_WIDE_INT offset;
329 int max;
330 const char *ptr;
332 STRIP_NOPS (src);
333 if (TREE_CODE (src) == COND_EXPR
334 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
336 tree len1, len2;
338 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
339 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
340 if (tree_int_cst_equal (len1, len2))
341 return len1;
344 if (TREE_CODE (src) == COMPOUND_EXPR
345 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
346 return c_strlen (TREE_OPERAND (src, 1), only_value);
348 src = string_constant (src, &offset_node);
349 if (src == 0)
350 return 0;
352 max = TREE_STRING_LENGTH (src) - 1;
353 ptr = TREE_STRING_POINTER (src);
355 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
357 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
358 compute the offset to the following null if we don't know where to
359 start searching for it. */
360 int i;
362 for (i = 0; i < max; i++)
363 if (ptr[i] == 0)
364 return 0;
366 /* We don't know the starting offset, but we do know that the string
367 has no internal zero bytes. We can assume that the offset falls
368 within the bounds of the string; otherwise, the programmer deserves
369 what he gets. Subtract the offset from the length of the string,
370 and return that. This would perhaps not be valid if we were dealing
371 with named arrays in addition to literal string constants. */
373 return size_diffop (size_int (max), offset_node);
376 /* We have a known offset into the string. Start searching there for
377 a null character if we can represent it as a single HOST_WIDE_INT. */
378 if (offset_node == 0)
379 offset = 0;
380 else if (! host_integerp (offset_node, 0))
381 offset = -1;
382 else
383 offset = tree_low_cst (offset_node, 0);
385 /* If the offset is known to be out of bounds, warn, and call strlen at
386 runtime. */
387 if (offset < 0 || offset > max)
389 warning (0, "offset outside bounds of constant string");
390 return 0;
393 /* Use strlen to search for the first zero byte. Since any strings
394 constructed with build_string will have nulls appended, we win even
395 if we get handed something like (char[4])"abcd".
397 Since OFFSET is our starting index into the string, no further
398 calculation is needed. */
399 return ssize_int (strlen (ptr + offset));
402 /* Return a char pointer for a C string if it is a string constant
403 or sum of string constant and integer constant. */
405 static const char *
406 c_getstr (tree src)
408 tree offset_node;
410 src = string_constant (src, &offset_node);
411 if (src == 0)
412 return 0;
414 if (offset_node == 0)
415 return TREE_STRING_POINTER (src);
416 else if (!host_integerp (offset_node, 1)
417 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
418 return 0;
420 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
423 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
424 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
426 static rtx
427 c_readstr (const char *str, enum machine_mode mode)
429 HOST_WIDE_INT c[2];
430 HOST_WIDE_INT ch;
431 unsigned int i, j;
433 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
435 c[0] = 0;
436 c[1] = 0;
437 ch = 1;
438 for (i = 0; i < GET_MODE_SIZE (mode); i++)
440 j = i;
441 if (WORDS_BIG_ENDIAN)
442 j = GET_MODE_SIZE (mode) - i - 1;
443 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
444 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
445 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
446 j *= BITS_PER_UNIT;
447 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
449 if (ch)
450 ch = (unsigned char) str[i];
451 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
453 return immed_double_const (c[0], c[1], mode);
456 /* Cast a target constant CST to target CHAR and if that value fits into
457 host char type, return zero and put that value into variable pointed to by
458 P. */
460 static int
461 target_char_cast (tree cst, char *p)
463 unsigned HOST_WIDE_INT val, hostval;
465 if (!host_integerp (cst, 1)
466 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
467 return 1;
469 val = tree_low_cst (cst, 1);
470 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
471 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
473 hostval = val;
474 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
475 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
477 if (val != hostval)
478 return 1;
480 *p = hostval;
481 return 0;
484 /* Similar to save_expr, but assumes that arbitrary code is not executed
485 in between the multiple evaluations. In particular, we assume that a
486 non-addressable local variable will not be modified. */
488 static tree
489 builtin_save_expr (tree exp)
491 if (TREE_ADDRESSABLE (exp) == 0
492 && (TREE_CODE (exp) == PARM_DECL
493 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
494 return exp;
496 return save_expr (exp);
499 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
500 times to get the address of either a higher stack frame, or a return
501 address located within it (depending on FNDECL_CODE). */
503 static rtx
504 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
506 int i;
508 #ifdef INITIAL_FRAME_ADDRESS_RTX
509 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
510 #else
511 rtx tem;
513 /* For a zero count, we don't care what frame address we return, so frame
514 pointer elimination is OK, and using the soft frame pointer is OK.
515 For a nonzero count, we require a stable offset from the current frame
516 pointer to the previous one, so we must use the hard frame pointer, and
517 we must disable frame pointer elimination. */
518 if (count == 0)
519 tem = frame_pointer_rtx;
520 else
522 tem = hard_frame_pointer_rtx;
524 /* Tell reload not to eliminate the frame pointer. */
525 current_function_accesses_prior_frames = 1;
527 #endif
529 /* Some machines need special handling before we can access
530 arbitrary frames. For example, on the sparc, we must first flush
531 all register windows to the stack. */
532 #ifdef SETUP_FRAME_ADDRESSES
533 if (count > 0)
534 SETUP_FRAME_ADDRESSES ();
535 #endif
537 /* On the sparc, the return address is not in the frame, it is in a
538 register. There is no way to access it off of the current frame
539 pointer, but it can be accessed off the previous frame pointer by
540 reading the value from the register window save area. */
541 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
542 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
543 count--;
544 #endif
546 /* Scan back COUNT frames to the specified frame. */
547 for (i = 0; i < count; i++)
549 /* Assume the dynamic chain pointer is in the word that the
550 frame address points to, unless otherwise specified. */
551 #ifdef DYNAMIC_CHAIN_ADDRESS
552 tem = DYNAMIC_CHAIN_ADDRESS (tem);
553 #endif
554 tem = memory_address (Pmode, tem);
555 tem = gen_frame_mem (Pmode, tem);
556 tem = copy_to_reg (tem);
559 /* For __builtin_frame_address, return what we've got. */
560 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
561 return tem;
563 /* For __builtin_return_address, Get the return address from that
564 frame. */
565 #ifdef RETURN_ADDR_RTX
566 tem = RETURN_ADDR_RTX (count, tem);
567 #else
568 tem = memory_address (Pmode,
569 plus_constant (tem, GET_MODE_SIZE (Pmode)));
570 tem = gen_frame_mem (Pmode, tem);
571 #endif
572 return tem;
575 /* Alias set used for setjmp buffer. */
576 static HOST_WIDE_INT setjmp_alias_set = -1;
578 /* Construct the leading half of a __builtin_setjmp call. Control will
579 return to RECEIVER_LABEL. This is used directly by sjlj exception
580 handling code. */
582 void
583 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
585 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
586 rtx stack_save;
587 rtx mem;
589 if (setjmp_alias_set == -1)
590 setjmp_alias_set = new_alias_set ();
592 buf_addr = convert_memory_address (Pmode, buf_addr);
594 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
596 /* We store the frame pointer and the address of receiver_label in
597 the buffer and use the rest of it for the stack save area, which
598 is machine-dependent. */
600 mem = gen_rtx_MEM (Pmode, buf_addr);
601 set_mem_alias_set (mem, setjmp_alias_set);
602 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
604 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
605 set_mem_alias_set (mem, setjmp_alias_set);
607 emit_move_insn (validize_mem (mem),
608 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
610 stack_save = gen_rtx_MEM (sa_mode,
611 plus_constant (buf_addr,
612 2 * GET_MODE_SIZE (Pmode)));
613 set_mem_alias_set (stack_save, setjmp_alias_set);
614 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
616 /* If there is further processing to do, do it. */
617 #ifdef HAVE_builtin_setjmp_setup
618 if (HAVE_builtin_setjmp_setup)
619 emit_insn (gen_builtin_setjmp_setup (buf_addr));
620 #endif
622 /* Tell optimize_save_area_alloca that extra work is going to
623 need to go on during alloca. */
624 current_function_calls_setjmp = 1;
626 /* Set this so all the registers get saved in our frame; we need to be
627 able to copy the saved values for any registers from frames we unwind. */
628 current_function_has_nonlocal_label = 1;
631 /* Construct the trailing part of a __builtin_setjmp call.
632 This is used directly by sjlj exception handling code. */
634 void
635 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
637 /* Clobber the FP when we get here, so we have to make sure it's
638 marked as used by this function. */
639 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
641 /* Mark the static chain as clobbered here so life information
642 doesn't get messed up for it. */
643 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
645 /* Now put in the code to restore the frame pointer, and argument
646 pointer, if needed. */
647 #ifdef HAVE_nonlocal_goto
648 if (! HAVE_nonlocal_goto)
649 #endif
650 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
652 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
653 if (fixed_regs[ARG_POINTER_REGNUM])
655 #ifdef ELIMINABLE_REGS
656 size_t i;
657 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
659 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
660 if (elim_regs[i].from == ARG_POINTER_REGNUM
661 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
662 break;
664 if (i == ARRAY_SIZE (elim_regs))
665 #endif
667 /* Now restore our arg pointer from the address at which it
668 was saved in our stack frame. */
669 emit_move_insn (virtual_incoming_args_rtx,
670 copy_to_reg (get_arg_pointer_save_area (cfun)));
673 #endif
675 #ifdef HAVE_builtin_setjmp_receiver
676 if (HAVE_builtin_setjmp_receiver)
677 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
678 else
679 #endif
680 #ifdef HAVE_nonlocal_goto_receiver
681 if (HAVE_nonlocal_goto_receiver)
682 emit_insn (gen_nonlocal_goto_receiver ());
683 else
684 #endif
685 { /* Nothing */ }
687 /* @@@ This is a kludge. Not all machine descriptions define a blockage
688 insn, but we must not allow the code we just generated to be reordered
689 by scheduling. Specifically, the update of the frame pointer must
690 happen immediately, not later. So emit an ASM_INPUT to act as blockage
691 insn. */
692 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
695 /* __builtin_setjmp is passed a pointer to an array of five words (not
696 all will be used on all machines). It operates similarly to the C
697 library function of the same name, but is more efficient. Much of
698 the code below (and for longjmp) is copied from the handling of
699 non-local gotos.
701 NOTE: This is intended for use by GNAT and the exception handling
702 scheme in the compiler and will only work in the method used by
703 them. */
705 static rtx
706 expand_builtin_setjmp (tree arglist, rtx target)
708 rtx buf_addr, next_lab, cont_lab;
710 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
711 return NULL_RTX;
713 if (target == 0 || !REG_P (target)
714 || REGNO (target) < FIRST_PSEUDO_REGISTER)
715 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
717 buf_addr = expand_normal (TREE_VALUE (arglist));
719 next_lab = gen_label_rtx ();
720 cont_lab = gen_label_rtx ();
722 expand_builtin_setjmp_setup (buf_addr, next_lab);
724 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
725 ensure that pending stack adjustments are flushed. */
726 emit_move_insn (target, const0_rtx);
727 emit_jump (cont_lab);
729 emit_label (next_lab);
731 expand_builtin_setjmp_receiver (next_lab);
733 /* Set TARGET to one. */
734 emit_move_insn (target, const1_rtx);
735 emit_label (cont_lab);
737 /* Tell flow about the strange goings on. Putting `next_lab' on
738 `nonlocal_goto_handler_labels' to indicates that function
739 calls may traverse the arc back to this label. */
741 current_function_has_nonlocal_label = 1;
742 nonlocal_goto_handler_labels
743 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
745 return target;
748 /* __builtin_longjmp is passed a pointer to an array of five words (not
749 all will be used on all machines). It operates similarly to the C
750 library function of the same name, but is more efficient. Much of
751 the code below is copied from the handling of non-local gotos.
753 NOTE: This is intended for use by GNAT and the exception handling
754 scheme in the compiler and will only work in the method used by
755 them. */
757 static void
758 expand_builtin_longjmp (rtx buf_addr, rtx value)
760 rtx fp, lab, stack, insn, last;
761 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
763 if (setjmp_alias_set == -1)
764 setjmp_alias_set = new_alias_set ();
766 buf_addr = convert_memory_address (Pmode, buf_addr);
768 buf_addr = force_reg (Pmode, buf_addr);
770 /* We used to store value in static_chain_rtx, but that fails if pointers
771 are smaller than integers. We instead require that the user must pass
772 a second argument of 1, because that is what builtin_setjmp will
773 return. This also makes EH slightly more efficient, since we are no
774 longer copying around a value that we don't care about. */
775 gcc_assert (value == const1_rtx);
777 last = get_last_insn ();
778 #ifdef HAVE_builtin_longjmp
779 if (HAVE_builtin_longjmp)
780 emit_insn (gen_builtin_longjmp (buf_addr));
781 else
782 #endif
784 fp = gen_rtx_MEM (Pmode, buf_addr);
785 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
786 GET_MODE_SIZE (Pmode)));
788 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
789 2 * GET_MODE_SIZE (Pmode)));
790 set_mem_alias_set (fp, setjmp_alias_set);
791 set_mem_alias_set (lab, setjmp_alias_set);
792 set_mem_alias_set (stack, setjmp_alias_set);
794 /* Pick up FP, label, and SP from the block and jump. This code is
795 from expand_goto in stmt.c; see there for detailed comments. */
796 #ifdef HAVE_nonlocal_goto
797 if (HAVE_nonlocal_goto)
798 /* We have to pass a value to the nonlocal_goto pattern that will
799 get copied into the static_chain pointer, but it does not matter
800 what that value is, because builtin_setjmp does not use it. */
801 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
802 else
803 #endif
805 lab = copy_to_reg (lab);
807 emit_insn (gen_rtx_CLOBBER (VOIDmode,
808 gen_rtx_MEM (BLKmode,
809 gen_rtx_SCRATCH (VOIDmode))));
810 emit_insn (gen_rtx_CLOBBER (VOIDmode,
811 gen_rtx_MEM (BLKmode,
812 hard_frame_pointer_rtx)));
814 emit_move_insn (hard_frame_pointer_rtx, fp);
815 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
817 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
818 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
819 emit_indirect_jump (lab);
823 /* Search backwards and mark the jump insn as a non-local goto.
824 Note that this precludes the use of __builtin_longjmp to a
825 __builtin_setjmp target in the same function. However, we've
826 already cautioned the user that these functions are for
827 internal exception handling use only. */
828 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
830 gcc_assert (insn != last);
832 if (JUMP_P (insn))
834 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
835 REG_NOTES (insn));
836 break;
838 else if (CALL_P (insn))
839 break;
843 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
844 and the address of the save area. */
846 static rtx
847 expand_builtin_nonlocal_goto (tree arglist)
849 tree t_label, t_save_area;
850 rtx r_label, r_save_area, r_fp, r_sp, insn;
852 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
853 return NULL_RTX;
855 t_label = TREE_VALUE (arglist);
856 arglist = TREE_CHAIN (arglist);
857 t_save_area = TREE_VALUE (arglist);
859 r_label = expand_normal (t_label);
860 r_label = convert_memory_address (Pmode, r_label);
861 r_save_area = expand_normal (t_save_area);
862 r_save_area = convert_memory_address (Pmode, r_save_area);
863 r_fp = gen_rtx_MEM (Pmode, r_save_area);
864 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
865 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
867 current_function_has_nonlocal_goto = 1;
869 #ifdef HAVE_nonlocal_goto
870 /* ??? We no longer need to pass the static chain value, afaik. */
871 if (HAVE_nonlocal_goto)
872 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
873 else
874 #endif
876 r_label = copy_to_reg (r_label);
878 emit_insn (gen_rtx_CLOBBER (VOIDmode,
879 gen_rtx_MEM (BLKmode,
880 gen_rtx_SCRATCH (VOIDmode))));
882 emit_insn (gen_rtx_CLOBBER (VOIDmode,
883 gen_rtx_MEM (BLKmode,
884 hard_frame_pointer_rtx)));
886 /* Restore frame pointer for containing function.
887 This sets the actual hard register used for the frame pointer
888 to the location of the function's incoming static chain info.
889 The non-local goto handler will then adjust it to contain the
890 proper value and reload the argument pointer, if needed. */
891 emit_move_insn (hard_frame_pointer_rtx, r_fp);
892 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
894 /* USE of hard_frame_pointer_rtx added for consistency;
895 not clear if really needed. */
896 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
897 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
898 emit_indirect_jump (r_label);
901 /* Search backwards to the jump insn and mark it as a
902 non-local goto. */
903 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
905 if (JUMP_P (insn))
907 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
908 const0_rtx, REG_NOTES (insn));
909 break;
911 else if (CALL_P (insn))
912 break;
915 return const0_rtx;
918 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
919 (not all will be used on all machines) that was passed to __builtin_setjmp.
920 It updates the stack pointer in that block to correspond to the current
921 stack pointer. */
923 static void
924 expand_builtin_update_setjmp_buf (rtx buf_addr)
926 enum machine_mode sa_mode = Pmode;
927 rtx stack_save;
930 #ifdef HAVE_save_stack_nonlocal
931 if (HAVE_save_stack_nonlocal)
932 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
933 #endif
934 #ifdef STACK_SAVEAREA_MODE
935 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
936 #endif
938 stack_save
939 = gen_rtx_MEM (sa_mode,
940 memory_address
941 (sa_mode,
942 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
944 #ifdef HAVE_setjmp
945 if (HAVE_setjmp)
946 emit_insn (gen_setjmp ());
947 #endif
949 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
952 /* Expand a call to __builtin_prefetch. For a target that does not support
953 data prefetch, evaluate the memory address argument in case it has side
954 effects. */
956 static void
957 expand_builtin_prefetch (tree arglist)
959 tree arg0, arg1, arg2;
960 rtx op0, op1, op2;
962 if (!validate_arglist (arglist, POINTER_TYPE, 0))
963 return;
965 arg0 = TREE_VALUE (arglist);
966 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
967 zero (read) and argument 2 (locality) defaults to 3 (high degree of
968 locality). */
969 if (TREE_CHAIN (arglist))
971 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
972 if (TREE_CHAIN (TREE_CHAIN (arglist)))
973 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
974 else
975 arg2 = build_int_cst (NULL_TREE, 3);
977 else
979 arg1 = integer_zero_node;
980 arg2 = build_int_cst (NULL_TREE, 3);
983 /* Argument 0 is an address. */
984 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
986 /* Argument 1 (read/write flag) must be a compile-time constant int. */
987 if (TREE_CODE (arg1) != INTEGER_CST)
989 error ("second argument to %<__builtin_prefetch%> must be a constant");
990 arg1 = integer_zero_node;
992 op1 = expand_normal (arg1);
993 /* Argument 1 must be either zero or one. */
994 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
996 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
997 " using zero");
998 op1 = const0_rtx;
1001 /* Argument 2 (locality) must be a compile-time constant int. */
1002 if (TREE_CODE (arg2) != INTEGER_CST)
1004 error ("third argument to %<__builtin_prefetch%> must be a constant");
1005 arg2 = integer_zero_node;
1007 op2 = expand_normal (arg2);
1008 /* Argument 2 must be 0, 1, 2, or 3. */
1009 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1011 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1012 op2 = const0_rtx;
1015 #ifdef HAVE_prefetch
1016 if (HAVE_prefetch)
1018 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1019 (op0,
1020 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1021 || (GET_MODE (op0) != Pmode))
1023 op0 = convert_memory_address (Pmode, op0);
1024 op0 = force_reg (Pmode, op0);
1026 emit_insn (gen_prefetch (op0, op1, op2));
1028 #endif
1030 /* Don't do anything with direct references to volatile memory, but
1031 generate code to handle other side effects. */
1032 if (!MEM_P (op0) && side_effects_p (op0))
1033 emit_insn (op0);
1036 /* Get a MEM rtx for expression EXP which is the address of an operand
1037 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1038 the maximum length of the block of memory that might be accessed or
1039 NULL if unknown. */
1041 static rtx
1042 get_memory_rtx (tree exp, tree len)
1044 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1045 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1047 /* Get an expression we can use to find the attributes to assign to MEM.
1048 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1049 we can. First remove any nops. */
1050 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1051 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1052 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1053 exp = TREE_OPERAND (exp, 0);
1055 if (TREE_CODE (exp) == ADDR_EXPR)
1056 exp = TREE_OPERAND (exp, 0);
1057 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1058 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1059 else
1060 exp = NULL;
1062 /* Honor attributes derived from exp, except for the alias set
1063 (as builtin stringops may alias with anything) and the size
1064 (as stringops may access multiple array elements). */
1065 if (exp)
1067 set_mem_attributes (mem, exp, 0);
1069 /* Allow the string and memory builtins to overflow from one
1070 field into another, see http://gcc.gnu.org/PR23561.
1071 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1072 memory accessed by the string or memory builtin will fit
1073 within the field. */
1074 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1076 tree mem_expr = MEM_EXPR (mem);
1077 HOST_WIDE_INT offset = -1, length = -1;
1078 tree inner = exp;
1080 while (TREE_CODE (inner) == ARRAY_REF
1081 || TREE_CODE (inner) == NOP_EXPR
1082 || TREE_CODE (inner) == CONVERT_EXPR
1083 || TREE_CODE (inner) == NON_LVALUE_EXPR
1084 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1085 || TREE_CODE (inner) == SAVE_EXPR)
1086 inner = TREE_OPERAND (inner, 0);
1088 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1090 if (MEM_OFFSET (mem)
1091 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1092 offset = INTVAL (MEM_OFFSET (mem));
1094 if (offset >= 0 && len && host_integerp (len, 0))
1095 length = tree_low_cst (len, 0);
1097 while (TREE_CODE (inner) == COMPONENT_REF)
1099 tree field = TREE_OPERAND (inner, 1);
1100 gcc_assert (! DECL_BIT_FIELD (field));
1101 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1102 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1104 if (length >= 0
1105 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1106 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1108 HOST_WIDE_INT size
1109 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1110 /* If we can prove the memory starting at XEXP (mem, 0)
1111 and ending at XEXP (mem, 0) + LENGTH will fit into
1112 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1113 if (offset <= size
1114 && length <= size
1115 && offset + length <= size)
1116 break;
1119 if (offset >= 0
1120 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1121 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1122 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1123 / BITS_PER_UNIT;
1124 else
1126 offset = -1;
1127 length = -1;
1130 mem_expr = TREE_OPERAND (mem_expr, 0);
1131 inner = TREE_OPERAND (inner, 0);
1134 if (mem_expr == NULL)
1135 offset = -1;
1136 if (mem_expr != MEM_EXPR (mem))
1138 set_mem_expr (mem, mem_expr);
1139 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1142 set_mem_alias_set (mem, 0);
1143 set_mem_size (mem, NULL_RTX);
1146 return mem;
1149 /* Built-in functions to perform an untyped call and return. */
1151 /* For each register that may be used for calling a function, this
1152 gives a mode used to copy the register's value. VOIDmode indicates
1153 the register is not used for calling a function. If the machine
1154 has register windows, this gives only the outbound registers.
1155 INCOMING_REGNO gives the corresponding inbound register. */
1156 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1158 /* For each register that may be used for returning values, this gives
1159 a mode used to copy the register's value. VOIDmode indicates the
1160 register is not used for returning values. If the machine has
1161 register windows, this gives only the outbound registers.
1162 INCOMING_REGNO gives the corresponding inbound register. */
1163 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1165 /* For each register that may be used for calling a function, this
1166 gives the offset of that register into the block returned by
1167 __builtin_apply_args. 0 indicates that the register is not
1168 used for calling a function. */
1169 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1171 /* Return the size required for the block returned by __builtin_apply_args,
1172 and initialize apply_args_mode. */
1174 static int
1175 apply_args_size (void)
1177 static int size = -1;
1178 int align;
1179 unsigned int regno;
1180 enum machine_mode mode;
1182 /* The values computed by this function never change. */
1183 if (size < 0)
1185 /* The first value is the incoming arg-pointer. */
1186 size = GET_MODE_SIZE (Pmode);
1188 /* The second value is the structure value address unless this is
1189 passed as an "invisible" first argument. */
1190 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1191 size += GET_MODE_SIZE (Pmode);
1193 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1194 if (FUNCTION_ARG_REGNO_P (regno))
1196 mode = reg_raw_mode[regno];
1198 gcc_assert (mode != VOIDmode);
1200 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1201 if (size % align != 0)
1202 size = CEIL (size, align) * align;
1203 apply_args_reg_offset[regno] = size;
1204 size += GET_MODE_SIZE (mode);
1205 apply_args_mode[regno] = mode;
1207 else
1209 apply_args_mode[regno] = VOIDmode;
1210 apply_args_reg_offset[regno] = 0;
1213 return size;
1216 /* Return the size required for the block returned by __builtin_apply,
1217 and initialize apply_result_mode. */
1219 static int
1220 apply_result_size (void)
1222 static int size = -1;
1223 int align, regno;
1224 enum machine_mode mode;
1226 /* The values computed by this function never change. */
1227 if (size < 0)
1229 size = 0;
1231 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1232 if (FUNCTION_VALUE_REGNO_P (regno))
1234 mode = reg_raw_mode[regno];
1236 gcc_assert (mode != VOIDmode);
1238 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1239 if (size % align != 0)
1240 size = CEIL (size, align) * align;
1241 size += GET_MODE_SIZE (mode);
1242 apply_result_mode[regno] = mode;
1244 else
1245 apply_result_mode[regno] = VOIDmode;
1247 /* Allow targets that use untyped_call and untyped_return to override
1248 the size so that machine-specific information can be stored here. */
1249 #ifdef APPLY_RESULT_SIZE
1250 size = APPLY_RESULT_SIZE;
1251 #endif
1253 return size;
1256 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1257 /* Create a vector describing the result block RESULT. If SAVEP is true,
1258 the result block is used to save the values; otherwise it is used to
1259 restore the values. */
1261 static rtx
1262 result_vector (int savep, rtx result)
1264 int regno, size, align, nelts;
1265 enum machine_mode mode;
1266 rtx reg, mem;
1267 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1269 size = nelts = 0;
1270 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1271 if ((mode = apply_result_mode[regno]) != VOIDmode)
1273 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1274 if (size % align != 0)
1275 size = CEIL (size, align) * align;
1276 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1277 mem = adjust_address (result, mode, size);
1278 savevec[nelts++] = (savep
1279 ? gen_rtx_SET (VOIDmode, mem, reg)
1280 : gen_rtx_SET (VOIDmode, reg, mem));
1281 size += GET_MODE_SIZE (mode);
1283 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1285 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1287 /* Save the state required to perform an untyped call with the same
1288 arguments as were passed to the current function. */
1290 static rtx
1291 expand_builtin_apply_args_1 (void)
1293 rtx registers, tem;
1294 int size, align, regno;
1295 enum machine_mode mode;
1296 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1298 /* Create a block where the arg-pointer, structure value address,
1299 and argument registers can be saved. */
1300 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1302 /* Walk past the arg-pointer and structure value address. */
1303 size = GET_MODE_SIZE (Pmode);
1304 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1305 size += GET_MODE_SIZE (Pmode);
1307 /* Save each register used in calling a function to the block. */
1308 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1309 if ((mode = apply_args_mode[regno]) != VOIDmode)
1311 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1312 if (size % align != 0)
1313 size = CEIL (size, align) * align;
1315 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1317 emit_move_insn (adjust_address (registers, mode, size), tem);
1318 size += GET_MODE_SIZE (mode);
1321 /* Save the arg pointer to the block. */
1322 tem = copy_to_reg (virtual_incoming_args_rtx);
1323 #ifdef STACK_GROWS_DOWNWARD
1324 /* We need the pointer as the caller actually passed them to us, not
1325 as we might have pretended they were passed. Make sure it's a valid
1326 operand, as emit_move_insn isn't expected to handle a PLUS. */
1328 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1329 NULL_RTX);
1330 #endif
1331 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1333 size = GET_MODE_SIZE (Pmode);
1335 /* Save the structure value address unless this is passed as an
1336 "invisible" first argument. */
1337 if (struct_incoming_value)
1339 emit_move_insn (adjust_address (registers, Pmode, size),
1340 copy_to_reg (struct_incoming_value));
1341 size += GET_MODE_SIZE (Pmode);
1344 /* Return the address of the block. */
1345 return copy_addr_to_reg (XEXP (registers, 0));
1348 /* __builtin_apply_args returns block of memory allocated on
1349 the stack into which is stored the arg pointer, structure
1350 value address, static chain, and all the registers that might
1351 possibly be used in performing a function call. The code is
1352 moved to the start of the function so the incoming values are
1353 saved. */
1355 static rtx
1356 expand_builtin_apply_args (void)
1358 /* Don't do __builtin_apply_args more than once in a function.
1359 Save the result of the first call and reuse it. */
1360 if (apply_args_value != 0)
1361 return apply_args_value;
1363 /* When this function is called, it means that registers must be
1364 saved on entry to this function. So we migrate the
1365 call to the first insn of this function. */
1366 rtx temp;
1367 rtx seq;
1369 start_sequence ();
1370 temp = expand_builtin_apply_args_1 ();
1371 seq = get_insns ();
1372 end_sequence ();
1374 apply_args_value = temp;
1376 /* Put the insns after the NOTE that starts the function.
1377 If this is inside a start_sequence, make the outer-level insn
1378 chain current, so the code is placed at the start of the
1379 function. */
1380 push_topmost_sequence ();
1381 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1382 pop_topmost_sequence ();
1383 return temp;
1387 /* Perform an untyped call and save the state required to perform an
1388 untyped return of whatever value was returned by the given function. */
1390 static rtx
1391 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1393 int size, align, regno;
1394 enum machine_mode mode;
1395 rtx incoming_args, result, reg, dest, src, call_insn;
1396 rtx old_stack_level = 0;
1397 rtx call_fusage = 0;
1398 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1400 arguments = convert_memory_address (Pmode, arguments);
1402 /* Create a block where the return registers can be saved. */
1403 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1405 /* Fetch the arg pointer from the ARGUMENTS block. */
1406 incoming_args = gen_reg_rtx (Pmode);
1407 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1408 #ifndef STACK_GROWS_DOWNWARD
1409 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1410 incoming_args, 0, OPTAB_LIB_WIDEN);
1411 #endif
1413 /* Push a new argument block and copy the arguments. Do not allow
1414 the (potential) memcpy call below to interfere with our stack
1415 manipulations. */
1416 do_pending_stack_adjust ();
1417 NO_DEFER_POP;
1419 /* Save the stack with nonlocal if available. */
1420 #ifdef HAVE_save_stack_nonlocal
1421 if (HAVE_save_stack_nonlocal)
1422 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1423 else
1424 #endif
1425 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1427 /* Allocate a block of memory onto the stack and copy the memory
1428 arguments to the outgoing arguments address. */
1429 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1430 dest = virtual_outgoing_args_rtx;
1431 #ifndef STACK_GROWS_DOWNWARD
1432 if (GET_CODE (argsize) == CONST_INT)
1433 dest = plus_constant (dest, -INTVAL (argsize));
1434 else
1435 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1436 #endif
1437 dest = gen_rtx_MEM (BLKmode, dest);
1438 set_mem_align (dest, PARM_BOUNDARY);
1439 src = gen_rtx_MEM (BLKmode, incoming_args);
1440 set_mem_align (src, PARM_BOUNDARY);
1441 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1443 /* Refer to the argument block. */
1444 apply_args_size ();
1445 arguments = gen_rtx_MEM (BLKmode, arguments);
1446 set_mem_align (arguments, PARM_BOUNDARY);
1448 /* Walk past the arg-pointer and structure value address. */
1449 size = GET_MODE_SIZE (Pmode);
1450 if (struct_value)
1451 size += GET_MODE_SIZE (Pmode);
1453 /* Restore each of the registers previously saved. Make USE insns
1454 for each of these registers for use in making the call. */
1455 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1456 if ((mode = apply_args_mode[regno]) != VOIDmode)
1458 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1459 if (size % align != 0)
1460 size = CEIL (size, align) * align;
1461 reg = gen_rtx_REG (mode, regno);
1462 emit_move_insn (reg, adjust_address (arguments, mode, size));
1463 use_reg (&call_fusage, reg);
1464 size += GET_MODE_SIZE (mode);
1467 /* Restore the structure value address unless this is passed as an
1468 "invisible" first argument. */
1469 size = GET_MODE_SIZE (Pmode);
1470 if (struct_value)
1472 rtx value = gen_reg_rtx (Pmode);
1473 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1474 emit_move_insn (struct_value, value);
1475 if (REG_P (struct_value))
1476 use_reg (&call_fusage, struct_value);
1477 size += GET_MODE_SIZE (Pmode);
1480 /* All arguments and registers used for the call are set up by now! */
1481 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1483 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1484 and we don't want to load it into a register as an optimization,
1485 because prepare_call_address already did it if it should be done. */
1486 if (GET_CODE (function) != SYMBOL_REF)
1487 function = memory_address (FUNCTION_MODE, function);
1489 /* Generate the actual call instruction and save the return value. */
1490 #ifdef HAVE_untyped_call
1491 if (HAVE_untyped_call)
1492 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1493 result, result_vector (1, result)));
1494 else
1495 #endif
1496 #ifdef HAVE_call_value
1497 if (HAVE_call_value)
1499 rtx valreg = 0;
1501 /* Locate the unique return register. It is not possible to
1502 express a call that sets more than one return register using
1503 call_value; use untyped_call for that. In fact, untyped_call
1504 only needs to save the return registers in the given block. */
1505 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1506 if ((mode = apply_result_mode[regno]) != VOIDmode)
1508 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1510 valreg = gen_rtx_REG (mode, regno);
1513 emit_call_insn (GEN_CALL_VALUE (valreg,
1514 gen_rtx_MEM (FUNCTION_MODE, function),
1515 const0_rtx, NULL_RTX, const0_rtx));
1517 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1519 else
1520 #endif
1521 gcc_unreachable ();
1523 /* Find the CALL insn we just emitted, and attach the register usage
1524 information. */
1525 call_insn = last_call_insn ();
1526 add_function_usage_to (call_insn, call_fusage);
1528 /* Restore the stack. */
1529 #ifdef HAVE_save_stack_nonlocal
1530 if (HAVE_save_stack_nonlocal)
1531 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1532 else
1533 #endif
1534 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1536 OK_DEFER_POP;
1538 /* Return the address of the result block. */
1539 result = copy_addr_to_reg (XEXP (result, 0));
1540 return convert_memory_address (ptr_mode, result);
1543 /* Perform an untyped return. */
1545 static void
1546 expand_builtin_return (rtx result)
1548 int size, align, regno;
1549 enum machine_mode mode;
1550 rtx reg;
1551 rtx call_fusage = 0;
1553 result = convert_memory_address (Pmode, result);
1555 apply_result_size ();
1556 result = gen_rtx_MEM (BLKmode, result);
1558 #ifdef HAVE_untyped_return
1559 if (HAVE_untyped_return)
1561 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1562 emit_barrier ();
1563 return;
1565 #endif
1567 /* Restore the return value and note that each value is used. */
1568 size = 0;
1569 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1570 if ((mode = apply_result_mode[regno]) != VOIDmode)
1572 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1573 if (size % align != 0)
1574 size = CEIL (size, align) * align;
1575 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1576 emit_move_insn (reg, adjust_address (result, mode, size));
1578 push_to_sequence (call_fusage);
1579 emit_insn (gen_rtx_USE (VOIDmode, reg));
1580 call_fusage = get_insns ();
1581 end_sequence ();
1582 size += GET_MODE_SIZE (mode);
1585 /* Put the USE insns before the return. */
1586 emit_insn (call_fusage);
1588 /* Return whatever values was restored by jumping directly to the end
1589 of the function. */
1590 expand_naked_return ();
1593 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1595 static enum type_class
1596 type_to_class (tree type)
1598 switch (TREE_CODE (type))
1600 case VOID_TYPE: return void_type_class;
1601 case INTEGER_TYPE: return integer_type_class;
1602 case ENUMERAL_TYPE: return enumeral_type_class;
1603 case BOOLEAN_TYPE: return boolean_type_class;
1604 case POINTER_TYPE: return pointer_type_class;
1605 case REFERENCE_TYPE: return reference_type_class;
1606 case OFFSET_TYPE: return offset_type_class;
1607 case REAL_TYPE: return real_type_class;
1608 case COMPLEX_TYPE: return complex_type_class;
1609 case FUNCTION_TYPE: return function_type_class;
1610 case METHOD_TYPE: return method_type_class;
1611 case RECORD_TYPE: return record_type_class;
1612 case UNION_TYPE:
1613 case QUAL_UNION_TYPE: return union_type_class;
1614 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1615 ? string_type_class : array_type_class);
1616 case LANG_TYPE: return lang_type_class;
1617 default: return no_type_class;
1621 /* Expand a call to __builtin_classify_type with arguments found in
1622 ARGLIST. */
1624 static rtx
1625 expand_builtin_classify_type (tree arglist)
1627 if (arglist != 0)
1628 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1629 return GEN_INT (no_type_class);
1632 /* This helper macro, meant to be used in mathfn_built_in below,
1633 determines which among a set of three builtin math functions is
1634 appropriate for a given type mode. The `F' and `L' cases are
1635 automatically generated from the `double' case. */
1636 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1637 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1638 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1639 fcodel = BUILT_IN_MATHFN##L ; break;
1641 /* Return mathematic function equivalent to FN but operating directly
1642 on TYPE, if available. If we can't do the conversion, return zero. */
1643 tree
1644 mathfn_built_in (tree type, enum built_in_function fn)
1646 enum built_in_function fcode, fcodef, fcodel;
1648 switch (fn)
1650 CASE_MATHFN (BUILT_IN_ACOS)
1651 CASE_MATHFN (BUILT_IN_ACOSH)
1652 CASE_MATHFN (BUILT_IN_ASIN)
1653 CASE_MATHFN (BUILT_IN_ASINH)
1654 CASE_MATHFN (BUILT_IN_ATAN)
1655 CASE_MATHFN (BUILT_IN_ATAN2)
1656 CASE_MATHFN (BUILT_IN_ATANH)
1657 CASE_MATHFN (BUILT_IN_CBRT)
1658 CASE_MATHFN (BUILT_IN_CEIL)
1659 CASE_MATHFN (BUILT_IN_COPYSIGN)
1660 CASE_MATHFN (BUILT_IN_COS)
1661 CASE_MATHFN (BUILT_IN_COSH)
1662 CASE_MATHFN (BUILT_IN_DREM)
1663 CASE_MATHFN (BUILT_IN_ERF)
1664 CASE_MATHFN (BUILT_IN_ERFC)
1665 CASE_MATHFN (BUILT_IN_EXP)
1666 CASE_MATHFN (BUILT_IN_EXP10)
1667 CASE_MATHFN (BUILT_IN_EXP2)
1668 CASE_MATHFN (BUILT_IN_EXPM1)
1669 CASE_MATHFN (BUILT_IN_FABS)
1670 CASE_MATHFN (BUILT_IN_FDIM)
1671 CASE_MATHFN (BUILT_IN_FLOOR)
1672 CASE_MATHFN (BUILT_IN_FMA)
1673 CASE_MATHFN (BUILT_IN_FMAX)
1674 CASE_MATHFN (BUILT_IN_FMIN)
1675 CASE_MATHFN (BUILT_IN_FMOD)
1676 CASE_MATHFN (BUILT_IN_FREXP)
1677 CASE_MATHFN (BUILT_IN_GAMMA)
1678 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1679 CASE_MATHFN (BUILT_IN_HYPOT)
1680 CASE_MATHFN (BUILT_IN_ILOGB)
1681 CASE_MATHFN (BUILT_IN_INF)
1682 CASE_MATHFN (BUILT_IN_J0)
1683 CASE_MATHFN (BUILT_IN_J1)
1684 CASE_MATHFN (BUILT_IN_JN)
1685 CASE_MATHFN (BUILT_IN_LCEIL)
1686 CASE_MATHFN (BUILT_IN_LDEXP)
1687 CASE_MATHFN (BUILT_IN_LFLOOR)
1688 CASE_MATHFN (BUILT_IN_LGAMMA)
1689 CASE_MATHFN (BUILT_IN_LLCEIL)
1690 CASE_MATHFN (BUILT_IN_LLFLOOR)
1691 CASE_MATHFN (BUILT_IN_LLRINT)
1692 CASE_MATHFN (BUILT_IN_LLROUND)
1693 CASE_MATHFN (BUILT_IN_LOG)
1694 CASE_MATHFN (BUILT_IN_LOG10)
1695 CASE_MATHFN (BUILT_IN_LOG1P)
1696 CASE_MATHFN (BUILT_IN_LOG2)
1697 CASE_MATHFN (BUILT_IN_LOGB)
1698 CASE_MATHFN (BUILT_IN_LRINT)
1699 CASE_MATHFN (BUILT_IN_LROUND)
1700 CASE_MATHFN (BUILT_IN_MODF)
1701 CASE_MATHFN (BUILT_IN_NAN)
1702 CASE_MATHFN (BUILT_IN_NANS)
1703 CASE_MATHFN (BUILT_IN_NEARBYINT)
1704 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1705 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1706 CASE_MATHFN (BUILT_IN_POW)
1707 CASE_MATHFN (BUILT_IN_POWI)
1708 CASE_MATHFN (BUILT_IN_POW10)
1709 CASE_MATHFN (BUILT_IN_REMAINDER)
1710 CASE_MATHFN (BUILT_IN_REMQUO)
1711 CASE_MATHFN (BUILT_IN_RINT)
1712 CASE_MATHFN (BUILT_IN_ROUND)
1713 CASE_MATHFN (BUILT_IN_SCALB)
1714 CASE_MATHFN (BUILT_IN_SCALBLN)
1715 CASE_MATHFN (BUILT_IN_SCALBN)
1716 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1717 CASE_MATHFN (BUILT_IN_SIN)
1718 CASE_MATHFN (BUILT_IN_SINCOS)
1719 CASE_MATHFN (BUILT_IN_SINH)
1720 CASE_MATHFN (BUILT_IN_SQRT)
1721 CASE_MATHFN (BUILT_IN_TAN)
1722 CASE_MATHFN (BUILT_IN_TANH)
1723 CASE_MATHFN (BUILT_IN_TGAMMA)
1724 CASE_MATHFN (BUILT_IN_TRUNC)
1725 CASE_MATHFN (BUILT_IN_Y0)
1726 CASE_MATHFN (BUILT_IN_Y1)
1727 CASE_MATHFN (BUILT_IN_YN)
1729 default:
1730 return 0;
1733 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1734 return implicit_built_in_decls[fcode];
1735 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1736 return implicit_built_in_decls[fcodef];
1737 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1738 return implicit_built_in_decls[fcodel];
1739 else
1740 return 0;
1743 /* If errno must be maintained, expand the RTL to check if the result,
1744 TARGET, of a built-in function call, EXP, is NaN, and if so set
1745 errno to EDOM. */
1747 static void
1748 expand_errno_check (tree exp, rtx target)
1750 rtx lab = gen_label_rtx ();
1752 /* Test the result; if it is NaN, set errno=EDOM because
1753 the argument was not in the domain. */
1754 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1755 0, lab);
1757 #ifdef TARGET_EDOM
1758 /* If this built-in doesn't throw an exception, set errno directly. */
1759 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1761 #ifdef GEN_ERRNO_RTX
1762 rtx errno_rtx = GEN_ERRNO_RTX;
1763 #else
1764 rtx errno_rtx
1765 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1766 #endif
1767 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1768 emit_label (lab);
1769 return;
1771 #endif
1773 /* We can't set errno=EDOM directly; let the library call do it.
1774 Pop the arguments right away in case the call gets deleted. */
1775 NO_DEFER_POP;
1776 expand_call (exp, target, 0);
1777 OK_DEFER_POP;
1778 emit_label (lab);
1782 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1783 Return 0 if a normal call should be emitted rather than expanding the
1784 function in-line. EXP is the expression that is a call to the builtin
1785 function; if convenient, the result should be placed in TARGET.
1786 SUBTARGET may be used as the target for computing one of EXP's operands. */
1788 static rtx
1789 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1791 optab builtin_optab;
1792 rtx op0, insns, before_call;
1793 tree fndecl = get_callee_fndecl (exp);
1794 tree arglist = TREE_OPERAND (exp, 1);
1795 enum machine_mode mode;
1796 bool errno_set = false;
1797 tree arg, narg;
1799 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1800 return 0;
1802 arg = TREE_VALUE (arglist);
1804 switch (DECL_FUNCTION_CODE (fndecl))
1806 CASE_FLT_FN (BUILT_IN_SQRT):
1807 errno_set = ! tree_expr_nonnegative_p (arg);
1808 builtin_optab = sqrt_optab;
1809 break;
1810 CASE_FLT_FN (BUILT_IN_EXP):
1811 errno_set = true; builtin_optab = exp_optab; break;
1812 CASE_FLT_FN (BUILT_IN_EXP10):
1813 CASE_FLT_FN (BUILT_IN_POW10):
1814 errno_set = true; builtin_optab = exp10_optab; break;
1815 CASE_FLT_FN (BUILT_IN_EXP2):
1816 errno_set = true; builtin_optab = exp2_optab; break;
1817 CASE_FLT_FN (BUILT_IN_EXPM1):
1818 errno_set = true; builtin_optab = expm1_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOGB):
1820 errno_set = true; builtin_optab = logb_optab; break;
1821 CASE_FLT_FN (BUILT_IN_ILOGB):
1822 errno_set = true; builtin_optab = ilogb_optab; break;
1823 CASE_FLT_FN (BUILT_IN_LOG):
1824 errno_set = true; builtin_optab = log_optab; break;
1825 CASE_FLT_FN (BUILT_IN_LOG10):
1826 errno_set = true; builtin_optab = log10_optab; break;
1827 CASE_FLT_FN (BUILT_IN_LOG2):
1828 errno_set = true; builtin_optab = log2_optab; break;
1829 CASE_FLT_FN (BUILT_IN_LOG1P):
1830 errno_set = true; builtin_optab = log1p_optab; break;
1831 CASE_FLT_FN (BUILT_IN_ASIN):
1832 builtin_optab = asin_optab; break;
1833 CASE_FLT_FN (BUILT_IN_ACOS):
1834 builtin_optab = acos_optab; break;
1835 CASE_FLT_FN (BUILT_IN_TAN):
1836 builtin_optab = tan_optab; break;
1837 CASE_FLT_FN (BUILT_IN_ATAN):
1838 builtin_optab = atan_optab; break;
1839 CASE_FLT_FN (BUILT_IN_FLOOR):
1840 builtin_optab = floor_optab; break;
1841 CASE_FLT_FN (BUILT_IN_CEIL):
1842 builtin_optab = ceil_optab; break;
1843 CASE_FLT_FN (BUILT_IN_TRUNC):
1844 builtin_optab = btrunc_optab; break;
1845 CASE_FLT_FN (BUILT_IN_ROUND):
1846 builtin_optab = round_optab; break;
1847 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1848 builtin_optab = nearbyint_optab; break;
1849 CASE_FLT_FN (BUILT_IN_RINT):
1850 builtin_optab = rint_optab; break;
1851 CASE_FLT_FN (BUILT_IN_LRINT):
1852 CASE_FLT_FN (BUILT_IN_LLRINT):
1853 builtin_optab = lrint_optab; break;
1854 default:
1855 gcc_unreachable ();
1858 /* Make a suitable register to place result in. */
1859 mode = TYPE_MODE (TREE_TYPE (exp));
1861 if (! flag_errno_math || ! HONOR_NANS (mode))
1862 errno_set = false;
1864 /* Before working hard, check whether the instruction is available. */
1865 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1867 target = gen_reg_rtx (mode);
1869 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1870 need to expand the argument again. This way, we will not perform
1871 side-effects more the once. */
1872 narg = builtin_save_expr (arg);
1873 if (narg != arg)
1875 arg = narg;
1876 arglist = build_tree_list (NULL_TREE, arg);
1877 exp = build_function_call_expr (fndecl, arglist);
1880 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1882 start_sequence ();
1884 /* Compute into TARGET.
1885 Set TARGET to wherever the result comes back. */
1886 target = expand_unop (mode, builtin_optab, op0, target, 0);
1888 if (target != 0)
1890 if (errno_set)
1891 expand_errno_check (exp, target);
1893 /* Output the entire sequence. */
1894 insns = get_insns ();
1895 end_sequence ();
1896 emit_insn (insns);
1897 return target;
1900 /* If we were unable to expand via the builtin, stop the sequence
1901 (without outputting the insns) and call to the library function
1902 with the stabilized argument list. */
1903 end_sequence ();
1906 before_call = get_last_insn ();
1908 target = expand_call (exp, target, target == const0_rtx);
1910 /* If this is a sqrt operation and we don't care about errno, try to
1911 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1912 This allows the semantics of the libcall to be visible to the RTL
1913 optimizers. */
1914 if (builtin_optab == sqrt_optab && !errno_set)
1916 /* Search backwards through the insns emitted by expand_call looking
1917 for the instruction with the REG_RETVAL note. */
1918 rtx last = get_last_insn ();
1919 while (last != before_call)
1921 if (find_reg_note (last, REG_RETVAL, NULL))
1923 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1924 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1925 two elements, i.e. symbol_ref(sqrt) and the operand. */
1926 if (note
1927 && GET_CODE (note) == EXPR_LIST
1928 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1929 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1930 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1932 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1933 /* Check operand is a register with expected mode. */
1934 if (operand
1935 && REG_P (operand)
1936 && GET_MODE (operand) == mode)
1938 /* Replace the REG_EQUAL note with a SQRT rtx. */
1939 rtx equiv = gen_rtx_SQRT (mode, operand);
1940 set_unique_reg_note (last, REG_EQUAL, equiv);
1943 break;
1945 last = PREV_INSN (last);
1949 return target;
1952 /* Expand a call to the builtin binary math functions (pow and atan2).
1953 Return 0 if a normal call should be emitted rather than expanding the
1954 function in-line. EXP is the expression that is a call to the builtin
1955 function; if convenient, the result should be placed in TARGET.
1956 SUBTARGET may be used as the target for computing one of EXP's
1957 operands. */
1959 static rtx
1960 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1962 optab builtin_optab;
1963 rtx op0, op1, insns;
1964 int op1_type = REAL_TYPE;
1965 tree fndecl = get_callee_fndecl (exp);
1966 tree arglist = TREE_OPERAND (exp, 1);
1967 tree arg0, arg1, temp, narg;
1968 enum machine_mode mode;
1969 bool errno_set = true;
1970 bool stable = true;
1972 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1973 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1974 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1975 op1_type = INTEGER_TYPE;
1977 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1978 return 0;
1980 arg0 = TREE_VALUE (arglist);
1981 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1983 switch (DECL_FUNCTION_CODE (fndecl))
1985 CASE_FLT_FN (BUILT_IN_POW):
1986 builtin_optab = pow_optab; break;
1987 CASE_FLT_FN (BUILT_IN_ATAN2):
1988 builtin_optab = atan2_optab; break;
1989 CASE_FLT_FN (BUILT_IN_LDEXP):
1990 builtin_optab = ldexp_optab; break;
1991 CASE_FLT_FN (BUILT_IN_FMOD):
1992 builtin_optab = fmod_optab; break;
1993 CASE_FLT_FN (BUILT_IN_DREM):
1994 builtin_optab = drem_optab; break;
1995 default:
1996 gcc_unreachable ();
1999 /* Make a suitable register to place result in. */
2000 mode = TYPE_MODE (TREE_TYPE (exp));
2002 /* Before working hard, check whether the instruction is available. */
2003 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2004 return 0;
2006 target = gen_reg_rtx (mode);
2008 if (! flag_errno_math || ! HONOR_NANS (mode))
2009 errno_set = false;
2011 /* Always stabilize the argument list. */
2012 narg = builtin_save_expr (arg1);
2013 if (narg != arg1)
2015 arg1 = narg;
2016 temp = build_tree_list (NULL_TREE, narg);
2017 stable = false;
2019 else
2020 temp = TREE_CHAIN (arglist);
2022 narg = builtin_save_expr (arg0);
2023 if (narg != arg0)
2025 arg0 = narg;
2026 arglist = tree_cons (NULL_TREE, narg, temp);
2027 stable = false;
2029 else if (! stable)
2030 arglist = tree_cons (NULL_TREE, arg0, temp);
2032 if (! stable)
2033 exp = build_function_call_expr (fndecl, arglist);
2035 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2036 op1 = expand_normal (arg1);
2038 start_sequence ();
2040 /* Compute into TARGET.
2041 Set TARGET to wherever the result comes back. */
2042 target = expand_binop (mode, builtin_optab, op0, op1,
2043 target, 0, OPTAB_DIRECT);
2045 /* If we were unable to expand via the builtin, stop the sequence
2046 (without outputting the insns) and call to the library function
2047 with the stabilized argument list. */
2048 if (target == 0)
2050 end_sequence ();
2051 return expand_call (exp, target, target == const0_rtx);
2054 if (errno_set)
2055 expand_errno_check (exp, target);
2057 /* Output the entire sequence. */
2058 insns = get_insns ();
2059 end_sequence ();
2060 emit_insn (insns);
2062 return target;
2065 /* Expand a call to the builtin sin and cos math functions.
2066 Return 0 if a normal call should be emitted rather than expanding the
2067 function in-line. EXP is the expression that is a call to the builtin
2068 function; if convenient, the result should be placed in TARGET.
2069 SUBTARGET may be used as the target for computing one of EXP's
2070 operands. */
2072 static rtx
2073 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2075 optab builtin_optab;
2076 rtx op0, insns;
2077 tree fndecl = get_callee_fndecl (exp);
2078 tree arglist = TREE_OPERAND (exp, 1);
2079 enum machine_mode mode;
2080 tree arg, narg;
2082 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2083 return 0;
2085 arg = TREE_VALUE (arglist);
2087 switch (DECL_FUNCTION_CODE (fndecl))
2089 CASE_FLT_FN (BUILT_IN_SIN):
2090 CASE_FLT_FN (BUILT_IN_COS):
2091 builtin_optab = sincos_optab; break;
2092 default:
2093 gcc_unreachable ();
2096 /* Make a suitable register to place result in. */
2097 mode = TYPE_MODE (TREE_TYPE (exp));
2099 /* Check if sincos insn is available, otherwise fallback
2100 to sin or cos insn. */
2101 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2102 switch (DECL_FUNCTION_CODE (fndecl))
2104 CASE_FLT_FN (BUILT_IN_SIN):
2105 builtin_optab = sin_optab; break;
2106 CASE_FLT_FN (BUILT_IN_COS):
2107 builtin_optab = cos_optab; break;
2108 default:
2109 gcc_unreachable ();
2113 /* Before working hard, check whether the instruction is available. */
2114 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2116 target = gen_reg_rtx (mode);
2118 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2119 need to expand the argument again. This way, we will not perform
2120 side-effects more the once. */
2121 narg = save_expr (arg);
2122 if (narg != arg)
2124 arg = narg;
2125 arglist = build_tree_list (NULL_TREE, arg);
2126 exp = build_function_call_expr (fndecl, arglist);
2129 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2131 start_sequence ();
2133 /* Compute into TARGET.
2134 Set TARGET to wherever the result comes back. */
2135 if (builtin_optab == sincos_optab)
2137 int result;
2139 switch (DECL_FUNCTION_CODE (fndecl))
2141 CASE_FLT_FN (BUILT_IN_SIN):
2142 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2143 break;
2144 CASE_FLT_FN (BUILT_IN_COS):
2145 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2146 break;
2147 default:
2148 gcc_unreachable ();
2150 gcc_assert (result);
2152 else
2154 target = expand_unop (mode, builtin_optab, op0, target, 0);
2157 if (target != 0)
2159 /* Output the entire sequence. */
2160 insns = get_insns ();
2161 end_sequence ();
2162 emit_insn (insns);
2163 return target;
2166 /* If we were unable to expand via the builtin, stop the sequence
2167 (without outputting the insns) and call to the library function
2168 with the stabilized argument list. */
2169 end_sequence ();
2172 target = expand_call (exp, target, target == const0_rtx);
2174 return target;
2177 /* Expand a call to the builtin sincos math function.
2178 Return 0 if a normal call should be emitted rather than expanding the
2179 function in-line. EXP is the expression that is a call to the builtin
2180 function. */
2182 static rtx
2183 expand_builtin_sincos (tree exp)
2185 rtx op0, op1, op2, target1, target2;
2186 tree arglist = TREE_OPERAND (exp, 1);
2187 enum machine_mode mode;
2188 tree arg, sinp, cosp;
2189 int result;
2191 if (!validate_arglist (arglist, REAL_TYPE,
2192 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2193 return 0;
2195 arg = TREE_VALUE (arglist);
2196 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2197 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2199 /* Make a suitable register to place result in. */
2200 mode = TYPE_MODE (TREE_TYPE (arg));
2202 /* Check if sincos insn is available, otherwise emit the call. */
2203 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2204 return NULL_RTX;
2206 target1 = gen_reg_rtx (mode);
2207 target2 = gen_reg_rtx (mode);
2209 op0 = expand_normal (arg);
2210 op1 = expand_normal (build_fold_indirect_ref (sinp));
2211 op2 = expand_normal (build_fold_indirect_ref (cosp));
2213 /* Compute into target1 and target2.
2214 Set TARGET to wherever the result comes back. */
2215 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2216 gcc_assert (result);
2218 /* Move target1 and target2 to the memory locations indicated
2219 by op1 and op2. */
2220 emit_move_insn (op1, target1);
2221 emit_move_insn (op2, target2);
2223 return const0_rtx;
2226 /* Expand a call to one of the builtin rounding functions (lfloor).
2227 If expanding via optab fails, lower expression to (int)(floor(x)).
2228 EXP is the expression that is a call to the builtin function;
2229 if convenient, the result should be placed in TARGET. SUBTARGET may
2230 be used as the target for computing one of EXP's operands. */
2232 static rtx
2233 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2235 optab builtin_optab;
2236 rtx op0, insns, tmp;
2237 tree fndecl = get_callee_fndecl (exp);
2238 tree arglist = TREE_OPERAND (exp, 1);
2239 enum built_in_function fallback_fn;
2240 tree fallback_fndecl;
2241 enum machine_mode mode;
2242 tree arg, narg;
2244 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2245 gcc_unreachable ();
2247 arg = TREE_VALUE (arglist);
2249 switch (DECL_FUNCTION_CODE (fndecl))
2251 CASE_FLT_FN (BUILT_IN_LCEIL):
2252 CASE_FLT_FN (BUILT_IN_LLCEIL):
2253 builtin_optab = lceil_optab;
2254 fallback_fn = BUILT_IN_CEIL;
2255 break;
2257 CASE_FLT_FN (BUILT_IN_LFLOOR):
2258 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2259 builtin_optab = lfloor_optab;
2260 fallback_fn = BUILT_IN_FLOOR;
2261 break;
2263 default:
2264 gcc_unreachable ();
2267 /* Make a suitable register to place result in. */
2268 mode = TYPE_MODE (TREE_TYPE (exp));
2270 /* Before working hard, check whether the instruction is available. */
2271 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2273 target = gen_reg_rtx (mode);
2275 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2276 need to expand the argument again. This way, we will not perform
2277 side-effects more the once. */
2278 narg = builtin_save_expr (arg);
2279 if (narg != arg)
2281 arg = narg;
2282 arglist = build_tree_list (NULL_TREE, arg);
2283 exp = build_function_call_expr (fndecl, arglist);
2286 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2288 start_sequence ();
2290 /* Compute into TARGET.
2291 Set TARGET to wherever the result comes back. */
2292 target = expand_unop (mode, builtin_optab, op0, target, 0);
2294 if (target != 0)
2296 /* Output the entire sequence. */
2297 insns = get_insns ();
2298 end_sequence ();
2299 emit_insn (insns);
2300 return target;
2303 /* If we were unable to expand via the builtin, stop the sequence
2304 (without outputting the insns). */
2305 end_sequence ();
2308 /* Fall back to floating point rounding optab. */
2309 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2310 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2311 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2312 gcc_assert (fallback_fndecl != NULL_TREE);
2313 exp = build_function_call_expr (fallback_fndecl, arglist);
2315 tmp = expand_normal (exp);
2317 /* Truncate the result of floating point optab to integer
2318 via expand_fix (). */
2319 target = gen_reg_rtx (mode);
2320 expand_fix (target, tmp, 0);
2322 return target;
2325 /* To evaluate powi(x,n), the floating point value x raised to the
2326 constant integer exponent n, we use a hybrid algorithm that
2327 combines the "window method" with look-up tables. For an
2328 introduction to exponentiation algorithms and "addition chains",
2329 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2330 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2331 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2332 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2334 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2335 multiplications to inline before calling the system library's pow
2336 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2337 so this default never requires calling pow, powf or powl. */
2339 #ifndef POWI_MAX_MULTS
2340 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2341 #endif
2343 /* The size of the "optimal power tree" lookup table. All
2344 exponents less than this value are simply looked up in the
2345 powi_table below. This threshold is also used to size the
2346 cache of pseudo registers that hold intermediate results. */
2347 #define POWI_TABLE_SIZE 256
2349 /* The size, in bits of the window, used in the "window method"
2350 exponentiation algorithm. This is equivalent to a radix of
2351 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2352 #define POWI_WINDOW_SIZE 3
2354 /* The following table is an efficient representation of an
2355 "optimal power tree". For each value, i, the corresponding
2356 value, j, in the table states than an optimal evaluation
2357 sequence for calculating pow(x,i) can be found by evaluating
2358 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2359 100 integers is given in Knuth's "Seminumerical algorithms". */
2361 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2363 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2364 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2365 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2366 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2367 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2368 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2369 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2370 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2371 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2372 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2373 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2374 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2375 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2376 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2377 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2378 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2379 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2380 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2381 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2382 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2383 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2384 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2385 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2386 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2387 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2388 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2389 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2390 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2391 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2392 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2393 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2394 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2398 /* Return the number of multiplications required to calculate
2399 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2400 subroutine of powi_cost. CACHE is an array indicating
2401 which exponents have already been calculated. */
2403 static int
2404 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2406 /* If we've already calculated this exponent, then this evaluation
2407 doesn't require any additional multiplications. */
2408 if (cache[n])
2409 return 0;
2411 cache[n] = true;
2412 return powi_lookup_cost (n - powi_table[n], cache)
2413 + powi_lookup_cost (powi_table[n], cache) + 1;
2416 /* Return the number of multiplications required to calculate
2417 powi(x,n) for an arbitrary x, given the exponent N. This
2418 function needs to be kept in sync with expand_powi below. */
2420 static int
2421 powi_cost (HOST_WIDE_INT n)
2423 bool cache[POWI_TABLE_SIZE];
2424 unsigned HOST_WIDE_INT digit;
2425 unsigned HOST_WIDE_INT val;
2426 int result;
2428 if (n == 0)
2429 return 0;
2431 /* Ignore the reciprocal when calculating the cost. */
2432 val = (n < 0) ? -n : n;
2434 /* Initialize the exponent cache. */
2435 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2436 cache[1] = true;
2438 result = 0;
2440 while (val >= POWI_TABLE_SIZE)
2442 if (val & 1)
2444 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2445 result += powi_lookup_cost (digit, cache)
2446 + POWI_WINDOW_SIZE + 1;
2447 val >>= POWI_WINDOW_SIZE;
2449 else
2451 val >>= 1;
2452 result++;
2456 return result + powi_lookup_cost (val, cache);
2459 /* Recursive subroutine of expand_powi. This function takes the array,
2460 CACHE, of already calculated exponents and an exponent N and returns
2461 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2463 static rtx
2464 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2466 unsigned HOST_WIDE_INT digit;
2467 rtx target, result;
2468 rtx op0, op1;
2470 if (n < POWI_TABLE_SIZE)
2472 if (cache[n])
2473 return cache[n];
2475 target = gen_reg_rtx (mode);
2476 cache[n] = target;
2478 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2479 op1 = expand_powi_1 (mode, powi_table[n], cache);
2481 else if (n & 1)
2483 target = gen_reg_rtx (mode);
2484 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2485 op0 = expand_powi_1 (mode, n - digit, cache);
2486 op1 = expand_powi_1 (mode, digit, cache);
2488 else
2490 target = gen_reg_rtx (mode);
2491 op0 = expand_powi_1 (mode, n >> 1, cache);
2492 op1 = op0;
2495 result = expand_mult (mode, op0, op1, target, 0);
2496 if (result != target)
2497 emit_move_insn (target, result);
2498 return target;
2501 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2502 floating point operand in mode MODE, and N is the exponent. This
2503 function needs to be kept in sync with powi_cost above. */
2505 static rtx
2506 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2508 unsigned HOST_WIDE_INT val;
2509 rtx cache[POWI_TABLE_SIZE];
2510 rtx result;
2512 if (n == 0)
2513 return CONST1_RTX (mode);
2515 val = (n < 0) ? -n : n;
2517 memset (cache, 0, sizeof (cache));
2518 cache[1] = x;
2520 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2522 /* If the original exponent was negative, reciprocate the result. */
2523 if (n < 0)
2524 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2525 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2527 return result;
2530 /* Expand a call to the pow built-in mathematical function. Return 0 if
2531 a normal call should be emitted rather than expanding the function
2532 in-line. EXP is the expression that is a call to the builtin
2533 function; if convenient, the result should be placed in TARGET. */
2535 static rtx
2536 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2538 tree arglist = TREE_OPERAND (exp, 1);
2539 tree arg0, arg1;
2541 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2542 return 0;
2544 arg0 = TREE_VALUE (arglist);
2545 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2547 if (TREE_CODE (arg1) == REAL_CST
2548 && ! TREE_CONSTANT_OVERFLOW (arg1))
2550 REAL_VALUE_TYPE cint;
2551 REAL_VALUE_TYPE c;
2552 HOST_WIDE_INT n;
2554 c = TREE_REAL_CST (arg1);
2555 n = real_to_integer (&c);
2556 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2557 if (real_identical (&c, &cint))
2559 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2560 Otherwise, check the number of multiplications required.
2561 Note that pow never sets errno for an integer exponent. */
2562 if ((n >= -1 && n <= 2)
2563 || (flag_unsafe_math_optimizations
2564 && ! optimize_size
2565 && powi_cost (n) <= POWI_MAX_MULTS))
2567 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2568 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2569 op = force_reg (mode, op);
2570 return expand_powi (op, mode, n);
2575 if (! flag_unsafe_math_optimizations)
2576 return NULL_RTX;
2577 return expand_builtin_mathfn_2 (exp, target, subtarget);
2580 /* Expand a call to the powi built-in mathematical function. Return 0 if
2581 a normal call should be emitted rather than expanding the function
2582 in-line. EXP is the expression that is a call to the builtin
2583 function; if convenient, the result should be placed in TARGET. */
2585 static rtx
2586 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2588 tree arglist = TREE_OPERAND (exp, 1);
2589 tree arg0, arg1;
2590 rtx op0, op1;
2591 enum machine_mode mode;
2592 enum machine_mode mode2;
2594 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2595 return 0;
2597 arg0 = TREE_VALUE (arglist);
2598 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2599 mode = TYPE_MODE (TREE_TYPE (exp));
2601 /* Handle constant power. */
2603 if (TREE_CODE (arg1) == INTEGER_CST
2604 && ! TREE_CONSTANT_OVERFLOW (arg1))
2606 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2608 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2609 Otherwise, check the number of multiplications required. */
2610 if ((TREE_INT_CST_HIGH (arg1) == 0
2611 || TREE_INT_CST_HIGH (arg1) == -1)
2612 && ((n >= -1 && n <= 2)
2613 || (! optimize_size
2614 && powi_cost (n) <= POWI_MAX_MULTS)))
2616 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2617 op0 = force_reg (mode, op0);
2618 return expand_powi (op0, mode, n);
2622 /* Emit a libcall to libgcc. */
2624 /* Mode of the 2nd argument must match that of an int. */
2625 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2627 if (target == NULL_RTX)
2628 target = gen_reg_rtx (mode);
2630 op0 = expand_expr (arg0, subtarget, mode, 0);
2631 if (GET_MODE (op0) != mode)
2632 op0 = convert_to_mode (mode, op0, 0);
2633 op1 = expand_expr (arg1, 0, mode2, 0);
2634 if (GET_MODE (op1) != mode2)
2635 op1 = convert_to_mode (mode2, op1, 0);
2637 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2638 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2639 op0, mode, op1, mode2);
2641 return target;
2644 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2645 if we failed the caller should emit a normal call, otherwise
2646 try to get the result in TARGET, if convenient. */
2648 static rtx
2649 expand_builtin_strlen (tree arglist, rtx target,
2650 enum machine_mode target_mode)
2652 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2653 return 0;
2654 else
2656 rtx pat;
2657 tree len, src = TREE_VALUE (arglist);
2658 rtx result, src_reg, char_rtx, before_strlen;
2659 enum machine_mode insn_mode = target_mode, char_mode;
2660 enum insn_code icode = CODE_FOR_nothing;
2661 int align;
2663 /* If the length can be computed at compile-time, return it. */
2664 len = c_strlen (src, 0);
2665 if (len)
2666 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2668 /* If the length can be computed at compile-time and is constant
2669 integer, but there are side-effects in src, evaluate
2670 src for side-effects, then return len.
2671 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2672 can be optimized into: i++; x = 3; */
2673 len = c_strlen (src, 1);
2674 if (len && TREE_CODE (len) == INTEGER_CST)
2676 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2677 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2680 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2682 /* If SRC is not a pointer type, don't do this operation inline. */
2683 if (align == 0)
2684 return 0;
2686 /* Bail out if we can't compute strlen in the right mode. */
2687 while (insn_mode != VOIDmode)
2689 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2690 if (icode != CODE_FOR_nothing)
2691 break;
2693 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2695 if (insn_mode == VOIDmode)
2696 return 0;
2698 /* Make a place to write the result of the instruction. */
2699 result = target;
2700 if (! (result != 0
2701 && REG_P (result)
2702 && GET_MODE (result) == insn_mode
2703 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2704 result = gen_reg_rtx (insn_mode);
2706 /* Make a place to hold the source address. We will not expand
2707 the actual source until we are sure that the expansion will
2708 not fail -- there are trees that cannot be expanded twice. */
2709 src_reg = gen_reg_rtx (Pmode);
2711 /* Mark the beginning of the strlen sequence so we can emit the
2712 source operand later. */
2713 before_strlen = get_last_insn ();
2715 char_rtx = const0_rtx;
2716 char_mode = insn_data[(int) icode].operand[2].mode;
2717 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2718 char_mode))
2719 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2721 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2722 char_rtx, GEN_INT (align));
2723 if (! pat)
2724 return 0;
2725 emit_insn (pat);
2727 /* Now that we are assured of success, expand the source. */
2728 start_sequence ();
2729 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2730 if (pat != src_reg)
2731 emit_move_insn (src_reg, pat);
2732 pat = get_insns ();
2733 end_sequence ();
2735 if (before_strlen)
2736 emit_insn_after (pat, before_strlen);
2737 else
2738 emit_insn_before (pat, get_insns ());
2740 /* Return the value in the proper mode for this function. */
2741 if (GET_MODE (result) == target_mode)
2742 target = result;
2743 else if (target != 0)
2744 convert_move (target, result, 0);
2745 else
2746 target = convert_to_mode (target_mode, result, 0);
2748 return target;
2752 /* Expand a call to the strstr builtin. Return 0 if we failed the
2753 caller should emit a normal call, otherwise try to get the result
2754 in TARGET, if convenient (and in mode MODE if that's convenient). */
2756 static rtx
2757 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2759 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2761 tree result = fold_builtin_strstr (arglist, type);
2762 if (result)
2763 return expand_expr (result, target, mode, EXPAND_NORMAL);
2765 return 0;
2768 /* Expand a call to the strchr builtin. Return 0 if we failed the
2769 caller should emit a normal call, otherwise try to get the result
2770 in TARGET, if convenient (and in mode MODE if that's convenient). */
2772 static rtx
2773 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2775 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2777 tree result = fold_builtin_strchr (arglist, type);
2778 if (result)
2779 return expand_expr (result, target, mode, EXPAND_NORMAL);
2781 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2783 return 0;
2786 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2787 caller should emit a normal call, otherwise try to get the result
2788 in TARGET, if convenient (and in mode MODE if that's convenient). */
2790 static rtx
2791 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2793 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2795 tree result = fold_builtin_strrchr (arglist, type);
2796 if (result)
2797 return expand_expr (result, target, mode, EXPAND_NORMAL);
2799 return 0;
2802 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2803 caller should emit a normal call, otherwise try to get the result
2804 in TARGET, if convenient (and in mode MODE if that's convenient). */
2806 static rtx
2807 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2809 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2811 tree result = fold_builtin_strpbrk (arglist, type);
2812 if (result)
2813 return expand_expr (result, target, mode, EXPAND_NORMAL);
2815 return 0;
2818 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2819 bytes from constant string DATA + OFFSET and return it as target
2820 constant. */
2822 static rtx
2823 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2824 enum machine_mode mode)
2826 const char *str = (const char *) data;
2828 gcc_assert (offset >= 0
2829 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2830 <= strlen (str) + 1));
2832 return c_readstr (str + offset, mode);
2835 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2836 Return 0 if we failed, the caller should emit a normal call,
2837 otherwise try to get the result in TARGET, if convenient (and in
2838 mode MODE if that's convenient). */
2839 static rtx
2840 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2842 tree fndecl = get_callee_fndecl (exp);
2843 tree arglist = TREE_OPERAND (exp, 1);
2844 if (!validate_arglist (arglist,
2845 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2846 return 0;
2847 else
2849 tree dest = TREE_VALUE (arglist);
2850 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2851 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2852 const char *src_str;
2853 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2854 unsigned int dest_align
2855 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2856 rtx dest_mem, src_mem, dest_addr, len_rtx;
2857 tree result = fold_builtin_memcpy (fndecl, arglist);
2859 if (result)
2860 return expand_expr (result, target, mode, EXPAND_NORMAL);
2862 /* If DEST is not a pointer type, call the normal function. */
2863 if (dest_align == 0)
2864 return 0;
2866 /* If either SRC is not a pointer type, don't do this
2867 operation in-line. */
2868 if (src_align == 0)
2869 return 0;
2871 dest_mem = get_memory_rtx (dest, len);
2872 set_mem_align (dest_mem, dest_align);
2873 len_rtx = expand_normal (len);
2874 src_str = c_getstr (src);
2876 /* If SRC is a string constant and block move would be done
2877 by pieces, we can avoid loading the string from memory
2878 and only stored the computed constants. */
2879 if (src_str
2880 && GET_CODE (len_rtx) == CONST_INT
2881 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2882 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2883 (void *) src_str, dest_align))
2885 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2886 builtin_memcpy_read_str,
2887 (void *) src_str, dest_align, 0);
2888 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2889 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2890 return dest_mem;
2893 src_mem = get_memory_rtx (src, len);
2894 set_mem_align (src_mem, src_align);
2896 /* Copy word part most expediently. */
2897 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2898 CALL_EXPR_TAILCALL (exp)
2899 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2901 if (dest_addr == 0)
2903 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2904 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2906 return dest_addr;
2910 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2911 Return 0 if we failed; the caller should emit a normal call,
2912 otherwise try to get the result in TARGET, if convenient (and in
2913 mode MODE if that's convenient). If ENDP is 0 return the
2914 destination pointer, if ENDP is 1 return the end pointer ala
2915 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2916 stpcpy. */
2918 static rtx
2919 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2920 int endp)
2922 if (!validate_arglist (arglist,
2923 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2924 return 0;
2925 /* If return value is ignored, transform mempcpy into memcpy. */
2926 else if (target == const0_rtx)
2928 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2930 if (!fn)
2931 return 0;
2933 return expand_expr (build_function_call_expr (fn, arglist),
2934 target, mode, EXPAND_NORMAL);
2936 else
2938 tree dest = TREE_VALUE (arglist);
2939 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2940 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2941 const char *src_str;
2942 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2943 unsigned int dest_align
2944 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2945 rtx dest_mem, src_mem, len_rtx;
2946 tree result = fold_builtin_mempcpy (arglist, type, endp);
2948 if (result)
2949 return expand_expr (result, target, mode, EXPAND_NORMAL);
2951 /* If either SRC or DEST is not a pointer type, don't do this
2952 operation in-line. */
2953 if (dest_align == 0 || src_align == 0)
2954 return 0;
2956 /* If LEN is not constant, call the normal function. */
2957 if (! host_integerp (len, 1))
2958 return 0;
2960 len_rtx = expand_normal (len);
2961 src_str = c_getstr (src);
2963 /* If SRC is a string constant and block move would be done
2964 by pieces, we can avoid loading the string from memory
2965 and only stored the computed constants. */
2966 if (src_str
2967 && GET_CODE (len_rtx) == CONST_INT
2968 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2969 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2970 (void *) src_str, dest_align))
2972 dest_mem = get_memory_rtx (dest, len);
2973 set_mem_align (dest_mem, dest_align);
2974 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2975 builtin_memcpy_read_str,
2976 (void *) src_str, dest_align, endp);
2977 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2978 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2979 return dest_mem;
2982 if (GET_CODE (len_rtx) == CONST_INT
2983 && can_move_by_pieces (INTVAL (len_rtx),
2984 MIN (dest_align, src_align)))
2986 dest_mem = get_memory_rtx (dest, len);
2987 set_mem_align (dest_mem, dest_align);
2988 src_mem = get_memory_rtx (src, len);
2989 set_mem_align (src_mem, src_align);
2990 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2991 MIN (dest_align, src_align), endp);
2992 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2993 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2994 return dest_mem;
2997 return 0;
3001 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3002 if we failed; the caller should emit a normal call. */
3004 static rtx
3005 expand_builtin_memmove (tree arglist, tree type, rtx target,
3006 enum machine_mode mode, tree orig_exp)
3008 if (!validate_arglist (arglist,
3009 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3010 return 0;
3011 else
3013 tree dest = TREE_VALUE (arglist);
3014 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3015 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3017 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3018 unsigned int dest_align
3019 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3020 tree result = fold_builtin_memmove (arglist, type);
3022 if (result)
3023 return expand_expr (result, target, mode, EXPAND_NORMAL);
3025 /* If DEST is not a pointer type, call the normal function. */
3026 if (dest_align == 0)
3027 return 0;
3029 /* If either SRC is not a pointer type, don't do this
3030 operation in-line. */
3031 if (src_align == 0)
3032 return 0;
3034 /* If src is categorized for a readonly section we can use
3035 normal memcpy. */
3036 if (readonly_data_expr (src))
3038 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3039 if (!fn)
3040 return 0;
3041 fn = build_function_call_expr (fn, arglist);
3042 if (TREE_CODE (fn) == CALL_EXPR)
3043 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3044 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3047 /* If length is 1 and we can expand memcpy call inline,
3048 it is ok to use memcpy as well. */
3049 if (integer_onep (len))
3051 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3052 /*endp=*/0);
3053 if (ret)
3054 return ret;
3057 /* Otherwise, call the normal function. */
3058 return 0;
3062 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3063 if we failed the caller should emit a normal call. */
3065 static rtx
3066 expand_builtin_bcopy (tree exp)
3068 tree arglist = TREE_OPERAND (exp, 1);
3069 tree type = TREE_TYPE (exp);
3070 tree src, dest, size, newarglist;
3072 if (!validate_arglist (arglist,
3073 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3074 return NULL_RTX;
3076 src = TREE_VALUE (arglist);
3077 dest = TREE_VALUE (TREE_CHAIN (arglist));
3078 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3080 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3081 memmove(ptr y, ptr x, size_t z). This is done this way
3082 so that if it isn't expanded inline, we fallback to
3083 calling bcopy instead of memmove. */
3085 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3086 newarglist = tree_cons (NULL_TREE, src, newarglist);
3087 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3089 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3092 #ifndef HAVE_movstr
3093 # define HAVE_movstr 0
3094 # define CODE_FOR_movstr CODE_FOR_nothing
3095 #endif
3097 /* Expand into a movstr instruction, if one is available. Return 0 if
3098 we failed, the caller should emit a normal call, otherwise try to
3099 get the result in TARGET, if convenient. If ENDP is 0 return the
3100 destination pointer, if ENDP is 1 return the end pointer ala
3101 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3102 stpcpy. */
3104 static rtx
3105 expand_movstr (tree dest, tree src, rtx target, int endp)
3107 rtx end;
3108 rtx dest_mem;
3109 rtx src_mem;
3110 rtx insn;
3111 const struct insn_data * data;
3113 if (!HAVE_movstr)
3114 return 0;
3116 dest_mem = get_memory_rtx (dest, NULL);
3117 src_mem = get_memory_rtx (src, NULL);
3118 if (!endp)
3120 target = force_reg (Pmode, XEXP (dest_mem, 0));
3121 dest_mem = replace_equiv_address (dest_mem, target);
3122 end = gen_reg_rtx (Pmode);
3124 else
3126 if (target == 0 || target == const0_rtx)
3128 end = gen_reg_rtx (Pmode);
3129 if (target == 0)
3130 target = end;
3132 else
3133 end = target;
3136 data = insn_data + CODE_FOR_movstr;
3138 if (data->operand[0].mode != VOIDmode)
3139 end = gen_lowpart (data->operand[0].mode, end);
3141 insn = data->genfun (end, dest_mem, src_mem);
3143 gcc_assert (insn);
3145 emit_insn (insn);
3147 /* movstr is supposed to set end to the address of the NUL
3148 terminator. If the caller requested a mempcpy-like return value,
3149 adjust it. */
3150 if (endp == 1 && target != const0_rtx)
3152 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3153 emit_move_insn (target, force_operand (tem, NULL_RTX));
3156 return target;
3159 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3160 if we failed the caller should emit a normal call, otherwise try to get
3161 the result in TARGET, if convenient (and in mode MODE if that's
3162 convenient). */
3164 static rtx
3165 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3167 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3169 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3170 if (result)
3171 return expand_expr (result, target, mode, EXPAND_NORMAL);
3173 return expand_movstr (TREE_VALUE (arglist),
3174 TREE_VALUE (TREE_CHAIN (arglist)),
3175 target, /*endp=*/0);
3177 return 0;
3180 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3181 Return 0 if we failed the caller should emit a normal call,
3182 otherwise try to get the result in TARGET, if convenient (and in
3183 mode MODE if that's convenient). */
3185 static rtx
3186 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3188 tree arglist = TREE_OPERAND (exp, 1);
3189 /* If return value is ignored, transform stpcpy into strcpy. */
3190 if (target == const0_rtx)
3192 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3193 if (!fn)
3194 return 0;
3196 return expand_expr (build_function_call_expr (fn, arglist),
3197 target, mode, EXPAND_NORMAL);
3200 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3201 return 0;
3202 else
3204 tree dst, src, len, lenp1;
3205 tree narglist;
3206 rtx ret;
3208 /* Ensure we get an actual string whose length can be evaluated at
3209 compile-time, not an expression containing a string. This is
3210 because the latter will potentially produce pessimized code
3211 when used to produce the return value. */
3212 src = TREE_VALUE (TREE_CHAIN (arglist));
3213 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3214 return expand_movstr (TREE_VALUE (arglist),
3215 TREE_VALUE (TREE_CHAIN (arglist)),
3216 target, /*endp=*/2);
3218 dst = TREE_VALUE (arglist);
3219 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3220 narglist = build_tree_list (NULL_TREE, lenp1);
3221 narglist = tree_cons (NULL_TREE, src, narglist);
3222 narglist = tree_cons (NULL_TREE, dst, narglist);
3223 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3224 target, mode, /*endp=*/2);
3226 if (ret)
3227 return ret;
3229 if (TREE_CODE (len) == INTEGER_CST)
3231 rtx len_rtx = expand_normal (len);
3233 if (GET_CODE (len_rtx) == CONST_INT)
3235 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3236 arglist, target, mode);
3238 if (ret)
3240 if (! target)
3242 if (mode != VOIDmode)
3243 target = gen_reg_rtx (mode);
3244 else
3245 target = gen_reg_rtx (GET_MODE (ret));
3247 if (GET_MODE (target) != GET_MODE (ret))
3248 ret = gen_lowpart (GET_MODE (target), ret);
3250 ret = plus_constant (ret, INTVAL (len_rtx));
3251 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3252 gcc_assert (ret);
3254 return target;
3259 return expand_movstr (TREE_VALUE (arglist),
3260 TREE_VALUE (TREE_CHAIN (arglist)),
3261 target, /*endp=*/2);
3265 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3266 bytes from constant string DATA + OFFSET and return it as target
3267 constant. */
3269 static rtx
3270 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3271 enum machine_mode mode)
3273 const char *str = (const char *) data;
3275 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3276 return const0_rtx;
3278 return c_readstr (str + offset, mode);
3281 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3282 if we failed the caller should emit a normal call. */
3284 static rtx
3285 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3287 tree fndecl = get_callee_fndecl (exp);
3288 tree arglist = TREE_OPERAND (exp, 1);
3289 if (validate_arglist (arglist,
3290 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3292 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3293 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3294 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3296 if (result)
3297 return expand_expr (result, target, mode, EXPAND_NORMAL);
3299 /* We must be passed a constant len and src parameter. */
3300 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3301 return 0;
3303 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3305 /* We're required to pad with trailing zeros if the requested
3306 len is greater than strlen(s2)+1. In that case try to
3307 use store_by_pieces, if it fails, punt. */
3308 if (tree_int_cst_lt (slen, len))
3310 tree dest = TREE_VALUE (arglist);
3311 unsigned int dest_align
3312 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3313 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3314 rtx dest_mem;
3316 if (!p || dest_align == 0 || !host_integerp (len, 1)
3317 || !can_store_by_pieces (tree_low_cst (len, 1),
3318 builtin_strncpy_read_str,
3319 (void *) p, dest_align))
3320 return 0;
3322 dest_mem = get_memory_rtx (dest, len);
3323 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3324 builtin_strncpy_read_str,
3325 (void *) p, dest_align, 0);
3326 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3327 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3328 return dest_mem;
3331 return 0;
3334 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3335 bytes from constant string DATA + OFFSET and return it as target
3336 constant. */
3338 static rtx
3339 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3340 enum machine_mode mode)
3342 const char *c = (const char *) data;
3343 char *p = alloca (GET_MODE_SIZE (mode));
3345 memset (p, *c, GET_MODE_SIZE (mode));
3347 return c_readstr (p, mode);
3350 /* Callback routine for store_by_pieces. Return the RTL of a register
3351 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3352 char value given in the RTL register data. For example, if mode is
3353 4 bytes wide, return the RTL for 0x01010101*data. */
3355 static rtx
3356 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3357 enum machine_mode mode)
3359 rtx target, coeff;
3360 size_t size;
3361 char *p;
3363 size = GET_MODE_SIZE (mode);
3364 if (size == 1)
3365 return (rtx) data;
3367 p = alloca (size);
3368 memset (p, 1, size);
3369 coeff = c_readstr (p, mode);
3371 target = convert_to_mode (mode, (rtx) data, 1);
3372 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3373 return force_reg (mode, target);
3376 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3377 if we failed the caller should emit a normal call, otherwise try to get
3378 the result in TARGET, if convenient (and in mode MODE if that's
3379 convenient). */
3381 static rtx
3382 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3383 tree orig_exp)
3385 if (!validate_arglist (arglist,
3386 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3387 return 0;
3388 else
3390 tree dest = TREE_VALUE (arglist);
3391 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3392 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3393 tree fndecl, fn;
3394 enum built_in_function fcode;
3395 char c;
3396 unsigned int dest_align;
3397 rtx dest_mem, dest_addr, len_rtx;
3399 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3401 /* If DEST is not a pointer type, don't do this
3402 operation in-line. */
3403 if (dest_align == 0)
3404 return 0;
3406 /* If the LEN parameter is zero, return DEST. */
3407 if (integer_zerop (len))
3409 /* Evaluate and ignore VAL in case it has side-effects. */
3410 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3411 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3414 /* Stabilize the arguments in case we fail. */
3415 dest = builtin_save_expr (dest);
3416 val = builtin_save_expr (val);
3417 len = builtin_save_expr (len);
3419 len_rtx = expand_normal (len);
3420 dest_mem = get_memory_rtx (dest, len);
3422 if (TREE_CODE (val) != INTEGER_CST)
3424 rtx val_rtx;
3426 val_rtx = expand_normal (val);
3427 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3428 val_rtx, 0);
3430 /* Assume that we can memset by pieces if we can store the
3431 * the coefficients by pieces (in the required modes).
3432 * We can't pass builtin_memset_gen_str as that emits RTL. */
3433 c = 1;
3434 if (host_integerp (len, 1)
3435 && !(optimize_size && tree_low_cst (len, 1) > 1)
3436 && can_store_by_pieces (tree_low_cst (len, 1),
3437 builtin_memset_read_str, &c, dest_align))
3439 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3440 val_rtx);
3441 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3442 builtin_memset_gen_str, val_rtx, dest_align, 0);
3444 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3445 dest_align))
3446 goto do_libcall;
3448 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3449 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3450 return dest_mem;
3453 if (target_char_cast (val, &c))
3454 goto do_libcall;
3456 if (c)
3458 if (host_integerp (len, 1)
3459 && !(optimize_size && tree_low_cst (len, 1) > 1)
3460 && can_store_by_pieces (tree_low_cst (len, 1),
3461 builtin_memset_read_str, &c, dest_align))
3462 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3463 builtin_memset_read_str, &c, dest_align, 0);
3464 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3465 dest_align))
3466 goto do_libcall;
3468 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3469 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3470 return dest_mem;
3473 set_mem_align (dest_mem, dest_align);
3474 dest_addr = clear_storage (dest_mem, len_rtx,
3475 CALL_EXPR_TAILCALL (orig_exp)
3476 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3478 if (dest_addr == 0)
3480 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3481 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3484 return dest_addr;
3486 do_libcall:
3487 fndecl = get_callee_fndecl (orig_exp);
3488 fcode = DECL_FUNCTION_CODE (fndecl);
3489 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3490 arglist = build_tree_list (NULL_TREE, len);
3491 if (fcode == BUILT_IN_MEMSET)
3492 arglist = tree_cons (NULL_TREE, val, arglist);
3493 arglist = tree_cons (NULL_TREE, dest, arglist);
3494 fn = build_function_call_expr (fndecl, arglist);
3495 if (TREE_CODE (fn) == CALL_EXPR)
3496 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3497 return expand_call (fn, target, target == const0_rtx);
3501 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3502 if we failed the caller should emit a normal call. */
3504 static rtx
3505 expand_builtin_bzero (tree exp)
3507 tree arglist = TREE_OPERAND (exp, 1);
3508 tree dest, size, newarglist;
3510 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3511 return NULL_RTX;
3513 dest = TREE_VALUE (arglist);
3514 size = TREE_VALUE (TREE_CHAIN (arglist));
3516 /* New argument list transforming bzero(ptr x, int y) to
3517 memset(ptr x, int 0, size_t y). This is done this way
3518 so that if it isn't expanded inline, we fallback to
3519 calling bzero instead of memset. */
3521 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3522 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3523 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3525 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3528 /* Expand expression EXP, which is a call to the memcmp built-in function.
3529 ARGLIST is the argument list for this call. Return 0 if we failed and the
3530 caller should emit a normal call, otherwise try to get the result in
3531 TARGET, if convenient (and in mode MODE, if that's convenient). */
3533 static rtx
3534 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3535 enum machine_mode mode)
3537 if (!validate_arglist (arglist,
3538 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3539 return 0;
3540 else
3542 tree result = fold_builtin_memcmp (arglist);
3543 if (result)
3544 return expand_expr (result, target, mode, EXPAND_NORMAL);
3547 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3549 tree arg1 = TREE_VALUE (arglist);
3550 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3551 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3552 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3553 rtx result;
3554 rtx insn;
3556 int arg1_align
3557 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3558 int arg2_align
3559 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3560 enum machine_mode insn_mode;
3562 #ifdef HAVE_cmpmemsi
3563 if (HAVE_cmpmemsi)
3564 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3565 else
3566 #endif
3567 #ifdef HAVE_cmpstrnsi
3568 if (HAVE_cmpstrnsi)
3569 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3570 else
3571 #endif
3572 return 0;
3574 /* If we don't have POINTER_TYPE, call the function. */
3575 if (arg1_align == 0 || arg2_align == 0)
3576 return 0;
3578 /* Make a place to write the result of the instruction. */
3579 result = target;
3580 if (! (result != 0
3581 && REG_P (result) && GET_MODE (result) == insn_mode
3582 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3583 result = gen_reg_rtx (insn_mode);
3585 arg1_rtx = get_memory_rtx (arg1, len);
3586 arg2_rtx = get_memory_rtx (arg2, len);
3587 arg3_rtx = expand_normal (len);
3589 /* Set MEM_SIZE as appropriate. */
3590 if (GET_CODE (arg3_rtx) == CONST_INT)
3592 set_mem_size (arg1_rtx, arg3_rtx);
3593 set_mem_size (arg2_rtx, arg3_rtx);
3596 #ifdef HAVE_cmpmemsi
3597 if (HAVE_cmpmemsi)
3598 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3599 GEN_INT (MIN (arg1_align, arg2_align)));
3600 else
3601 #endif
3602 #ifdef HAVE_cmpstrnsi
3603 if (HAVE_cmpstrnsi)
3604 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3605 GEN_INT (MIN (arg1_align, arg2_align)));
3606 else
3607 #endif
3608 gcc_unreachable ();
3610 if (insn)
3611 emit_insn (insn);
3612 else
3613 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3614 TYPE_MODE (integer_type_node), 3,
3615 XEXP (arg1_rtx, 0), Pmode,
3616 XEXP (arg2_rtx, 0), Pmode,
3617 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3618 TYPE_UNSIGNED (sizetype)),
3619 TYPE_MODE (sizetype));
3621 /* Return the value in the proper mode for this function. */
3622 mode = TYPE_MODE (TREE_TYPE (exp));
3623 if (GET_MODE (result) == mode)
3624 return result;
3625 else if (target != 0)
3627 convert_move (target, result, 0);
3628 return target;
3630 else
3631 return convert_to_mode (mode, result, 0);
3633 #endif
3635 return 0;
3638 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3639 if we failed the caller should emit a normal call, otherwise try to get
3640 the result in TARGET, if convenient. */
3642 static rtx
3643 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3645 tree arglist = TREE_OPERAND (exp, 1);
3647 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3648 return 0;
3649 else
3651 tree result = fold_builtin_strcmp (arglist);
3652 if (result)
3653 return expand_expr (result, target, mode, EXPAND_NORMAL);
3656 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3657 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3658 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3660 rtx arg1_rtx, arg2_rtx;
3661 rtx result, insn = NULL_RTX;
3662 tree fndecl, fn;
3664 tree arg1 = TREE_VALUE (arglist);
3665 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3666 int arg1_align
3667 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3668 int arg2_align
3669 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3671 /* If we don't have POINTER_TYPE, call the function. */
3672 if (arg1_align == 0 || arg2_align == 0)
3673 return 0;
3675 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3676 arg1 = builtin_save_expr (arg1);
3677 arg2 = builtin_save_expr (arg2);
3679 arg1_rtx = get_memory_rtx (arg1, NULL);
3680 arg2_rtx = get_memory_rtx (arg2, NULL);
3682 #ifdef HAVE_cmpstrsi
3683 /* Try to call cmpstrsi. */
3684 if (HAVE_cmpstrsi)
3686 enum machine_mode insn_mode
3687 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3689 /* Make a place to write the result of the instruction. */
3690 result = target;
3691 if (! (result != 0
3692 && REG_P (result) && GET_MODE (result) == insn_mode
3693 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3694 result = gen_reg_rtx (insn_mode);
3696 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3697 GEN_INT (MIN (arg1_align, arg2_align)));
3699 #endif
3700 #ifdef HAVE_cmpstrnsi
3701 /* Try to determine at least one length and call cmpstrnsi. */
3702 if (!insn && HAVE_cmpstrnsi)
3704 tree len;
3705 rtx arg3_rtx;
3707 enum machine_mode insn_mode
3708 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3709 tree len1 = c_strlen (arg1, 1);
3710 tree len2 = c_strlen (arg2, 1);
3712 if (len1)
3713 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3714 if (len2)
3715 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3717 /* If we don't have a constant length for the first, use the length
3718 of the second, if we know it. We don't require a constant for
3719 this case; some cost analysis could be done if both are available
3720 but neither is constant. For now, assume they're equally cheap,
3721 unless one has side effects. If both strings have constant lengths,
3722 use the smaller. */
3724 if (!len1)
3725 len = len2;
3726 else if (!len2)
3727 len = len1;
3728 else if (TREE_SIDE_EFFECTS (len1))
3729 len = len2;
3730 else if (TREE_SIDE_EFFECTS (len2))
3731 len = len1;
3732 else if (TREE_CODE (len1) != INTEGER_CST)
3733 len = len2;
3734 else if (TREE_CODE (len2) != INTEGER_CST)
3735 len = len1;
3736 else if (tree_int_cst_lt (len1, len2))
3737 len = len1;
3738 else
3739 len = len2;
3741 /* If both arguments have side effects, we cannot optimize. */
3742 if (!len || TREE_SIDE_EFFECTS (len))
3743 goto do_libcall;
3745 arg3_rtx = expand_normal (len);
3747 /* Make a place to write the result of the instruction. */
3748 result = target;
3749 if (! (result != 0
3750 && REG_P (result) && GET_MODE (result) == insn_mode
3751 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3752 result = gen_reg_rtx (insn_mode);
3754 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3755 GEN_INT (MIN (arg1_align, arg2_align)));
3757 #endif
3759 if (insn)
3761 emit_insn (insn);
3763 /* Return the value in the proper mode for this function. */
3764 mode = TYPE_MODE (TREE_TYPE (exp));
3765 if (GET_MODE (result) == mode)
3766 return result;
3767 if (target == 0)
3768 return convert_to_mode (mode, result, 0);
3769 convert_move (target, result, 0);
3770 return target;
3773 /* Expand the library call ourselves using a stabilized argument
3774 list to avoid re-evaluating the function's arguments twice. */
3775 #ifdef HAVE_cmpstrnsi
3776 do_libcall:
3777 #endif
3778 arglist = build_tree_list (NULL_TREE, arg2);
3779 arglist = tree_cons (NULL_TREE, arg1, arglist);
3780 fndecl = get_callee_fndecl (exp);
3781 fn = build_function_call_expr (fndecl, arglist);
3782 if (TREE_CODE (fn) == CALL_EXPR)
3783 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3784 return expand_call (fn, target, target == const0_rtx);
3786 #endif
3787 return 0;
3790 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3791 if we failed the caller should emit a normal call, otherwise try to get
3792 the result in TARGET, if convenient. */
3794 static rtx
3795 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3797 tree arglist = TREE_OPERAND (exp, 1);
3799 if (!validate_arglist (arglist,
3800 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3801 return 0;
3802 else
3804 tree result = fold_builtin_strncmp (arglist);
3805 if (result)
3806 return expand_expr (result, target, mode, EXPAND_NORMAL);
3809 /* If c_strlen can determine an expression for one of the string
3810 lengths, and it doesn't have side effects, then emit cmpstrnsi
3811 using length MIN(strlen(string)+1, arg3). */
3812 #ifdef HAVE_cmpstrnsi
3813 if (HAVE_cmpstrnsi)
3815 tree arg1 = TREE_VALUE (arglist);
3816 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3817 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3818 tree len, len1, len2;
3819 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3820 rtx result, insn;
3821 tree fndecl, fn;
3823 int arg1_align
3824 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3825 int arg2_align
3826 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3827 enum machine_mode insn_mode
3828 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3830 len1 = c_strlen (arg1, 1);
3831 len2 = c_strlen (arg2, 1);
3833 if (len1)
3834 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3835 if (len2)
3836 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3838 /* If we don't have a constant length for the first, use the length
3839 of the second, if we know it. We don't require a constant for
3840 this case; some cost analysis could be done if both are available
3841 but neither is constant. For now, assume they're equally cheap,
3842 unless one has side effects. If both strings have constant lengths,
3843 use the smaller. */
3845 if (!len1)
3846 len = len2;
3847 else if (!len2)
3848 len = len1;
3849 else if (TREE_SIDE_EFFECTS (len1))
3850 len = len2;
3851 else if (TREE_SIDE_EFFECTS (len2))
3852 len = len1;
3853 else if (TREE_CODE (len1) != INTEGER_CST)
3854 len = len2;
3855 else if (TREE_CODE (len2) != INTEGER_CST)
3856 len = len1;
3857 else if (tree_int_cst_lt (len1, len2))
3858 len = len1;
3859 else
3860 len = len2;
3862 /* If both arguments have side effects, we cannot optimize. */
3863 if (!len || TREE_SIDE_EFFECTS (len))
3864 return 0;
3866 /* The actual new length parameter is MIN(len,arg3). */
3867 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3868 fold_convert (TREE_TYPE (len), arg3));
3870 /* If we don't have POINTER_TYPE, call the function. */
3871 if (arg1_align == 0 || arg2_align == 0)
3872 return 0;
3874 /* Make a place to write the result of the instruction. */
3875 result = target;
3876 if (! (result != 0
3877 && REG_P (result) && GET_MODE (result) == insn_mode
3878 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3879 result = gen_reg_rtx (insn_mode);
3881 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3882 arg1 = builtin_save_expr (arg1);
3883 arg2 = builtin_save_expr (arg2);
3884 len = builtin_save_expr (len);
3886 arg1_rtx = get_memory_rtx (arg1, len);
3887 arg2_rtx = get_memory_rtx (arg2, len);
3888 arg3_rtx = expand_normal (len);
3889 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3890 GEN_INT (MIN (arg1_align, arg2_align)));
3891 if (insn)
3893 emit_insn (insn);
3895 /* Return the value in the proper mode for this function. */
3896 mode = TYPE_MODE (TREE_TYPE (exp));
3897 if (GET_MODE (result) == mode)
3898 return result;
3899 if (target == 0)
3900 return convert_to_mode (mode, result, 0);
3901 convert_move (target, result, 0);
3902 return target;
3905 /* Expand the library call ourselves using a stabilized argument
3906 list to avoid re-evaluating the function's arguments twice. */
3907 arglist = build_tree_list (NULL_TREE, len);
3908 arglist = tree_cons (NULL_TREE, arg2, arglist);
3909 arglist = tree_cons (NULL_TREE, arg1, arglist);
3910 fndecl = get_callee_fndecl (exp);
3911 fn = build_function_call_expr (fndecl, arglist);
3912 if (TREE_CODE (fn) == CALL_EXPR)
3913 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3914 return expand_call (fn, target, target == const0_rtx);
3916 #endif
3917 return 0;
3920 /* Expand expression EXP, which is a call to the strcat builtin.
3921 Return 0 if we failed the caller should emit a normal call,
3922 otherwise try to get the result in TARGET, if convenient. */
3924 static rtx
3925 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3927 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3928 return 0;
3929 else
3931 tree dst = TREE_VALUE (arglist),
3932 src = TREE_VALUE (TREE_CHAIN (arglist));
3933 const char *p = c_getstr (src);
3935 /* If the string length is zero, return the dst parameter. */
3936 if (p && *p == '\0')
3937 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3939 if (!optimize_size)
3941 /* See if we can store by pieces into (dst + strlen(dst)). */
3942 tree newsrc, newdst,
3943 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3944 rtx insns;
3946 /* Stabilize the argument list. */
3947 newsrc = builtin_save_expr (src);
3948 if (newsrc != src)
3949 arglist = build_tree_list (NULL_TREE, newsrc);
3950 else
3951 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3953 dst = builtin_save_expr (dst);
3955 start_sequence ();
3957 /* Create strlen (dst). */
3958 newdst =
3959 build_function_call_expr (strlen_fn,
3960 build_tree_list (NULL_TREE, dst));
3961 /* Create (dst + (cast) strlen (dst)). */
3962 newdst = fold_convert (TREE_TYPE (dst), newdst);
3963 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3965 newdst = builtin_save_expr (newdst);
3966 arglist = tree_cons (NULL_TREE, newdst, arglist);
3968 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3970 end_sequence (); /* Stop sequence. */
3971 return 0;
3974 /* Output the entire sequence. */
3975 insns = get_insns ();
3976 end_sequence ();
3977 emit_insn (insns);
3979 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3982 return 0;
3986 /* Expand expression EXP, which is a call to the strncat builtin.
3987 Return 0 if we failed the caller should emit a normal call,
3988 otherwise try to get the result in TARGET, if convenient. */
3990 static rtx
3991 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3993 if (validate_arglist (arglist,
3994 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3996 tree result = fold_builtin_strncat (arglist);
3997 if (result)
3998 return expand_expr (result, target, mode, EXPAND_NORMAL);
4000 return 0;
4003 /* Expand expression EXP, which is a call to the strspn builtin.
4004 Return 0 if we failed the caller should emit a normal call,
4005 otherwise try to get the result in TARGET, if convenient. */
4007 static rtx
4008 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4010 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4012 tree result = fold_builtin_strspn (arglist);
4013 if (result)
4014 return expand_expr (result, target, mode, EXPAND_NORMAL);
4016 return 0;
4019 /* Expand expression EXP, which is a call to the strcspn builtin.
4020 Return 0 if we failed the caller should emit a normal call,
4021 otherwise try to get the result in TARGET, if convenient. */
4023 static rtx
4024 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4026 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4028 tree result = fold_builtin_strcspn (arglist);
4029 if (result)
4030 return expand_expr (result, target, mode, EXPAND_NORMAL);
4032 return 0;
4035 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4036 if that's convenient. */
4039 expand_builtin_saveregs (void)
4041 rtx val, seq;
4043 /* Don't do __builtin_saveregs more than once in a function.
4044 Save the result of the first call and reuse it. */
4045 if (saveregs_value != 0)
4046 return saveregs_value;
4048 /* When this function is called, it means that registers must be
4049 saved on entry to this function. So we migrate the call to the
4050 first insn of this function. */
4052 start_sequence ();
4054 /* Do whatever the machine needs done in this case. */
4055 val = targetm.calls.expand_builtin_saveregs ();
4057 seq = get_insns ();
4058 end_sequence ();
4060 saveregs_value = val;
4062 /* Put the insns after the NOTE that starts the function. If this
4063 is inside a start_sequence, make the outer-level insn chain current, so
4064 the code is placed at the start of the function. */
4065 push_topmost_sequence ();
4066 emit_insn_after (seq, entry_of_function ());
4067 pop_topmost_sequence ();
4069 return val;
4072 /* __builtin_args_info (N) returns word N of the arg space info
4073 for the current function. The number and meanings of words
4074 is controlled by the definition of CUMULATIVE_ARGS. */
4076 static rtx
4077 expand_builtin_args_info (tree arglist)
4079 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4080 int *word_ptr = (int *) &current_function_args_info;
4082 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4084 if (arglist != 0)
4086 if (!host_integerp (TREE_VALUE (arglist), 0))
4087 error ("argument of %<__builtin_args_info%> must be constant");
4088 else
4090 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4092 if (wordnum < 0 || wordnum >= nwords)
4093 error ("argument of %<__builtin_args_info%> out of range");
4094 else
4095 return GEN_INT (word_ptr[wordnum]);
4098 else
4099 error ("missing argument in %<__builtin_args_info%>");
4101 return const0_rtx;
4104 /* Expand a call to __builtin_next_arg. */
4106 static rtx
4107 expand_builtin_next_arg (void)
4109 /* Checking arguments is already done in fold_builtin_next_arg
4110 that must be called before this function. */
4111 return expand_binop (Pmode, add_optab,
4112 current_function_internal_arg_pointer,
4113 current_function_arg_offset_rtx,
4114 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4117 /* Make it easier for the backends by protecting the valist argument
4118 from multiple evaluations. */
4120 static tree
4121 stabilize_va_list (tree valist, int needs_lvalue)
4123 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4125 if (TREE_SIDE_EFFECTS (valist))
4126 valist = save_expr (valist);
4128 /* For this case, the backends will be expecting a pointer to
4129 TREE_TYPE (va_list_type_node), but it's possible we've
4130 actually been given an array (an actual va_list_type_node).
4131 So fix it. */
4132 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4134 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4135 valist = build_fold_addr_expr_with_type (valist, p1);
4138 else
4140 tree pt;
4142 if (! needs_lvalue)
4144 if (! TREE_SIDE_EFFECTS (valist))
4145 return valist;
4147 pt = build_pointer_type (va_list_type_node);
4148 valist = fold_build1 (ADDR_EXPR, pt, valist);
4149 TREE_SIDE_EFFECTS (valist) = 1;
4152 if (TREE_SIDE_EFFECTS (valist))
4153 valist = save_expr (valist);
4154 valist = build_fold_indirect_ref (valist);
4157 return valist;
4160 /* The "standard" definition of va_list is void*. */
4162 tree
4163 std_build_builtin_va_list (void)
4165 return ptr_type_node;
4168 /* The "standard" implementation of va_start: just assign `nextarg' to
4169 the variable. */
4171 void
4172 std_expand_builtin_va_start (tree valist, rtx nextarg)
4174 tree t;
4176 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4177 make_tree (ptr_type_node, nextarg));
4178 TREE_SIDE_EFFECTS (t) = 1;
4180 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4183 /* Expand ARGLIST, from a call to __builtin_va_start. */
4185 static rtx
4186 expand_builtin_va_start (tree arglist)
4188 rtx nextarg;
4189 tree chain, valist;
4191 chain = TREE_CHAIN (arglist);
4193 if (!chain)
4195 error ("too few arguments to function %<va_start%>");
4196 return const0_rtx;
4199 if (fold_builtin_next_arg (chain))
4200 return const0_rtx;
4202 nextarg = expand_builtin_next_arg ();
4203 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4205 #ifdef EXPAND_BUILTIN_VA_START
4206 EXPAND_BUILTIN_VA_START (valist, nextarg);
4207 #else
4208 std_expand_builtin_va_start (valist, nextarg);
4209 #endif
4211 return const0_rtx;
4214 /* The "standard" implementation of va_arg: read the value from the
4215 current (padded) address and increment by the (padded) size. */
4217 tree
4218 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4220 tree addr, t, type_size, rounded_size, valist_tmp;
4221 unsigned HOST_WIDE_INT align, boundary;
4222 bool indirect;
4224 #ifdef ARGS_GROW_DOWNWARD
4225 /* All of the alignment and movement below is for args-grow-up machines.
4226 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4227 implement their own specialized gimplify_va_arg_expr routines. */
4228 gcc_unreachable ();
4229 #endif
4231 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4232 if (indirect)
4233 type = build_pointer_type (type);
4235 align = PARM_BOUNDARY / BITS_PER_UNIT;
4236 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4238 /* Hoist the valist value into a temporary for the moment. */
4239 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4241 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4242 requires greater alignment, we must perform dynamic alignment. */
4243 if (boundary > align
4244 && !integer_zerop (TYPE_SIZE (type)))
4246 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4247 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4248 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4249 gimplify_and_add (t, pre_p);
4251 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4252 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4253 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4254 gimplify_and_add (t, pre_p);
4256 else
4257 boundary = align;
4259 /* If the actual alignment is less than the alignment of the type,
4260 adjust the type accordingly so that we don't assume strict alignment
4261 when deferencing the pointer. */
4262 boundary *= BITS_PER_UNIT;
4263 if (boundary < TYPE_ALIGN (type))
4265 type = build_variant_type_copy (type);
4266 TYPE_ALIGN (type) = boundary;
4269 /* Compute the rounded size of the type. */
4270 type_size = size_in_bytes (type);
4271 rounded_size = round_up (type_size, align);
4273 /* Reduce rounded_size so it's sharable with the postqueue. */
4274 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4276 /* Get AP. */
4277 addr = valist_tmp;
4278 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4280 /* Small args are padded downward. */
4281 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4282 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4283 size_binop (MINUS_EXPR, rounded_size, type_size));
4284 t = fold_convert (TREE_TYPE (addr), t);
4285 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4288 /* Compute new value for AP. */
4289 t = fold_convert (TREE_TYPE (valist), rounded_size);
4290 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4291 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4292 gimplify_and_add (t, pre_p);
4294 addr = fold_convert (build_pointer_type (type), addr);
4296 if (indirect)
4297 addr = build_va_arg_indirect_ref (addr);
4299 return build_va_arg_indirect_ref (addr);
4302 /* Build an indirect-ref expression over the given TREE, which represents a
4303 piece of a va_arg() expansion. */
4304 tree
4305 build_va_arg_indirect_ref (tree addr)
4307 addr = build_fold_indirect_ref (addr);
4309 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4310 mf_mark (addr);
4312 return addr;
4315 /* Return a dummy expression of type TYPE in order to keep going after an
4316 error. */
4318 static tree
4319 dummy_object (tree type)
4321 tree t = build_int_cst (build_pointer_type (type), 0);
4322 return build1 (INDIRECT_REF, type, t);
4325 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4326 builtin function, but a very special sort of operator. */
4328 enum gimplify_status
4329 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4331 tree promoted_type, want_va_type, have_va_type;
4332 tree valist = TREE_OPERAND (*expr_p, 0);
4333 tree type = TREE_TYPE (*expr_p);
4334 tree t;
4336 /* Verify that valist is of the proper type. */
4337 want_va_type = va_list_type_node;
4338 have_va_type = TREE_TYPE (valist);
4340 if (have_va_type == error_mark_node)
4341 return GS_ERROR;
4343 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4345 /* If va_list is an array type, the argument may have decayed
4346 to a pointer type, e.g. by being passed to another function.
4347 In that case, unwrap both types so that we can compare the
4348 underlying records. */
4349 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4350 || POINTER_TYPE_P (have_va_type))
4352 want_va_type = TREE_TYPE (want_va_type);
4353 have_va_type = TREE_TYPE (have_va_type);
4357 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4359 error ("first argument to %<va_arg%> not of type %<va_list%>");
4360 return GS_ERROR;
4363 /* Generate a diagnostic for requesting data of a type that cannot
4364 be passed through `...' due to type promotion at the call site. */
4365 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4366 != type)
4368 static bool gave_help;
4370 /* Unfortunately, this is merely undefined, rather than a constraint
4371 violation, so we cannot make this an error. If this call is never
4372 executed, the program is still strictly conforming. */
4373 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4374 type, promoted_type);
4375 if (! gave_help)
4377 gave_help = true;
4378 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4379 promoted_type, type);
4382 /* We can, however, treat "undefined" any way we please.
4383 Call abort to encourage the user to fix the program. */
4384 inform ("if this code is reached, the program will abort");
4385 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4386 NULL);
4387 append_to_statement_list (t, pre_p);
4389 /* This is dead code, but go ahead and finish so that the
4390 mode of the result comes out right. */
4391 *expr_p = dummy_object (type);
4392 return GS_ALL_DONE;
4394 else
4396 /* Make it easier for the backends by protecting the valist argument
4397 from multiple evaluations. */
4398 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4400 /* For this case, the backends will be expecting a pointer to
4401 TREE_TYPE (va_list_type_node), but it's possible we've
4402 actually been given an array (an actual va_list_type_node).
4403 So fix it. */
4404 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4406 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4407 valist = build_fold_addr_expr_with_type (valist, p1);
4409 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4411 else
4412 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4414 if (!targetm.gimplify_va_arg_expr)
4415 /* FIXME:Once most targets are converted we should merely
4416 assert this is non-null. */
4417 return GS_ALL_DONE;
4419 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4420 return GS_OK;
4424 /* Expand ARGLIST, from a call to __builtin_va_end. */
4426 static rtx
4427 expand_builtin_va_end (tree arglist)
4429 tree valist = TREE_VALUE (arglist);
4431 /* Evaluate for side effects, if needed. I hate macros that don't
4432 do that. */
4433 if (TREE_SIDE_EFFECTS (valist))
4434 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4436 return const0_rtx;
4439 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4440 builtin rather than just as an assignment in stdarg.h because of the
4441 nastiness of array-type va_list types. */
4443 static rtx
4444 expand_builtin_va_copy (tree arglist)
4446 tree dst, src, t;
4448 dst = TREE_VALUE (arglist);
4449 src = TREE_VALUE (TREE_CHAIN (arglist));
4451 dst = stabilize_va_list (dst, 1);
4452 src = stabilize_va_list (src, 0);
4454 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4456 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4457 TREE_SIDE_EFFECTS (t) = 1;
4458 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4460 else
4462 rtx dstb, srcb, size;
4464 /* Evaluate to pointers. */
4465 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4466 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4467 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4468 VOIDmode, EXPAND_NORMAL);
4470 dstb = convert_memory_address (Pmode, dstb);
4471 srcb = convert_memory_address (Pmode, srcb);
4473 /* "Dereference" to BLKmode memories. */
4474 dstb = gen_rtx_MEM (BLKmode, dstb);
4475 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4476 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4477 srcb = gen_rtx_MEM (BLKmode, srcb);
4478 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4479 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4481 /* Copy. */
4482 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4485 return const0_rtx;
4488 /* Expand a call to one of the builtin functions __builtin_frame_address or
4489 __builtin_return_address. */
4491 static rtx
4492 expand_builtin_frame_address (tree fndecl, tree arglist)
4494 /* The argument must be a nonnegative integer constant.
4495 It counts the number of frames to scan up the stack.
4496 The value is the return address saved in that frame. */
4497 if (arglist == 0)
4498 /* Warning about missing arg was already issued. */
4499 return const0_rtx;
4500 else if (! host_integerp (TREE_VALUE (arglist), 1))
4502 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4503 error ("invalid argument to %<__builtin_frame_address%>");
4504 else
4505 error ("invalid argument to %<__builtin_return_address%>");
4506 return const0_rtx;
4508 else
4510 rtx tem
4511 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4512 tree_low_cst (TREE_VALUE (arglist), 1));
4514 /* Some ports cannot access arbitrary stack frames. */
4515 if (tem == NULL)
4517 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4518 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4519 else
4520 warning (0, "unsupported argument to %<__builtin_return_address%>");
4521 return const0_rtx;
4524 /* For __builtin_frame_address, return what we've got. */
4525 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4526 return tem;
4528 if (!REG_P (tem)
4529 && ! CONSTANT_P (tem))
4530 tem = copy_to_mode_reg (Pmode, tem);
4531 return tem;
4535 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4536 we failed and the caller should emit a normal call, otherwise try to get
4537 the result in TARGET, if convenient. */
4539 static rtx
4540 expand_builtin_alloca (tree arglist, rtx target)
4542 rtx op0;
4543 rtx result;
4545 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4546 should always expand to function calls. These can be intercepted
4547 in libmudflap. */
4548 if (flag_mudflap)
4549 return 0;
4551 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4552 return 0;
4554 /* Compute the argument. */
4555 op0 = expand_normal (TREE_VALUE (arglist));
4557 /* Allocate the desired space. */
4558 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4559 result = convert_memory_address (ptr_mode, result);
4561 return result;
4564 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4565 Return 0 if a normal call should be emitted rather than expanding the
4566 function in-line. If convenient, the result should be placed in TARGET.
4567 SUBTARGET may be used as the target for computing one of EXP's operands. */
4569 static rtx
4570 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4571 rtx subtarget, optab op_optab)
4573 rtx op0;
4574 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4575 return 0;
4577 /* Compute the argument. */
4578 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4579 /* Compute op, into TARGET if possible.
4580 Set TARGET to wherever the result comes back. */
4581 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4582 op_optab, op0, target, 1);
4583 gcc_assert (target);
4585 return convert_to_mode (target_mode, target, 0);
4588 /* If the string passed to fputs is a constant and is one character
4589 long, we attempt to transform this call into __builtin_fputc(). */
4591 static rtx
4592 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4594 /* Verify the arguments in the original call. */
4595 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4597 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4598 unlocked, NULL_TREE);
4599 if (result)
4600 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4602 return 0;
4605 /* Expand a call to __builtin_expect. We return our argument and emit a
4606 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4607 a non-jump context. */
4609 static rtx
4610 expand_builtin_expect (tree arglist, rtx target)
4612 tree exp, c;
4613 rtx note, rtx_c;
4615 if (arglist == NULL_TREE
4616 || TREE_CHAIN (arglist) == NULL_TREE)
4617 return const0_rtx;
4618 exp = TREE_VALUE (arglist);
4619 c = TREE_VALUE (TREE_CHAIN (arglist));
4621 if (TREE_CODE (c) != INTEGER_CST)
4623 error ("second argument to %<__builtin_expect%> must be a constant");
4624 c = integer_zero_node;
4627 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4629 /* Don't bother with expected value notes for integral constants. */
4630 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4632 /* We do need to force this into a register so that we can be
4633 moderately sure to be able to correctly interpret the branch
4634 condition later. */
4635 target = force_reg (GET_MODE (target), target);
4637 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4639 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4640 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4643 return target;
4646 /* Like expand_builtin_expect, except do this in a jump context. This is
4647 called from do_jump if the conditional is a __builtin_expect. Return either
4648 a list of insns to emit the jump or NULL if we cannot optimize
4649 __builtin_expect. We need to optimize this at jump time so that machines
4650 like the PowerPC don't turn the test into a SCC operation, and then jump
4651 based on the test being 0/1. */
4654 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4656 tree arglist = TREE_OPERAND (exp, 1);
4657 tree arg0 = TREE_VALUE (arglist);
4658 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4659 rtx ret = NULL_RTX;
4661 /* Only handle __builtin_expect (test, 0) and
4662 __builtin_expect (test, 1). */
4663 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4664 && (integer_zerop (arg1) || integer_onep (arg1)))
4666 rtx insn, drop_through_label, temp;
4668 /* Expand the jump insns. */
4669 start_sequence ();
4670 do_jump (arg0, if_false_label, if_true_label);
4671 ret = get_insns ();
4673 drop_through_label = get_last_insn ();
4674 if (drop_through_label && NOTE_P (drop_through_label))
4675 drop_through_label = prev_nonnote_insn (drop_through_label);
4676 if (drop_through_label && !LABEL_P (drop_through_label))
4677 drop_through_label = NULL_RTX;
4678 end_sequence ();
4680 if (! if_true_label)
4681 if_true_label = drop_through_label;
4682 if (! if_false_label)
4683 if_false_label = drop_through_label;
4685 /* Go through and add the expect's to each of the conditional jumps. */
4686 insn = ret;
4687 while (insn != NULL_RTX)
4689 rtx next = NEXT_INSN (insn);
4691 if (JUMP_P (insn) && any_condjump_p (insn))
4693 rtx ifelse = SET_SRC (pc_set (insn));
4694 rtx then_dest = XEXP (ifelse, 1);
4695 rtx else_dest = XEXP (ifelse, 2);
4696 int taken = -1;
4698 /* First check if we recognize any of the labels. */
4699 if (GET_CODE (then_dest) == LABEL_REF
4700 && XEXP (then_dest, 0) == if_true_label)
4701 taken = 1;
4702 else if (GET_CODE (then_dest) == LABEL_REF
4703 && XEXP (then_dest, 0) == if_false_label)
4704 taken = 0;
4705 else if (GET_CODE (else_dest) == LABEL_REF
4706 && XEXP (else_dest, 0) == if_false_label)
4707 taken = 1;
4708 else if (GET_CODE (else_dest) == LABEL_REF
4709 && XEXP (else_dest, 0) == if_true_label)
4710 taken = 0;
4711 /* Otherwise check where we drop through. */
4712 else if (else_dest == pc_rtx)
4714 if (next && NOTE_P (next))
4715 next = next_nonnote_insn (next);
4717 if (next && JUMP_P (next)
4718 && any_uncondjump_p (next))
4719 temp = XEXP (SET_SRC (pc_set (next)), 0);
4720 else
4721 temp = next;
4723 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4724 else that can't possibly match either target label. */
4725 if (temp == if_false_label)
4726 taken = 1;
4727 else if (temp == if_true_label)
4728 taken = 0;
4730 else if (then_dest == pc_rtx)
4732 if (next && NOTE_P (next))
4733 next = next_nonnote_insn (next);
4735 if (next && JUMP_P (next)
4736 && any_uncondjump_p (next))
4737 temp = XEXP (SET_SRC (pc_set (next)), 0);
4738 else
4739 temp = next;
4741 if (temp == if_false_label)
4742 taken = 0;
4743 else if (temp == if_true_label)
4744 taken = 1;
4747 if (taken != -1)
4749 /* If the test is expected to fail, reverse the
4750 probabilities. */
4751 if (integer_zerop (arg1))
4752 taken = 1 - taken;
4753 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4757 insn = next;
4761 return ret;
4764 void
4765 expand_builtin_trap (void)
4767 #ifdef HAVE_trap
4768 if (HAVE_trap)
4769 emit_insn (gen_trap ());
4770 else
4771 #endif
4772 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4773 emit_barrier ();
4776 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4777 Return 0 if a normal call should be emitted rather than expanding
4778 the function inline. If convenient, the result should be placed
4779 in TARGET. SUBTARGET may be used as the target for computing
4780 the operand. */
4782 static rtx
4783 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4785 enum machine_mode mode;
4786 tree arg;
4787 rtx op0;
4789 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4790 return 0;
4792 arg = TREE_VALUE (arglist);
4793 mode = TYPE_MODE (TREE_TYPE (arg));
4794 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4795 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4798 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4799 Return NULL is a normal call should be emitted rather than expanding the
4800 function inline. If convenient, the result should be placed in TARGET.
4801 SUBTARGET may be used as the target for computing the operand. */
4803 static rtx
4804 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4806 rtx op0, op1;
4807 tree arg;
4809 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4810 return 0;
4812 arg = TREE_VALUE (arglist);
4813 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4815 arg = TREE_VALUE (TREE_CHAIN (arglist));
4816 op1 = expand_normal (arg);
4818 return expand_copysign (op0, op1, target);
4821 /* Create a new constant string literal and return a char* pointer to it.
4822 The STRING_CST value is the LEN characters at STR. */
4823 tree
4824 build_string_literal (int len, const char *str)
4826 tree t, elem, index, type;
4828 t = build_string (len, str);
4829 elem = build_type_variant (char_type_node, 1, 0);
4830 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4831 type = build_array_type (elem, index);
4832 TREE_TYPE (t) = type;
4833 TREE_CONSTANT (t) = 1;
4834 TREE_INVARIANT (t) = 1;
4835 TREE_READONLY (t) = 1;
4836 TREE_STATIC (t) = 1;
4838 type = build_pointer_type (type);
4839 t = build1 (ADDR_EXPR, type, t);
4841 type = build_pointer_type (elem);
4842 t = build1 (NOP_EXPR, type, t);
4843 return t;
4846 /* Expand EXP, a call to printf or printf_unlocked.
4847 Return 0 if a normal call should be emitted rather than transforming
4848 the function inline. If convenient, the result should be placed in
4849 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4850 call. */
4851 static rtx
4852 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4853 bool unlocked)
4855 tree arglist = TREE_OPERAND (exp, 1);
4856 /* If we're using an unlocked function, assume the other unlocked
4857 functions exist explicitly. */
4858 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4859 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4860 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4861 : implicit_built_in_decls[BUILT_IN_PUTS];
4862 const char *fmt_str;
4863 tree fn, fmt, arg;
4865 /* If the return value is used, don't do the transformation. */
4866 if (target != const0_rtx)
4867 return 0;
4869 /* Verify the required arguments in the original call. */
4870 if (! arglist)
4871 return 0;
4872 fmt = TREE_VALUE (arglist);
4873 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4874 return 0;
4875 arglist = TREE_CHAIN (arglist);
4877 /* Check whether the format is a literal string constant. */
4878 fmt_str = c_getstr (fmt);
4879 if (fmt_str == NULL)
4880 return 0;
4882 if (!init_target_chars())
4883 return 0;
4885 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4886 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4888 if (! arglist
4889 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4890 || TREE_CHAIN (arglist))
4891 return 0;
4892 fn = fn_puts;
4894 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4895 else if (strcmp (fmt_str, target_percent_c) == 0)
4897 if (! arglist
4898 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4899 || TREE_CHAIN (arglist))
4900 return 0;
4901 fn = fn_putchar;
4903 else
4905 /* We can't handle anything else with % args or %% ... yet. */
4906 if (strchr (fmt_str, target_percent))
4907 return 0;
4909 if (arglist)
4910 return 0;
4912 /* If the format specifier was "", printf does nothing. */
4913 if (fmt_str[0] == '\0')
4914 return const0_rtx;
4915 /* If the format specifier has length of 1, call putchar. */
4916 if (fmt_str[1] == '\0')
4918 /* Given printf("c"), (where c is any one character,)
4919 convert "c"[0] to an int and pass that to the replacement
4920 function. */
4921 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4922 arglist = build_tree_list (NULL_TREE, arg);
4923 fn = fn_putchar;
4925 else
4927 /* If the format specifier was "string\n", call puts("string"). */
4928 size_t len = strlen (fmt_str);
4929 if ((unsigned char)fmt_str[len - 1] == target_newline)
4931 /* Create a NUL-terminated string that's one char shorter
4932 than the original, stripping off the trailing '\n'. */
4933 char *newstr = alloca (len);
4934 memcpy (newstr, fmt_str, len - 1);
4935 newstr[len - 1] = 0;
4937 arg = build_string_literal (len, newstr);
4938 arglist = build_tree_list (NULL_TREE, arg);
4939 fn = fn_puts;
4941 else
4942 /* We'd like to arrange to call fputs(string,stdout) here,
4943 but we need stdout and don't have a way to get it yet. */
4944 return 0;
4948 if (!fn)
4949 return 0;
4950 fn = build_function_call_expr (fn, arglist);
4951 if (TREE_CODE (fn) == CALL_EXPR)
4952 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4953 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4956 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4957 Return 0 if a normal call should be emitted rather than transforming
4958 the function inline. If convenient, the result should be placed in
4959 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4960 call. */
4961 static rtx
4962 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4963 bool unlocked)
4965 tree arglist = TREE_OPERAND (exp, 1);
4966 /* If we're using an unlocked function, assume the other unlocked
4967 functions exist explicitly. */
4968 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4969 : implicit_built_in_decls[BUILT_IN_FPUTC];
4970 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4971 : implicit_built_in_decls[BUILT_IN_FPUTS];
4972 const char *fmt_str;
4973 tree fn, fmt, fp, arg;
4975 /* If the return value is used, don't do the transformation. */
4976 if (target != const0_rtx)
4977 return 0;
4979 /* Verify the required arguments in the original call. */
4980 if (! arglist)
4981 return 0;
4982 fp = TREE_VALUE (arglist);
4983 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4984 return 0;
4985 arglist = TREE_CHAIN (arglist);
4986 if (! arglist)
4987 return 0;
4988 fmt = TREE_VALUE (arglist);
4989 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4990 return 0;
4991 arglist = TREE_CHAIN (arglist);
4993 /* Check whether the format is a literal string constant. */
4994 fmt_str = c_getstr (fmt);
4995 if (fmt_str == NULL)
4996 return 0;
4998 if (!init_target_chars())
4999 return 0;
5001 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5002 if (strcmp (fmt_str, target_percent_s) == 0)
5004 if (! arglist
5005 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5006 || TREE_CHAIN (arglist))
5007 return 0;
5008 arg = TREE_VALUE (arglist);
5009 arglist = build_tree_list (NULL_TREE, fp);
5010 arglist = tree_cons (NULL_TREE, arg, arglist);
5011 fn = fn_fputs;
5013 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5014 else if (strcmp (fmt_str, target_percent_c) == 0)
5016 if (! arglist
5017 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5018 || TREE_CHAIN (arglist))
5019 return 0;
5020 arg = TREE_VALUE (arglist);
5021 arglist = build_tree_list (NULL_TREE, fp);
5022 arglist = tree_cons (NULL_TREE, arg, arglist);
5023 fn = fn_fputc;
5025 else
5027 /* We can't handle anything else with % args or %% ... yet. */
5028 if (strchr (fmt_str, target_percent))
5029 return 0;
5031 if (arglist)
5032 return 0;
5034 /* If the format specifier was "", fprintf does nothing. */
5035 if (fmt_str[0] == '\0')
5037 /* Evaluate and ignore FILE* argument for side-effects. */
5038 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5039 return const0_rtx;
5042 /* When "string" doesn't contain %, replace all cases of
5043 fprintf(stream,string) with fputs(string,stream). The fputs
5044 builtin will take care of special cases like length == 1. */
5045 arglist = build_tree_list (NULL_TREE, fp);
5046 arglist = tree_cons (NULL_TREE, fmt, arglist);
5047 fn = fn_fputs;
5050 if (!fn)
5051 return 0;
5052 fn = build_function_call_expr (fn, arglist);
5053 if (TREE_CODE (fn) == CALL_EXPR)
5054 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5055 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5058 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5059 a normal call should be emitted rather than expanding the function
5060 inline. If convenient, the result should be placed in TARGET with
5061 mode MODE. */
5063 static rtx
5064 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5066 tree orig_arglist, dest, fmt;
5067 const char *fmt_str;
5069 orig_arglist = arglist;
5071 /* Verify the required arguments in the original call. */
5072 if (! arglist)
5073 return 0;
5074 dest = TREE_VALUE (arglist);
5075 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5076 return 0;
5077 arglist = TREE_CHAIN (arglist);
5078 if (! arglist)
5079 return 0;
5080 fmt = TREE_VALUE (arglist);
5081 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5082 return 0;
5083 arglist = TREE_CHAIN (arglist);
5085 /* Check whether the format is a literal string constant. */
5086 fmt_str = c_getstr (fmt);
5087 if (fmt_str == NULL)
5088 return 0;
5090 if (!init_target_chars())
5091 return 0;
5093 /* If the format doesn't contain % args or %%, use strcpy. */
5094 if (strchr (fmt_str, target_percent) == 0)
5096 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5097 tree exp;
5099 if (arglist || ! fn)
5100 return 0;
5101 expand_expr (build_function_call_expr (fn, orig_arglist),
5102 const0_rtx, VOIDmode, EXPAND_NORMAL);
5103 if (target == const0_rtx)
5104 return const0_rtx;
5105 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5106 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5108 /* If the format is "%s", use strcpy if the result isn't used. */
5109 else if (strcmp (fmt_str, target_percent_s) == 0)
5111 tree fn, arg, len;
5112 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5114 if (! fn)
5115 return 0;
5117 if (! arglist || TREE_CHAIN (arglist))
5118 return 0;
5119 arg = TREE_VALUE (arglist);
5120 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5121 return 0;
5123 if (target != const0_rtx)
5125 len = c_strlen (arg, 1);
5126 if (! len || TREE_CODE (len) != INTEGER_CST)
5127 return 0;
5129 else
5130 len = NULL_TREE;
5132 arglist = build_tree_list (NULL_TREE, arg);
5133 arglist = tree_cons (NULL_TREE, dest, arglist);
5134 expand_expr (build_function_call_expr (fn, arglist),
5135 const0_rtx, VOIDmode, EXPAND_NORMAL);
5137 if (target == const0_rtx)
5138 return const0_rtx;
5139 return expand_expr (len, target, mode, EXPAND_NORMAL);
5142 return 0;
5145 /* Expand a call to either the entry or exit function profiler. */
5147 static rtx
5148 expand_builtin_profile_func (bool exitp)
5150 rtx this, which;
5152 this = DECL_RTL (current_function_decl);
5153 gcc_assert (MEM_P (this));
5154 this = XEXP (this, 0);
5156 if (exitp)
5157 which = profile_function_exit_libfunc;
5158 else
5159 which = profile_function_entry_libfunc;
5161 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5162 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5164 Pmode);
5166 return const0_rtx;
5169 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5171 static rtx
5172 round_trampoline_addr (rtx tramp)
5174 rtx temp, addend, mask;
5176 /* If we don't need too much alignment, we'll have been guaranteed
5177 proper alignment by get_trampoline_type. */
5178 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5179 return tramp;
5181 /* Round address up to desired boundary. */
5182 temp = gen_reg_rtx (Pmode);
5183 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5184 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5186 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5187 temp, 0, OPTAB_LIB_WIDEN);
5188 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5189 temp, 0, OPTAB_LIB_WIDEN);
5191 return tramp;
5194 static rtx
5195 expand_builtin_init_trampoline (tree arglist)
5197 tree t_tramp, t_func, t_chain;
5198 rtx r_tramp, r_func, r_chain;
5199 #ifdef TRAMPOLINE_TEMPLATE
5200 rtx blktramp;
5201 #endif
5203 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5204 POINTER_TYPE, VOID_TYPE))
5205 return NULL_RTX;
5207 t_tramp = TREE_VALUE (arglist);
5208 arglist = TREE_CHAIN (arglist);
5209 t_func = TREE_VALUE (arglist);
5210 arglist = TREE_CHAIN (arglist);
5211 t_chain = TREE_VALUE (arglist);
5213 r_tramp = expand_normal (t_tramp);
5214 r_func = expand_normal (t_func);
5215 r_chain = expand_normal (t_chain);
5217 /* Generate insns to initialize the trampoline. */
5218 r_tramp = round_trampoline_addr (r_tramp);
5219 #ifdef TRAMPOLINE_TEMPLATE
5220 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5221 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5222 emit_block_move (blktramp, assemble_trampoline_template (),
5223 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5224 #endif
5225 trampolines_created = 1;
5226 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5228 return const0_rtx;
5231 static rtx
5232 expand_builtin_adjust_trampoline (tree arglist)
5234 rtx tramp;
5236 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5237 return NULL_RTX;
5239 tramp = expand_normal (TREE_VALUE (arglist));
5240 tramp = round_trampoline_addr (tramp);
5241 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5242 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5243 #endif
5245 return tramp;
5248 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5249 Return NULL_RTX if a normal call should be emitted rather than expanding
5250 the function in-line. EXP is the expression that is a call to the builtin
5251 function; if convenient, the result should be placed in TARGET. */
5253 static rtx
5254 expand_builtin_signbit (tree exp, rtx target)
5256 const struct real_format *fmt;
5257 enum machine_mode fmode, imode, rmode;
5258 HOST_WIDE_INT hi, lo;
5259 tree arg, arglist;
5260 int word, bitpos;
5261 rtx temp;
5263 arglist = TREE_OPERAND (exp, 1);
5264 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5265 return 0;
5267 arg = TREE_VALUE (arglist);
5268 fmode = TYPE_MODE (TREE_TYPE (arg));
5269 rmode = TYPE_MODE (TREE_TYPE (exp));
5270 fmt = REAL_MODE_FORMAT (fmode);
5272 /* For floating point formats without a sign bit, implement signbit
5273 as "ARG < 0.0". */
5274 bitpos = fmt->signbit_ro;
5275 if (bitpos < 0)
5277 /* But we can't do this if the format supports signed zero. */
5278 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5279 return 0;
5281 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5282 build_real (TREE_TYPE (arg), dconst0));
5283 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5286 temp = expand_normal (arg);
5287 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5289 imode = int_mode_for_mode (fmode);
5290 if (imode == BLKmode)
5291 return 0;
5292 temp = gen_lowpart (imode, temp);
5294 else
5296 imode = word_mode;
5297 /* Handle targets with different FP word orders. */
5298 if (FLOAT_WORDS_BIG_ENDIAN)
5299 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5300 else
5301 word = bitpos / BITS_PER_WORD;
5302 temp = operand_subword_force (temp, word, fmode);
5303 bitpos = bitpos % BITS_PER_WORD;
5306 /* Force the intermediate word_mode (or narrower) result into a
5307 register. This avoids attempting to create paradoxical SUBREGs
5308 of floating point modes below. */
5309 temp = force_reg (imode, temp);
5311 /* If the bitpos is within the "result mode" lowpart, the operation
5312 can be implement with a single bitwise AND. Otherwise, we need
5313 a right shift and an AND. */
5315 if (bitpos < GET_MODE_BITSIZE (rmode))
5317 if (bitpos < HOST_BITS_PER_WIDE_INT)
5319 hi = 0;
5320 lo = (HOST_WIDE_INT) 1 << bitpos;
5322 else
5324 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5325 lo = 0;
5328 if (imode != rmode)
5329 temp = gen_lowpart (rmode, temp);
5330 temp = expand_binop (rmode, and_optab, temp,
5331 immed_double_const (lo, hi, rmode),
5332 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5334 else
5336 /* Perform a logical right shift to place the signbit in the least
5337 significant bit, then truncate the result to the desired mode
5338 and mask just this bit. */
5339 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5340 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5341 temp = gen_lowpart (rmode, temp);
5342 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5343 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5346 return temp;
5349 /* Expand fork or exec calls. TARGET is the desired target of the
5350 call. ARGLIST is the list of arguments of the call. FN is the
5351 identificator of the actual function. IGNORE is nonzero if the
5352 value is to be ignored. */
5354 static rtx
5355 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5357 tree id, decl;
5358 tree call;
5360 /* If we are not profiling, just call the function. */
5361 if (!profile_arc_flag)
5362 return NULL_RTX;
5364 /* Otherwise call the wrapper. This should be equivalent for the rest of
5365 compiler, so the code does not diverge, and the wrapper may run the
5366 code necessary for keeping the profiling sane. */
5368 switch (DECL_FUNCTION_CODE (fn))
5370 case BUILT_IN_FORK:
5371 id = get_identifier ("__gcov_fork");
5372 break;
5374 case BUILT_IN_EXECL:
5375 id = get_identifier ("__gcov_execl");
5376 break;
5378 case BUILT_IN_EXECV:
5379 id = get_identifier ("__gcov_execv");
5380 break;
5382 case BUILT_IN_EXECLP:
5383 id = get_identifier ("__gcov_execlp");
5384 break;
5386 case BUILT_IN_EXECLE:
5387 id = get_identifier ("__gcov_execle");
5388 break;
5390 case BUILT_IN_EXECVP:
5391 id = get_identifier ("__gcov_execvp");
5392 break;
5394 case BUILT_IN_EXECVE:
5395 id = get_identifier ("__gcov_execve");
5396 break;
5398 default:
5399 gcc_unreachable ();
5402 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5403 DECL_EXTERNAL (decl) = 1;
5404 TREE_PUBLIC (decl) = 1;
5405 DECL_ARTIFICIAL (decl) = 1;
5406 TREE_NOTHROW (decl) = 1;
5407 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5408 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5409 call = build_function_call_expr (decl, arglist);
5411 return expand_call (call, target, ignore);
5415 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5416 the pointer in these functions is void*, the tree optimizers may remove
5417 casts. The mode computed in expand_builtin isn't reliable either, due
5418 to __sync_bool_compare_and_swap.
5420 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5421 group of builtins. This gives us log2 of the mode size. */
5423 static inline enum machine_mode
5424 get_builtin_sync_mode (int fcode_diff)
5426 /* The size is not negotiable, so ask not to get BLKmode in return
5427 if the target indicates that a smaller size would be better. */
5428 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5431 /* Expand the memory expression LOC and return the appropriate memory operand
5432 for the builtin_sync operations. */
5434 static rtx
5435 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5437 rtx addr, mem;
5439 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5441 /* Note that we explicitly do not want any alias information for this
5442 memory, so that we kill all other live memories. Otherwise we don't
5443 satisfy the full barrier semantics of the intrinsic. */
5444 mem = validize_mem (gen_rtx_MEM (mode, addr));
5446 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5447 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5448 MEM_VOLATILE_P (mem) = 1;
5450 return mem;
5453 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5454 ARGLIST is the operands list to the function. CODE is the rtx code
5455 that corresponds to the arithmetic or logical operation from the name;
5456 an exception here is that NOT actually means NAND. TARGET is an optional
5457 place for us to store the results; AFTER is true if this is the
5458 fetch_and_xxx form. IGNORE is true if we don't actually care about
5459 the result of the operation at all. */
5461 static rtx
5462 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5463 enum rtx_code code, bool after,
5464 rtx target, bool ignore)
5466 rtx val, mem;
5468 /* Expand the operands. */
5469 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5471 arglist = TREE_CHAIN (arglist);
5472 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5474 if (ignore)
5475 return expand_sync_operation (mem, val, code);
5476 else
5477 return expand_sync_fetch_operation (mem, val, code, after, target);
5480 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5481 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5482 true if this is the boolean form. TARGET is a place for us to store the
5483 results; this is NOT optional if IS_BOOL is true. */
5485 static rtx
5486 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5487 bool is_bool, rtx target)
5489 rtx old_val, new_val, mem;
5491 /* Expand the operands. */
5492 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5494 arglist = TREE_CHAIN (arglist);
5495 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5497 arglist = TREE_CHAIN (arglist);
5498 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5500 if (is_bool)
5501 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5502 else
5503 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5506 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5507 general form is actually an atomic exchange, and some targets only
5508 support a reduced form with the second argument being a constant 1.
5509 ARGLIST is the operands list to the function; TARGET is an optional
5510 place for us to store the results. */
5512 static rtx
5513 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5514 rtx target)
5516 rtx val, mem;
5518 /* Expand the operands. */
5519 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5521 arglist = TREE_CHAIN (arglist);
5522 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5524 return expand_sync_lock_test_and_set (mem, val, target);
5527 /* Expand the __sync_synchronize intrinsic. */
5529 static void
5530 expand_builtin_synchronize (void)
5532 tree x;
5534 #ifdef HAVE_memory_barrier
5535 if (HAVE_memory_barrier)
5537 emit_insn (gen_memory_barrier ());
5538 return;
5540 #endif
5542 /* If no explicit memory barrier instruction is available, create an
5543 empty asm stmt with a memory clobber. */
5544 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5545 tree_cons (NULL, build_string (6, "memory"), NULL));
5546 ASM_VOLATILE_P (x) = 1;
5547 expand_asm_expr (x);
5550 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5551 to the function. */
5553 static void
5554 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5556 enum insn_code icode;
5557 rtx mem, insn;
5558 rtx val = const0_rtx;
5560 /* Expand the operands. */
5561 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5563 /* If there is an explicit operation in the md file, use it. */
5564 icode = sync_lock_release[mode];
5565 if (icode != CODE_FOR_nothing)
5567 if (!insn_data[icode].operand[1].predicate (val, mode))
5568 val = force_reg (mode, val);
5570 insn = GEN_FCN (icode) (mem, val);
5571 if (insn)
5573 emit_insn (insn);
5574 return;
5578 /* Otherwise we can implement this operation by emitting a barrier
5579 followed by a store of zero. */
5580 expand_builtin_synchronize ();
5581 emit_move_insn (mem, val);
5584 /* Expand an expression EXP that calls a built-in function,
5585 with result going to TARGET if that's convenient
5586 (and in mode MODE if that's convenient).
5587 SUBTARGET may be used as the target for computing one of EXP's operands.
5588 IGNORE is nonzero if the value is to be ignored. */
5591 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5592 int ignore)
5594 tree fndecl = get_callee_fndecl (exp);
5595 tree arglist = TREE_OPERAND (exp, 1);
5596 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5597 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5599 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5600 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5601 else
5603 /* Try expanding the builtin via the generic target hook. */
5604 rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
5605 mode, ignore);
5606 if (tmp != NULL_RTX)
5607 return tmp;
5610 /* When not optimizing, generate calls to library functions for a certain
5611 set of builtins. */
5612 if (!optimize
5613 && !called_as_built_in (fndecl)
5614 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5615 && fcode != BUILT_IN_ALLOCA)
5616 return expand_call (exp, target, ignore);
5618 /* The built-in function expanders test for target == const0_rtx
5619 to determine whether the function's result will be ignored. */
5620 if (ignore)
5621 target = const0_rtx;
5623 /* If the result of a pure or const built-in function is ignored, and
5624 none of its arguments are volatile, we can avoid expanding the
5625 built-in call and just evaluate the arguments for side-effects. */
5626 if (target == const0_rtx
5627 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5629 bool volatilep = false;
5630 tree arg;
5632 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5633 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5635 volatilep = true;
5636 break;
5639 if (! volatilep)
5641 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5642 expand_expr (TREE_VALUE (arg), const0_rtx,
5643 VOIDmode, EXPAND_NORMAL);
5644 return const0_rtx;
5648 switch (fcode)
5650 CASE_FLT_FN (BUILT_IN_FABS):
5651 target = expand_builtin_fabs (arglist, target, subtarget);
5652 if (target)
5653 return target;
5654 break;
5656 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5657 target = expand_builtin_copysign (arglist, target, subtarget);
5658 if (target)
5659 return target;
5660 break;
5662 /* Just do a normal library call if we were unable to fold
5663 the values. */
5664 CASE_FLT_FN (BUILT_IN_CABS):
5665 break;
5667 CASE_FLT_FN (BUILT_IN_EXP):
5668 CASE_FLT_FN (BUILT_IN_EXP10):
5669 CASE_FLT_FN (BUILT_IN_POW10):
5670 CASE_FLT_FN (BUILT_IN_EXP2):
5671 CASE_FLT_FN (BUILT_IN_EXPM1):
5672 CASE_FLT_FN (BUILT_IN_LOGB):
5673 CASE_FLT_FN (BUILT_IN_ILOGB):
5674 CASE_FLT_FN (BUILT_IN_LOG):
5675 CASE_FLT_FN (BUILT_IN_LOG10):
5676 CASE_FLT_FN (BUILT_IN_LOG2):
5677 CASE_FLT_FN (BUILT_IN_LOG1P):
5678 CASE_FLT_FN (BUILT_IN_TAN):
5679 CASE_FLT_FN (BUILT_IN_ASIN):
5680 CASE_FLT_FN (BUILT_IN_ACOS):
5681 CASE_FLT_FN (BUILT_IN_ATAN):
5682 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5683 because of possible accuracy problems. */
5684 if (! flag_unsafe_math_optimizations)
5685 break;
5686 CASE_FLT_FN (BUILT_IN_SQRT):
5687 CASE_FLT_FN (BUILT_IN_FLOOR):
5688 CASE_FLT_FN (BUILT_IN_CEIL):
5689 CASE_FLT_FN (BUILT_IN_TRUNC):
5690 CASE_FLT_FN (BUILT_IN_ROUND):
5691 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5692 CASE_FLT_FN (BUILT_IN_RINT):
5693 CASE_FLT_FN (BUILT_IN_LRINT):
5694 CASE_FLT_FN (BUILT_IN_LLRINT):
5695 target = expand_builtin_mathfn (exp, target, subtarget);
5696 if (target)
5697 return target;
5698 break;
5700 CASE_FLT_FN (BUILT_IN_LCEIL):
5701 CASE_FLT_FN (BUILT_IN_LLCEIL):
5702 CASE_FLT_FN (BUILT_IN_LFLOOR):
5703 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5704 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5705 if (target)
5706 return target;
5707 break;
5709 CASE_FLT_FN (BUILT_IN_POW):
5710 target = expand_builtin_pow (exp, target, subtarget);
5711 if (target)
5712 return target;
5713 break;
5715 CASE_FLT_FN (BUILT_IN_POWI):
5716 target = expand_builtin_powi (exp, target, subtarget);
5717 if (target)
5718 return target;
5719 break;
5721 CASE_FLT_FN (BUILT_IN_ATAN2):
5722 CASE_FLT_FN (BUILT_IN_LDEXP):
5723 CASE_FLT_FN (BUILT_IN_FMOD):
5724 CASE_FLT_FN (BUILT_IN_DREM):
5725 if (! flag_unsafe_math_optimizations)
5726 break;
5727 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5728 if (target)
5729 return target;
5730 break;
5732 CASE_FLT_FN (BUILT_IN_SIN):
5733 CASE_FLT_FN (BUILT_IN_COS):
5734 if (! flag_unsafe_math_optimizations)
5735 break;
5736 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5737 if (target)
5738 return target;
5739 break;
5741 CASE_FLT_FN (BUILT_IN_SINCOS):
5742 if (! flag_unsafe_math_optimizations)
5743 break;
5744 target = expand_builtin_sincos (exp);
5745 if (target)
5746 return target;
5747 break;
5749 case BUILT_IN_APPLY_ARGS:
5750 return expand_builtin_apply_args ();
5752 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5753 FUNCTION with a copy of the parameters described by
5754 ARGUMENTS, and ARGSIZE. It returns a block of memory
5755 allocated on the stack into which is stored all the registers
5756 that might possibly be used for returning the result of a
5757 function. ARGUMENTS is the value returned by
5758 __builtin_apply_args. ARGSIZE is the number of bytes of
5759 arguments that must be copied. ??? How should this value be
5760 computed? We'll also need a safe worst case value for varargs
5761 functions. */
5762 case BUILT_IN_APPLY:
5763 if (!validate_arglist (arglist, POINTER_TYPE,
5764 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5765 && !validate_arglist (arglist, REFERENCE_TYPE,
5766 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5767 return const0_rtx;
5768 else
5770 int i;
5771 tree t;
5772 rtx ops[3];
5774 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5775 ops[i] = expand_normal (TREE_VALUE (t));
5777 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5780 /* __builtin_return (RESULT) causes the function to return the
5781 value described by RESULT. RESULT is address of the block of
5782 memory returned by __builtin_apply. */
5783 case BUILT_IN_RETURN:
5784 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5785 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5786 return const0_rtx;
5788 case BUILT_IN_SAVEREGS:
5789 return expand_builtin_saveregs ();
5791 case BUILT_IN_ARGS_INFO:
5792 return expand_builtin_args_info (arglist);
5794 /* Return the address of the first anonymous stack arg. */
5795 case BUILT_IN_NEXT_ARG:
5796 if (fold_builtin_next_arg (arglist))
5797 return const0_rtx;
5798 return expand_builtin_next_arg ();
5800 case BUILT_IN_CLASSIFY_TYPE:
5801 return expand_builtin_classify_type (arglist);
5803 case BUILT_IN_CONSTANT_P:
5804 return const0_rtx;
5806 case BUILT_IN_FRAME_ADDRESS:
5807 case BUILT_IN_RETURN_ADDRESS:
5808 return expand_builtin_frame_address (fndecl, arglist);
5810 /* Returns the address of the area where the structure is returned.
5811 0 otherwise. */
5812 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5813 if (arglist != 0
5814 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5815 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5816 return const0_rtx;
5817 else
5818 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5820 case BUILT_IN_ALLOCA:
5821 target = expand_builtin_alloca (arglist, target);
5822 if (target)
5823 return target;
5824 break;
5826 case BUILT_IN_STACK_SAVE:
5827 return expand_stack_save ();
5829 case BUILT_IN_STACK_RESTORE:
5830 expand_stack_restore (TREE_VALUE (arglist));
5831 return const0_rtx;
5833 CASE_INT_FN (BUILT_IN_FFS):
5834 case BUILT_IN_FFSIMAX:
5835 target = expand_builtin_unop (target_mode, arglist, target,
5836 subtarget, ffs_optab);
5837 if (target)
5838 return target;
5839 break;
5841 CASE_INT_FN (BUILT_IN_CLZ):
5842 case BUILT_IN_CLZIMAX:
5843 target = expand_builtin_unop (target_mode, arglist, target,
5844 subtarget, clz_optab);
5845 if (target)
5846 return target;
5847 break;
5849 CASE_INT_FN (BUILT_IN_CTZ):
5850 case BUILT_IN_CTZIMAX:
5851 target = expand_builtin_unop (target_mode, arglist, target,
5852 subtarget, ctz_optab);
5853 if (target)
5854 return target;
5855 break;
5857 CASE_INT_FN (BUILT_IN_POPCOUNT):
5858 case BUILT_IN_POPCOUNTIMAX:
5859 target = expand_builtin_unop (target_mode, arglist, target,
5860 subtarget, popcount_optab);
5861 if (target)
5862 return target;
5863 break;
5865 CASE_INT_FN (BUILT_IN_PARITY):
5866 case BUILT_IN_PARITYIMAX:
5867 target = expand_builtin_unop (target_mode, arglist, target,
5868 subtarget, parity_optab);
5869 if (target)
5870 return target;
5871 break;
5873 case BUILT_IN_STRLEN:
5874 target = expand_builtin_strlen (arglist, target, target_mode);
5875 if (target)
5876 return target;
5877 break;
5879 case BUILT_IN_STRCPY:
5880 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5881 if (target)
5882 return target;
5883 break;
5885 case BUILT_IN_STRNCPY:
5886 target = expand_builtin_strncpy (exp, target, mode);
5887 if (target)
5888 return target;
5889 break;
5891 case BUILT_IN_STPCPY:
5892 target = expand_builtin_stpcpy (exp, target, mode);
5893 if (target)
5894 return target;
5895 break;
5897 case BUILT_IN_STRCAT:
5898 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5899 if (target)
5900 return target;
5901 break;
5903 case BUILT_IN_STRNCAT:
5904 target = expand_builtin_strncat (arglist, target, mode);
5905 if (target)
5906 return target;
5907 break;
5909 case BUILT_IN_STRSPN:
5910 target = expand_builtin_strspn (arglist, target, mode);
5911 if (target)
5912 return target;
5913 break;
5915 case BUILT_IN_STRCSPN:
5916 target = expand_builtin_strcspn (arglist, target, mode);
5917 if (target)
5918 return target;
5919 break;
5921 case BUILT_IN_STRSTR:
5922 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5923 if (target)
5924 return target;
5925 break;
5927 case BUILT_IN_STRPBRK:
5928 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5929 if (target)
5930 return target;
5931 break;
5933 case BUILT_IN_INDEX:
5934 case BUILT_IN_STRCHR:
5935 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5936 if (target)
5937 return target;
5938 break;
5940 case BUILT_IN_RINDEX:
5941 case BUILT_IN_STRRCHR:
5942 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5943 if (target)
5944 return target;
5945 break;
5947 case BUILT_IN_MEMCPY:
5948 target = expand_builtin_memcpy (exp, target, mode);
5949 if (target)
5950 return target;
5951 break;
5953 case BUILT_IN_MEMPCPY:
5954 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5955 if (target)
5956 return target;
5957 break;
5959 case BUILT_IN_MEMMOVE:
5960 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5961 mode, exp);
5962 if (target)
5963 return target;
5964 break;
5966 case BUILT_IN_BCOPY:
5967 target = expand_builtin_bcopy (exp);
5968 if (target)
5969 return target;
5970 break;
5972 case BUILT_IN_MEMSET:
5973 target = expand_builtin_memset (arglist, target, mode, exp);
5974 if (target)
5975 return target;
5976 break;
5978 case BUILT_IN_BZERO:
5979 target = expand_builtin_bzero (exp);
5980 if (target)
5981 return target;
5982 break;
5984 case BUILT_IN_STRCMP:
5985 target = expand_builtin_strcmp (exp, target, mode);
5986 if (target)
5987 return target;
5988 break;
5990 case BUILT_IN_STRNCMP:
5991 target = expand_builtin_strncmp (exp, target, mode);
5992 if (target)
5993 return target;
5994 break;
5996 case BUILT_IN_BCMP:
5997 case BUILT_IN_MEMCMP:
5998 target = expand_builtin_memcmp (exp, arglist, target, mode);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_SETJMP:
6004 target = expand_builtin_setjmp (arglist, target);
6005 if (target)
6006 return target;
6007 break;
6009 /* __builtin_longjmp is passed a pointer to an array of five words.
6010 It's similar to the C library longjmp function but works with
6011 __builtin_setjmp above. */
6012 case BUILT_IN_LONGJMP:
6013 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6014 break;
6015 else
6017 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6018 VOIDmode, EXPAND_NORMAL);
6019 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6021 if (value != const1_rtx)
6023 error ("%<__builtin_longjmp%> second argument must be 1");
6024 return const0_rtx;
6027 expand_builtin_longjmp (buf_addr, value);
6028 return const0_rtx;
6031 case BUILT_IN_NONLOCAL_GOTO:
6032 target = expand_builtin_nonlocal_goto (arglist);
6033 if (target)
6034 return target;
6035 break;
6037 /* This updates the setjmp buffer that is its argument with the value
6038 of the current stack pointer. */
6039 case BUILT_IN_UPDATE_SETJMP_BUF:
6040 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6042 rtx buf_addr
6043 = expand_normal (TREE_VALUE (arglist));
6045 expand_builtin_update_setjmp_buf (buf_addr);
6046 return const0_rtx;
6048 break;
6050 case BUILT_IN_TRAP:
6051 expand_builtin_trap ();
6052 return const0_rtx;
6054 case BUILT_IN_PRINTF:
6055 target = expand_builtin_printf (exp, target, mode, false);
6056 if (target)
6057 return target;
6058 break;
6060 case BUILT_IN_PRINTF_UNLOCKED:
6061 target = expand_builtin_printf (exp, target, mode, true);
6062 if (target)
6063 return target;
6064 break;
6066 case BUILT_IN_FPUTS:
6067 target = expand_builtin_fputs (arglist, target, false);
6068 if (target)
6069 return target;
6070 break;
6071 case BUILT_IN_FPUTS_UNLOCKED:
6072 target = expand_builtin_fputs (arglist, target, true);
6073 if (target)
6074 return target;
6075 break;
6077 case BUILT_IN_FPRINTF:
6078 target = expand_builtin_fprintf (exp, target, mode, false);
6079 if (target)
6080 return target;
6081 break;
6083 case BUILT_IN_FPRINTF_UNLOCKED:
6084 target = expand_builtin_fprintf (exp, target, mode, true);
6085 if (target)
6086 return target;
6087 break;
6089 case BUILT_IN_SPRINTF:
6090 target = expand_builtin_sprintf (arglist, target, mode);
6091 if (target)
6092 return target;
6093 break;
6095 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6096 target = expand_builtin_signbit (exp, target);
6097 if (target)
6098 return target;
6099 break;
6101 /* Various hooks for the DWARF 2 __throw routine. */
6102 case BUILT_IN_UNWIND_INIT:
6103 expand_builtin_unwind_init ();
6104 return const0_rtx;
6105 case BUILT_IN_DWARF_CFA:
6106 return virtual_cfa_rtx;
6107 #ifdef DWARF2_UNWIND_INFO
6108 case BUILT_IN_DWARF_SP_COLUMN:
6109 return expand_builtin_dwarf_sp_column ();
6110 case BUILT_IN_INIT_DWARF_REG_SIZES:
6111 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6112 return const0_rtx;
6113 #endif
6114 case BUILT_IN_FROB_RETURN_ADDR:
6115 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6116 case BUILT_IN_EXTRACT_RETURN_ADDR:
6117 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6118 case BUILT_IN_EH_RETURN:
6119 expand_builtin_eh_return (TREE_VALUE (arglist),
6120 TREE_VALUE (TREE_CHAIN (arglist)));
6121 return const0_rtx;
6122 #ifdef EH_RETURN_DATA_REGNO
6123 case BUILT_IN_EH_RETURN_DATA_REGNO:
6124 return expand_builtin_eh_return_data_regno (arglist);
6125 #endif
6126 case BUILT_IN_EXTEND_POINTER:
6127 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6129 case BUILT_IN_VA_START:
6130 case BUILT_IN_STDARG_START:
6131 return expand_builtin_va_start (arglist);
6132 case BUILT_IN_VA_END:
6133 return expand_builtin_va_end (arglist);
6134 case BUILT_IN_VA_COPY:
6135 return expand_builtin_va_copy (arglist);
6136 case BUILT_IN_EXPECT:
6137 return expand_builtin_expect (arglist, target);
6138 case BUILT_IN_PREFETCH:
6139 expand_builtin_prefetch (arglist);
6140 return const0_rtx;
6142 case BUILT_IN_PROFILE_FUNC_ENTER:
6143 return expand_builtin_profile_func (false);
6144 case BUILT_IN_PROFILE_FUNC_EXIT:
6145 return expand_builtin_profile_func (true);
6147 case BUILT_IN_INIT_TRAMPOLINE:
6148 return expand_builtin_init_trampoline (arglist);
6149 case BUILT_IN_ADJUST_TRAMPOLINE:
6150 return expand_builtin_adjust_trampoline (arglist);
6152 case BUILT_IN_FORK:
6153 case BUILT_IN_EXECL:
6154 case BUILT_IN_EXECV:
6155 case BUILT_IN_EXECLP:
6156 case BUILT_IN_EXECLE:
6157 case BUILT_IN_EXECVP:
6158 case BUILT_IN_EXECVE:
6159 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6160 if (target)
6161 return target;
6162 break;
6164 case BUILT_IN_FETCH_AND_ADD_1:
6165 case BUILT_IN_FETCH_AND_ADD_2:
6166 case BUILT_IN_FETCH_AND_ADD_4:
6167 case BUILT_IN_FETCH_AND_ADD_8:
6168 case BUILT_IN_FETCH_AND_ADD_16:
6169 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6170 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6171 false, target, ignore);
6172 if (target)
6173 return target;
6174 break;
6176 case BUILT_IN_FETCH_AND_SUB_1:
6177 case BUILT_IN_FETCH_AND_SUB_2:
6178 case BUILT_IN_FETCH_AND_SUB_4:
6179 case BUILT_IN_FETCH_AND_SUB_8:
6180 case BUILT_IN_FETCH_AND_SUB_16:
6181 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6182 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6183 false, target, ignore);
6184 if (target)
6185 return target;
6186 break;
6188 case BUILT_IN_FETCH_AND_OR_1:
6189 case BUILT_IN_FETCH_AND_OR_2:
6190 case BUILT_IN_FETCH_AND_OR_4:
6191 case BUILT_IN_FETCH_AND_OR_8:
6192 case BUILT_IN_FETCH_AND_OR_16:
6193 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6194 target = expand_builtin_sync_operation (mode, arglist, IOR,
6195 false, target, ignore);
6196 if (target)
6197 return target;
6198 break;
6200 case BUILT_IN_FETCH_AND_AND_1:
6201 case BUILT_IN_FETCH_AND_AND_2:
6202 case BUILT_IN_FETCH_AND_AND_4:
6203 case BUILT_IN_FETCH_AND_AND_8:
6204 case BUILT_IN_FETCH_AND_AND_16:
6205 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6206 target = expand_builtin_sync_operation (mode, arglist, AND,
6207 false, target, ignore);
6208 if (target)
6209 return target;
6210 break;
6212 case BUILT_IN_FETCH_AND_XOR_1:
6213 case BUILT_IN_FETCH_AND_XOR_2:
6214 case BUILT_IN_FETCH_AND_XOR_4:
6215 case BUILT_IN_FETCH_AND_XOR_8:
6216 case BUILT_IN_FETCH_AND_XOR_16:
6217 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6218 target = expand_builtin_sync_operation (mode, arglist, XOR,
6219 false, target, ignore);
6220 if (target)
6221 return target;
6222 break;
6224 case BUILT_IN_FETCH_AND_NAND_1:
6225 case BUILT_IN_FETCH_AND_NAND_2:
6226 case BUILT_IN_FETCH_AND_NAND_4:
6227 case BUILT_IN_FETCH_AND_NAND_8:
6228 case BUILT_IN_FETCH_AND_NAND_16:
6229 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6230 target = expand_builtin_sync_operation (mode, arglist, NOT,
6231 false, target, ignore);
6232 if (target)
6233 return target;
6234 break;
6236 case BUILT_IN_ADD_AND_FETCH_1:
6237 case BUILT_IN_ADD_AND_FETCH_2:
6238 case BUILT_IN_ADD_AND_FETCH_4:
6239 case BUILT_IN_ADD_AND_FETCH_8:
6240 case BUILT_IN_ADD_AND_FETCH_16:
6241 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6242 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6243 true, target, ignore);
6244 if (target)
6245 return target;
6246 break;
6248 case BUILT_IN_SUB_AND_FETCH_1:
6249 case BUILT_IN_SUB_AND_FETCH_2:
6250 case BUILT_IN_SUB_AND_FETCH_4:
6251 case BUILT_IN_SUB_AND_FETCH_8:
6252 case BUILT_IN_SUB_AND_FETCH_16:
6253 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6254 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6255 true, target, ignore);
6256 if (target)
6257 return target;
6258 break;
6260 case BUILT_IN_OR_AND_FETCH_1:
6261 case BUILT_IN_OR_AND_FETCH_2:
6262 case BUILT_IN_OR_AND_FETCH_4:
6263 case BUILT_IN_OR_AND_FETCH_8:
6264 case BUILT_IN_OR_AND_FETCH_16:
6265 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6266 target = expand_builtin_sync_operation (mode, arglist, IOR,
6267 true, target, ignore);
6268 if (target)
6269 return target;
6270 break;
6272 case BUILT_IN_AND_AND_FETCH_1:
6273 case BUILT_IN_AND_AND_FETCH_2:
6274 case BUILT_IN_AND_AND_FETCH_4:
6275 case BUILT_IN_AND_AND_FETCH_8:
6276 case BUILT_IN_AND_AND_FETCH_16:
6277 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6278 target = expand_builtin_sync_operation (mode, arglist, AND,
6279 true, target, ignore);
6280 if (target)
6281 return target;
6282 break;
6284 case BUILT_IN_XOR_AND_FETCH_1:
6285 case BUILT_IN_XOR_AND_FETCH_2:
6286 case BUILT_IN_XOR_AND_FETCH_4:
6287 case BUILT_IN_XOR_AND_FETCH_8:
6288 case BUILT_IN_XOR_AND_FETCH_16:
6289 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6290 target = expand_builtin_sync_operation (mode, arglist, XOR,
6291 true, target, ignore);
6292 if (target)
6293 return target;
6294 break;
6296 case BUILT_IN_NAND_AND_FETCH_1:
6297 case BUILT_IN_NAND_AND_FETCH_2:
6298 case BUILT_IN_NAND_AND_FETCH_4:
6299 case BUILT_IN_NAND_AND_FETCH_8:
6300 case BUILT_IN_NAND_AND_FETCH_16:
6301 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6302 target = expand_builtin_sync_operation (mode, arglist, NOT,
6303 true, target, ignore);
6304 if (target)
6305 return target;
6306 break;
6308 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6309 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6310 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6311 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6312 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6313 if (mode == VOIDmode)
6314 mode = TYPE_MODE (boolean_type_node);
6315 if (!target || !register_operand (target, mode))
6316 target = gen_reg_rtx (mode);
6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6319 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6320 if (target)
6321 return target;
6322 break;
6324 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6325 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6326 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6327 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6328 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6329 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6330 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6331 if (target)
6332 return target;
6333 break;
6335 case BUILT_IN_LOCK_TEST_AND_SET_1:
6336 case BUILT_IN_LOCK_TEST_AND_SET_2:
6337 case BUILT_IN_LOCK_TEST_AND_SET_4:
6338 case BUILT_IN_LOCK_TEST_AND_SET_8:
6339 case BUILT_IN_LOCK_TEST_AND_SET_16:
6340 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6341 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6342 if (target)
6343 return target;
6344 break;
6346 case BUILT_IN_LOCK_RELEASE_1:
6347 case BUILT_IN_LOCK_RELEASE_2:
6348 case BUILT_IN_LOCK_RELEASE_4:
6349 case BUILT_IN_LOCK_RELEASE_8:
6350 case BUILT_IN_LOCK_RELEASE_16:
6351 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6352 expand_builtin_lock_release (mode, arglist);
6353 return const0_rtx;
6355 case BUILT_IN_SYNCHRONIZE:
6356 expand_builtin_synchronize ();
6357 return const0_rtx;
6359 case BUILT_IN_OBJECT_SIZE:
6360 return expand_builtin_object_size (exp);
6362 case BUILT_IN_MEMCPY_CHK:
6363 case BUILT_IN_MEMPCPY_CHK:
6364 case BUILT_IN_MEMMOVE_CHK:
6365 case BUILT_IN_MEMSET_CHK:
6366 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6367 if (target)
6368 return target;
6369 break;
6371 case BUILT_IN_STRCPY_CHK:
6372 case BUILT_IN_STPCPY_CHK:
6373 case BUILT_IN_STRNCPY_CHK:
6374 case BUILT_IN_STRCAT_CHK:
6375 case BUILT_IN_SNPRINTF_CHK:
6376 case BUILT_IN_VSNPRINTF_CHK:
6377 maybe_emit_chk_warning (exp, fcode);
6378 break;
6380 case BUILT_IN_SPRINTF_CHK:
6381 case BUILT_IN_VSPRINTF_CHK:
6382 maybe_emit_sprintf_chk_warning (exp, fcode);
6383 break;
6385 default: /* just do library call, if unknown builtin */
6386 break;
6389 /* The switch statement above can drop through to cause the function
6390 to be called normally. */
6391 return expand_call (exp, target, ignore);
6394 /* Determine whether a tree node represents a call to a built-in
6395 function. If the tree T is a call to a built-in function with
6396 the right number of arguments of the appropriate types, return
6397 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6398 Otherwise the return value is END_BUILTINS. */
6400 enum built_in_function
6401 builtin_mathfn_code (tree t)
6403 tree fndecl, arglist, parmlist;
6404 tree argtype, parmtype;
6406 if (TREE_CODE (t) != CALL_EXPR
6407 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6408 return END_BUILTINS;
6410 fndecl = get_callee_fndecl (t);
6411 if (fndecl == NULL_TREE
6412 || TREE_CODE (fndecl) != FUNCTION_DECL
6413 || ! DECL_BUILT_IN (fndecl)
6414 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6415 return END_BUILTINS;
6417 arglist = TREE_OPERAND (t, 1);
6418 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6419 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6421 /* If a function doesn't take a variable number of arguments,
6422 the last element in the list will have type `void'. */
6423 parmtype = TREE_VALUE (parmlist);
6424 if (VOID_TYPE_P (parmtype))
6426 if (arglist)
6427 return END_BUILTINS;
6428 return DECL_FUNCTION_CODE (fndecl);
6431 if (! arglist)
6432 return END_BUILTINS;
6434 argtype = TREE_TYPE (TREE_VALUE (arglist));
6436 if (SCALAR_FLOAT_TYPE_P (parmtype))
6438 if (! SCALAR_FLOAT_TYPE_P (argtype))
6439 return END_BUILTINS;
6441 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6443 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6444 return END_BUILTINS;
6446 else if (POINTER_TYPE_P (parmtype))
6448 if (! POINTER_TYPE_P (argtype))
6449 return END_BUILTINS;
6451 else if (INTEGRAL_TYPE_P (parmtype))
6453 if (! INTEGRAL_TYPE_P (argtype))
6454 return END_BUILTINS;
6456 else
6457 return END_BUILTINS;
6459 arglist = TREE_CHAIN (arglist);
6462 /* Variable-length argument list. */
6463 return DECL_FUNCTION_CODE (fndecl);
6466 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6467 constant. ARGLIST is the argument list of the call. */
6469 static tree
6470 fold_builtin_constant_p (tree arglist)
6472 if (arglist == 0)
6473 return 0;
6475 arglist = TREE_VALUE (arglist);
6477 /* We return 1 for a numeric type that's known to be a constant
6478 value at compile-time or for an aggregate type that's a
6479 literal constant. */
6480 STRIP_NOPS (arglist);
6482 /* If we know this is a constant, emit the constant of one. */
6483 if (CONSTANT_CLASS_P (arglist)
6484 || (TREE_CODE (arglist) == CONSTRUCTOR
6485 && TREE_CONSTANT (arglist)))
6486 return integer_one_node;
6487 if (TREE_CODE (arglist) == ADDR_EXPR)
6489 tree op = TREE_OPERAND (arglist, 0);
6490 if (TREE_CODE (op) == STRING_CST
6491 || (TREE_CODE (op) == ARRAY_REF
6492 && integer_zerop (TREE_OPERAND (op, 1))
6493 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6494 return integer_one_node;
6497 /* If this expression has side effects, show we don't know it to be a
6498 constant. Likewise if it's a pointer or aggregate type since in
6499 those case we only want literals, since those are only optimized
6500 when generating RTL, not later.
6501 And finally, if we are compiling an initializer, not code, we
6502 need to return a definite result now; there's not going to be any
6503 more optimization done. */
6504 if (TREE_SIDE_EFFECTS (arglist)
6505 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6506 || POINTER_TYPE_P (TREE_TYPE (arglist))
6507 || cfun == 0)
6508 return integer_zero_node;
6510 return 0;
6513 /* Fold a call to __builtin_expect, if we expect that a comparison against
6514 the argument will fold to a constant. In practice, this means a true
6515 constant or the address of a non-weak symbol. ARGLIST is the argument
6516 list of the call. */
6518 static tree
6519 fold_builtin_expect (tree arglist)
6521 tree arg, inner;
6523 if (arglist == 0)
6524 return 0;
6526 arg = TREE_VALUE (arglist);
6528 /* If the argument isn't invariant, then there's nothing we can do. */
6529 if (!TREE_INVARIANT (arg))
6530 return 0;
6532 /* If we're looking at an address of a weak decl, then do not fold. */
6533 inner = arg;
6534 STRIP_NOPS (inner);
6535 if (TREE_CODE (inner) == ADDR_EXPR)
6539 inner = TREE_OPERAND (inner, 0);
6541 while (TREE_CODE (inner) == COMPONENT_REF
6542 || TREE_CODE (inner) == ARRAY_REF);
6543 if (DECL_P (inner) && DECL_WEAK (inner))
6544 return 0;
6547 /* Otherwise, ARG already has the proper type for the return value. */
6548 return arg;
6551 /* Fold a call to __builtin_classify_type. */
6553 static tree
6554 fold_builtin_classify_type (tree arglist)
6556 if (arglist == 0)
6557 return build_int_cst (NULL_TREE, no_type_class);
6559 return build_int_cst (NULL_TREE,
6560 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6563 /* Fold a call to __builtin_strlen. */
6565 static tree
6566 fold_builtin_strlen (tree arglist)
6568 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6569 return NULL_TREE;
6570 else
6572 tree len = c_strlen (TREE_VALUE (arglist), 0);
6574 if (len)
6576 /* Convert from the internal "sizetype" type to "size_t". */
6577 if (size_type_node)
6578 len = fold_convert (size_type_node, len);
6579 return len;
6582 return NULL_TREE;
6586 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6588 static tree
6589 fold_builtin_inf (tree type, int warn)
6591 REAL_VALUE_TYPE real;
6593 /* __builtin_inff is intended to be usable to define INFINITY on all
6594 targets. If an infinity is not available, INFINITY expands "to a
6595 positive constant of type float that overflows at translation
6596 time", footnote "In this case, using INFINITY will violate the
6597 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6598 Thus we pedwarn to ensure this constraint violation is
6599 diagnosed. */
6600 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6601 pedwarn ("target format does not support infinity");
6603 real_inf (&real);
6604 return build_real (type, real);
6607 /* Fold a call to __builtin_nan or __builtin_nans. */
6609 static tree
6610 fold_builtin_nan (tree arglist, tree type, int quiet)
6612 REAL_VALUE_TYPE real;
6613 const char *str;
6615 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6616 return 0;
6617 str = c_getstr (TREE_VALUE (arglist));
6618 if (!str)
6619 return 0;
6621 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6622 return 0;
6624 return build_real (type, real);
6627 /* Return true if the floating point expression T has an integer value.
6628 We also allow +Inf, -Inf and NaN to be considered integer values. */
6630 static bool
6631 integer_valued_real_p (tree t)
6633 switch (TREE_CODE (t))
6635 case FLOAT_EXPR:
6636 return true;
6638 case ABS_EXPR:
6639 case SAVE_EXPR:
6640 case NON_LVALUE_EXPR:
6641 return integer_valued_real_p (TREE_OPERAND (t, 0));
6643 case COMPOUND_EXPR:
6644 case MODIFY_EXPR:
6645 case BIND_EXPR:
6646 return integer_valued_real_p (TREE_OPERAND (t, 1));
6648 case PLUS_EXPR:
6649 case MINUS_EXPR:
6650 case MULT_EXPR:
6651 case MIN_EXPR:
6652 case MAX_EXPR:
6653 return integer_valued_real_p (TREE_OPERAND (t, 0))
6654 && integer_valued_real_p (TREE_OPERAND (t, 1));
6656 case COND_EXPR:
6657 return integer_valued_real_p (TREE_OPERAND (t, 1))
6658 && integer_valued_real_p (TREE_OPERAND (t, 2));
6660 case REAL_CST:
6661 if (! TREE_CONSTANT_OVERFLOW (t))
6663 REAL_VALUE_TYPE c, cint;
6665 c = TREE_REAL_CST (t);
6666 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6667 return real_identical (&c, &cint);
6669 break;
6671 case NOP_EXPR:
6673 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6674 if (TREE_CODE (type) == INTEGER_TYPE)
6675 return true;
6676 if (TREE_CODE (type) == REAL_TYPE)
6677 return integer_valued_real_p (TREE_OPERAND (t, 0));
6678 break;
6681 case CALL_EXPR:
6682 switch (builtin_mathfn_code (t))
6684 CASE_FLT_FN (BUILT_IN_CEIL):
6685 CASE_FLT_FN (BUILT_IN_FLOOR):
6686 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6687 CASE_FLT_FN (BUILT_IN_RINT):
6688 CASE_FLT_FN (BUILT_IN_ROUND):
6689 CASE_FLT_FN (BUILT_IN_TRUNC):
6690 return true;
6692 default:
6693 break;
6695 break;
6697 default:
6698 break;
6700 return false;
6703 /* EXP is assumed to be builtin call where truncation can be propagated
6704 across (for instance floor((double)f) == (double)floorf (f).
6705 Do the transformation. */
6707 static tree
6708 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6710 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6711 tree arg;
6713 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6714 return 0;
6716 arg = TREE_VALUE (arglist);
6717 /* Integer rounding functions are idempotent. */
6718 if (fcode == builtin_mathfn_code (arg))
6719 return arg;
6721 /* If argument is already integer valued, and we don't need to worry
6722 about setting errno, there's no need to perform rounding. */
6723 if (! flag_errno_math && integer_valued_real_p (arg))
6724 return arg;
6726 if (optimize)
6728 tree arg0 = strip_float_extensions (arg);
6729 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6730 tree newtype = TREE_TYPE (arg0);
6731 tree decl;
6733 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6734 && (decl = mathfn_built_in (newtype, fcode)))
6736 arglist =
6737 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6738 return fold_convert (ftype,
6739 build_function_call_expr (decl, arglist));
6742 return 0;
6745 /* EXP is assumed to be builtin call which can narrow the FP type of
6746 the argument, for instance lround((double)f) -> lroundf (f). */
6748 static tree
6749 fold_fixed_mathfn (tree fndecl, tree arglist)
6751 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6752 tree arg;
6754 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6755 return 0;
6757 arg = TREE_VALUE (arglist);
6759 /* If argument is already integer valued, and we don't need to worry
6760 about setting errno, there's no need to perform rounding. */
6761 if (! flag_errno_math && integer_valued_real_p (arg))
6762 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6764 if (optimize)
6766 tree ftype = TREE_TYPE (arg);
6767 tree arg0 = strip_float_extensions (arg);
6768 tree newtype = TREE_TYPE (arg0);
6769 tree decl;
6771 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6772 && (decl = mathfn_built_in (newtype, fcode)))
6774 arglist =
6775 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6776 return build_function_call_expr (decl, arglist);
6779 return 0;
6782 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6783 is the argument list and TYPE is the return type. Return
6784 NULL_TREE if no if no simplification can be made. */
6786 static tree
6787 fold_builtin_cabs (tree arglist, tree type)
6789 tree arg;
6791 if (!arglist || TREE_CHAIN (arglist))
6792 return NULL_TREE;
6794 arg = TREE_VALUE (arglist);
6795 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6796 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6797 return NULL_TREE;
6799 /* Evaluate cabs of a constant at compile-time. */
6800 if (flag_unsafe_math_optimizations
6801 && TREE_CODE (arg) == COMPLEX_CST
6802 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6803 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6804 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6805 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6807 REAL_VALUE_TYPE r, i;
6809 r = TREE_REAL_CST (TREE_REALPART (arg));
6810 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6812 real_arithmetic (&r, MULT_EXPR, &r, &r);
6813 real_arithmetic (&i, MULT_EXPR, &i, &i);
6814 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6815 if (real_sqrt (&r, TYPE_MODE (type), &r)
6816 || ! flag_trapping_math)
6817 return build_real (type, r);
6820 /* If either part is zero, cabs is fabs of the other. */
6821 if (TREE_CODE (arg) == COMPLEX_EXPR
6822 && real_zerop (TREE_OPERAND (arg, 0)))
6823 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6824 if (TREE_CODE (arg) == COMPLEX_EXPR
6825 && real_zerop (TREE_OPERAND (arg, 1)))
6826 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6828 /* Don't do this when optimizing for size. */
6829 if (flag_unsafe_math_optimizations
6830 && optimize && !optimize_size)
6832 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6834 if (sqrtfn != NULL_TREE)
6836 tree rpart, ipart, result, arglist;
6838 arg = builtin_save_expr (arg);
6840 rpart = fold_build1 (REALPART_EXPR, type, arg);
6841 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6843 rpart = builtin_save_expr (rpart);
6844 ipart = builtin_save_expr (ipart);
6846 result = fold_build2 (PLUS_EXPR, type,
6847 fold_build2 (MULT_EXPR, type,
6848 rpart, rpart),
6849 fold_build2 (MULT_EXPR, type,
6850 ipart, ipart));
6852 arglist = build_tree_list (NULL_TREE, result);
6853 return build_function_call_expr (sqrtfn, arglist);
6857 return NULL_TREE;
6860 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6861 NULL_TREE if no simplification can be made. */
6863 static tree
6864 fold_builtin_sqrt (tree arglist, tree type)
6867 enum built_in_function fcode;
6868 tree arg = TREE_VALUE (arglist);
6870 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6871 return NULL_TREE;
6873 /* Optimize sqrt of constant value. */
6874 if (TREE_CODE (arg) == REAL_CST
6875 && ! TREE_CONSTANT_OVERFLOW (arg))
6877 REAL_VALUE_TYPE r, x;
6879 x = TREE_REAL_CST (arg);
6880 if (real_sqrt (&r, TYPE_MODE (type), &x)
6881 || (!flag_trapping_math && !flag_errno_math))
6882 return build_real (type, r);
6885 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6886 fcode = builtin_mathfn_code (arg);
6887 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6889 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6890 arg = fold_build2 (MULT_EXPR, type,
6891 TREE_VALUE (TREE_OPERAND (arg, 1)),
6892 build_real (type, dconsthalf));
6893 arglist = build_tree_list (NULL_TREE, arg);
6894 return build_function_call_expr (expfn, arglist);
6897 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6898 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6900 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6902 if (powfn)
6904 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6905 tree tree_root;
6906 /* The inner root was either sqrt or cbrt. */
6907 REAL_VALUE_TYPE dconstroot =
6908 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6910 /* Adjust for the outer root. */
6911 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6912 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6913 tree_root = build_real (type, dconstroot);
6914 arglist = tree_cons (NULL_TREE, arg0,
6915 build_tree_list (NULL_TREE, tree_root));
6916 return build_function_call_expr (powfn, arglist);
6920 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6921 if (flag_unsafe_math_optimizations
6922 && (fcode == BUILT_IN_POW
6923 || fcode == BUILT_IN_POWF
6924 || fcode == BUILT_IN_POWL))
6926 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6927 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6928 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6929 tree narg1;
6930 if (!tree_expr_nonnegative_p (arg0))
6931 arg0 = build1 (ABS_EXPR, type, arg0);
6932 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6933 build_real (type, dconsthalf));
6934 arglist = tree_cons (NULL_TREE, arg0,
6935 build_tree_list (NULL_TREE, narg1));
6936 return build_function_call_expr (powfn, arglist);
6939 return NULL_TREE;
6942 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6943 NULL_TREE if no simplification can be made. */
6944 static tree
6945 fold_builtin_cbrt (tree arglist, tree type)
6947 tree arg = TREE_VALUE (arglist);
6948 const enum built_in_function fcode = builtin_mathfn_code (arg);
6950 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6951 return NULL_TREE;
6953 /* Optimize cbrt of constant value. */
6954 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6955 return arg;
6957 if (flag_unsafe_math_optimizations)
6959 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6960 if (BUILTIN_EXPONENT_P (fcode))
6962 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6963 const REAL_VALUE_TYPE third_trunc =
6964 real_value_truncate (TYPE_MODE (type), dconstthird);
6965 arg = fold_build2 (MULT_EXPR, type,
6966 TREE_VALUE (TREE_OPERAND (arg, 1)),
6967 build_real (type, third_trunc));
6968 arglist = build_tree_list (NULL_TREE, arg);
6969 return build_function_call_expr (expfn, arglist);
6972 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6973 if (BUILTIN_SQRT_P (fcode))
6975 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6977 if (powfn)
6979 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6980 tree tree_root;
6981 REAL_VALUE_TYPE dconstroot = dconstthird;
6983 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6984 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6985 tree_root = build_real (type, dconstroot);
6986 arglist = tree_cons (NULL_TREE, arg0,
6987 build_tree_list (NULL_TREE, tree_root));
6988 return build_function_call_expr (powfn, arglist);
6992 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6993 if (BUILTIN_CBRT_P (fcode))
6995 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6996 if (tree_expr_nonnegative_p (arg0))
6998 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7000 if (powfn)
7002 tree tree_root;
7003 REAL_VALUE_TYPE dconstroot;
7005 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7006 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7007 tree_root = build_real (type, dconstroot);
7008 arglist = tree_cons (NULL_TREE, arg0,
7009 build_tree_list (NULL_TREE, tree_root));
7010 return build_function_call_expr (powfn, arglist);
7015 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7016 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7017 || fcode == BUILT_IN_POWL)
7019 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7020 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7021 if (tree_expr_nonnegative_p (arg00))
7023 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7024 const REAL_VALUE_TYPE dconstroot
7025 = real_value_truncate (TYPE_MODE (type), dconstthird);
7026 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7027 build_real (type, dconstroot));
7028 arglist = tree_cons (NULL_TREE, arg00,
7029 build_tree_list (NULL_TREE, narg01));
7030 return build_function_call_expr (powfn, arglist);
7034 return NULL_TREE;
7037 /* Fold function call to builtin sin, sinf, or sinl. Return
7038 NULL_TREE if no simplification can be made. */
7039 static tree
7040 fold_builtin_sin (tree arglist)
7042 tree arg = TREE_VALUE (arglist);
7044 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7045 return NULL_TREE;
7047 /* Optimize sin (0.0) = 0.0. */
7048 if (real_zerop (arg))
7049 return arg;
7051 return NULL_TREE;
7054 /* Fold function call to builtin cos, cosf, or cosl. Return
7055 NULL_TREE if no simplification can be made. */
7056 static tree
7057 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7059 tree arg = TREE_VALUE (arglist);
7061 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7062 return NULL_TREE;
7064 /* Optimize cos (0.0) = 1.0. */
7065 if (real_zerop (arg))
7066 return build_real (type, dconst1);
7068 /* Optimize cos(-x) into cos (x). */
7069 if (TREE_CODE (arg) == NEGATE_EXPR)
7071 tree args = build_tree_list (NULL_TREE,
7072 TREE_OPERAND (arg, 0));
7073 return build_function_call_expr (fndecl, args);
7076 return NULL_TREE;
7079 /* Fold function call to builtin tan, tanf, or tanl. Return
7080 NULL_TREE if no simplification can be made. */
7081 static tree
7082 fold_builtin_tan (tree arglist)
7084 enum built_in_function fcode;
7085 tree arg = TREE_VALUE (arglist);
7087 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7088 return NULL_TREE;
7090 /* Optimize tan(0.0) = 0.0. */
7091 if (real_zerop (arg))
7092 return arg;
7094 /* Optimize tan(atan(x)) = x. */
7095 fcode = builtin_mathfn_code (arg);
7096 if (flag_unsafe_math_optimizations
7097 && (fcode == BUILT_IN_ATAN
7098 || fcode == BUILT_IN_ATANF
7099 || fcode == BUILT_IN_ATANL))
7100 return TREE_VALUE (TREE_OPERAND (arg, 1));
7102 return NULL_TREE;
7105 /* Fold function call to builtin atan, atanf, or atanl. Return
7106 NULL_TREE if no simplification can be made. */
7108 static tree
7109 fold_builtin_atan (tree arglist, tree type)
7112 tree arg = TREE_VALUE (arglist);
7114 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7115 return NULL_TREE;
7117 /* Optimize atan(0.0) = 0.0. */
7118 if (real_zerop (arg))
7119 return arg;
7121 /* Optimize atan(1.0) = pi/4. */
7122 if (real_onep (arg))
7124 REAL_VALUE_TYPE cst;
7126 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7127 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7128 return build_real (type, cst);
7131 return NULL_TREE;
7134 /* Fold function call to builtin trunc, truncf or truncl. Return
7135 NULL_TREE if no simplification can be made. */
7137 static tree
7138 fold_builtin_trunc (tree fndecl, tree arglist)
7140 tree arg;
7142 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7143 return 0;
7145 /* Optimize trunc of constant value. */
7146 arg = TREE_VALUE (arglist);
7147 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7149 REAL_VALUE_TYPE r, x;
7150 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7152 x = TREE_REAL_CST (arg);
7153 real_trunc (&r, TYPE_MODE (type), &x);
7154 return build_real (type, r);
7157 return fold_trunc_transparent_mathfn (fndecl, arglist);
7160 /* Fold function call to builtin floor, floorf or floorl. Return
7161 NULL_TREE if no simplification can be made. */
7163 static tree
7164 fold_builtin_floor (tree fndecl, tree arglist)
7166 tree arg;
7168 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7169 return 0;
7171 /* Optimize floor of constant value. */
7172 arg = TREE_VALUE (arglist);
7173 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7175 REAL_VALUE_TYPE x;
7177 x = TREE_REAL_CST (arg);
7178 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7180 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7181 REAL_VALUE_TYPE r;
7183 real_floor (&r, TYPE_MODE (type), &x);
7184 return build_real (type, r);
7188 return fold_trunc_transparent_mathfn (fndecl, arglist);
7191 /* Fold function call to builtin ceil, ceilf or ceill. Return
7192 NULL_TREE if no simplification can be made. */
7194 static tree
7195 fold_builtin_ceil (tree fndecl, tree arglist)
7197 tree arg;
7199 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7200 return 0;
7202 /* Optimize ceil of constant value. */
7203 arg = TREE_VALUE (arglist);
7204 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7206 REAL_VALUE_TYPE x;
7208 x = TREE_REAL_CST (arg);
7209 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7211 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7212 REAL_VALUE_TYPE r;
7214 real_ceil (&r, TYPE_MODE (type), &x);
7215 return build_real (type, r);
7219 return fold_trunc_transparent_mathfn (fndecl, arglist);
7222 /* Fold function call to builtin round, roundf or roundl. Return
7223 NULL_TREE if no simplification can be made. */
7225 static tree
7226 fold_builtin_round (tree fndecl, tree arglist)
7228 tree arg;
7230 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7231 return 0;
7233 /* Optimize round of constant value. */
7234 arg = TREE_VALUE (arglist);
7235 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7237 REAL_VALUE_TYPE x;
7239 x = TREE_REAL_CST (arg);
7240 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7242 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7243 REAL_VALUE_TYPE r;
7245 real_round (&r, TYPE_MODE (type), &x);
7246 return build_real (type, r);
7250 return fold_trunc_transparent_mathfn (fndecl, arglist);
7253 /* Fold function call to builtin lround, lroundf or lroundl (or the
7254 corresponding long long versions) and other rounding functions.
7255 Return NULL_TREE if no simplification can be made. */
7257 static tree
7258 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7260 tree arg;
7262 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7263 return 0;
7265 /* Optimize lround of constant value. */
7266 arg = TREE_VALUE (arglist);
7267 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7269 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7271 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7273 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7274 tree ftype = TREE_TYPE (arg), result;
7275 HOST_WIDE_INT hi, lo;
7276 REAL_VALUE_TYPE r;
7278 switch (DECL_FUNCTION_CODE (fndecl))
7280 CASE_FLT_FN (BUILT_IN_LFLOOR):
7281 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7282 real_floor (&r, TYPE_MODE (ftype), &x);
7283 break;
7285 CASE_FLT_FN (BUILT_IN_LCEIL):
7286 CASE_FLT_FN (BUILT_IN_LLCEIL):
7287 real_ceil (&r, TYPE_MODE (ftype), &x);
7288 break;
7290 CASE_FLT_FN (BUILT_IN_LROUND):
7291 CASE_FLT_FN (BUILT_IN_LLROUND):
7292 real_round (&r, TYPE_MODE (ftype), &x);
7293 break;
7295 default:
7296 gcc_unreachable ();
7299 REAL_VALUE_TO_INT (&lo, &hi, r);
7300 result = build_int_cst_wide (NULL_TREE, lo, hi);
7301 if (int_fits_type_p (result, itype))
7302 return fold_convert (itype, result);
7306 return fold_fixed_mathfn (fndecl, arglist);
7309 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7310 and their long and long long variants (i.e. ffsl and ffsll).
7311 Return NULL_TREE if no simplification can be made. */
7313 static tree
7314 fold_builtin_bitop (tree fndecl, tree arglist)
7316 tree arg;
7318 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7319 return NULL_TREE;
7321 /* Optimize for constant argument. */
7322 arg = TREE_VALUE (arglist);
7323 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7325 HOST_WIDE_INT hi, width, result;
7326 unsigned HOST_WIDE_INT lo;
7327 tree type;
7329 type = TREE_TYPE (arg);
7330 width = TYPE_PRECISION (type);
7331 lo = TREE_INT_CST_LOW (arg);
7333 /* Clear all the bits that are beyond the type's precision. */
7334 if (width > HOST_BITS_PER_WIDE_INT)
7336 hi = TREE_INT_CST_HIGH (arg);
7337 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7338 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7340 else
7342 hi = 0;
7343 if (width < HOST_BITS_PER_WIDE_INT)
7344 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7347 switch (DECL_FUNCTION_CODE (fndecl))
7349 CASE_INT_FN (BUILT_IN_FFS):
7350 if (lo != 0)
7351 result = exact_log2 (lo & -lo) + 1;
7352 else if (hi != 0)
7353 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7354 else
7355 result = 0;
7356 break;
7358 CASE_INT_FN (BUILT_IN_CLZ):
7359 if (hi != 0)
7360 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7361 else if (lo != 0)
7362 result = width - floor_log2 (lo) - 1;
7363 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7364 result = width;
7365 break;
7367 CASE_INT_FN (BUILT_IN_CTZ):
7368 if (lo != 0)
7369 result = exact_log2 (lo & -lo);
7370 else if (hi != 0)
7371 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7372 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7373 result = width;
7374 break;
7376 CASE_INT_FN (BUILT_IN_POPCOUNT):
7377 result = 0;
7378 while (lo)
7379 result++, lo &= lo - 1;
7380 while (hi)
7381 result++, hi &= hi - 1;
7382 break;
7384 CASE_INT_FN (BUILT_IN_PARITY):
7385 result = 0;
7386 while (lo)
7387 result++, lo &= lo - 1;
7388 while (hi)
7389 result++, hi &= hi - 1;
7390 result &= 1;
7391 break;
7393 default:
7394 gcc_unreachable ();
7397 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7400 return NULL_TREE;
7403 /* Return true if EXPR is the real constant contained in VALUE. */
7405 static bool
7406 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7408 STRIP_NOPS (expr);
7410 return ((TREE_CODE (expr) == REAL_CST
7411 && ! TREE_CONSTANT_OVERFLOW (expr)
7412 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7413 || (TREE_CODE (expr) == COMPLEX_CST
7414 && real_dconstp (TREE_REALPART (expr), value)
7415 && real_zerop (TREE_IMAGPART (expr))));
7418 /* A subroutine of fold_builtin to fold the various logarithmic
7419 functions. EXP is the CALL_EXPR of a call to a builtin logN
7420 function. VALUE is the base of the logN function. */
7422 static tree
7423 fold_builtin_logarithm (tree fndecl, tree arglist,
7424 const REAL_VALUE_TYPE *value)
7426 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7428 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7429 tree arg = TREE_VALUE (arglist);
7430 const enum built_in_function fcode = builtin_mathfn_code (arg);
7432 /* Optimize logN(1.0) = 0.0. */
7433 if (real_onep (arg))
7434 return build_real (type, dconst0);
7436 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7437 exactly, then only do this if flag_unsafe_math_optimizations. */
7438 if (exact_real_truncate (TYPE_MODE (type), value)
7439 || flag_unsafe_math_optimizations)
7441 const REAL_VALUE_TYPE value_truncate =
7442 real_value_truncate (TYPE_MODE (type), *value);
7443 if (real_dconstp (arg, &value_truncate))
7444 return build_real (type, dconst1);
7447 /* Special case, optimize logN(expN(x)) = x. */
7448 if (flag_unsafe_math_optimizations
7449 && ((value == &dconste
7450 && (fcode == BUILT_IN_EXP
7451 || fcode == BUILT_IN_EXPF
7452 || fcode == BUILT_IN_EXPL))
7453 || (value == &dconst2
7454 && (fcode == BUILT_IN_EXP2
7455 || fcode == BUILT_IN_EXP2F
7456 || fcode == BUILT_IN_EXP2L))
7457 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7458 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7460 /* Optimize logN(func()) for various exponential functions. We
7461 want to determine the value "x" and the power "exponent" in
7462 order to transform logN(x**exponent) into exponent*logN(x). */
7463 if (flag_unsafe_math_optimizations)
7465 tree exponent = 0, x = 0;
7467 switch (fcode)
7469 CASE_FLT_FN (BUILT_IN_EXP):
7470 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7471 x = build_real (type,
7472 real_value_truncate (TYPE_MODE (type), dconste));
7473 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7474 break;
7475 CASE_FLT_FN (BUILT_IN_EXP2):
7476 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7477 x = build_real (type, dconst2);
7478 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7479 break;
7480 CASE_FLT_FN (BUILT_IN_EXP10):
7481 CASE_FLT_FN (BUILT_IN_POW10):
7482 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7483 x = build_real (type, dconst10);
7484 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7485 break;
7486 CASE_FLT_FN (BUILT_IN_SQRT):
7487 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7488 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7489 exponent = build_real (type, dconsthalf);
7490 break;
7491 CASE_FLT_FN (BUILT_IN_CBRT):
7492 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7493 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7494 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7495 dconstthird));
7496 break;
7497 CASE_FLT_FN (BUILT_IN_POW):
7498 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7499 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7500 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7501 break;
7502 default:
7503 break;
7506 /* Now perform the optimization. */
7507 if (x && exponent)
7509 tree logfn;
7510 arglist = build_tree_list (NULL_TREE, x);
7511 logfn = build_function_call_expr (fndecl, arglist);
7512 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7517 return 0;
7520 /* Fold a builtin function call to pow, powf, or powl. Return
7521 NULL_TREE if no simplification can be made. */
7522 static tree
7523 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7525 tree arg0 = TREE_VALUE (arglist);
7526 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7528 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7529 return NULL_TREE;
7531 /* Optimize pow(1.0,y) = 1.0. */
7532 if (real_onep (arg0))
7533 return omit_one_operand (type, build_real (type, dconst1), arg1);
7535 if (TREE_CODE (arg1) == REAL_CST
7536 && ! TREE_CONSTANT_OVERFLOW (arg1))
7538 REAL_VALUE_TYPE cint;
7539 REAL_VALUE_TYPE c;
7540 HOST_WIDE_INT n;
7542 c = TREE_REAL_CST (arg1);
7544 /* Optimize pow(x,0.0) = 1.0. */
7545 if (REAL_VALUES_EQUAL (c, dconst0))
7546 return omit_one_operand (type, build_real (type, dconst1),
7547 arg0);
7549 /* Optimize pow(x,1.0) = x. */
7550 if (REAL_VALUES_EQUAL (c, dconst1))
7551 return arg0;
7553 /* Optimize pow(x,-1.0) = 1.0/x. */
7554 if (REAL_VALUES_EQUAL (c, dconstm1))
7555 return fold_build2 (RDIV_EXPR, type,
7556 build_real (type, dconst1), arg0);
7558 /* Optimize pow(x,0.5) = sqrt(x). */
7559 if (flag_unsafe_math_optimizations
7560 && REAL_VALUES_EQUAL (c, dconsthalf))
7562 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7564 if (sqrtfn != NULL_TREE)
7566 tree arglist = build_tree_list (NULL_TREE, arg0);
7567 return build_function_call_expr (sqrtfn, arglist);
7571 /* Check for an integer exponent. */
7572 n = real_to_integer (&c);
7573 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7574 if (real_identical (&c, &cint))
7576 /* Attempt to evaluate pow at compile-time. */
7577 if (TREE_CODE (arg0) == REAL_CST
7578 && ! TREE_CONSTANT_OVERFLOW (arg0))
7580 REAL_VALUE_TYPE x;
7581 bool inexact;
7583 x = TREE_REAL_CST (arg0);
7584 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7585 if (flag_unsafe_math_optimizations || !inexact)
7586 return build_real (type, x);
7589 /* Strip sign ops from even integer powers. */
7590 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7592 tree narg0 = fold_strip_sign_ops (arg0);
7593 if (narg0)
7595 arglist = build_tree_list (NULL_TREE, arg1);
7596 arglist = tree_cons (NULL_TREE, narg0, arglist);
7597 return build_function_call_expr (fndecl, arglist);
7603 if (flag_unsafe_math_optimizations)
7605 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7607 /* Optimize pow(expN(x),y) = expN(x*y). */
7608 if (BUILTIN_EXPONENT_P (fcode))
7610 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7611 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7612 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7613 arglist = build_tree_list (NULL_TREE, arg);
7614 return build_function_call_expr (expfn, arglist);
7617 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7618 if (BUILTIN_SQRT_P (fcode))
7620 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7621 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7622 build_real (type, dconsthalf));
7624 arglist = tree_cons (NULL_TREE, narg0,
7625 build_tree_list (NULL_TREE, narg1));
7626 return build_function_call_expr (fndecl, arglist);
7629 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7630 if (BUILTIN_CBRT_P (fcode))
7632 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7633 if (tree_expr_nonnegative_p (arg))
7635 const REAL_VALUE_TYPE dconstroot
7636 = real_value_truncate (TYPE_MODE (type), dconstthird);
7637 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7638 build_real (type, dconstroot));
7639 arglist = tree_cons (NULL_TREE, arg,
7640 build_tree_list (NULL_TREE, narg1));
7641 return build_function_call_expr (fndecl, arglist);
7645 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7646 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7647 || fcode == BUILT_IN_POWL)
7649 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7650 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7651 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7652 arglist = tree_cons (NULL_TREE, arg00,
7653 build_tree_list (NULL_TREE, narg1));
7654 return build_function_call_expr (fndecl, arglist);
7658 return NULL_TREE;
7661 /* Fold a builtin function call to powi, powif, or powil. Return
7662 NULL_TREE if no simplification can be made. */
7663 static tree
7664 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7666 tree arg0 = TREE_VALUE (arglist);
7667 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7669 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7670 return NULL_TREE;
7672 /* Optimize pow(1.0,y) = 1.0. */
7673 if (real_onep (arg0))
7674 return omit_one_operand (type, build_real (type, dconst1), arg1);
7676 if (host_integerp (arg1, 0))
7678 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7680 /* Evaluate powi at compile-time. */
7681 if (TREE_CODE (arg0) == REAL_CST
7682 && ! TREE_CONSTANT_OVERFLOW (arg0))
7684 REAL_VALUE_TYPE x;
7685 x = TREE_REAL_CST (arg0);
7686 real_powi (&x, TYPE_MODE (type), &x, c);
7687 return build_real (type, x);
7690 /* Optimize pow(x,0) = 1.0. */
7691 if (c == 0)
7692 return omit_one_operand (type, build_real (type, dconst1),
7693 arg0);
7695 /* Optimize pow(x,1) = x. */
7696 if (c == 1)
7697 return arg0;
7699 /* Optimize pow(x,-1) = 1.0/x. */
7700 if (c == -1)
7701 return fold_build2 (RDIV_EXPR, type,
7702 build_real (type, dconst1), arg0);
7705 return NULL_TREE;
7708 /* A subroutine of fold_builtin to fold the various exponent
7709 functions. EXP is the CALL_EXPR of a call to a builtin function.
7710 VALUE is the value which will be raised to a power. */
7712 static tree
7713 fold_builtin_exponent (tree fndecl, tree arglist,
7714 const REAL_VALUE_TYPE *value)
7716 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7718 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7719 tree arg = TREE_VALUE (arglist);
7721 /* Optimize exp*(0.0) = 1.0. */
7722 if (real_zerop (arg))
7723 return build_real (type, dconst1);
7725 /* Optimize expN(1.0) = N. */
7726 if (real_onep (arg))
7728 REAL_VALUE_TYPE cst;
7730 real_convert (&cst, TYPE_MODE (type), value);
7731 return build_real (type, cst);
7734 /* Attempt to evaluate expN(integer) at compile-time. */
7735 if (flag_unsafe_math_optimizations
7736 && TREE_CODE (arg) == REAL_CST
7737 && ! TREE_CONSTANT_OVERFLOW (arg))
7739 REAL_VALUE_TYPE cint;
7740 REAL_VALUE_TYPE c;
7741 HOST_WIDE_INT n;
7743 c = TREE_REAL_CST (arg);
7744 n = real_to_integer (&c);
7745 real_from_integer (&cint, VOIDmode, n,
7746 n < 0 ? -1 : 0, 0);
7747 if (real_identical (&c, &cint))
7749 REAL_VALUE_TYPE x;
7751 real_powi (&x, TYPE_MODE (type), value, n);
7752 return build_real (type, x);
7756 /* Optimize expN(logN(x)) = x. */
7757 if (flag_unsafe_math_optimizations)
7759 const enum built_in_function fcode = builtin_mathfn_code (arg);
7761 if ((value == &dconste
7762 && (fcode == BUILT_IN_LOG
7763 || fcode == BUILT_IN_LOGF
7764 || fcode == BUILT_IN_LOGL))
7765 || (value == &dconst2
7766 && (fcode == BUILT_IN_LOG2
7767 || fcode == BUILT_IN_LOG2F
7768 || fcode == BUILT_IN_LOG2L))
7769 || (value == &dconst10
7770 && (fcode == BUILT_IN_LOG10
7771 || fcode == BUILT_IN_LOG10F
7772 || fcode == BUILT_IN_LOG10L)))
7773 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7777 return 0;
7780 /* Fold function call to builtin memcpy. Return
7781 NULL_TREE if no simplification can be made. */
7783 static tree
7784 fold_builtin_memcpy (tree fndecl, tree arglist)
7786 tree dest, src, len;
7788 if (!validate_arglist (arglist,
7789 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7790 return 0;
7792 dest = TREE_VALUE (arglist);
7793 src = TREE_VALUE (TREE_CHAIN (arglist));
7794 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7796 /* If the LEN parameter is zero, return DEST. */
7797 if (integer_zerop (len))
7798 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7800 /* If SRC and DEST are the same (and not volatile), return DEST. */
7801 if (operand_equal_p (src, dest, 0))
7802 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7804 return 0;
7807 /* Fold function call to builtin mempcpy. Return
7808 NULL_TREE if no simplification can be made. */
7810 static tree
7811 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7813 if (validate_arglist (arglist,
7814 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7816 tree dest = TREE_VALUE (arglist);
7817 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7818 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7820 /* If the LEN parameter is zero, return DEST. */
7821 if (integer_zerop (len))
7822 return omit_one_operand (type, dest, src);
7824 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7825 if (operand_equal_p (src, dest, 0))
7827 if (endp == 0)
7828 return omit_one_operand (type, dest, len);
7830 if (endp == 2)
7831 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7832 ssize_int (1));
7834 len = fold_convert (TREE_TYPE (dest), len);
7835 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7836 return fold_convert (type, len);
7839 return 0;
7842 /* Fold function call to builtin memmove. Return
7843 NULL_TREE if no simplification can be made. */
7845 static tree
7846 fold_builtin_memmove (tree arglist, tree type)
7848 tree dest, src, len;
7850 if (!validate_arglist (arglist,
7851 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7852 return 0;
7854 dest = TREE_VALUE (arglist);
7855 src = TREE_VALUE (TREE_CHAIN (arglist));
7856 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7858 /* If the LEN parameter is zero, return DEST. */
7859 if (integer_zerop (len))
7860 return omit_one_operand (type, dest, src);
7862 /* If SRC and DEST are the same (and not volatile), return DEST. */
7863 if (operand_equal_p (src, dest, 0))
7864 return omit_one_operand (type, dest, len);
7866 return 0;
7869 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7870 the length of the string to be copied. Return NULL_TREE if no
7871 simplification can be made. */
7873 tree
7874 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7876 tree dest, src, fn;
7878 if (!validate_arglist (arglist,
7879 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7880 return 0;
7882 dest = TREE_VALUE (arglist);
7883 src = TREE_VALUE (TREE_CHAIN (arglist));
7885 /* If SRC and DEST are the same (and not volatile), return DEST. */
7886 if (operand_equal_p (src, dest, 0))
7887 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7889 if (optimize_size)
7890 return 0;
7892 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7893 if (!fn)
7894 return 0;
7896 if (!len)
7898 len = c_strlen (src, 1);
7899 if (! len || TREE_SIDE_EFFECTS (len))
7900 return 0;
7903 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7904 arglist = build_tree_list (NULL_TREE, len);
7905 arglist = tree_cons (NULL_TREE, src, arglist);
7906 arglist = tree_cons (NULL_TREE, dest, arglist);
7907 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7908 build_function_call_expr (fn, arglist));
7911 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7912 the length of the source string. Return NULL_TREE if no simplification
7913 can be made. */
7915 tree
7916 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7918 tree dest, src, len, fn;
7920 if (!validate_arglist (arglist,
7921 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7922 return 0;
7924 dest = TREE_VALUE (arglist);
7925 src = TREE_VALUE (TREE_CHAIN (arglist));
7926 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7928 /* If the LEN parameter is zero, return DEST. */
7929 if (integer_zerop (len))
7930 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7932 /* We can't compare slen with len as constants below if len is not a
7933 constant. */
7934 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7935 return 0;
7937 if (!slen)
7938 slen = c_strlen (src, 1);
7940 /* Now, we must be passed a constant src ptr parameter. */
7941 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7942 return 0;
7944 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7946 /* We do not support simplification of this case, though we do
7947 support it when expanding trees into RTL. */
7948 /* FIXME: generate a call to __builtin_memset. */
7949 if (tree_int_cst_lt (slen, len))
7950 return 0;
7952 /* OK transform into builtin memcpy. */
7953 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7954 if (!fn)
7955 return 0;
7956 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7957 build_function_call_expr (fn, arglist));
7960 /* Fold function call to builtin memcmp. Return
7961 NULL_TREE if no simplification can be made. */
7963 static tree
7964 fold_builtin_memcmp (tree arglist)
7966 tree arg1, arg2, len;
7967 const char *p1, *p2;
7969 if (!validate_arglist (arglist,
7970 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7971 return 0;
7973 arg1 = TREE_VALUE (arglist);
7974 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7975 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7977 /* If the LEN parameter is zero, return zero. */
7978 if (integer_zerop (len))
7979 return omit_two_operands (integer_type_node, integer_zero_node,
7980 arg1, arg2);
7982 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7983 if (operand_equal_p (arg1, arg2, 0))
7984 return omit_one_operand (integer_type_node, integer_zero_node, len);
7986 p1 = c_getstr (arg1);
7987 p2 = c_getstr (arg2);
7989 /* If all arguments are constant, and the value of len is not greater
7990 than the lengths of arg1 and arg2, evaluate at compile-time. */
7991 if (host_integerp (len, 1) && p1 && p2
7992 && compare_tree_int (len, strlen (p1) + 1) <= 0
7993 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7995 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7997 if (r > 0)
7998 return integer_one_node;
7999 else if (r < 0)
8000 return integer_minus_one_node;
8001 else
8002 return integer_zero_node;
8005 /* If len parameter is one, return an expression corresponding to
8006 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8007 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8009 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8010 tree cst_uchar_ptr_node
8011 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8013 tree ind1 = fold_convert (integer_type_node,
8014 build1 (INDIRECT_REF, cst_uchar_node,
8015 fold_convert (cst_uchar_ptr_node,
8016 arg1)));
8017 tree ind2 = fold_convert (integer_type_node,
8018 build1 (INDIRECT_REF, cst_uchar_node,
8019 fold_convert (cst_uchar_ptr_node,
8020 arg2)));
8021 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8024 return 0;
8027 /* Fold function call to builtin strcmp. Return
8028 NULL_TREE if no simplification can be made. */
8030 static tree
8031 fold_builtin_strcmp (tree arglist)
8033 tree arg1, arg2;
8034 const char *p1, *p2;
8036 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8037 return 0;
8039 arg1 = TREE_VALUE (arglist);
8040 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8042 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8043 if (operand_equal_p (arg1, arg2, 0))
8044 return integer_zero_node;
8046 p1 = c_getstr (arg1);
8047 p2 = c_getstr (arg2);
8049 if (p1 && p2)
8051 const int i = strcmp (p1, p2);
8052 if (i < 0)
8053 return integer_minus_one_node;
8054 else if (i > 0)
8055 return integer_one_node;
8056 else
8057 return integer_zero_node;
8060 /* If the second arg is "", return *(const unsigned char*)arg1. */
8061 if (p2 && *p2 == '\0')
8063 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8064 tree cst_uchar_ptr_node
8065 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8067 return fold_convert (integer_type_node,
8068 build1 (INDIRECT_REF, cst_uchar_node,
8069 fold_convert (cst_uchar_ptr_node,
8070 arg1)));
8073 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8074 if (p1 && *p1 == '\0')
8076 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8077 tree cst_uchar_ptr_node
8078 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8080 tree temp = fold_convert (integer_type_node,
8081 build1 (INDIRECT_REF, cst_uchar_node,
8082 fold_convert (cst_uchar_ptr_node,
8083 arg2)));
8084 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8087 return 0;
8090 /* Fold function call to builtin strncmp. Return
8091 NULL_TREE if no simplification can be made. */
8093 static tree
8094 fold_builtin_strncmp (tree arglist)
8096 tree arg1, arg2, len;
8097 const char *p1, *p2;
8099 if (!validate_arglist (arglist,
8100 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8101 return 0;
8103 arg1 = TREE_VALUE (arglist);
8104 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8105 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8107 /* If the LEN parameter is zero, return zero. */
8108 if (integer_zerop (len))
8109 return omit_two_operands (integer_type_node, integer_zero_node,
8110 arg1, arg2);
8112 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8113 if (operand_equal_p (arg1, arg2, 0))
8114 return omit_one_operand (integer_type_node, integer_zero_node, len);
8116 p1 = c_getstr (arg1);
8117 p2 = c_getstr (arg2);
8119 if (host_integerp (len, 1) && p1 && p2)
8121 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8122 if (i > 0)
8123 return integer_one_node;
8124 else if (i < 0)
8125 return integer_minus_one_node;
8126 else
8127 return integer_zero_node;
8130 /* If the second arg is "", and the length is greater than zero,
8131 return *(const unsigned char*)arg1. */
8132 if (p2 && *p2 == '\0'
8133 && TREE_CODE (len) == INTEGER_CST
8134 && tree_int_cst_sgn (len) == 1)
8136 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8137 tree cst_uchar_ptr_node
8138 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8140 return fold_convert (integer_type_node,
8141 build1 (INDIRECT_REF, cst_uchar_node,
8142 fold_convert (cst_uchar_ptr_node,
8143 arg1)));
8146 /* If the first arg is "", and the length is greater than zero,
8147 return -*(const unsigned char*)arg2. */
8148 if (p1 && *p1 == '\0'
8149 && TREE_CODE (len) == INTEGER_CST
8150 && tree_int_cst_sgn (len) == 1)
8152 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8153 tree cst_uchar_ptr_node
8154 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8156 tree temp = fold_convert (integer_type_node,
8157 build1 (INDIRECT_REF, cst_uchar_node,
8158 fold_convert (cst_uchar_ptr_node,
8159 arg2)));
8160 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8163 /* If len parameter is one, return an expression corresponding to
8164 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8165 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8167 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8168 tree cst_uchar_ptr_node
8169 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8171 tree ind1 = fold_convert (integer_type_node,
8172 build1 (INDIRECT_REF, cst_uchar_node,
8173 fold_convert (cst_uchar_ptr_node,
8174 arg1)));
8175 tree ind2 = fold_convert (integer_type_node,
8176 build1 (INDIRECT_REF, cst_uchar_node,
8177 fold_convert (cst_uchar_ptr_node,
8178 arg2)));
8179 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8182 return 0;
8185 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8186 NULL_TREE if no simplification can be made. */
8188 static tree
8189 fold_builtin_signbit (tree fndecl, tree arglist)
8191 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8192 tree arg, temp;
8194 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8195 return NULL_TREE;
8197 arg = TREE_VALUE (arglist);
8199 /* If ARG is a compile-time constant, determine the result. */
8200 if (TREE_CODE (arg) == REAL_CST
8201 && !TREE_CONSTANT_OVERFLOW (arg))
8203 REAL_VALUE_TYPE c;
8205 c = TREE_REAL_CST (arg);
8206 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8207 return fold_convert (type, temp);
8210 /* If ARG is non-negative, the result is always zero. */
8211 if (tree_expr_nonnegative_p (arg))
8212 return omit_one_operand (type, integer_zero_node, arg);
8214 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8215 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8216 return fold_build2 (LT_EXPR, type, arg,
8217 build_real (TREE_TYPE (arg), dconst0));
8219 return NULL_TREE;
8222 /* Fold function call to builtin copysign, copysignf or copysignl.
8223 Return NULL_TREE if no simplification can be made. */
8225 static tree
8226 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8228 tree arg1, arg2, tem;
8230 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8231 return NULL_TREE;
8233 arg1 = TREE_VALUE (arglist);
8234 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8236 /* copysign(X,X) is X. */
8237 if (operand_equal_p (arg1, arg2, 0))
8238 return fold_convert (type, arg1);
8240 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8241 if (TREE_CODE (arg1) == REAL_CST
8242 && TREE_CODE (arg2) == REAL_CST
8243 && !TREE_CONSTANT_OVERFLOW (arg1)
8244 && !TREE_CONSTANT_OVERFLOW (arg2))
8246 REAL_VALUE_TYPE c1, c2;
8248 c1 = TREE_REAL_CST (arg1);
8249 c2 = TREE_REAL_CST (arg2);
8250 /* c1.sign := c2.sign. */
8251 real_copysign (&c1, &c2);
8252 return build_real (type, c1);
8255 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8256 Remember to evaluate Y for side-effects. */
8257 if (tree_expr_nonnegative_p (arg2))
8258 return omit_one_operand (type,
8259 fold_build1 (ABS_EXPR, type, arg1),
8260 arg2);
8262 /* Strip sign changing operations for the first argument. */
8263 tem = fold_strip_sign_ops (arg1);
8264 if (tem)
8266 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8267 return build_function_call_expr (fndecl, arglist);
8270 return NULL_TREE;
8273 /* Fold a call to builtin isascii. */
8275 static tree
8276 fold_builtin_isascii (tree arglist)
8278 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8279 return 0;
8280 else
8282 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8283 tree arg = TREE_VALUE (arglist);
8285 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8286 build_int_cst (NULL_TREE,
8287 ~ (unsigned HOST_WIDE_INT) 0x7f));
8288 arg = fold_build2 (EQ_EXPR, integer_type_node,
8289 arg, integer_zero_node);
8291 if (in_gimple_form && !TREE_CONSTANT (arg))
8292 return NULL_TREE;
8293 else
8294 return arg;
8298 /* Fold a call to builtin toascii. */
8300 static tree
8301 fold_builtin_toascii (tree arglist)
8303 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8304 return 0;
8305 else
8307 /* Transform toascii(c) -> (c & 0x7f). */
8308 tree arg = TREE_VALUE (arglist);
8310 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8311 build_int_cst (NULL_TREE, 0x7f));
8315 /* Fold a call to builtin isdigit. */
8317 static tree
8318 fold_builtin_isdigit (tree arglist)
8320 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8321 return 0;
8322 else
8324 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8325 /* According to the C standard, isdigit is unaffected by locale.
8326 However, it definitely is affected by the target character set. */
8327 tree arg;
8328 unsigned HOST_WIDE_INT target_digit0
8329 = lang_hooks.to_target_charset ('0');
8331 if (target_digit0 == 0)
8332 return NULL_TREE;
8334 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8335 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8336 build_int_cst (unsigned_type_node, target_digit0));
8337 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8338 build_int_cst (unsigned_type_node, 9));
8339 if (in_gimple_form && !TREE_CONSTANT (arg))
8340 return NULL_TREE;
8341 else
8342 return arg;
8346 /* Fold a call to fabs, fabsf or fabsl. */
8348 static tree
8349 fold_builtin_fabs (tree arglist, tree type)
8351 tree arg;
8353 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8354 return 0;
8356 arg = TREE_VALUE (arglist);
8357 arg = fold_convert (type, arg);
8358 if (TREE_CODE (arg) == REAL_CST)
8359 return fold_abs_const (arg, type);
8360 return fold_build1 (ABS_EXPR, type, arg);
8363 /* Fold a call to abs, labs, llabs or imaxabs. */
8365 static tree
8366 fold_builtin_abs (tree arglist, tree type)
8368 tree arg;
8370 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8371 return 0;
8373 arg = TREE_VALUE (arglist);
8374 arg = fold_convert (type, arg);
8375 if (TREE_CODE (arg) == INTEGER_CST)
8376 return fold_abs_const (arg, type);
8377 return fold_build1 (ABS_EXPR, type, arg);
8380 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8381 EXP is the CALL_EXPR for the call. */
8383 static tree
8384 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8386 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8387 tree arg;
8388 REAL_VALUE_TYPE r;
8390 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8392 /* Check that we have exactly one argument. */
8393 if (arglist == 0)
8395 error ("too few arguments to function %qs",
8396 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8397 return error_mark_node;
8399 else if (TREE_CHAIN (arglist) != 0)
8401 error ("too many arguments to function %qs",
8402 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8403 return error_mark_node;
8405 else
8407 error ("non-floating-point argument to function %qs",
8408 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8409 return error_mark_node;
8413 arg = TREE_VALUE (arglist);
8414 switch (builtin_index)
8416 case BUILT_IN_ISINF:
8417 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8418 return omit_one_operand (type, integer_zero_node, arg);
8420 if (TREE_CODE (arg) == REAL_CST)
8422 r = TREE_REAL_CST (arg);
8423 if (real_isinf (&r))
8424 return real_compare (GT_EXPR, &r, &dconst0)
8425 ? integer_one_node : integer_minus_one_node;
8426 else
8427 return integer_zero_node;
8430 return NULL_TREE;
8432 case BUILT_IN_FINITE:
8433 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8434 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8435 return omit_one_operand (type, integer_zero_node, arg);
8437 if (TREE_CODE (arg) == REAL_CST)
8439 r = TREE_REAL_CST (arg);
8440 return real_isinf (&r) || real_isnan (&r)
8441 ? integer_zero_node : integer_one_node;
8444 return NULL_TREE;
8446 case BUILT_IN_ISNAN:
8447 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8448 return omit_one_operand (type, integer_zero_node, arg);
8450 if (TREE_CODE (arg) == REAL_CST)
8452 r = TREE_REAL_CST (arg);
8453 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8456 arg = builtin_save_expr (arg);
8457 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8459 default:
8460 gcc_unreachable ();
8464 /* Fold a call to an unordered comparison function such as
8465 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8466 being called and ARGLIST is the argument list for the call.
8467 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8468 the opposite of the desired result. UNORDERED_CODE is used
8469 for modes that can hold NaNs and ORDERED_CODE is used for
8470 the rest. */
8472 static tree
8473 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8474 enum tree_code unordered_code,
8475 enum tree_code ordered_code)
8477 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8478 enum tree_code code;
8479 tree arg0, arg1;
8480 tree type0, type1;
8481 enum tree_code code0, code1;
8482 tree cmp_type = NULL_TREE;
8484 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8486 /* Check that we have exactly two arguments. */
8487 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8489 error ("too few arguments to function %qs",
8490 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8491 return error_mark_node;
8493 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8495 error ("too many arguments to function %qs",
8496 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8497 return error_mark_node;
8501 arg0 = TREE_VALUE (arglist);
8502 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8504 type0 = TREE_TYPE (arg0);
8505 type1 = TREE_TYPE (arg1);
8507 code0 = TREE_CODE (type0);
8508 code1 = TREE_CODE (type1);
8510 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8511 /* Choose the wider of two real types. */
8512 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8513 ? type0 : type1;
8514 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8515 cmp_type = type0;
8516 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8517 cmp_type = type1;
8518 else
8520 error ("non-floating-point argument to function %qs",
8521 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8522 return error_mark_node;
8525 arg0 = fold_convert (cmp_type, arg0);
8526 arg1 = fold_convert (cmp_type, arg1);
8528 if (unordered_code == UNORDERED_EXPR)
8530 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8531 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8532 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8535 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8536 : ordered_code;
8537 return fold_build1 (TRUTH_NOT_EXPR, type,
8538 fold_build2 (code, type, arg0, arg1));
8541 /* Used by constant folding to simplify calls to builtin functions. EXP is
8542 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8543 result of the function call is ignored. This function returns NULL_TREE
8544 if no simplification was possible. */
8546 static tree
8547 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8549 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8550 enum built_in_function fcode;
8552 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8553 return targetm.fold_builtin (fndecl, arglist, ignore);
8555 fcode = DECL_FUNCTION_CODE (fndecl);
8556 switch (fcode)
8558 case BUILT_IN_FPUTS:
8559 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8561 case BUILT_IN_FPUTS_UNLOCKED:
8562 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8564 case BUILT_IN_STRSTR:
8565 return fold_builtin_strstr (arglist, type);
8567 case BUILT_IN_STRCAT:
8568 return fold_builtin_strcat (arglist);
8570 case BUILT_IN_STRNCAT:
8571 return fold_builtin_strncat (arglist);
8573 case BUILT_IN_STRSPN:
8574 return fold_builtin_strspn (arglist);
8576 case BUILT_IN_STRCSPN:
8577 return fold_builtin_strcspn (arglist);
8579 case BUILT_IN_STRCHR:
8580 case BUILT_IN_INDEX:
8581 return fold_builtin_strchr (arglist, type);
8583 case BUILT_IN_STRRCHR:
8584 case BUILT_IN_RINDEX:
8585 return fold_builtin_strrchr (arglist, type);
8587 case BUILT_IN_STRCPY:
8588 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8590 case BUILT_IN_STRNCPY:
8591 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8593 case BUILT_IN_STRCMP:
8594 return fold_builtin_strcmp (arglist);
8596 case BUILT_IN_STRNCMP:
8597 return fold_builtin_strncmp (arglist);
8599 case BUILT_IN_STRPBRK:
8600 return fold_builtin_strpbrk (arglist, type);
8602 case BUILT_IN_BCMP:
8603 case BUILT_IN_MEMCMP:
8604 return fold_builtin_memcmp (arglist);
8606 case BUILT_IN_SPRINTF:
8607 return fold_builtin_sprintf (arglist, ignore);
8609 case BUILT_IN_CONSTANT_P:
8611 tree val;
8613 val = fold_builtin_constant_p (arglist);
8614 /* Gimplification will pull the CALL_EXPR for the builtin out of
8615 an if condition. When not optimizing, we'll not CSE it back.
8616 To avoid link error types of regressions, return false now. */
8617 if (!val && !optimize)
8618 val = integer_zero_node;
8620 return val;
8623 case BUILT_IN_EXPECT:
8624 return fold_builtin_expect (arglist);
8626 case BUILT_IN_CLASSIFY_TYPE:
8627 return fold_builtin_classify_type (arglist);
8629 case BUILT_IN_STRLEN:
8630 return fold_builtin_strlen (arglist);
8632 CASE_FLT_FN (BUILT_IN_FABS):
8633 return fold_builtin_fabs (arglist, type);
8635 case BUILT_IN_ABS:
8636 case BUILT_IN_LABS:
8637 case BUILT_IN_LLABS:
8638 case BUILT_IN_IMAXABS:
8639 return fold_builtin_abs (arglist, type);
8641 CASE_FLT_FN (BUILT_IN_CONJ):
8642 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8643 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8644 break;
8646 CASE_FLT_FN (BUILT_IN_CREAL):
8647 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8648 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8649 TREE_VALUE (arglist)));
8650 break;
8652 CASE_FLT_FN (BUILT_IN_CIMAG):
8653 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8654 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8655 TREE_VALUE (arglist)));
8656 break;
8658 CASE_FLT_FN (BUILT_IN_CABS):
8659 return fold_builtin_cabs (arglist, type);
8661 CASE_FLT_FN (BUILT_IN_SQRT):
8662 return fold_builtin_sqrt (arglist, type);
8664 CASE_FLT_FN (BUILT_IN_CBRT):
8665 return fold_builtin_cbrt (arglist, type);
8667 CASE_FLT_FN (BUILT_IN_SIN):
8668 return fold_builtin_sin (arglist);
8670 CASE_FLT_FN (BUILT_IN_COS):
8671 return fold_builtin_cos (arglist, type, fndecl);
8673 CASE_FLT_FN (BUILT_IN_EXP):
8674 return fold_builtin_exponent (fndecl, arglist, &dconste);
8676 CASE_FLT_FN (BUILT_IN_EXP2):
8677 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8679 CASE_FLT_FN (BUILT_IN_EXP10):
8680 CASE_FLT_FN (BUILT_IN_POW10):
8681 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8683 CASE_FLT_FN (BUILT_IN_LOG):
8684 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8686 CASE_FLT_FN (BUILT_IN_LOG2):
8687 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8689 CASE_FLT_FN (BUILT_IN_LOG10):
8690 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8692 CASE_FLT_FN (BUILT_IN_TAN):
8693 return fold_builtin_tan (arglist);
8695 CASE_FLT_FN (BUILT_IN_ATAN):
8696 return fold_builtin_atan (arglist, type);
8698 CASE_FLT_FN (BUILT_IN_POW):
8699 return fold_builtin_pow (fndecl, arglist, type);
8701 CASE_FLT_FN (BUILT_IN_POWI):
8702 return fold_builtin_powi (fndecl, arglist, type);
8704 CASE_FLT_FN (BUILT_IN_INF):
8705 case BUILT_IN_INFD32:
8706 case BUILT_IN_INFD64:
8707 case BUILT_IN_INFD128:
8708 return fold_builtin_inf (type, true);
8710 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8711 return fold_builtin_inf (type, false);
8713 CASE_FLT_FN (BUILT_IN_NAN):
8714 case BUILT_IN_NAND32:
8715 case BUILT_IN_NAND64:
8716 case BUILT_IN_NAND128:
8717 return fold_builtin_nan (arglist, type, true);
8719 CASE_FLT_FN (BUILT_IN_NANS):
8720 return fold_builtin_nan (arglist, type, false);
8722 CASE_FLT_FN (BUILT_IN_FLOOR):
8723 return fold_builtin_floor (fndecl, arglist);
8725 CASE_FLT_FN (BUILT_IN_CEIL):
8726 return fold_builtin_ceil (fndecl, arglist);
8728 CASE_FLT_FN (BUILT_IN_TRUNC):
8729 return fold_builtin_trunc (fndecl, arglist);
8731 CASE_FLT_FN (BUILT_IN_ROUND):
8732 return fold_builtin_round (fndecl, arglist);
8734 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8735 CASE_FLT_FN (BUILT_IN_RINT):
8736 return fold_trunc_transparent_mathfn (fndecl, arglist);
8738 CASE_FLT_FN (BUILT_IN_LCEIL):
8739 CASE_FLT_FN (BUILT_IN_LLCEIL):
8740 CASE_FLT_FN (BUILT_IN_LFLOOR):
8741 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8742 CASE_FLT_FN (BUILT_IN_LROUND):
8743 CASE_FLT_FN (BUILT_IN_LLROUND):
8744 return fold_builtin_int_roundingfn (fndecl, arglist);
8746 CASE_FLT_FN (BUILT_IN_LRINT):
8747 CASE_FLT_FN (BUILT_IN_LLRINT):
8748 return fold_fixed_mathfn (fndecl, arglist);
8750 CASE_INT_FN (BUILT_IN_FFS):
8751 CASE_INT_FN (BUILT_IN_CLZ):
8752 CASE_INT_FN (BUILT_IN_CTZ):
8753 CASE_INT_FN (BUILT_IN_POPCOUNT):
8754 CASE_INT_FN (BUILT_IN_PARITY):
8755 return fold_builtin_bitop (fndecl, arglist);
8757 case BUILT_IN_MEMCPY:
8758 return fold_builtin_memcpy (fndecl, arglist);
8760 case BUILT_IN_MEMPCPY:
8761 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8763 case BUILT_IN_MEMMOVE:
8764 return fold_builtin_memmove (arglist, type);
8766 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8767 return fold_builtin_signbit (fndecl, arglist);
8769 case BUILT_IN_ISASCII:
8770 return fold_builtin_isascii (arglist);
8772 case BUILT_IN_TOASCII:
8773 return fold_builtin_toascii (arglist);
8775 case BUILT_IN_ISDIGIT:
8776 return fold_builtin_isdigit (arglist);
8778 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8779 return fold_builtin_copysign (fndecl, arglist, type);
8781 CASE_FLT_FN (BUILT_IN_FINITE):
8782 case BUILT_IN_FINITED32:
8783 case BUILT_IN_FINITED64:
8784 case BUILT_IN_FINITED128:
8785 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8787 CASE_FLT_FN (BUILT_IN_ISINF):
8788 case BUILT_IN_ISINFD32:
8789 case BUILT_IN_ISINFD64:
8790 case BUILT_IN_ISINFD128:
8791 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8793 CASE_FLT_FN (BUILT_IN_ISNAN):
8794 case BUILT_IN_ISNAND32:
8795 case BUILT_IN_ISNAND64:
8796 case BUILT_IN_ISNAND128:
8797 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8799 case BUILT_IN_ISGREATER:
8800 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8801 case BUILT_IN_ISGREATEREQUAL:
8802 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8803 case BUILT_IN_ISLESS:
8804 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8805 case BUILT_IN_ISLESSEQUAL:
8806 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8807 case BUILT_IN_ISLESSGREATER:
8808 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8809 case BUILT_IN_ISUNORDERED:
8810 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8811 NOP_EXPR);
8813 /* We do the folding for va_start in the expander. */
8814 case BUILT_IN_VA_START:
8815 break;
8817 case BUILT_IN_OBJECT_SIZE:
8818 return fold_builtin_object_size (arglist);
8819 case BUILT_IN_MEMCPY_CHK:
8820 case BUILT_IN_MEMPCPY_CHK:
8821 case BUILT_IN_MEMMOVE_CHK:
8822 case BUILT_IN_MEMSET_CHK:
8823 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8824 DECL_FUNCTION_CODE (fndecl));
8825 case BUILT_IN_STRCPY_CHK:
8826 case BUILT_IN_STPCPY_CHK:
8827 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8828 DECL_FUNCTION_CODE (fndecl));
8829 case BUILT_IN_STRNCPY_CHK:
8830 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8831 case BUILT_IN_STRCAT_CHK:
8832 return fold_builtin_strcat_chk (fndecl, arglist);
8833 case BUILT_IN_STRNCAT_CHK:
8834 return fold_builtin_strncat_chk (fndecl, arglist);
8835 case BUILT_IN_SPRINTF_CHK:
8836 case BUILT_IN_VSPRINTF_CHK:
8837 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8838 case BUILT_IN_SNPRINTF_CHK:
8839 case BUILT_IN_VSNPRINTF_CHK:
8840 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8841 DECL_FUNCTION_CODE (fndecl));
8843 case BUILT_IN_PRINTF:
8844 case BUILT_IN_PRINTF_UNLOCKED:
8845 case BUILT_IN_VPRINTF:
8846 case BUILT_IN_PRINTF_CHK:
8847 case BUILT_IN_VPRINTF_CHK:
8848 return fold_builtin_printf (fndecl, arglist, ignore,
8849 DECL_FUNCTION_CODE (fndecl));
8851 case BUILT_IN_FPRINTF:
8852 case BUILT_IN_FPRINTF_UNLOCKED:
8853 case BUILT_IN_VFPRINTF:
8854 case BUILT_IN_FPRINTF_CHK:
8855 case BUILT_IN_VFPRINTF_CHK:
8856 return fold_builtin_fprintf (fndecl, arglist, ignore,
8857 DECL_FUNCTION_CODE (fndecl));
8859 default:
8860 break;
8863 return 0;
8866 /* A wrapper function for builtin folding that prevents warnings for
8867 "statement without effect" and the like, caused by removing the
8868 call node earlier than the warning is generated. */
8870 tree
8871 fold_builtin (tree fndecl, tree arglist, bool ignore)
8873 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8874 if (exp)
8876 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8877 TREE_NO_WARNING (exp) = 1;
8880 return exp;
8883 /* Conveniently construct a function call expression. */
8885 tree
8886 build_function_call_expr (tree fn, tree arglist)
8888 tree call_expr;
8890 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8891 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8892 call_expr, arglist, NULL_TREE);
8895 /* This function validates the types of a function call argument list
8896 represented as a tree chain of parameters against a specified list
8897 of tree_codes. If the last specifier is a 0, that represents an
8898 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8900 static int
8901 validate_arglist (tree arglist, ...)
8903 enum tree_code code;
8904 int res = 0;
8905 va_list ap;
8907 va_start (ap, arglist);
8911 code = va_arg (ap, enum tree_code);
8912 switch (code)
8914 case 0:
8915 /* This signifies an ellipses, any further arguments are all ok. */
8916 res = 1;
8917 goto end;
8918 case VOID_TYPE:
8919 /* This signifies an endlink, if no arguments remain, return
8920 true, otherwise return false. */
8921 res = arglist == 0;
8922 goto end;
8923 default:
8924 /* If no parameters remain or the parameter's code does not
8925 match the specified code, return false. Otherwise continue
8926 checking any remaining arguments. */
8927 if (arglist == 0)
8928 goto end;
8929 if (code == POINTER_TYPE)
8931 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8932 goto end;
8934 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8935 goto end;
8936 break;
8938 arglist = TREE_CHAIN (arglist);
8940 while (1);
8942 /* We need gotos here since we can only have one VA_CLOSE in a
8943 function. */
8944 end: ;
8945 va_end (ap);
8947 return res;
8950 /* Default target-specific builtin expander that does nothing. */
8953 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8954 rtx target ATTRIBUTE_UNUSED,
8955 rtx subtarget ATTRIBUTE_UNUSED,
8956 enum machine_mode mode ATTRIBUTE_UNUSED,
8957 int ignore ATTRIBUTE_UNUSED)
8959 return NULL_RTX;
8962 /* Default target-specific library builtin expander that does nothing. */
8965 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
8966 rtx target ATTRIBUTE_UNUSED,
8967 rtx subtarget ATTRIBUTE_UNUSED,
8968 enum machine_mode mode ATTRIBUTE_UNUSED,
8969 int ignore ATTRIBUTE_UNUSED)
8971 return NULL_RTX;
8974 /* Returns true is EXP represents data that would potentially reside
8975 in a readonly section. */
8977 static bool
8978 readonly_data_expr (tree exp)
8980 STRIP_NOPS (exp);
8982 if (TREE_CODE (exp) != ADDR_EXPR)
8983 return false;
8985 exp = get_base_address (TREE_OPERAND (exp, 0));
8986 if (!exp)
8987 return false;
8989 /* Make sure we call decl_readonly_section only for trees it
8990 can handle (since it returns true for everything it doesn't
8991 understand). */
8992 if (TREE_CODE (exp) == STRING_CST
8993 || TREE_CODE (exp) == CONSTRUCTOR
8994 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8995 return decl_readonly_section (exp, 0);
8996 else
8997 return false;
9000 /* Simplify a call to the strstr builtin.
9002 Return 0 if no simplification was possible, otherwise return the
9003 simplified form of the call as a tree.
9005 The simplified form may be a constant or other expression which
9006 computes the same value, but in a more efficient manner (including
9007 calls to other builtin functions).
9009 The call may contain arguments which need to be evaluated, but
9010 which are not useful to determine the result of the call. In
9011 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9012 COMPOUND_EXPR will be an argument which must be evaluated.
9013 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9014 COMPOUND_EXPR in the chain will contain the tree for the simplified
9015 form of the builtin function call. */
9017 static tree
9018 fold_builtin_strstr (tree arglist, tree type)
9020 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9021 return 0;
9022 else
9024 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9025 tree fn;
9026 const char *p1, *p2;
9028 p2 = c_getstr (s2);
9029 if (p2 == NULL)
9030 return 0;
9032 p1 = c_getstr (s1);
9033 if (p1 != NULL)
9035 const char *r = strstr (p1, p2);
9036 tree tem;
9038 if (r == NULL)
9039 return build_int_cst (TREE_TYPE (s1), 0);
9041 /* Return an offset into the constant string argument. */
9042 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9043 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9044 return fold_convert (type, tem);
9047 /* The argument is const char *, and the result is char *, so we need
9048 a type conversion here to avoid a warning. */
9049 if (p2[0] == '\0')
9050 return fold_convert (type, s1);
9052 if (p2[1] != '\0')
9053 return 0;
9055 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9056 if (!fn)
9057 return 0;
9059 /* New argument list transforming strstr(s1, s2) to
9060 strchr(s1, s2[0]). */
9061 arglist = build_tree_list (NULL_TREE,
9062 build_int_cst (NULL_TREE, p2[0]));
9063 arglist = tree_cons (NULL_TREE, s1, arglist);
9064 return build_function_call_expr (fn, arglist);
9068 /* Simplify a call to the strchr builtin.
9070 Return 0 if no simplification was possible, otherwise return the
9071 simplified form of the call as a tree.
9073 The simplified form may be a constant or other expression which
9074 computes the same value, but in a more efficient manner (including
9075 calls to other builtin functions).
9077 The call may contain arguments which need to be evaluated, but
9078 which are not useful to determine the result of the call. In
9079 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9080 COMPOUND_EXPR will be an argument which must be evaluated.
9081 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9082 COMPOUND_EXPR in the chain will contain the tree for the simplified
9083 form of the builtin function call. */
9085 static tree
9086 fold_builtin_strchr (tree arglist, tree type)
9088 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9089 return 0;
9090 else
9092 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9093 const char *p1;
9095 if (TREE_CODE (s2) != INTEGER_CST)
9096 return 0;
9098 p1 = c_getstr (s1);
9099 if (p1 != NULL)
9101 char c;
9102 const char *r;
9103 tree tem;
9105 if (target_char_cast (s2, &c))
9106 return 0;
9108 r = strchr (p1, c);
9110 if (r == NULL)
9111 return build_int_cst (TREE_TYPE (s1), 0);
9113 /* Return an offset into the constant string argument. */
9114 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9115 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9116 return fold_convert (type, tem);
9118 return 0;
9122 /* Simplify a call to the strrchr builtin.
9124 Return 0 if no simplification was possible, otherwise return the
9125 simplified form of the call as a tree.
9127 The simplified form may be a constant or other expression which
9128 computes the same value, but in a more efficient manner (including
9129 calls to other builtin functions).
9131 The call may contain arguments which need to be evaluated, but
9132 which are not useful to determine the result of the call. In
9133 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9134 COMPOUND_EXPR will be an argument which must be evaluated.
9135 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9136 COMPOUND_EXPR in the chain will contain the tree for the simplified
9137 form of the builtin function call. */
9139 static tree
9140 fold_builtin_strrchr (tree arglist, tree type)
9142 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9143 return 0;
9144 else
9146 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9147 tree fn;
9148 const char *p1;
9150 if (TREE_CODE (s2) != INTEGER_CST)
9151 return 0;
9153 p1 = c_getstr (s1);
9154 if (p1 != NULL)
9156 char c;
9157 const char *r;
9158 tree tem;
9160 if (target_char_cast (s2, &c))
9161 return 0;
9163 r = strrchr (p1, c);
9165 if (r == NULL)
9166 return build_int_cst (TREE_TYPE (s1), 0);
9168 /* Return an offset into the constant string argument. */
9169 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9170 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9171 return fold_convert (type, tem);
9174 if (! integer_zerop (s2))
9175 return 0;
9177 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9178 if (!fn)
9179 return 0;
9181 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9182 return build_function_call_expr (fn, arglist);
9186 /* Simplify a call to the strpbrk builtin.
9188 Return 0 if no simplification was possible, otherwise return the
9189 simplified form of the call as a tree.
9191 The simplified form may be a constant or other expression which
9192 computes the same value, but in a more efficient manner (including
9193 calls to other builtin functions).
9195 The call may contain arguments which need to be evaluated, but
9196 which are not useful to determine the result of the call. In
9197 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9198 COMPOUND_EXPR will be an argument which must be evaluated.
9199 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9200 COMPOUND_EXPR in the chain will contain the tree for the simplified
9201 form of the builtin function call. */
9203 static tree
9204 fold_builtin_strpbrk (tree arglist, tree type)
9206 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9207 return 0;
9208 else
9210 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9211 tree fn;
9212 const char *p1, *p2;
9214 p2 = c_getstr (s2);
9215 if (p2 == NULL)
9216 return 0;
9218 p1 = c_getstr (s1);
9219 if (p1 != NULL)
9221 const char *r = strpbrk (p1, p2);
9222 tree tem;
9224 if (r == NULL)
9225 return build_int_cst (TREE_TYPE (s1), 0);
9227 /* Return an offset into the constant string argument. */
9228 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9229 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9230 return fold_convert (type, tem);
9233 if (p2[0] == '\0')
9234 /* strpbrk(x, "") == NULL.
9235 Evaluate and ignore s1 in case it had side-effects. */
9236 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9238 if (p2[1] != '\0')
9239 return 0; /* Really call strpbrk. */
9241 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9242 if (!fn)
9243 return 0;
9245 /* New argument list transforming strpbrk(s1, s2) to
9246 strchr(s1, s2[0]). */
9247 arglist = build_tree_list (NULL_TREE,
9248 build_int_cst (NULL_TREE, p2[0]));
9249 arglist = tree_cons (NULL_TREE, s1, arglist);
9250 return build_function_call_expr (fn, arglist);
9254 /* Simplify a call to the strcat builtin.
9256 Return 0 if no simplification was possible, otherwise return the
9257 simplified form of the call as a tree.
9259 The simplified form may be a constant or other expression which
9260 computes the same value, but in a more efficient manner (including
9261 calls to other builtin functions).
9263 The call may contain arguments which need to be evaluated, but
9264 which are not useful to determine the result of the call. In
9265 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9266 COMPOUND_EXPR will be an argument which must be evaluated.
9267 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9268 COMPOUND_EXPR in the chain will contain the tree for the simplified
9269 form of the builtin function call. */
9271 static tree
9272 fold_builtin_strcat (tree arglist)
9274 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9275 return 0;
9276 else
9278 tree dst = TREE_VALUE (arglist),
9279 src = TREE_VALUE (TREE_CHAIN (arglist));
9280 const char *p = c_getstr (src);
9282 /* If the string length is zero, return the dst parameter. */
9283 if (p && *p == '\0')
9284 return dst;
9286 return 0;
9290 /* Simplify a call to the strncat builtin.
9292 Return 0 if no simplification was possible, otherwise return the
9293 simplified form of the call as a tree.
9295 The simplified form may be a constant or other expression which
9296 computes the same value, but in a more efficient manner (including
9297 calls to other builtin functions).
9299 The call may contain arguments which need to be evaluated, but
9300 which are not useful to determine the result of the call. In
9301 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9302 COMPOUND_EXPR will be an argument which must be evaluated.
9303 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9304 COMPOUND_EXPR in the chain will contain the tree for the simplified
9305 form of the builtin function call. */
9307 static tree
9308 fold_builtin_strncat (tree arglist)
9310 if (!validate_arglist (arglist,
9311 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9312 return 0;
9313 else
9315 tree dst = TREE_VALUE (arglist);
9316 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9317 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9318 const char *p = c_getstr (src);
9320 /* If the requested length is zero, or the src parameter string
9321 length is zero, return the dst parameter. */
9322 if (integer_zerop (len) || (p && *p == '\0'))
9323 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9325 /* If the requested len is greater than or equal to the string
9326 length, call strcat. */
9327 if (TREE_CODE (len) == INTEGER_CST && p
9328 && compare_tree_int (len, strlen (p)) >= 0)
9330 tree newarglist
9331 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9332 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9334 /* If the replacement _DECL isn't initialized, don't do the
9335 transformation. */
9336 if (!fn)
9337 return 0;
9339 return build_function_call_expr (fn, newarglist);
9341 return 0;
9345 /* Simplify a call to the strspn builtin.
9347 Return 0 if no simplification was possible, otherwise return the
9348 simplified form of the call as a tree.
9350 The simplified form may be a constant or other expression which
9351 computes the same value, but in a more efficient manner (including
9352 calls to other builtin functions).
9354 The call may contain arguments which need to be evaluated, but
9355 which are not useful to determine the result of the call. In
9356 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9357 COMPOUND_EXPR will be an argument which must be evaluated.
9358 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9359 COMPOUND_EXPR in the chain will contain the tree for the simplified
9360 form of the builtin function call. */
9362 static tree
9363 fold_builtin_strspn (tree arglist)
9365 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9366 return 0;
9367 else
9369 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9370 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9372 /* If both arguments are constants, evaluate at compile-time. */
9373 if (p1 && p2)
9375 const size_t r = strspn (p1, p2);
9376 return size_int (r);
9379 /* If either argument is "", return 0. */
9380 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9381 /* Evaluate and ignore both arguments in case either one has
9382 side-effects. */
9383 return omit_two_operands (integer_type_node, integer_zero_node,
9384 s1, s2);
9385 return 0;
9389 /* Simplify a call to the strcspn builtin.
9391 Return 0 if no simplification was possible, otherwise return the
9392 simplified form of the call as a tree.
9394 The simplified form may be a constant or other expression which
9395 computes the same value, but in a more efficient manner (including
9396 calls to other builtin functions).
9398 The call may contain arguments which need to be evaluated, but
9399 which are not useful to determine the result of the call. In
9400 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9401 COMPOUND_EXPR will be an argument which must be evaluated.
9402 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9403 COMPOUND_EXPR in the chain will contain the tree for the simplified
9404 form of the builtin function call. */
9406 static tree
9407 fold_builtin_strcspn (tree arglist)
9409 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9410 return 0;
9411 else
9413 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9414 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9416 /* If both arguments are constants, evaluate at compile-time. */
9417 if (p1 && p2)
9419 const size_t r = strcspn (p1, p2);
9420 return size_int (r);
9423 /* If the first argument is "", return 0. */
9424 if (p1 && *p1 == '\0')
9426 /* Evaluate and ignore argument s2 in case it has
9427 side-effects. */
9428 return omit_one_operand (integer_type_node,
9429 integer_zero_node, s2);
9432 /* If the second argument is "", return __builtin_strlen(s1). */
9433 if (p2 && *p2 == '\0')
9435 tree newarglist = build_tree_list (NULL_TREE, s1),
9436 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9438 /* If the replacement _DECL isn't initialized, don't do the
9439 transformation. */
9440 if (!fn)
9441 return 0;
9443 return build_function_call_expr (fn, newarglist);
9445 return 0;
9449 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9450 by the builtin will be ignored. UNLOCKED is true is true if this
9451 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9452 the known length of the string. Return NULL_TREE if no simplification
9453 was possible. */
9455 tree
9456 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9458 tree fn;
9459 /* If we're using an unlocked function, assume the other unlocked
9460 functions exist explicitly. */
9461 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9462 : implicit_built_in_decls[BUILT_IN_FPUTC];
9463 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9464 : implicit_built_in_decls[BUILT_IN_FWRITE];
9466 /* If the return value is used, don't do the transformation. */
9467 if (!ignore)
9468 return 0;
9470 /* Verify the arguments in the original call. */
9471 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9472 return 0;
9474 if (! len)
9475 len = c_strlen (TREE_VALUE (arglist), 0);
9477 /* Get the length of the string passed to fputs. If the length
9478 can't be determined, punt. */
9479 if (!len
9480 || TREE_CODE (len) != INTEGER_CST)
9481 return 0;
9483 switch (compare_tree_int (len, 1))
9485 case -1: /* length is 0, delete the call entirely . */
9486 return omit_one_operand (integer_type_node, integer_zero_node,
9487 TREE_VALUE (TREE_CHAIN (arglist)));
9489 case 0: /* length is 1, call fputc. */
9491 const char *p = c_getstr (TREE_VALUE (arglist));
9493 if (p != NULL)
9495 /* New argument list transforming fputs(string, stream) to
9496 fputc(string[0], stream). */
9497 arglist = build_tree_list (NULL_TREE,
9498 TREE_VALUE (TREE_CHAIN (arglist)));
9499 arglist = tree_cons (NULL_TREE,
9500 build_int_cst (NULL_TREE, p[0]),
9501 arglist);
9502 fn = fn_fputc;
9503 break;
9506 /* FALLTHROUGH */
9507 case 1: /* length is greater than 1, call fwrite. */
9509 tree string_arg;
9511 /* If optimizing for size keep fputs. */
9512 if (optimize_size)
9513 return 0;
9514 string_arg = TREE_VALUE (arglist);
9515 /* New argument list transforming fputs(string, stream) to
9516 fwrite(string, 1, len, stream). */
9517 arglist = build_tree_list (NULL_TREE,
9518 TREE_VALUE (TREE_CHAIN (arglist)));
9519 arglist = tree_cons (NULL_TREE, len, arglist);
9520 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9521 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9522 fn = fn_fwrite;
9523 break;
9525 default:
9526 gcc_unreachable ();
9529 /* If the replacement _DECL isn't initialized, don't do the
9530 transformation. */
9531 if (!fn)
9532 return 0;
9534 /* These optimizations are only performed when the result is ignored,
9535 hence there's no need to cast the result to integer_type_node. */
9536 return build_function_call_expr (fn, arglist);
9539 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9540 produced. False otherwise. This is done so that we don't output the error
9541 or warning twice or three times. */
9542 bool
9543 fold_builtin_next_arg (tree arglist)
9545 tree fntype = TREE_TYPE (current_function_decl);
9547 if (TYPE_ARG_TYPES (fntype) == 0
9548 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9549 == void_type_node))
9551 error ("%<va_start%> used in function with fixed args");
9552 return true;
9554 else if (!arglist)
9556 /* Evidently an out of date version of <stdarg.h>; can't validate
9557 va_start's second argument, but can still work as intended. */
9558 warning (0, "%<__builtin_next_arg%> called without an argument");
9559 return true;
9561 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9562 when we checked the arguments and if needed issued a warning. */
9563 else if (!TREE_CHAIN (arglist)
9564 || !integer_zerop (TREE_VALUE (arglist))
9565 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9566 || TREE_CHAIN (TREE_CHAIN (arglist)))
9568 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9569 tree arg = TREE_VALUE (arglist);
9571 if (TREE_CHAIN (arglist))
9573 error ("%<va_start%> used with too many arguments");
9574 return true;
9577 /* Strip off all nops for the sake of the comparison. This
9578 is not quite the same as STRIP_NOPS. It does more.
9579 We must also strip off INDIRECT_EXPR for C++ reference
9580 parameters. */
9581 while (TREE_CODE (arg) == NOP_EXPR
9582 || TREE_CODE (arg) == CONVERT_EXPR
9583 || TREE_CODE (arg) == NON_LVALUE_EXPR
9584 || TREE_CODE (arg) == INDIRECT_REF)
9585 arg = TREE_OPERAND (arg, 0);
9586 if (arg != last_parm)
9588 /* FIXME: Sometimes with the tree optimizers we can get the
9589 not the last argument even though the user used the last
9590 argument. We just warn and set the arg to be the last
9591 argument so that we will get wrong-code because of
9592 it. */
9593 warning (0, "second parameter of %<va_start%> not last named argument");
9595 /* We want to verify the second parameter just once before the tree
9596 optimizers are run and then avoid keeping it in the tree,
9597 as otherwise we could warn even for correct code like:
9598 void foo (int i, ...)
9599 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9600 TREE_VALUE (arglist) = integer_zero_node;
9601 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9603 return false;
9607 /* Simplify a call to the sprintf builtin.
9609 Return 0 if no simplification was possible, otherwise return the
9610 simplified form of the call as a tree. If IGNORED is true, it means that
9611 the caller does not use the returned value of the function. */
9613 static tree
9614 fold_builtin_sprintf (tree arglist, int ignored)
9616 tree call, retval, dest, fmt;
9617 const char *fmt_str = NULL;
9619 /* Verify the required arguments in the original call. We deal with two
9620 types of sprintf() calls: 'sprintf (str, fmt)' and
9621 'sprintf (dest, "%s", orig)'. */
9622 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9623 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9624 VOID_TYPE))
9625 return NULL_TREE;
9627 /* Get the destination string and the format specifier. */
9628 dest = TREE_VALUE (arglist);
9629 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9631 /* Check whether the format is a literal string constant. */
9632 fmt_str = c_getstr (fmt);
9633 if (fmt_str == NULL)
9634 return NULL_TREE;
9636 call = NULL_TREE;
9637 retval = NULL_TREE;
9639 if (!init_target_chars())
9640 return 0;
9642 /* If the format doesn't contain % args or %%, use strcpy. */
9643 if (strchr (fmt_str, target_percent) == NULL)
9645 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9647 if (!fn)
9648 return NULL_TREE;
9650 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9651 'format' is known to contain no % formats. */
9652 arglist = build_tree_list (NULL_TREE, fmt);
9653 arglist = tree_cons (NULL_TREE, dest, arglist);
9654 call = build_function_call_expr (fn, arglist);
9655 if (!ignored)
9656 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9659 /* If the format is "%s", use strcpy if the result isn't used. */
9660 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9662 tree fn, orig;
9663 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9665 if (!fn)
9666 return NULL_TREE;
9668 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9669 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9670 arglist = build_tree_list (NULL_TREE, orig);
9671 arglist = tree_cons (NULL_TREE, dest, arglist);
9672 if (!ignored)
9674 retval = c_strlen (orig, 1);
9675 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9676 return NULL_TREE;
9678 call = build_function_call_expr (fn, arglist);
9681 if (call && retval)
9683 retval = fold_convert
9684 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9685 retval);
9686 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9688 else
9689 return call;
9692 /* Expand a call to __builtin_object_size. */
9695 expand_builtin_object_size (tree exp)
9697 tree ost;
9698 int object_size_type;
9699 tree fndecl = get_callee_fndecl (exp);
9700 tree arglist = TREE_OPERAND (exp, 1);
9701 location_t locus = EXPR_LOCATION (exp);
9703 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9705 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9706 &locus, fndecl);
9707 expand_builtin_trap ();
9708 return const0_rtx;
9711 ost = TREE_VALUE (TREE_CHAIN (arglist));
9712 STRIP_NOPS (ost);
9714 if (TREE_CODE (ost) != INTEGER_CST
9715 || tree_int_cst_sgn (ost) < 0
9716 || compare_tree_int (ost, 3) > 0)
9718 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9719 &locus, fndecl);
9720 expand_builtin_trap ();
9721 return const0_rtx;
9724 object_size_type = tree_low_cst (ost, 0);
9726 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9729 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9730 FCODE is the BUILT_IN_* to use.
9731 Return 0 if we failed; the caller should emit a normal call,
9732 otherwise try to get the result in TARGET, if convenient (and in
9733 mode MODE if that's convenient). */
9735 static rtx
9736 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9737 enum built_in_function fcode)
9739 tree arglist = TREE_OPERAND (exp, 1);
9740 tree dest, src, len, size;
9742 if (!validate_arglist (arglist,
9743 POINTER_TYPE,
9744 fcode == BUILT_IN_MEMSET_CHK
9745 ? INTEGER_TYPE : POINTER_TYPE,
9746 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9747 return 0;
9749 dest = TREE_VALUE (arglist);
9750 src = TREE_VALUE (TREE_CHAIN (arglist));
9751 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9752 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9754 if (! host_integerp (size, 1))
9755 return 0;
9757 if (host_integerp (len, 1) || integer_all_onesp (size))
9759 tree fn;
9761 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9763 location_t locus = EXPR_LOCATION (exp);
9764 warning (0, "%Hcall to %D will always overflow destination buffer",
9765 &locus, get_callee_fndecl (exp));
9766 return 0;
9769 arglist = build_tree_list (NULL_TREE, len);
9770 arglist = tree_cons (NULL_TREE, src, arglist);
9771 arglist = tree_cons (NULL_TREE, dest, arglist);
9773 fn = NULL_TREE;
9774 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9775 mem{cpy,pcpy,move,set} is available. */
9776 switch (fcode)
9778 case BUILT_IN_MEMCPY_CHK:
9779 fn = built_in_decls[BUILT_IN_MEMCPY];
9780 break;
9781 case BUILT_IN_MEMPCPY_CHK:
9782 fn = built_in_decls[BUILT_IN_MEMPCPY];
9783 break;
9784 case BUILT_IN_MEMMOVE_CHK:
9785 fn = built_in_decls[BUILT_IN_MEMMOVE];
9786 break;
9787 case BUILT_IN_MEMSET_CHK:
9788 fn = built_in_decls[BUILT_IN_MEMSET];
9789 break;
9790 default:
9791 break;
9794 if (! fn)
9795 return 0;
9797 fn = build_function_call_expr (fn, arglist);
9798 if (TREE_CODE (fn) == CALL_EXPR)
9799 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9800 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9802 else if (fcode == BUILT_IN_MEMSET_CHK)
9803 return 0;
9804 else
9806 unsigned int dest_align
9807 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9809 /* If DEST is not a pointer type, call the normal function. */
9810 if (dest_align == 0)
9811 return 0;
9813 /* If SRC and DEST are the same (and not volatile), do nothing. */
9814 if (operand_equal_p (src, dest, 0))
9816 tree expr;
9818 if (fcode != BUILT_IN_MEMPCPY_CHK)
9820 /* Evaluate and ignore LEN in case it has side-effects. */
9821 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9822 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9825 len = fold_convert (TREE_TYPE (dest), len);
9826 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9827 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9830 /* __memmove_chk special case. */
9831 if (fcode == BUILT_IN_MEMMOVE_CHK)
9833 unsigned int src_align
9834 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9836 if (src_align == 0)
9837 return 0;
9839 /* If src is categorized for a readonly section we can use
9840 normal __memcpy_chk. */
9841 if (readonly_data_expr (src))
9843 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9844 if (!fn)
9845 return 0;
9846 fn = build_function_call_expr (fn, arglist);
9847 if (TREE_CODE (fn) == CALL_EXPR)
9848 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9849 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9852 return 0;
9856 /* Emit warning if a buffer overflow is detected at compile time. */
9858 static void
9859 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9861 int arg_mask, is_strlen = 0;
9862 tree arglist = TREE_OPERAND (exp, 1), a;
9863 tree len, size;
9864 location_t locus;
9866 switch (fcode)
9868 case BUILT_IN_STRCPY_CHK:
9869 case BUILT_IN_STPCPY_CHK:
9870 /* For __strcat_chk the warning will be emitted only if overflowing
9871 by at least strlen (dest) + 1 bytes. */
9872 case BUILT_IN_STRCAT_CHK:
9873 arg_mask = 6;
9874 is_strlen = 1;
9875 break;
9876 case BUILT_IN_STRNCPY_CHK:
9877 arg_mask = 12;
9878 break;
9879 case BUILT_IN_SNPRINTF_CHK:
9880 case BUILT_IN_VSNPRINTF_CHK:
9881 arg_mask = 10;
9882 break;
9883 default:
9884 gcc_unreachable ();
9887 len = NULL_TREE;
9888 size = NULL_TREE;
9889 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9890 if (arg_mask & 1)
9892 if (len)
9893 size = a;
9894 else
9895 len = a;
9898 if (!len || !size)
9899 return;
9901 len = TREE_VALUE (len);
9902 size = TREE_VALUE (size);
9904 if (! host_integerp (size, 1) || integer_all_onesp (size))
9905 return;
9907 if (is_strlen)
9909 len = c_strlen (len, 1);
9910 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9911 return;
9913 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9914 return;
9916 locus = EXPR_LOCATION (exp);
9917 warning (0, "%Hcall to %D will always overflow destination buffer",
9918 &locus, get_callee_fndecl (exp));
9921 /* Emit warning if a buffer overflow is detected at compile time
9922 in __sprintf_chk/__vsprintf_chk calls. */
9924 static void
9925 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9927 tree arglist = TREE_OPERAND (exp, 1);
9928 tree dest, size, len, fmt, flag;
9929 const char *fmt_str;
9931 /* Verify the required arguments in the original call. */
9932 if (! arglist)
9933 return;
9934 dest = TREE_VALUE (arglist);
9935 arglist = TREE_CHAIN (arglist);
9936 if (! arglist)
9937 return;
9938 flag = TREE_VALUE (arglist);
9939 arglist = TREE_CHAIN (arglist);
9940 if (! arglist)
9941 return;
9942 size = TREE_VALUE (arglist);
9943 arglist = TREE_CHAIN (arglist);
9944 if (! arglist)
9945 return;
9946 fmt = TREE_VALUE (arglist);
9947 arglist = TREE_CHAIN (arglist);
9949 if (! host_integerp (size, 1) || integer_all_onesp (size))
9950 return;
9952 /* Check whether the format is a literal string constant. */
9953 fmt_str = c_getstr (fmt);
9954 if (fmt_str == NULL)
9955 return;
9957 if (!init_target_chars())
9958 return;
9960 /* If the format doesn't contain % args or %%, we know its size. */
9961 if (strchr (fmt_str, target_percent) == 0)
9962 len = build_int_cstu (size_type_node, strlen (fmt_str));
9963 /* If the format is "%s" and first ... argument is a string literal,
9964 we know it too. */
9965 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9967 tree arg;
9969 if (! arglist)
9970 return;
9971 arg = TREE_VALUE (arglist);
9972 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9973 return;
9975 len = c_strlen (arg, 1);
9976 if (!len || ! host_integerp (len, 1))
9977 return;
9979 else
9980 return;
9982 if (! tree_int_cst_lt (len, size))
9984 location_t locus = EXPR_LOCATION (exp);
9985 warning (0, "%Hcall to %D will always overflow destination buffer",
9986 &locus, get_callee_fndecl (exp));
9990 /* Fold a call to __builtin_object_size, if possible. */
9992 tree
9993 fold_builtin_object_size (tree arglist)
9995 tree ptr, ost, ret = 0;
9996 int object_size_type;
9998 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9999 return 0;
10001 ptr = TREE_VALUE (arglist);
10002 ost = TREE_VALUE (TREE_CHAIN (arglist));
10003 STRIP_NOPS (ost);
10005 if (TREE_CODE (ost) != INTEGER_CST
10006 || tree_int_cst_sgn (ost) < 0
10007 || compare_tree_int (ost, 3) > 0)
10008 return 0;
10010 object_size_type = tree_low_cst (ost, 0);
10012 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10013 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10014 and (size_t) 0 for types 2 and 3. */
10015 if (TREE_SIDE_EFFECTS (ptr))
10016 return fold_convert (size_type_node,
10017 object_size_type < 2
10018 ? integer_minus_one_node : integer_zero_node);
10020 if (TREE_CODE (ptr) == ADDR_EXPR)
10021 ret = build_int_cstu (size_type_node,
10022 compute_builtin_object_size (ptr, object_size_type));
10024 else if (TREE_CODE (ptr) == SSA_NAME)
10026 unsigned HOST_WIDE_INT bytes;
10028 /* If object size is not known yet, delay folding until
10029 later. Maybe subsequent passes will help determining
10030 it. */
10031 bytes = compute_builtin_object_size (ptr, object_size_type);
10032 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10033 ? -1 : 0))
10034 ret = build_int_cstu (size_type_node, bytes);
10037 if (ret)
10039 ret = force_fit_type (ret, -1, false, false);
10040 if (TREE_CONSTANT_OVERFLOW (ret))
10041 ret = 0;
10044 return ret;
10047 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10048 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10049 code of the builtin. If MAXLEN is not NULL, it is maximum length
10050 passed as third argument. */
10052 tree
10053 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10054 enum built_in_function fcode)
10056 tree dest, src, len, size, fn;
10058 if (!validate_arglist (arglist,
10059 POINTER_TYPE,
10060 fcode == BUILT_IN_MEMSET_CHK
10061 ? INTEGER_TYPE : POINTER_TYPE,
10062 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10063 return 0;
10065 dest = TREE_VALUE (arglist);
10066 /* Actually val for __memset_chk, but it doesn't matter. */
10067 src = TREE_VALUE (TREE_CHAIN (arglist));
10068 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10069 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10071 /* If SRC and DEST are the same (and not volatile), return DEST
10072 (resp. DEST+LEN for __mempcpy_chk). */
10073 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10075 if (fcode != BUILT_IN_MEMPCPY_CHK)
10076 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10077 else
10079 tree temp = fold_convert (TREE_TYPE (dest), len);
10080 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10081 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10085 if (! host_integerp (size, 1))
10086 return 0;
10088 if (! integer_all_onesp (size))
10090 if (! host_integerp (len, 1))
10092 /* If LEN is not constant, try MAXLEN too.
10093 For MAXLEN only allow optimizing into non-_ocs function
10094 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10095 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10097 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10099 /* (void) __mempcpy_chk () can be optimized into
10100 (void) __memcpy_chk (). */
10101 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10102 if (!fn)
10103 return 0;
10105 return build_function_call_expr (fn, arglist);
10107 return 0;
10110 else
10111 maxlen = len;
10113 if (tree_int_cst_lt (size, maxlen))
10114 return 0;
10117 arglist = build_tree_list (NULL_TREE, len);
10118 arglist = tree_cons (NULL_TREE, src, arglist);
10119 arglist = tree_cons (NULL_TREE, dest, arglist);
10121 fn = NULL_TREE;
10122 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10123 mem{cpy,pcpy,move,set} is available. */
10124 switch (fcode)
10126 case BUILT_IN_MEMCPY_CHK:
10127 fn = built_in_decls[BUILT_IN_MEMCPY];
10128 break;
10129 case BUILT_IN_MEMPCPY_CHK:
10130 fn = built_in_decls[BUILT_IN_MEMPCPY];
10131 break;
10132 case BUILT_IN_MEMMOVE_CHK:
10133 fn = built_in_decls[BUILT_IN_MEMMOVE];
10134 break;
10135 case BUILT_IN_MEMSET_CHK:
10136 fn = built_in_decls[BUILT_IN_MEMSET];
10137 break;
10138 default:
10139 break;
10142 if (!fn)
10143 return 0;
10145 return build_function_call_expr (fn, arglist);
10148 /* Fold a call to the __st[rp]cpy_chk builtin.
10149 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10150 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10151 strings passed as second argument. */
10153 tree
10154 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10155 enum built_in_function fcode)
10157 tree dest, src, size, len, fn;
10159 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10160 VOID_TYPE))
10161 return 0;
10163 dest = TREE_VALUE (arglist);
10164 src = TREE_VALUE (TREE_CHAIN (arglist));
10165 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10167 /* If SRC and DEST are the same (and not volatile), return DEST. */
10168 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10169 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10171 if (! host_integerp (size, 1))
10172 return 0;
10174 if (! integer_all_onesp (size))
10176 len = c_strlen (src, 1);
10177 if (! len || ! host_integerp (len, 1))
10179 /* If LEN is not constant, try MAXLEN too.
10180 For MAXLEN only allow optimizing into non-_ocs function
10181 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10182 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10184 if (fcode == BUILT_IN_STPCPY_CHK)
10186 if (! ignore)
10187 return 0;
10189 /* If return value of __stpcpy_chk is ignored,
10190 optimize into __strcpy_chk. */
10191 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10192 if (!fn)
10193 return 0;
10195 return build_function_call_expr (fn, arglist);
10198 if (! len || TREE_SIDE_EFFECTS (len))
10199 return 0;
10201 /* If c_strlen returned something, but not a constant,
10202 transform __strcpy_chk into __memcpy_chk. */
10203 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10204 if (!fn)
10205 return 0;
10207 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10208 arglist = build_tree_list (NULL_TREE, size);
10209 arglist = tree_cons (NULL_TREE, len, arglist);
10210 arglist = tree_cons (NULL_TREE, src, arglist);
10211 arglist = tree_cons (NULL_TREE, dest, arglist);
10212 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10213 build_function_call_expr (fn, arglist));
10216 else
10217 maxlen = len;
10219 if (! tree_int_cst_lt (maxlen, size))
10220 return 0;
10223 arglist = build_tree_list (NULL_TREE, src);
10224 arglist = tree_cons (NULL_TREE, dest, arglist);
10226 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10227 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10228 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10229 if (!fn)
10230 return 0;
10232 return build_function_call_expr (fn, arglist);
10235 /* Fold a call to the __strncpy_chk builtin.
10236 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10238 tree
10239 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10241 tree dest, src, size, len, fn;
10243 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10244 INTEGER_TYPE, VOID_TYPE))
10245 return 0;
10247 dest = TREE_VALUE (arglist);
10248 src = TREE_VALUE (TREE_CHAIN (arglist));
10249 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10250 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10252 if (! host_integerp (size, 1))
10253 return 0;
10255 if (! integer_all_onesp (size))
10257 if (! host_integerp (len, 1))
10259 /* If LEN is not constant, try MAXLEN too.
10260 For MAXLEN only allow optimizing into non-_ocs function
10261 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10262 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10263 return 0;
10265 else
10266 maxlen = len;
10268 if (tree_int_cst_lt (size, maxlen))
10269 return 0;
10272 arglist = build_tree_list (NULL_TREE, len);
10273 arglist = tree_cons (NULL_TREE, src, arglist);
10274 arglist = tree_cons (NULL_TREE, dest, arglist);
10276 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10277 fn = built_in_decls[BUILT_IN_STRNCPY];
10278 if (!fn)
10279 return 0;
10281 return build_function_call_expr (fn, arglist);
10284 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10286 static tree
10287 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10289 tree dest, src, size, fn;
10290 const char *p;
10292 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10293 VOID_TYPE))
10294 return 0;
10296 dest = TREE_VALUE (arglist);
10297 src = TREE_VALUE (TREE_CHAIN (arglist));
10298 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10300 p = c_getstr (src);
10301 /* If the SRC parameter is "", return DEST. */
10302 if (p && *p == '\0')
10303 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10305 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10306 return 0;
10308 arglist = build_tree_list (NULL_TREE, src);
10309 arglist = tree_cons (NULL_TREE, dest, arglist);
10311 /* If __builtin_strcat_chk is used, assume strcat is available. */
10312 fn = built_in_decls[BUILT_IN_STRCAT];
10313 if (!fn)
10314 return 0;
10316 return build_function_call_expr (fn, arglist);
10319 /* Fold a call to the __strncat_chk builtin EXP. */
10321 static tree
10322 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10324 tree dest, src, size, len, fn;
10325 const char *p;
10327 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10328 INTEGER_TYPE, VOID_TYPE))
10329 return 0;
10331 dest = TREE_VALUE (arglist);
10332 src = TREE_VALUE (TREE_CHAIN (arglist));
10333 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10334 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10336 p = c_getstr (src);
10337 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10338 if (p && *p == '\0')
10339 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10340 else if (integer_zerop (len))
10341 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10343 if (! host_integerp (size, 1))
10344 return 0;
10346 if (! integer_all_onesp (size))
10348 tree src_len = c_strlen (src, 1);
10349 if (src_len
10350 && host_integerp (src_len, 1)
10351 && host_integerp (len, 1)
10352 && ! tree_int_cst_lt (len, src_len))
10354 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10355 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10356 if (!fn)
10357 return 0;
10359 arglist = build_tree_list (NULL_TREE, size);
10360 arglist = tree_cons (NULL_TREE, src, arglist);
10361 arglist = tree_cons (NULL_TREE, dest, arglist);
10362 return build_function_call_expr (fn, arglist);
10364 return 0;
10367 arglist = build_tree_list (NULL_TREE, len);
10368 arglist = tree_cons (NULL_TREE, src, arglist);
10369 arglist = tree_cons (NULL_TREE, dest, arglist);
10371 /* If __builtin_strncat_chk is used, assume strncat is available. */
10372 fn = built_in_decls[BUILT_IN_STRNCAT];
10373 if (!fn)
10374 return 0;
10376 return build_function_call_expr (fn, arglist);
10379 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10380 a normal call should be emitted rather than expanding the function
10381 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10383 static tree
10384 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10386 tree dest, size, len, fn, fmt, flag;
10387 const char *fmt_str;
10389 /* Verify the required arguments in the original call. */
10390 if (! arglist)
10391 return 0;
10392 dest = TREE_VALUE (arglist);
10393 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10394 return 0;
10395 arglist = TREE_CHAIN (arglist);
10396 if (! arglist)
10397 return 0;
10398 flag = TREE_VALUE (arglist);
10399 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10400 return 0;
10401 arglist = TREE_CHAIN (arglist);
10402 if (! arglist)
10403 return 0;
10404 size = TREE_VALUE (arglist);
10405 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10406 return 0;
10407 arglist = TREE_CHAIN (arglist);
10408 if (! arglist)
10409 return 0;
10410 fmt = TREE_VALUE (arglist);
10411 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10412 return 0;
10413 arglist = TREE_CHAIN (arglist);
10415 if (! host_integerp (size, 1))
10416 return 0;
10418 len = NULL_TREE;
10420 if (!init_target_chars())
10421 return 0;
10423 /* Check whether the format is a literal string constant. */
10424 fmt_str = c_getstr (fmt);
10425 if (fmt_str != NULL)
10427 /* If the format doesn't contain % args or %%, we know the size. */
10428 if (strchr (fmt_str, target_percent) == 0)
10430 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10431 len = build_int_cstu (size_type_node, strlen (fmt_str));
10433 /* If the format is "%s" and first ... argument is a string literal,
10434 we know the size too. */
10435 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10437 tree arg;
10439 if (arglist && !TREE_CHAIN (arglist))
10441 arg = TREE_VALUE (arglist);
10442 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10444 len = c_strlen (arg, 1);
10445 if (! len || ! host_integerp (len, 1))
10446 len = NULL_TREE;
10452 if (! integer_all_onesp (size))
10454 if (! len || ! tree_int_cst_lt (len, size))
10455 return 0;
10458 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10459 or if format doesn't contain % chars or is "%s". */
10460 if (! integer_zerop (flag))
10462 if (fmt_str == NULL)
10463 return 0;
10464 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10465 return 0;
10468 arglist = tree_cons (NULL_TREE, fmt, arglist);
10469 arglist = tree_cons (NULL_TREE, dest, arglist);
10471 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10472 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10473 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10474 if (!fn)
10475 return 0;
10477 return build_function_call_expr (fn, arglist);
10480 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10481 a normal call should be emitted rather than expanding the function
10482 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10483 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10484 passed as second argument. */
10486 tree
10487 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10488 enum built_in_function fcode)
10490 tree dest, size, len, fn, fmt, flag;
10491 const char *fmt_str;
10493 /* Verify the required arguments in the original call. */
10494 if (! arglist)
10495 return 0;
10496 dest = TREE_VALUE (arglist);
10497 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10498 return 0;
10499 arglist = TREE_CHAIN (arglist);
10500 if (! arglist)
10501 return 0;
10502 len = TREE_VALUE (arglist);
10503 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10504 return 0;
10505 arglist = TREE_CHAIN (arglist);
10506 if (! arglist)
10507 return 0;
10508 flag = TREE_VALUE (arglist);
10509 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10510 return 0;
10511 arglist = TREE_CHAIN (arglist);
10512 if (! arglist)
10513 return 0;
10514 size = TREE_VALUE (arglist);
10515 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10516 return 0;
10517 arglist = TREE_CHAIN (arglist);
10518 if (! arglist)
10519 return 0;
10520 fmt = TREE_VALUE (arglist);
10521 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10522 return 0;
10523 arglist = TREE_CHAIN (arglist);
10525 if (! host_integerp (size, 1))
10526 return 0;
10528 if (! integer_all_onesp (size))
10530 if (! host_integerp (len, 1))
10532 /* If LEN is not constant, try MAXLEN too.
10533 For MAXLEN only allow optimizing into non-_ocs function
10534 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10535 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10536 return 0;
10538 else
10539 maxlen = len;
10541 if (tree_int_cst_lt (size, maxlen))
10542 return 0;
10545 if (!init_target_chars())
10546 return 0;
10548 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10549 or if format doesn't contain % chars or is "%s". */
10550 if (! integer_zerop (flag))
10552 fmt_str = c_getstr (fmt);
10553 if (fmt_str == NULL)
10554 return 0;
10555 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10556 return 0;
10559 arglist = tree_cons (NULL_TREE, fmt, arglist);
10560 arglist = tree_cons (NULL_TREE, len, arglist);
10561 arglist = tree_cons (NULL_TREE, dest, arglist);
10563 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10564 available. */
10565 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10566 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10567 if (!fn)
10568 return 0;
10570 return build_function_call_expr (fn, arglist);
10573 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10575 Return 0 if no simplification was possible, otherwise return the
10576 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10577 code of the function to be simplified. */
10579 static tree
10580 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10581 enum built_in_function fcode)
10583 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10584 const char *fmt_str = NULL;
10586 /* If the return value is used, don't do the transformation. */
10587 if (! ignore)
10588 return 0;
10590 /* Verify the required arguments in the original call. */
10591 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10593 tree flag;
10595 if (! arglist)
10596 return 0;
10597 flag = TREE_VALUE (arglist);
10598 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10599 || TREE_SIDE_EFFECTS (flag))
10600 return 0;
10601 arglist = TREE_CHAIN (arglist);
10604 if (! arglist)
10605 return 0;
10606 fmt = TREE_VALUE (arglist);
10607 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10608 return 0;
10609 arglist = TREE_CHAIN (arglist);
10611 /* Check whether the format is a literal string constant. */
10612 fmt_str = c_getstr (fmt);
10613 if (fmt_str == NULL)
10614 return NULL_TREE;
10616 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10618 /* If we're using an unlocked function, assume the other
10619 unlocked functions exist explicitly. */
10620 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10621 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10623 else
10625 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10626 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10629 if (!init_target_chars())
10630 return 0;
10632 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10634 const char *str;
10636 if (strcmp (fmt_str, target_percent_s) == 0)
10638 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10639 return 0;
10641 if (! arglist
10642 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10643 || TREE_CHAIN (arglist))
10644 return 0;
10646 str = c_getstr (TREE_VALUE (arglist));
10647 if (str == NULL)
10648 return 0;
10650 else
10652 /* The format specifier doesn't contain any '%' characters. */
10653 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10654 && arglist)
10655 return 0;
10656 str = fmt_str;
10659 /* If the string was "", printf does nothing. */
10660 if (str[0] == '\0')
10661 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10663 /* If the string has length of 1, call putchar. */
10664 if (str[1] == '\0')
10666 /* Given printf("c"), (where c is any one character,)
10667 convert "c"[0] to an int and pass that to the replacement
10668 function. */
10669 arg = build_int_cst (NULL_TREE, str[0]);
10670 arglist = build_tree_list (NULL_TREE, arg);
10671 fn = fn_putchar;
10673 else
10675 /* If the string was "string\n", call puts("string"). */
10676 size_t len = strlen (str);
10677 if ((unsigned char)str[len - 1] == target_newline)
10679 /* Create a NUL-terminated string that's one char shorter
10680 than the original, stripping off the trailing '\n'. */
10681 char *newstr = alloca (len);
10682 memcpy (newstr, str, len - 1);
10683 newstr[len - 1] = 0;
10685 arg = build_string_literal (len, newstr);
10686 arglist = build_tree_list (NULL_TREE, arg);
10687 fn = fn_puts;
10689 else
10690 /* We'd like to arrange to call fputs(string,stdout) here,
10691 but we need stdout and don't have a way to get it yet. */
10692 return 0;
10696 /* The other optimizations can be done only on the non-va_list variants. */
10697 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10698 return 0;
10700 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10701 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10703 if (! arglist
10704 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10705 || TREE_CHAIN (arglist))
10706 return 0;
10707 fn = fn_puts;
10710 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10711 else if (strcmp (fmt_str, target_percent_c) == 0)
10713 if (! arglist
10714 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10715 || TREE_CHAIN (arglist))
10716 return 0;
10717 fn = fn_putchar;
10720 if (!fn)
10721 return 0;
10723 call = build_function_call_expr (fn, arglist);
10724 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10727 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10729 Return 0 if no simplification was possible, otherwise return the
10730 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10731 code of the function to be simplified. */
10733 static tree
10734 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10735 enum built_in_function fcode)
10737 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10738 const char *fmt_str = NULL;
10740 /* If the return value is used, don't do the transformation. */
10741 if (! ignore)
10742 return 0;
10744 /* Verify the required arguments in the original call. */
10745 if (! arglist)
10746 return 0;
10747 fp = TREE_VALUE (arglist);
10748 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10749 return 0;
10750 arglist = TREE_CHAIN (arglist);
10752 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10754 tree flag;
10756 if (! arglist)
10757 return 0;
10758 flag = TREE_VALUE (arglist);
10759 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10760 || TREE_SIDE_EFFECTS (flag))
10761 return 0;
10762 arglist = TREE_CHAIN (arglist);
10765 if (! arglist)
10766 return 0;
10767 fmt = TREE_VALUE (arglist);
10768 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10769 return 0;
10770 arglist = TREE_CHAIN (arglist);
10772 /* Check whether the format is a literal string constant. */
10773 fmt_str = c_getstr (fmt);
10774 if (fmt_str == NULL)
10775 return NULL_TREE;
10777 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10779 /* If we're using an unlocked function, assume the other
10780 unlocked functions exist explicitly. */
10781 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10782 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10784 else
10786 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10787 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10790 if (!init_target_chars())
10791 return 0;
10793 /* If the format doesn't contain % args or %%, use strcpy. */
10794 if (strchr (fmt_str, target_percent) == NULL)
10796 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10797 && arglist)
10798 return 0;
10800 /* If the format specifier was "", fprintf does nothing. */
10801 if (fmt_str[0] == '\0')
10803 /* If FP has side-effects, just wait until gimplification is
10804 done. */
10805 if (TREE_SIDE_EFFECTS (fp))
10806 return 0;
10808 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10811 /* When "string" doesn't contain %, replace all cases of
10812 fprintf (fp, string) with fputs (string, fp). The fputs
10813 builtin will take care of special cases like length == 1. */
10814 arglist = build_tree_list (NULL_TREE, fp);
10815 arglist = tree_cons (NULL_TREE, fmt, arglist);
10816 fn = fn_fputs;
10819 /* The other optimizations can be done only on the non-va_list variants. */
10820 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10821 return 0;
10823 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10824 else if (strcmp (fmt_str, target_percent_s) == 0)
10826 if (! arglist
10827 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10828 || TREE_CHAIN (arglist))
10829 return 0;
10830 arg = TREE_VALUE (arglist);
10831 arglist = build_tree_list (NULL_TREE, fp);
10832 arglist = tree_cons (NULL_TREE, arg, arglist);
10833 fn = fn_fputs;
10836 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10837 else if (strcmp (fmt_str, target_percent_c) == 0)
10839 if (! arglist
10840 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10841 || TREE_CHAIN (arglist))
10842 return 0;
10843 arg = TREE_VALUE (arglist);
10844 arglist = build_tree_list (NULL_TREE, fp);
10845 arglist = tree_cons (NULL_TREE, arg, arglist);
10846 fn = fn_fputc;
10849 if (!fn)
10850 return 0;
10852 call = build_function_call_expr (fn, arglist);
10853 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10856 /* Initialize format string characters in the target charset. */
10858 static bool
10859 init_target_chars (void)
10861 static bool init;
10862 if (!init)
10864 target_newline = lang_hooks.to_target_charset ('\n');
10865 target_percent = lang_hooks.to_target_charset ('%');
10866 target_c = lang_hooks.to_target_charset ('c');
10867 target_s = lang_hooks.to_target_charset ('s');
10868 if (target_newline == 0 || target_percent == 0 || target_c == 0
10869 || target_s == 0)
10870 return false;
10872 target_percent_c[0] = target_percent;
10873 target_percent_c[1] = target_c;
10874 target_percent_c[2] = '\0';
10876 target_percent_s[0] = target_percent;
10877 target_percent_s[1] = target_s;
10878 target_percent_s[2] = '\0';
10880 target_percent_s_newline[0] = target_percent;
10881 target_percent_s_newline[1] = target_s;
10882 target_percent_s_newline[2] = target_newline;
10883 target_percent_s_newline[3] = '\0';
10885 init = true;
10887 return true;