2006-01-05 Paolo Carlini <pcarlini@suse.de>
[official-gcc.git] / gcc / builtins.c
blob01d16dd5acb70a14e16f0da2f6b6681d89b789d9
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static tree build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx result_vector (int, rtx);
84 #endif
85 static rtx expand_builtin_setjmp (tree, rtx);
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_sin (tree);
155 static tree fold_builtin_cos (tree, tree, tree);
156 static tree fold_builtin_tan (tree);
157 static tree fold_builtin_atan (tree, tree);
158 static tree fold_builtin_trunc (tree, tree);
159 static tree fold_builtin_floor (tree, tree);
160 static tree fold_builtin_ceil (tree, tree);
161 static tree fold_builtin_round (tree, tree);
162 static tree fold_builtin_int_roundingfn (tree, tree);
163 static tree fold_builtin_bitop (tree, tree);
164 static tree fold_builtin_memcpy (tree, tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree, tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree, tree);
172 static tree fold_builtin_copysign (tree, tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 enum tree_code);
180 static tree fold_builtin_1 (tree, tree, bool);
182 static tree fold_builtin_strpbrk (tree, tree);
183 static tree fold_builtin_strstr (tree, tree);
184 static tree fold_builtin_strrchr (tree, tree);
185 static tree fold_builtin_strcat (tree);
186 static tree fold_builtin_strncat (tree);
187 static tree fold_builtin_strspn (tree);
188 static tree fold_builtin_strcspn (tree);
189 static tree fold_builtin_sprintf (tree, int);
191 static rtx expand_builtin_object_size (tree);
192 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193 enum built_in_function);
194 static void maybe_emit_chk_warning (tree, enum built_in_function);
195 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196 static tree fold_builtin_object_size (tree);
197 static tree fold_builtin_strcat_chk (tree, tree);
198 static tree fold_builtin_strncat_chk (tree, tree);
199 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline;
205 static unsigned HOST_WIDE_INT target_percent;
206 static unsigned HOST_WIDE_INT target_c;
207 static unsigned HOST_WIDE_INT target_s;
208 static char target_percent_c[3];
209 static char target_percent_s[3];
210 static char target_percent_s_newline[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node)
218 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
219 if (strncmp (name, "__builtin_", 10) == 0)
220 return true;
221 if (strncmp (name, "__sync_", 7) == 0)
222 return true;
223 return false;
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
234 static int
235 get_pointer_alignment (tree exp, unsigned int max_align)
237 unsigned int align, inner;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
240 return 0;
242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243 align = MIN (align, max_align);
245 while (1)
247 switch (TREE_CODE (exp))
249 case NOP_EXPR:
250 case CONVERT_EXPR:
251 case NON_LVALUE_EXPR:
252 exp = TREE_OPERAND (exp, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254 return align;
256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257 align = MIN (inner, max_align);
258 break;
260 case PLUS_EXPR:
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
263 ALIGN. */
264 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265 return align;
267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268 & (max_align / BITS_PER_UNIT - 1))
269 != 0)
270 max_align >>= 1;
272 exp = TREE_OPERAND (exp, 0);
273 break;
275 case ADDR_EXPR:
276 /* See what we are pointing at and look at its alignment. */
277 exp = TREE_OPERAND (exp, 0);
278 if (TREE_CODE (exp) == FUNCTION_DECL)
279 align = FUNCTION_BOUNDARY;
280 else if (DECL_P (exp))
281 align = DECL_ALIGN (exp);
282 #ifdef CONSTANT_ALIGNMENT
283 else if (CONSTANT_CLASS_P (exp))
284 align = CONSTANT_ALIGNMENT (exp, align);
285 #endif
286 return MIN (align, max_align);
288 default:
289 return align;
294 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
295 way, because it could contain a zero byte in the middle.
296 TREE_STRING_LENGTH is the size of the character array, not the string.
298 ONLY_VALUE should be nonzero if the result is not going to be emitted
299 into the instruction stream and zero if it is going to be expanded.
300 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
301 is returned, otherwise NULL, since
302 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
303 evaluate the side-effects.
305 The value returned is of type `ssizetype'.
307 Unfortunately, string_constant can't access the values of const char
308 arrays with initializers, so neither can we do so here. */
310 tree
311 c_strlen (tree src, int only_value)
313 tree offset_node;
314 HOST_WIDE_INT offset;
315 int max;
316 const char *ptr;
318 STRIP_NOPS (src);
319 if (TREE_CODE (src) == COND_EXPR
320 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
322 tree len1, len2;
324 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
325 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
326 if (tree_int_cst_equal (len1, len2))
327 return len1;
330 if (TREE_CODE (src) == COMPOUND_EXPR
331 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
332 return c_strlen (TREE_OPERAND (src, 1), only_value);
334 src = string_constant (src, &offset_node);
335 if (src == 0)
336 return 0;
338 max = TREE_STRING_LENGTH (src) - 1;
339 ptr = TREE_STRING_POINTER (src);
341 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
343 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
344 compute the offset to the following null if we don't know where to
345 start searching for it. */
346 int i;
348 for (i = 0; i < max; i++)
349 if (ptr[i] == 0)
350 return 0;
352 /* We don't know the starting offset, but we do know that the string
353 has no internal zero bytes. We can assume that the offset falls
354 within the bounds of the string; otherwise, the programmer deserves
355 what he gets. Subtract the offset from the length of the string,
356 and return that. This would perhaps not be valid if we were dealing
357 with named arrays in addition to literal string constants. */
359 return size_diffop (size_int (max), offset_node);
362 /* We have a known offset into the string. Start searching there for
363 a null character if we can represent it as a single HOST_WIDE_INT. */
364 if (offset_node == 0)
365 offset = 0;
366 else if (! host_integerp (offset_node, 0))
367 offset = -1;
368 else
369 offset = tree_low_cst (offset_node, 0);
371 /* If the offset is known to be out of bounds, warn, and call strlen at
372 runtime. */
373 if (offset < 0 || offset > max)
375 warning (0, "offset outside bounds of constant string");
376 return 0;
379 /* Use strlen to search for the first zero byte. Since any strings
380 constructed with build_string will have nulls appended, we win even
381 if we get handed something like (char[4])"abcd".
383 Since OFFSET is our starting index into the string, no further
384 calculation is needed. */
385 return ssize_int (strlen (ptr + offset));
388 /* Return a char pointer for a C string if it is a string constant
389 or sum of string constant and integer constant. */
391 static const char *
392 c_getstr (tree src)
394 tree offset_node;
396 src = string_constant (src, &offset_node);
397 if (src == 0)
398 return 0;
400 if (offset_node == 0)
401 return TREE_STRING_POINTER (src);
402 else if (!host_integerp (offset_node, 1)
403 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
404 return 0;
406 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
409 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
410 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
412 static rtx
413 c_readstr (const char *str, enum machine_mode mode)
415 HOST_WIDE_INT c[2];
416 HOST_WIDE_INT ch;
417 unsigned int i, j;
419 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
421 c[0] = 0;
422 c[1] = 0;
423 ch = 1;
424 for (i = 0; i < GET_MODE_SIZE (mode); i++)
426 j = i;
427 if (WORDS_BIG_ENDIAN)
428 j = GET_MODE_SIZE (mode) - i - 1;
429 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
430 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
431 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
432 j *= BITS_PER_UNIT;
433 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
435 if (ch)
436 ch = (unsigned char) str[i];
437 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
439 return immed_double_const (c[0], c[1], mode);
442 /* Cast a target constant CST to target CHAR and if that value fits into
443 host char type, return zero and put that value into variable pointed to by
444 P. */
446 static int
447 target_char_cast (tree cst, char *p)
449 unsigned HOST_WIDE_INT val, hostval;
451 if (!host_integerp (cst, 1)
452 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
453 return 1;
455 val = tree_low_cst (cst, 1);
456 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
457 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
459 hostval = val;
460 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
461 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
463 if (val != hostval)
464 return 1;
466 *p = hostval;
467 return 0;
470 /* Similar to save_expr, but assumes that arbitrary code is not executed
471 in between the multiple evaluations. In particular, we assume that a
472 non-addressable local variable will not be modified. */
474 static tree
475 builtin_save_expr (tree exp)
477 if (TREE_ADDRESSABLE (exp) == 0
478 && (TREE_CODE (exp) == PARM_DECL
479 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
480 return exp;
482 return save_expr (exp);
485 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
486 times to get the address of either a higher stack frame, or a return
487 address located within it (depending on FNDECL_CODE). */
489 static rtx
490 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
492 int i;
494 #ifdef INITIAL_FRAME_ADDRESS_RTX
495 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
496 #else
497 rtx tem;
499 /* For a zero count, we don't care what frame address we return, so frame
500 pointer elimination is OK, and using the soft frame pointer is OK.
501 For a non-zero count, we require a stable offset from the current frame
502 pointer to the previous one, so we must use the hard frame pointer, and
503 we must disable frame pointer elimination. */
504 if (count == 0)
505 tem = frame_pointer_rtx;
506 else
508 tem = hard_frame_pointer_rtx;
510 /* Tell reload not to eliminate the frame pointer. */
511 current_function_accesses_prior_frames = 1;
513 #endif
515 /* Some machines need special handling before we can access
516 arbitrary frames. For example, on the sparc, we must first flush
517 all register windows to the stack. */
518 #ifdef SETUP_FRAME_ADDRESSES
519 if (count > 0)
520 SETUP_FRAME_ADDRESSES ();
521 #endif
523 /* On the sparc, the return address is not in the frame, it is in a
524 register. There is no way to access it off of the current frame
525 pointer, but it can be accessed off the previous frame pointer by
526 reading the value from the register window save area. */
527 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
528 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
529 count--;
530 #endif
532 /* Scan back COUNT frames to the specified frame. */
533 for (i = 0; i < count; i++)
535 /* Assume the dynamic chain pointer is in the word that the
536 frame address points to, unless otherwise specified. */
537 #ifdef DYNAMIC_CHAIN_ADDRESS
538 tem = DYNAMIC_CHAIN_ADDRESS (tem);
539 #endif
540 tem = memory_address (Pmode, tem);
541 tem = gen_frame_mem (Pmode, tem);
542 tem = copy_to_reg (tem);
545 /* For __builtin_frame_address, return what we've got. */
546 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
547 return tem;
549 /* For __builtin_return_address, Get the return address from that
550 frame. */
551 #ifdef RETURN_ADDR_RTX
552 tem = RETURN_ADDR_RTX (count, tem);
553 #else
554 tem = memory_address (Pmode,
555 plus_constant (tem, GET_MODE_SIZE (Pmode)));
556 tem = gen_frame_mem (Pmode, tem);
557 #endif
558 return tem;
561 /* Alias set used for setjmp buffer. */
562 static HOST_WIDE_INT setjmp_alias_set = -1;
564 /* Construct the leading half of a __builtin_setjmp call. Control will
565 return to RECEIVER_LABEL. This is used directly by sjlj exception
566 handling code. */
568 void
569 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
571 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
572 rtx stack_save;
573 rtx mem;
575 if (setjmp_alias_set == -1)
576 setjmp_alias_set = new_alias_set ();
578 buf_addr = convert_memory_address (Pmode, buf_addr);
580 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
582 /* We store the frame pointer and the address of receiver_label in
583 the buffer and use the rest of it for the stack save area, which
584 is machine-dependent. */
586 mem = gen_rtx_MEM (Pmode, buf_addr);
587 set_mem_alias_set (mem, setjmp_alias_set);
588 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
590 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
591 set_mem_alias_set (mem, setjmp_alias_set);
593 emit_move_insn (validize_mem (mem),
594 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
596 stack_save = gen_rtx_MEM (sa_mode,
597 plus_constant (buf_addr,
598 2 * GET_MODE_SIZE (Pmode)));
599 set_mem_alias_set (stack_save, setjmp_alias_set);
600 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
602 /* If there is further processing to do, do it. */
603 #ifdef HAVE_builtin_setjmp_setup
604 if (HAVE_builtin_setjmp_setup)
605 emit_insn (gen_builtin_setjmp_setup (buf_addr));
606 #endif
608 /* Tell optimize_save_area_alloca that extra work is going to
609 need to go on during alloca. */
610 current_function_calls_setjmp = 1;
612 /* Set this so all the registers get saved in our frame; we need to be
613 able to copy the saved values for any registers from frames we unwind. */
614 current_function_has_nonlocal_label = 1;
617 /* Construct the trailing part of a __builtin_setjmp call.
618 This is used directly by sjlj exception handling code. */
620 void
621 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
623 /* Clobber the FP when we get here, so we have to make sure it's
624 marked as used by this function. */
625 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
627 /* Mark the static chain as clobbered here so life information
628 doesn't get messed up for it. */
629 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
631 /* Now put in the code to restore the frame pointer, and argument
632 pointer, if needed. */
633 #ifdef HAVE_nonlocal_goto
634 if (! HAVE_nonlocal_goto)
635 #endif
636 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
638 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
639 if (fixed_regs[ARG_POINTER_REGNUM])
641 #ifdef ELIMINABLE_REGS
642 size_t i;
643 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
645 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
646 if (elim_regs[i].from == ARG_POINTER_REGNUM
647 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
648 break;
650 if (i == ARRAY_SIZE (elim_regs))
651 #endif
653 /* Now restore our arg pointer from the address at which it
654 was saved in our stack frame. */
655 emit_move_insn (virtual_incoming_args_rtx,
656 copy_to_reg (get_arg_pointer_save_area (cfun)));
659 #endif
661 #ifdef HAVE_builtin_setjmp_receiver
662 if (HAVE_builtin_setjmp_receiver)
663 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
664 else
665 #endif
666 #ifdef HAVE_nonlocal_goto_receiver
667 if (HAVE_nonlocal_goto_receiver)
668 emit_insn (gen_nonlocal_goto_receiver ());
669 else
670 #endif
671 { /* Nothing */ }
673 /* @@@ This is a kludge. Not all machine descriptions define a blockage
674 insn, but we must not allow the code we just generated to be reordered
675 by scheduling. Specifically, the update of the frame pointer must
676 happen immediately, not later. So emit an ASM_INPUT to act as blockage
677 insn. */
678 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
681 /* __builtin_setjmp is passed a pointer to an array of five words (not
682 all will be used on all machines). It operates similarly to the C
683 library function of the same name, but is more efficient. Much of
684 the code below (and for longjmp) is copied from the handling of
685 non-local gotos.
687 NOTE: This is intended for use by GNAT and the exception handling
688 scheme in the compiler and will only work in the method used by
689 them. */
691 static rtx
692 expand_builtin_setjmp (tree arglist, rtx target)
694 rtx buf_addr, next_lab, cont_lab;
696 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
697 return NULL_RTX;
699 if (target == 0 || !REG_P (target)
700 || REGNO (target) < FIRST_PSEUDO_REGISTER)
701 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
703 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
705 next_lab = gen_label_rtx ();
706 cont_lab = gen_label_rtx ();
708 expand_builtin_setjmp_setup (buf_addr, next_lab);
710 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
711 ensure that pending stack adjustments are flushed. */
712 emit_move_insn (target, const0_rtx);
713 emit_jump (cont_lab);
715 emit_label (next_lab);
717 expand_builtin_setjmp_receiver (next_lab);
719 /* Set TARGET to one. */
720 emit_move_insn (target, const1_rtx);
721 emit_label (cont_lab);
723 /* Tell flow about the strange goings on. Putting `next_lab' on
724 `nonlocal_goto_handler_labels' to indicates that function
725 calls may traverse the arc back to this label. */
727 current_function_has_nonlocal_label = 1;
728 nonlocal_goto_handler_labels
729 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
731 return target;
734 /* __builtin_longjmp is passed a pointer to an array of five words (not
735 all will be used on all machines). It operates similarly to the C
736 library function of the same name, but is more efficient. Much of
737 the code below is copied from the handling of non-local gotos.
739 NOTE: This is intended for use by GNAT and the exception handling
740 scheme in the compiler and will only work in the method used by
741 them. */
743 static void
744 expand_builtin_longjmp (rtx buf_addr, rtx value)
746 rtx fp, lab, stack, insn, last;
747 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
749 if (setjmp_alias_set == -1)
750 setjmp_alias_set = new_alias_set ();
752 buf_addr = convert_memory_address (Pmode, buf_addr);
754 buf_addr = force_reg (Pmode, buf_addr);
756 /* We used to store value in static_chain_rtx, but that fails if pointers
757 are smaller than integers. We instead require that the user must pass
758 a second argument of 1, because that is what builtin_setjmp will
759 return. This also makes EH slightly more efficient, since we are no
760 longer copying around a value that we don't care about. */
761 gcc_assert (value == const1_rtx);
763 last = get_last_insn ();
764 #ifdef HAVE_builtin_longjmp
765 if (HAVE_builtin_longjmp)
766 emit_insn (gen_builtin_longjmp (buf_addr));
767 else
768 #endif
770 fp = gen_rtx_MEM (Pmode, buf_addr);
771 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
772 GET_MODE_SIZE (Pmode)));
774 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
775 2 * GET_MODE_SIZE (Pmode)));
776 set_mem_alias_set (fp, setjmp_alias_set);
777 set_mem_alias_set (lab, setjmp_alias_set);
778 set_mem_alias_set (stack, setjmp_alias_set);
780 /* Pick up FP, label, and SP from the block and jump. This code is
781 from expand_goto in stmt.c; see there for detailed comments. */
782 #if HAVE_nonlocal_goto
783 if (HAVE_nonlocal_goto)
784 /* We have to pass a value to the nonlocal_goto pattern that will
785 get copied into the static_chain pointer, but it does not matter
786 what that value is, because builtin_setjmp does not use it. */
787 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
788 else
789 #endif
791 lab = copy_to_reg (lab);
793 emit_insn (gen_rtx_CLOBBER (VOIDmode,
794 gen_rtx_MEM (BLKmode,
795 gen_rtx_SCRATCH (VOIDmode))));
796 emit_insn (gen_rtx_CLOBBER (VOIDmode,
797 gen_rtx_MEM (BLKmode,
798 hard_frame_pointer_rtx)));
800 emit_move_insn (hard_frame_pointer_rtx, fp);
801 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
803 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
804 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
805 emit_indirect_jump (lab);
809 /* Search backwards and mark the jump insn as a non-local goto.
810 Note that this precludes the use of __builtin_longjmp to a
811 __builtin_setjmp target in the same function. However, we've
812 already cautioned the user that these functions are for
813 internal exception handling use only. */
814 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
816 gcc_assert (insn != last);
818 if (JUMP_P (insn))
820 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
821 REG_NOTES (insn));
822 break;
824 else if (CALL_P (insn))
825 break;
829 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
830 and the address of the save area. */
832 static rtx
833 expand_builtin_nonlocal_goto (tree arglist)
835 tree t_label, t_save_area;
836 rtx r_label, r_save_area, r_fp, r_sp, insn;
838 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
839 return NULL_RTX;
841 t_label = TREE_VALUE (arglist);
842 arglist = TREE_CHAIN (arglist);
843 t_save_area = TREE_VALUE (arglist);
845 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
846 r_label = convert_memory_address (Pmode, r_label);
847 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
848 r_save_area = convert_memory_address (Pmode, r_save_area);
849 r_fp = gen_rtx_MEM (Pmode, r_save_area);
850 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
851 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
853 current_function_has_nonlocal_goto = 1;
855 #if HAVE_nonlocal_goto
856 /* ??? We no longer need to pass the static chain value, afaik. */
857 if (HAVE_nonlocal_goto)
858 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
859 else
860 #endif
862 r_label = copy_to_reg (r_label);
864 emit_insn (gen_rtx_CLOBBER (VOIDmode,
865 gen_rtx_MEM (BLKmode,
866 gen_rtx_SCRATCH (VOIDmode))));
868 emit_insn (gen_rtx_CLOBBER (VOIDmode,
869 gen_rtx_MEM (BLKmode,
870 hard_frame_pointer_rtx)));
872 /* Restore frame pointer for containing function.
873 This sets the actual hard register used for the frame pointer
874 to the location of the function's incoming static chain info.
875 The non-local goto handler will then adjust it to contain the
876 proper value and reload the argument pointer, if needed. */
877 emit_move_insn (hard_frame_pointer_rtx, r_fp);
878 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
880 /* USE of hard_frame_pointer_rtx added for consistency;
881 not clear if really needed. */
882 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
883 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
884 emit_indirect_jump (r_label);
887 /* Search backwards to the jump insn and mark it as a
888 non-local goto. */
889 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
891 if (JUMP_P (insn))
893 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
894 const0_rtx, REG_NOTES (insn));
895 break;
897 else if (CALL_P (insn))
898 break;
901 return const0_rtx;
904 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
905 (not all will be used on all machines) that was passed to __builtin_setjmp.
906 It updates the stack pointer in that block to correspond to the current
907 stack pointer. */
909 static void
910 expand_builtin_update_setjmp_buf (rtx buf_addr)
912 enum machine_mode sa_mode = Pmode;
913 rtx stack_save;
916 #ifdef HAVE_save_stack_nonlocal
917 if (HAVE_save_stack_nonlocal)
918 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
919 #endif
920 #ifdef STACK_SAVEAREA_MODE
921 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
922 #endif
924 stack_save
925 = gen_rtx_MEM (sa_mode,
926 memory_address
927 (sa_mode,
928 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
930 #ifdef HAVE_setjmp
931 if (HAVE_setjmp)
932 emit_insn (gen_setjmp ());
933 #endif
935 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
938 /* Expand a call to __builtin_prefetch. For a target that does not support
939 data prefetch, evaluate the memory address argument in case it has side
940 effects. */
942 static void
943 expand_builtin_prefetch (tree arglist)
945 tree arg0, arg1, arg2;
946 rtx op0, op1, op2;
948 if (!validate_arglist (arglist, POINTER_TYPE, 0))
949 return;
951 arg0 = TREE_VALUE (arglist);
952 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
953 zero (read) and argument 2 (locality) defaults to 3 (high degree of
954 locality). */
955 if (TREE_CHAIN (arglist))
957 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
958 if (TREE_CHAIN (TREE_CHAIN (arglist)))
959 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
960 else
961 arg2 = build_int_cst (NULL_TREE, 3);
963 else
965 arg1 = integer_zero_node;
966 arg2 = build_int_cst (NULL_TREE, 3);
969 /* Argument 0 is an address. */
970 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
972 /* Argument 1 (read/write flag) must be a compile-time constant int. */
973 if (TREE_CODE (arg1) != INTEGER_CST)
975 error ("second argument to %<__builtin_prefetch%> must be a constant");
976 arg1 = integer_zero_node;
978 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
979 /* Argument 1 must be either zero or one. */
980 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
982 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
983 " using zero");
984 op1 = const0_rtx;
987 /* Argument 2 (locality) must be a compile-time constant int. */
988 if (TREE_CODE (arg2) != INTEGER_CST)
990 error ("third argument to %<__builtin_prefetch%> must be a constant");
991 arg2 = integer_zero_node;
993 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
994 /* Argument 2 must be 0, 1, 2, or 3. */
995 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
997 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
998 op2 = const0_rtx;
1001 #ifdef HAVE_prefetch
1002 if (HAVE_prefetch)
1004 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1005 (op0,
1006 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1007 || (GET_MODE (op0) != Pmode))
1009 op0 = convert_memory_address (Pmode, op0);
1010 op0 = force_reg (Pmode, op0);
1012 emit_insn (gen_prefetch (op0, op1, op2));
1014 #endif
1016 /* Don't do anything with direct references to volatile memory, but
1017 generate code to handle other side effects. */
1018 if (!MEM_P (op0) && side_effects_p (op0))
1019 emit_insn (op0);
1022 /* Get a MEM rtx for expression EXP which is the address of an operand
1023 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1024 the maximum length of the block of memory that might be accessed or
1025 NULL if unknown. */
1027 static rtx
1028 get_memory_rtx (tree exp, tree len)
1030 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1031 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1033 /* Get an expression we can use to find the attributes to assign to MEM.
1034 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1035 we can. First remove any nops. */
1036 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1037 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1038 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1039 exp = TREE_OPERAND (exp, 0);
1041 if (TREE_CODE (exp) == ADDR_EXPR)
1042 exp = TREE_OPERAND (exp, 0);
1043 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1044 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1045 else
1046 exp = NULL;
1048 /* Honor attributes derived from exp, except for the alias set
1049 (as builtin stringops may alias with anything) and the size
1050 (as stringops may access multiple array elements). */
1051 if (exp)
1053 set_mem_attributes (mem, exp, 0);
1055 /* Allow the string and memory builtins to overflow from one
1056 field into another, see http://gcc.gnu.org/PR23561.
1057 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1058 memory accessed by the string or memory builtin will fit
1059 within the field. */
1060 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1062 tree mem_expr = MEM_EXPR (mem);
1063 HOST_WIDE_INT offset = -1, length = -1;
1064 tree inner = exp;
1066 while (TREE_CODE (inner) == ARRAY_REF
1067 || TREE_CODE (inner) == NOP_EXPR
1068 || TREE_CODE (inner) == CONVERT_EXPR
1069 || TREE_CODE (inner) == NON_LVALUE_EXPR
1070 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1071 || TREE_CODE (inner) == SAVE_EXPR)
1072 inner = TREE_OPERAND (inner, 0);
1074 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1076 if (MEM_OFFSET (mem)
1077 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1078 offset = INTVAL (MEM_OFFSET (mem));
1080 if (offset >= 0 && len && host_integerp (len, 0))
1081 length = tree_low_cst (len, 0);
1083 while (TREE_CODE (inner) == COMPONENT_REF)
1085 tree field = TREE_OPERAND (inner, 1);
1086 gcc_assert (! DECL_BIT_FIELD (field));
1087 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1088 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1090 if (length >= 0
1091 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1092 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1094 HOST_WIDE_INT size
1095 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1096 /* If we can prove the memory starting at XEXP (mem, 0)
1097 and ending at XEXP (mem, 0) + LENGTH will fit into
1098 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1099 if (offset <= size
1100 && length <= size
1101 && offset + length <= size)
1102 break;
1105 if (offset >= 0
1106 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1107 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1108 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1109 / BITS_PER_UNIT;
1110 else
1112 offset = -1;
1113 length = -1;
1116 mem_expr = TREE_OPERAND (mem_expr, 0);
1117 inner = TREE_OPERAND (inner, 0);
1120 if (mem_expr == NULL)
1121 offset = -1;
1122 if (mem_expr != MEM_EXPR (mem))
1124 set_mem_expr (mem, mem_expr);
1125 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1128 set_mem_alias_set (mem, 0);
1129 set_mem_size (mem, NULL_RTX);
1132 return mem;
1135 /* Built-in functions to perform an untyped call and return. */
1137 /* For each register that may be used for calling a function, this
1138 gives a mode used to copy the register's value. VOIDmode indicates
1139 the register is not used for calling a function. If the machine
1140 has register windows, this gives only the outbound registers.
1141 INCOMING_REGNO gives the corresponding inbound register. */
1142 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1144 /* For each register that may be used for returning values, this gives
1145 a mode used to copy the register's value. VOIDmode indicates the
1146 register is not used for returning values. If the machine has
1147 register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1151 /* For each register that may be used for calling a function, this
1152 gives the offset of that register into the block returned by
1153 __builtin_apply_args. 0 indicates that the register is not
1154 used for calling a function. */
1155 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1157 /* Return the size required for the block returned by __builtin_apply_args,
1158 and initialize apply_args_mode. */
1160 static int
1161 apply_args_size (void)
1163 static int size = -1;
1164 int align;
1165 unsigned int regno;
1166 enum machine_mode mode;
1168 /* The values computed by this function never change. */
1169 if (size < 0)
1171 /* The first value is the incoming arg-pointer. */
1172 size = GET_MODE_SIZE (Pmode);
1174 /* The second value is the structure value address unless this is
1175 passed as an "invisible" first argument. */
1176 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1177 size += GET_MODE_SIZE (Pmode);
1179 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1180 if (FUNCTION_ARG_REGNO_P (regno))
1182 mode = reg_raw_mode[regno];
1184 gcc_assert (mode != VOIDmode);
1186 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1187 if (size % align != 0)
1188 size = CEIL (size, align) * align;
1189 apply_args_reg_offset[regno] = size;
1190 size += GET_MODE_SIZE (mode);
1191 apply_args_mode[regno] = mode;
1193 else
1195 apply_args_mode[regno] = VOIDmode;
1196 apply_args_reg_offset[regno] = 0;
1199 return size;
1202 /* Return the size required for the block returned by __builtin_apply,
1203 and initialize apply_result_mode. */
1205 static int
1206 apply_result_size (void)
1208 static int size = -1;
1209 int align, regno;
1210 enum machine_mode mode;
1212 /* The values computed by this function never change. */
1213 if (size < 0)
1215 size = 0;
1217 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1218 if (FUNCTION_VALUE_REGNO_P (regno))
1220 mode = reg_raw_mode[regno];
1222 gcc_assert (mode != VOIDmode);
1224 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1225 if (size % align != 0)
1226 size = CEIL (size, align) * align;
1227 size += GET_MODE_SIZE (mode);
1228 apply_result_mode[regno] = mode;
1230 else
1231 apply_result_mode[regno] = VOIDmode;
1233 /* Allow targets that use untyped_call and untyped_return to override
1234 the size so that machine-specific information can be stored here. */
1235 #ifdef APPLY_RESULT_SIZE
1236 size = APPLY_RESULT_SIZE;
1237 #endif
1239 return size;
1242 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1243 /* Create a vector describing the result block RESULT. If SAVEP is true,
1244 the result block is used to save the values; otherwise it is used to
1245 restore the values. */
1247 static rtx
1248 result_vector (int savep, rtx result)
1250 int regno, size, align, nelts;
1251 enum machine_mode mode;
1252 rtx reg, mem;
1253 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1255 size = nelts = 0;
1256 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1257 if ((mode = apply_result_mode[regno]) != VOIDmode)
1259 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1260 if (size % align != 0)
1261 size = CEIL (size, align) * align;
1262 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1263 mem = adjust_address (result, mode, size);
1264 savevec[nelts++] = (savep
1265 ? gen_rtx_SET (VOIDmode, mem, reg)
1266 : gen_rtx_SET (VOIDmode, reg, mem));
1267 size += GET_MODE_SIZE (mode);
1269 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1271 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1273 /* Save the state required to perform an untyped call with the same
1274 arguments as were passed to the current function. */
1276 static rtx
1277 expand_builtin_apply_args_1 (void)
1279 rtx registers, tem;
1280 int size, align, regno;
1281 enum machine_mode mode;
1282 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1284 /* Create a block where the arg-pointer, structure value address,
1285 and argument registers can be saved. */
1286 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1288 /* Walk past the arg-pointer and structure value address. */
1289 size = GET_MODE_SIZE (Pmode);
1290 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1291 size += GET_MODE_SIZE (Pmode);
1293 /* Save each register used in calling a function to the block. */
1294 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1295 if ((mode = apply_args_mode[regno]) != VOIDmode)
1297 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1298 if (size % align != 0)
1299 size = CEIL (size, align) * align;
1301 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1303 emit_move_insn (adjust_address (registers, mode, size), tem);
1304 size += GET_MODE_SIZE (mode);
1307 /* Save the arg pointer to the block. */
1308 tem = copy_to_reg (virtual_incoming_args_rtx);
1309 #ifdef STACK_GROWS_DOWNWARD
1310 /* We need the pointer as the caller actually passed them to us, not
1311 as we might have pretended they were passed. Make sure it's a valid
1312 operand, as emit_move_insn isn't expected to handle a PLUS. */
1314 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1315 NULL_RTX);
1316 #endif
1317 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1319 size = GET_MODE_SIZE (Pmode);
1321 /* Save the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 if (struct_incoming_value)
1325 emit_move_insn (adjust_address (registers, Pmode, size),
1326 copy_to_reg (struct_incoming_value));
1327 size += GET_MODE_SIZE (Pmode);
1330 /* Return the address of the block. */
1331 return copy_addr_to_reg (XEXP (registers, 0));
1334 /* __builtin_apply_args returns block of memory allocated on
1335 the stack into which is stored the arg pointer, structure
1336 value address, static chain, and all the registers that might
1337 possibly be used in performing a function call. The code is
1338 moved to the start of the function so the incoming values are
1339 saved. */
1341 static rtx
1342 expand_builtin_apply_args (void)
1344 /* Don't do __builtin_apply_args more than once in a function.
1345 Save the result of the first call and reuse it. */
1346 if (apply_args_value != 0)
1347 return apply_args_value;
1349 /* When this function is called, it means that registers must be
1350 saved on entry to this function. So we migrate the
1351 call to the first insn of this function. */
1352 rtx temp;
1353 rtx seq;
1355 start_sequence ();
1356 temp = expand_builtin_apply_args_1 ();
1357 seq = get_insns ();
1358 end_sequence ();
1360 apply_args_value = temp;
1362 /* Put the insns after the NOTE that starts the function.
1363 If this is inside a start_sequence, make the outer-level insn
1364 chain current, so the code is placed at the start of the
1365 function. */
1366 push_topmost_sequence ();
1367 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1368 pop_topmost_sequence ();
1369 return temp;
1373 /* Perform an untyped call and save the state required to perform an
1374 untyped return of whatever value was returned by the given function. */
1376 static rtx
1377 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1379 int size, align, regno;
1380 enum machine_mode mode;
1381 rtx incoming_args, result, reg, dest, src, call_insn;
1382 rtx old_stack_level = 0;
1383 rtx call_fusage = 0;
1384 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1386 arguments = convert_memory_address (Pmode, arguments);
1388 /* Create a block where the return registers can be saved. */
1389 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1391 /* Fetch the arg pointer from the ARGUMENTS block. */
1392 incoming_args = gen_reg_rtx (Pmode);
1393 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1394 #ifndef STACK_GROWS_DOWNWARD
1395 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1396 incoming_args, 0, OPTAB_LIB_WIDEN);
1397 #endif
1399 /* Push a new argument block and copy the arguments. Do not allow
1400 the (potential) memcpy call below to interfere with our stack
1401 manipulations. */
1402 do_pending_stack_adjust ();
1403 NO_DEFER_POP;
1405 /* Save the stack with nonlocal if available. */
1406 #ifdef HAVE_save_stack_nonlocal
1407 if (HAVE_save_stack_nonlocal)
1408 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1409 else
1410 #endif
1411 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1413 /* Allocate a block of memory onto the stack and copy the memory
1414 arguments to the outgoing arguments address. */
1415 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1416 dest = virtual_outgoing_args_rtx;
1417 #ifndef STACK_GROWS_DOWNWARD
1418 if (GET_CODE (argsize) == CONST_INT)
1419 dest = plus_constant (dest, -INTVAL (argsize));
1420 else
1421 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1422 #endif
1423 dest = gen_rtx_MEM (BLKmode, dest);
1424 set_mem_align (dest, PARM_BOUNDARY);
1425 src = gen_rtx_MEM (BLKmode, incoming_args);
1426 set_mem_align (src, PARM_BOUNDARY);
1427 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1429 /* Refer to the argument block. */
1430 apply_args_size ();
1431 arguments = gen_rtx_MEM (BLKmode, arguments);
1432 set_mem_align (arguments, PARM_BOUNDARY);
1434 /* Walk past the arg-pointer and structure value address. */
1435 size = GET_MODE_SIZE (Pmode);
1436 if (struct_value)
1437 size += GET_MODE_SIZE (Pmode);
1439 /* Restore each of the registers previously saved. Make USE insns
1440 for each of these registers for use in making the call. */
1441 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1442 if ((mode = apply_args_mode[regno]) != VOIDmode)
1444 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1445 if (size % align != 0)
1446 size = CEIL (size, align) * align;
1447 reg = gen_rtx_REG (mode, regno);
1448 emit_move_insn (reg, adjust_address (arguments, mode, size));
1449 use_reg (&call_fusage, reg);
1450 size += GET_MODE_SIZE (mode);
1453 /* Restore the structure value address unless this is passed as an
1454 "invisible" first argument. */
1455 size = GET_MODE_SIZE (Pmode);
1456 if (struct_value)
1458 rtx value = gen_reg_rtx (Pmode);
1459 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1460 emit_move_insn (struct_value, value);
1461 if (REG_P (struct_value))
1462 use_reg (&call_fusage, struct_value);
1463 size += GET_MODE_SIZE (Pmode);
1466 /* All arguments and registers used for the call are set up by now! */
1467 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1469 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1470 and we don't want to load it into a register as an optimization,
1471 because prepare_call_address already did it if it should be done. */
1472 if (GET_CODE (function) != SYMBOL_REF)
1473 function = memory_address (FUNCTION_MODE, function);
1475 /* Generate the actual call instruction and save the return value. */
1476 #ifdef HAVE_untyped_call
1477 if (HAVE_untyped_call)
1478 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1479 result, result_vector (1, result)));
1480 else
1481 #endif
1482 #ifdef HAVE_call_value
1483 if (HAVE_call_value)
1485 rtx valreg = 0;
1487 /* Locate the unique return register. It is not possible to
1488 express a call that sets more than one return register using
1489 call_value; use untyped_call for that. In fact, untyped_call
1490 only needs to save the return registers in the given block. */
1491 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1492 if ((mode = apply_result_mode[regno]) != VOIDmode)
1494 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1496 valreg = gen_rtx_REG (mode, regno);
1499 emit_call_insn (GEN_CALL_VALUE (valreg,
1500 gen_rtx_MEM (FUNCTION_MODE, function),
1501 const0_rtx, NULL_RTX, const0_rtx));
1503 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1505 else
1506 #endif
1507 gcc_unreachable ();
1509 /* Find the CALL insn we just emitted, and attach the register usage
1510 information. */
1511 call_insn = last_call_insn ();
1512 add_function_usage_to (call_insn, call_fusage);
1514 /* Restore the stack. */
1515 #ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal)
1517 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1518 else
1519 #endif
1520 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1522 OK_DEFER_POP;
1524 /* Return the address of the result block. */
1525 result = copy_addr_to_reg (XEXP (result, 0));
1526 return convert_memory_address (ptr_mode, result);
1529 /* Perform an untyped return. */
1531 static void
1532 expand_builtin_return (rtx result)
1534 int size, align, regno;
1535 enum machine_mode mode;
1536 rtx reg;
1537 rtx call_fusage = 0;
1539 result = convert_memory_address (Pmode, result);
1541 apply_result_size ();
1542 result = gen_rtx_MEM (BLKmode, result);
1544 #ifdef HAVE_untyped_return
1545 if (HAVE_untyped_return)
1547 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1548 emit_barrier ();
1549 return;
1551 #endif
1553 /* Restore the return value and note that each value is used. */
1554 size = 0;
1555 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1556 if ((mode = apply_result_mode[regno]) != VOIDmode)
1558 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1559 if (size % align != 0)
1560 size = CEIL (size, align) * align;
1561 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1562 emit_move_insn (reg, adjust_address (result, mode, size));
1564 push_to_sequence (call_fusage);
1565 emit_insn (gen_rtx_USE (VOIDmode, reg));
1566 call_fusage = get_insns ();
1567 end_sequence ();
1568 size += GET_MODE_SIZE (mode);
1571 /* Put the USE insns before the return. */
1572 emit_insn (call_fusage);
1574 /* Return whatever values was restored by jumping directly to the end
1575 of the function. */
1576 expand_naked_return ();
1579 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1581 static enum type_class
1582 type_to_class (tree type)
1584 switch (TREE_CODE (type))
1586 case VOID_TYPE: return void_type_class;
1587 case INTEGER_TYPE: return integer_type_class;
1588 case CHAR_TYPE: return char_type_class;
1589 case ENUMERAL_TYPE: return enumeral_type_class;
1590 case BOOLEAN_TYPE: return boolean_type_class;
1591 case POINTER_TYPE: return pointer_type_class;
1592 case REFERENCE_TYPE: return reference_type_class;
1593 case OFFSET_TYPE: return offset_type_class;
1594 case REAL_TYPE: return real_type_class;
1595 case COMPLEX_TYPE: return complex_type_class;
1596 case FUNCTION_TYPE: return function_type_class;
1597 case METHOD_TYPE: return method_type_class;
1598 case RECORD_TYPE: return record_type_class;
1599 case UNION_TYPE:
1600 case QUAL_UNION_TYPE: return union_type_class;
1601 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1602 ? string_type_class : array_type_class);
1603 case LANG_TYPE: return lang_type_class;
1604 default: return no_type_class;
1608 /* Expand a call to __builtin_classify_type with arguments found in
1609 ARGLIST. */
1611 static rtx
1612 expand_builtin_classify_type (tree arglist)
1614 if (arglist != 0)
1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1616 return GEN_INT (no_type_class);
1619 /* This helper macro, meant to be used in mathfn_built_in below,
1620 determines which among a set of three builtin math functions is
1621 appropriate for a given type mode. The `F' and `L' cases are
1622 automatically generated from the `double' case. */
1623 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626 fcodel = BUILT_IN_MATHFN##L ; break;
1628 /* Return mathematic function equivalent to FN but operating directly
1629 on TYPE, if available. If we can't do the conversion, return zero. */
1630 tree
1631 mathfn_built_in (tree type, enum built_in_function fn)
1633 enum built_in_function fcode, fcodef, fcodel;
1635 switch (fn)
1637 CASE_MATHFN (BUILT_IN_ACOS)
1638 CASE_MATHFN (BUILT_IN_ACOSH)
1639 CASE_MATHFN (BUILT_IN_ASIN)
1640 CASE_MATHFN (BUILT_IN_ASINH)
1641 CASE_MATHFN (BUILT_IN_ATAN)
1642 CASE_MATHFN (BUILT_IN_ATAN2)
1643 CASE_MATHFN (BUILT_IN_ATANH)
1644 CASE_MATHFN (BUILT_IN_CBRT)
1645 CASE_MATHFN (BUILT_IN_CEIL)
1646 CASE_MATHFN (BUILT_IN_COPYSIGN)
1647 CASE_MATHFN (BUILT_IN_COS)
1648 CASE_MATHFN (BUILT_IN_COSH)
1649 CASE_MATHFN (BUILT_IN_DREM)
1650 CASE_MATHFN (BUILT_IN_ERF)
1651 CASE_MATHFN (BUILT_IN_ERFC)
1652 CASE_MATHFN (BUILT_IN_EXP)
1653 CASE_MATHFN (BUILT_IN_EXP10)
1654 CASE_MATHFN (BUILT_IN_EXP2)
1655 CASE_MATHFN (BUILT_IN_EXPM1)
1656 CASE_MATHFN (BUILT_IN_FABS)
1657 CASE_MATHFN (BUILT_IN_FDIM)
1658 CASE_MATHFN (BUILT_IN_FLOOR)
1659 CASE_MATHFN (BUILT_IN_FMA)
1660 CASE_MATHFN (BUILT_IN_FMAX)
1661 CASE_MATHFN (BUILT_IN_FMIN)
1662 CASE_MATHFN (BUILT_IN_FMOD)
1663 CASE_MATHFN (BUILT_IN_FREXP)
1664 CASE_MATHFN (BUILT_IN_GAMMA)
1665 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1666 CASE_MATHFN (BUILT_IN_HYPOT)
1667 CASE_MATHFN (BUILT_IN_ILOGB)
1668 CASE_MATHFN (BUILT_IN_INF)
1669 CASE_MATHFN (BUILT_IN_J0)
1670 CASE_MATHFN (BUILT_IN_J1)
1671 CASE_MATHFN (BUILT_IN_JN)
1672 CASE_MATHFN (BUILT_IN_LCEIL)
1673 CASE_MATHFN (BUILT_IN_LDEXP)
1674 CASE_MATHFN (BUILT_IN_LFLOOR)
1675 CASE_MATHFN (BUILT_IN_LGAMMA)
1676 CASE_MATHFN (BUILT_IN_LLCEIL)
1677 CASE_MATHFN (BUILT_IN_LLFLOOR)
1678 CASE_MATHFN (BUILT_IN_LLRINT)
1679 CASE_MATHFN (BUILT_IN_LLROUND)
1680 CASE_MATHFN (BUILT_IN_LOG)
1681 CASE_MATHFN (BUILT_IN_LOG10)
1682 CASE_MATHFN (BUILT_IN_LOG1P)
1683 CASE_MATHFN (BUILT_IN_LOG2)
1684 CASE_MATHFN (BUILT_IN_LOGB)
1685 CASE_MATHFN (BUILT_IN_LRINT)
1686 CASE_MATHFN (BUILT_IN_LROUND)
1687 CASE_MATHFN (BUILT_IN_MODF)
1688 CASE_MATHFN (BUILT_IN_NAN)
1689 CASE_MATHFN (BUILT_IN_NANS)
1690 CASE_MATHFN (BUILT_IN_NEARBYINT)
1691 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1693 CASE_MATHFN (BUILT_IN_POW)
1694 CASE_MATHFN (BUILT_IN_POWI)
1695 CASE_MATHFN (BUILT_IN_POW10)
1696 CASE_MATHFN (BUILT_IN_REMAINDER)
1697 CASE_MATHFN (BUILT_IN_REMQUO)
1698 CASE_MATHFN (BUILT_IN_RINT)
1699 CASE_MATHFN (BUILT_IN_ROUND)
1700 CASE_MATHFN (BUILT_IN_SCALB)
1701 CASE_MATHFN (BUILT_IN_SCALBLN)
1702 CASE_MATHFN (BUILT_IN_SCALBN)
1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1704 CASE_MATHFN (BUILT_IN_SIN)
1705 CASE_MATHFN (BUILT_IN_SINCOS)
1706 CASE_MATHFN (BUILT_IN_SINH)
1707 CASE_MATHFN (BUILT_IN_SQRT)
1708 CASE_MATHFN (BUILT_IN_TAN)
1709 CASE_MATHFN (BUILT_IN_TANH)
1710 CASE_MATHFN (BUILT_IN_TGAMMA)
1711 CASE_MATHFN (BUILT_IN_TRUNC)
1712 CASE_MATHFN (BUILT_IN_Y0)
1713 CASE_MATHFN (BUILT_IN_Y1)
1714 CASE_MATHFN (BUILT_IN_YN)
1716 default:
1717 return 0;
1720 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1721 return implicit_built_in_decls[fcode];
1722 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1723 return implicit_built_in_decls[fcodef];
1724 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1725 return implicit_built_in_decls[fcodel];
1726 else
1727 return 0;
1730 /* If errno must be maintained, expand the RTL to check if the result,
1731 TARGET, of a built-in function call, EXP, is NaN, and if so set
1732 errno to EDOM. */
1734 static void
1735 expand_errno_check (tree exp, rtx target)
1737 rtx lab = gen_label_rtx ();
1739 /* Test the result; if it is NaN, set errno=EDOM because
1740 the argument was not in the domain. */
1741 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1742 0, lab);
1744 #ifdef TARGET_EDOM
1745 /* If this built-in doesn't throw an exception, set errno directly. */
1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1748 #ifdef GEN_ERRNO_RTX
1749 rtx errno_rtx = GEN_ERRNO_RTX;
1750 #else
1751 rtx errno_rtx
1752 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1753 #endif
1754 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1755 emit_label (lab);
1756 return;
1758 #endif
1760 /* We can't set errno=EDOM directly; let the library call do it.
1761 Pop the arguments right away in case the call gets deleted. */
1762 NO_DEFER_POP;
1763 expand_call (exp, target, 0);
1764 OK_DEFER_POP;
1765 emit_label (lab);
1769 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770 Return 0 if a normal call should be emitted rather than expanding the
1771 function in-line. EXP is the expression that is a call to the builtin
1772 function; if convenient, the result should be placed in TARGET.
1773 SUBTARGET may be used as the target for computing one of EXP's operands. */
1775 static rtx
1776 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1778 optab builtin_optab;
1779 rtx op0, insns, before_call;
1780 tree fndecl = get_callee_fndecl (exp);
1781 tree arglist = TREE_OPERAND (exp, 1);
1782 enum machine_mode mode;
1783 bool errno_set = false;
1784 tree arg, narg;
1786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1787 return 0;
1789 arg = TREE_VALUE (arglist);
1791 switch (DECL_FUNCTION_CODE (fndecl))
1793 CASE_FLT_FN (BUILT_IN_SQRT):
1794 errno_set = ! tree_expr_nonnegative_p (arg);
1795 builtin_optab = sqrt_optab;
1796 break;
1797 CASE_FLT_FN (BUILT_IN_EXP):
1798 errno_set = true; builtin_optab = exp_optab; break;
1799 CASE_FLT_FN (BUILT_IN_EXP10):
1800 CASE_FLT_FN (BUILT_IN_POW10):
1801 errno_set = true; builtin_optab = exp10_optab; break;
1802 CASE_FLT_FN (BUILT_IN_EXP2):
1803 errno_set = true; builtin_optab = exp2_optab; break;
1804 CASE_FLT_FN (BUILT_IN_EXPM1):
1805 errno_set = true; builtin_optab = expm1_optab; break;
1806 CASE_FLT_FN (BUILT_IN_LOGB):
1807 errno_set = true; builtin_optab = logb_optab; break;
1808 CASE_FLT_FN (BUILT_IN_ILOGB):
1809 errno_set = true; builtin_optab = ilogb_optab; break;
1810 CASE_FLT_FN (BUILT_IN_LOG):
1811 errno_set = true; builtin_optab = log_optab; break;
1812 CASE_FLT_FN (BUILT_IN_LOG10):
1813 errno_set = true; builtin_optab = log10_optab; break;
1814 CASE_FLT_FN (BUILT_IN_LOG2):
1815 errno_set = true; builtin_optab = log2_optab; break;
1816 CASE_FLT_FN (BUILT_IN_LOG1P):
1817 errno_set = true; builtin_optab = log1p_optab; break;
1818 CASE_FLT_FN (BUILT_IN_ASIN):
1819 builtin_optab = asin_optab; break;
1820 CASE_FLT_FN (BUILT_IN_ACOS):
1821 builtin_optab = acos_optab; break;
1822 CASE_FLT_FN (BUILT_IN_TAN):
1823 builtin_optab = tan_optab; break;
1824 CASE_FLT_FN (BUILT_IN_ATAN):
1825 builtin_optab = atan_optab; break;
1826 CASE_FLT_FN (BUILT_IN_FLOOR):
1827 builtin_optab = floor_optab; break;
1828 CASE_FLT_FN (BUILT_IN_CEIL):
1829 builtin_optab = ceil_optab; break;
1830 CASE_FLT_FN (BUILT_IN_TRUNC):
1831 builtin_optab = btrunc_optab; break;
1832 CASE_FLT_FN (BUILT_IN_ROUND):
1833 builtin_optab = round_optab; break;
1834 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1835 builtin_optab = nearbyint_optab; break;
1836 CASE_FLT_FN (BUILT_IN_RINT):
1837 builtin_optab = rint_optab; break;
1838 CASE_FLT_FN (BUILT_IN_LRINT):
1839 CASE_FLT_FN (BUILT_IN_LLRINT):
1840 builtin_optab = lrint_optab; break;
1841 default:
1842 gcc_unreachable ();
1845 /* Make a suitable register to place result in. */
1846 mode = TYPE_MODE (TREE_TYPE (exp));
1848 if (! flag_errno_math || ! HONOR_NANS (mode))
1849 errno_set = false;
1851 /* Before working hard, check whether the instruction is available. */
1852 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1854 target = gen_reg_rtx (mode);
1856 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1857 need to expand the argument again. This way, we will not perform
1858 side-effects more the once. */
1859 narg = builtin_save_expr (arg);
1860 if (narg != arg)
1862 arg = narg;
1863 arglist = build_tree_list (NULL_TREE, arg);
1864 exp = build_function_call_expr (fndecl, arglist);
1867 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1869 start_sequence ();
1871 /* Compute into TARGET.
1872 Set TARGET to wherever the result comes back. */
1873 target = expand_unop (mode, builtin_optab, op0, target, 0);
1875 if (target != 0)
1877 if (errno_set)
1878 expand_errno_check (exp, target);
1880 /* Output the entire sequence. */
1881 insns = get_insns ();
1882 end_sequence ();
1883 emit_insn (insns);
1884 return target;
1887 /* If we were unable to expand via the builtin, stop the sequence
1888 (without outputting the insns) and call to the library function
1889 with the stabilized argument list. */
1890 end_sequence ();
1893 before_call = get_last_insn ();
1895 target = expand_call (exp, target, target == const0_rtx);
1897 /* If this is a sqrt operation and we don't care about errno, try to
1898 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1899 This allows the semantics of the libcall to be visible to the RTL
1900 optimizers. */
1901 if (builtin_optab == sqrt_optab && !errno_set)
1903 /* Search backwards through the insns emitted by expand_call looking
1904 for the instruction with the REG_RETVAL note. */
1905 rtx last = get_last_insn ();
1906 while (last != before_call)
1908 if (find_reg_note (last, REG_RETVAL, NULL))
1910 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1911 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1912 two elements, i.e. symbol_ref(sqrt) and the operand. */
1913 if (note
1914 && GET_CODE (note) == EXPR_LIST
1915 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1916 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1917 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1919 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1920 /* Check operand is a register with expected mode. */
1921 if (operand
1922 && REG_P (operand)
1923 && GET_MODE (operand) == mode)
1925 /* Replace the REG_EQUAL note with a SQRT rtx. */
1926 rtx equiv = gen_rtx_SQRT (mode, operand);
1927 set_unique_reg_note (last, REG_EQUAL, equiv);
1930 break;
1932 last = PREV_INSN (last);
1936 return target;
1939 /* Expand a call to the builtin binary math functions (pow and atan2).
1940 Return 0 if a normal call should be emitted rather than expanding the
1941 function in-line. EXP is the expression that is a call to the builtin
1942 function; if convenient, the result should be placed in TARGET.
1943 SUBTARGET may be used as the target for computing one of EXP's
1944 operands. */
1946 static rtx
1947 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1949 optab builtin_optab;
1950 rtx op0, op1, insns;
1951 int op1_type = REAL_TYPE;
1952 tree fndecl = get_callee_fndecl (exp);
1953 tree arglist = TREE_OPERAND (exp, 1);
1954 tree arg0, arg1, temp, narg;
1955 enum machine_mode mode;
1956 bool errno_set = true;
1957 bool stable = true;
1959 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1960 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1961 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1962 op1_type = INTEGER_TYPE;
1964 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1965 return 0;
1967 arg0 = TREE_VALUE (arglist);
1968 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1970 switch (DECL_FUNCTION_CODE (fndecl))
1972 CASE_FLT_FN (BUILT_IN_POW):
1973 builtin_optab = pow_optab; break;
1974 CASE_FLT_FN (BUILT_IN_ATAN2):
1975 builtin_optab = atan2_optab; break;
1976 CASE_FLT_FN (BUILT_IN_LDEXP):
1977 builtin_optab = ldexp_optab; break;
1978 CASE_FLT_FN (BUILT_IN_FMOD):
1979 builtin_optab = fmod_optab; break;
1980 CASE_FLT_FN (BUILT_IN_DREM):
1981 builtin_optab = drem_optab; break;
1982 default:
1983 gcc_unreachable ();
1986 /* Make a suitable register to place result in. */
1987 mode = TYPE_MODE (TREE_TYPE (exp));
1989 /* Before working hard, check whether the instruction is available. */
1990 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1991 return 0;
1993 target = gen_reg_rtx (mode);
1995 if (! flag_errno_math || ! HONOR_NANS (mode))
1996 errno_set = false;
1998 /* Always stabilize the argument list. */
1999 narg = builtin_save_expr (arg1);
2000 if (narg != arg1)
2002 arg1 = narg;
2003 temp = build_tree_list (NULL_TREE, narg);
2004 stable = false;
2006 else
2007 temp = TREE_CHAIN (arglist);
2009 narg = builtin_save_expr (arg0);
2010 if (narg != arg0)
2012 arg0 = narg;
2013 arglist = tree_cons (NULL_TREE, narg, temp);
2014 stable = false;
2016 else if (! stable)
2017 arglist = tree_cons (NULL_TREE, arg0, temp);
2019 if (! stable)
2020 exp = build_function_call_expr (fndecl, arglist);
2022 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2023 op1 = expand_expr (arg1, 0, VOIDmode, 0);
2025 start_sequence ();
2027 /* Compute into TARGET.
2028 Set TARGET to wherever the result comes back. */
2029 target = expand_binop (mode, builtin_optab, op0, op1,
2030 target, 0, OPTAB_DIRECT);
2032 /* If we were unable to expand via the builtin, stop the sequence
2033 (without outputting the insns) and call to the library function
2034 with the stabilized argument list. */
2035 if (target == 0)
2037 end_sequence ();
2038 return expand_call (exp, target, target == const0_rtx);
2041 if (errno_set)
2042 expand_errno_check (exp, target);
2044 /* Output the entire sequence. */
2045 insns = get_insns ();
2046 end_sequence ();
2047 emit_insn (insns);
2049 return target;
2052 /* Expand a call to the builtin sin and cos math functions.
2053 Return 0 if a normal call should be emitted rather than expanding the
2054 function in-line. EXP is the expression that is a call to the builtin
2055 function; if convenient, the result should be placed in TARGET.
2056 SUBTARGET may be used as the target for computing one of EXP's
2057 operands. */
2059 static rtx
2060 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2062 optab builtin_optab;
2063 rtx op0, insns;
2064 tree fndecl = get_callee_fndecl (exp);
2065 tree arglist = TREE_OPERAND (exp, 1);
2066 enum machine_mode mode;
2067 bool errno_set = false;
2068 tree arg, narg;
2070 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2071 return 0;
2073 arg = TREE_VALUE (arglist);
2075 switch (DECL_FUNCTION_CODE (fndecl))
2077 CASE_FLT_FN (BUILT_IN_SIN):
2078 CASE_FLT_FN (BUILT_IN_COS):
2079 builtin_optab = sincos_optab; break;
2080 default:
2081 gcc_unreachable ();
2084 /* Make a suitable register to place result in. */
2085 mode = TYPE_MODE (TREE_TYPE (exp));
2087 if (! flag_errno_math || ! HONOR_NANS (mode))
2088 errno_set = false;
2090 /* Check if sincos insn is available, otherwise fallback
2091 to sin or cos insn. */
2092 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2093 switch (DECL_FUNCTION_CODE (fndecl))
2095 CASE_FLT_FN (BUILT_IN_SIN):
2096 builtin_optab = sin_optab; break;
2097 CASE_FLT_FN (BUILT_IN_COS):
2098 builtin_optab = cos_optab; break;
2099 default:
2100 gcc_unreachable ();
2104 /* Before working hard, check whether the instruction is available. */
2105 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2107 target = gen_reg_rtx (mode);
2109 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2110 need to expand the argument again. This way, we will not perform
2111 side-effects more the once. */
2112 narg = save_expr (arg);
2113 if (narg != arg)
2115 arg = narg;
2116 arglist = build_tree_list (NULL_TREE, arg);
2117 exp = build_function_call_expr (fndecl, arglist);
2120 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2122 start_sequence ();
2124 /* Compute into TARGET.
2125 Set TARGET to wherever the result comes back. */
2126 if (builtin_optab == sincos_optab)
2128 int result;
2130 switch (DECL_FUNCTION_CODE (fndecl))
2132 CASE_FLT_FN (BUILT_IN_SIN):
2133 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2134 break;
2135 CASE_FLT_FN (BUILT_IN_COS):
2136 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2137 break;
2138 default:
2139 gcc_unreachable ();
2141 gcc_assert (result);
2143 else
2145 target = expand_unop (mode, builtin_optab, op0, target, 0);
2148 if (target != 0)
2150 if (errno_set)
2151 expand_errno_check (exp, target);
2153 /* Output the entire sequence. */
2154 insns = get_insns ();
2155 end_sequence ();
2156 emit_insn (insns);
2157 return target;
2160 /* If we were unable to expand via the builtin, stop the sequence
2161 (without outputting the insns) and call to the library function
2162 with the stabilized argument list. */
2163 end_sequence ();
2166 target = expand_call (exp, target, target == const0_rtx);
2168 return target;
2171 /* Expand a call to one of the builtin rounding functions (lfloor).
2172 If expanding via optab fails, lower expression to (int)(floor(x)).
2173 EXP is the expression that is a call to the builtin function;
2174 if convenient, the result should be placed in TARGET. SUBTARGET may
2175 be used as the target for computing one of EXP's operands. */
2177 static rtx
2178 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2180 optab builtin_optab;
2181 rtx op0, insns, tmp;
2182 tree fndecl = get_callee_fndecl (exp);
2183 tree arglist = TREE_OPERAND (exp, 1);
2184 enum built_in_function fallback_fn;
2185 tree fallback_fndecl;
2186 enum machine_mode mode;
2187 tree arg, narg;
2189 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2190 gcc_unreachable ();
2192 arg = TREE_VALUE (arglist);
2194 switch (DECL_FUNCTION_CODE (fndecl))
2196 CASE_FLT_FN (BUILT_IN_LCEIL):
2197 CASE_FLT_FN (BUILT_IN_LLCEIL):
2198 builtin_optab = lceil_optab;
2199 fallback_fn = BUILT_IN_CEIL;
2200 break;
2202 CASE_FLT_FN (BUILT_IN_LFLOOR):
2203 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2204 builtin_optab = lfloor_optab;
2205 fallback_fn = BUILT_IN_FLOOR;
2206 break;
2208 default:
2209 gcc_unreachable ();
2212 /* Make a suitable register to place result in. */
2213 mode = TYPE_MODE (TREE_TYPE (exp));
2215 /* Before working hard, check whether the instruction is available. */
2216 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2218 target = gen_reg_rtx (mode);
2220 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2221 need to expand the argument again. This way, we will not perform
2222 side-effects more the once. */
2223 narg = builtin_save_expr (arg);
2224 if (narg != arg)
2226 arg = narg;
2227 arglist = build_tree_list (NULL_TREE, arg);
2228 exp = build_function_call_expr (fndecl, arglist);
2231 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2233 start_sequence ();
2235 /* Compute into TARGET.
2236 Set TARGET to wherever the result comes back. */
2237 target = expand_unop (mode, builtin_optab, op0, target, 0);
2239 if (target != 0)
2241 /* Output the entire sequence. */
2242 insns = get_insns ();
2243 end_sequence ();
2244 emit_insn (insns);
2245 return target;
2248 /* If we were unable to expand via the builtin, stop the sequence
2249 (without outputting the insns). */
2250 end_sequence ();
2253 /* Fall back to floating point rounding optab. */
2254 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2255 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2256 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2257 gcc_assert (fallback_fndecl != NULL_TREE);
2258 exp = build_function_call_expr (fallback_fndecl, arglist);
2260 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2262 /* Truncate the result of floating point optab to integer
2263 via expand_fix (). */
2264 target = gen_reg_rtx (mode);
2265 expand_fix (target, tmp, 0);
2267 return target;
2270 /* To evaluate powi(x,n), the floating point value x raised to the
2271 constant integer exponent n, we use a hybrid algorithm that
2272 combines the "window method" with look-up tables. For an
2273 introduction to exponentiation algorithms and "addition chains",
2274 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2275 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2276 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2277 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2279 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2280 multiplications to inline before calling the system library's pow
2281 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2282 so this default never requires calling pow, powf or powl. */
2284 #ifndef POWI_MAX_MULTS
2285 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2286 #endif
2288 /* The size of the "optimal power tree" lookup table. All
2289 exponents less than this value are simply looked up in the
2290 powi_table below. This threshold is also used to size the
2291 cache of pseudo registers that hold intermediate results. */
2292 #define POWI_TABLE_SIZE 256
2294 /* The size, in bits of the window, used in the "window method"
2295 exponentiation algorithm. This is equivalent to a radix of
2296 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2297 #define POWI_WINDOW_SIZE 3
2299 /* The following table is an efficient representation of an
2300 "optimal power tree". For each value, i, the corresponding
2301 value, j, in the table states than an optimal evaluation
2302 sequence for calculating pow(x,i) can be found by evaluating
2303 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2304 100 integers is given in Knuth's "Seminumerical algorithms". */
2306 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2308 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2309 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2310 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2311 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2312 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2313 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2314 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2315 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2316 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2317 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2318 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2319 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2320 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2321 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2322 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2323 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2324 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2325 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2326 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2327 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2328 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2329 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2330 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2331 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2332 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2333 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2334 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2335 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2336 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2337 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2338 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2339 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2343 /* Return the number of multiplications required to calculate
2344 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2345 subroutine of powi_cost. CACHE is an array indicating
2346 which exponents have already been calculated. */
2348 static int
2349 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2351 /* If we've already calculated this exponent, then this evaluation
2352 doesn't require any additional multiplications. */
2353 if (cache[n])
2354 return 0;
2356 cache[n] = true;
2357 return powi_lookup_cost (n - powi_table[n], cache)
2358 + powi_lookup_cost (powi_table[n], cache) + 1;
2361 /* Return the number of multiplications required to calculate
2362 powi(x,n) for an arbitrary x, given the exponent N. This
2363 function needs to be kept in sync with expand_powi below. */
2365 static int
2366 powi_cost (HOST_WIDE_INT n)
2368 bool cache[POWI_TABLE_SIZE];
2369 unsigned HOST_WIDE_INT digit;
2370 unsigned HOST_WIDE_INT val;
2371 int result;
2373 if (n == 0)
2374 return 0;
2376 /* Ignore the reciprocal when calculating the cost. */
2377 val = (n < 0) ? -n : n;
2379 /* Initialize the exponent cache. */
2380 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2381 cache[1] = true;
2383 result = 0;
2385 while (val >= POWI_TABLE_SIZE)
2387 if (val & 1)
2389 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2390 result += powi_lookup_cost (digit, cache)
2391 + POWI_WINDOW_SIZE + 1;
2392 val >>= POWI_WINDOW_SIZE;
2394 else
2396 val >>= 1;
2397 result++;
2401 return result + powi_lookup_cost (val, cache);
2404 /* Recursive subroutine of expand_powi. This function takes the array,
2405 CACHE, of already calculated exponents and an exponent N and returns
2406 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2408 static rtx
2409 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2411 unsigned HOST_WIDE_INT digit;
2412 rtx target, result;
2413 rtx op0, op1;
2415 if (n < POWI_TABLE_SIZE)
2417 if (cache[n])
2418 return cache[n];
2420 target = gen_reg_rtx (mode);
2421 cache[n] = target;
2423 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2424 op1 = expand_powi_1 (mode, powi_table[n], cache);
2426 else if (n & 1)
2428 target = gen_reg_rtx (mode);
2429 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2430 op0 = expand_powi_1 (mode, n - digit, cache);
2431 op1 = expand_powi_1 (mode, digit, cache);
2433 else
2435 target = gen_reg_rtx (mode);
2436 op0 = expand_powi_1 (mode, n >> 1, cache);
2437 op1 = op0;
2440 result = expand_mult (mode, op0, op1, target, 0);
2441 if (result != target)
2442 emit_move_insn (target, result);
2443 return target;
2446 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2447 floating point operand in mode MODE, and N is the exponent. This
2448 function needs to be kept in sync with powi_cost above. */
2450 static rtx
2451 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2453 unsigned HOST_WIDE_INT val;
2454 rtx cache[POWI_TABLE_SIZE];
2455 rtx result;
2457 if (n == 0)
2458 return CONST1_RTX (mode);
2460 val = (n < 0) ? -n : n;
2462 memset (cache, 0, sizeof (cache));
2463 cache[1] = x;
2465 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2467 /* If the original exponent was negative, reciprocate the result. */
2468 if (n < 0)
2469 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2470 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2472 return result;
2475 /* Expand a call to the pow built-in mathematical function. Return 0 if
2476 a normal call should be emitted rather than expanding the function
2477 in-line. EXP is the expression that is a call to the builtin
2478 function; if convenient, the result should be placed in TARGET. */
2480 static rtx
2481 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2483 tree arglist = TREE_OPERAND (exp, 1);
2484 tree arg0, arg1;
2486 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2487 return 0;
2489 arg0 = TREE_VALUE (arglist);
2490 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2492 if (TREE_CODE (arg1) == REAL_CST
2493 && ! TREE_CONSTANT_OVERFLOW (arg1))
2495 REAL_VALUE_TYPE cint;
2496 REAL_VALUE_TYPE c;
2497 HOST_WIDE_INT n;
2499 c = TREE_REAL_CST (arg1);
2500 n = real_to_integer (&c);
2501 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2502 if (real_identical (&c, &cint))
2504 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2505 Otherwise, check the number of multiplications required.
2506 Note that pow never sets errno for an integer exponent. */
2507 if ((n >= -1 && n <= 2)
2508 || (flag_unsafe_math_optimizations
2509 && ! optimize_size
2510 && powi_cost (n) <= POWI_MAX_MULTS))
2512 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2513 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2514 op = force_reg (mode, op);
2515 return expand_powi (op, mode, n);
2520 if (! flag_unsafe_math_optimizations)
2521 return NULL_RTX;
2522 return expand_builtin_mathfn_2 (exp, target, subtarget);
2525 /* Expand a call to the powi built-in mathematical function. Return 0 if
2526 a normal call should be emitted rather than expanding the function
2527 in-line. EXP is the expression that is a call to the builtin
2528 function; if convenient, the result should be placed in TARGET. */
2530 static rtx
2531 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2533 tree arglist = TREE_OPERAND (exp, 1);
2534 tree arg0, arg1;
2535 rtx op0, op1;
2536 enum machine_mode mode;
2537 enum machine_mode mode2;
2539 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2540 return 0;
2542 arg0 = TREE_VALUE (arglist);
2543 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2544 mode = TYPE_MODE (TREE_TYPE (exp));
2546 /* Handle constant power. */
2548 if (TREE_CODE (arg1) == INTEGER_CST
2549 && ! TREE_CONSTANT_OVERFLOW (arg1))
2551 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2553 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2554 Otherwise, check the number of multiplications required. */
2555 if ((TREE_INT_CST_HIGH (arg1) == 0
2556 || TREE_INT_CST_HIGH (arg1) == -1)
2557 && ((n >= -1 && n <= 2)
2558 || (! optimize_size
2559 && powi_cost (n) <= POWI_MAX_MULTS)))
2561 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2562 op0 = force_reg (mode, op0);
2563 return expand_powi (op0, mode, n);
2567 /* Emit a libcall to libgcc. */
2569 /* Mode of the 2nd argument must match that of an int. */
2570 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2572 if (target == NULL_RTX)
2573 target = gen_reg_rtx (mode);
2575 op0 = expand_expr (arg0, subtarget, mode, 0);
2576 if (GET_MODE (op0) != mode)
2577 op0 = convert_to_mode (mode, op0, 0);
2578 op1 = expand_expr (arg1, 0, mode2, 0);
2579 if (GET_MODE (op1) != mode2)
2580 op1 = convert_to_mode (mode2, op1, 0);
2582 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2583 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2584 op0, mode, op1, mode2);
2586 return target;
2589 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2590 if we failed the caller should emit a normal call, otherwise
2591 try to get the result in TARGET, if convenient. */
2593 static rtx
2594 expand_builtin_strlen (tree arglist, rtx target,
2595 enum machine_mode target_mode)
2597 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2598 return 0;
2599 else
2601 rtx pat;
2602 tree len, src = TREE_VALUE (arglist);
2603 rtx result, src_reg, char_rtx, before_strlen;
2604 enum machine_mode insn_mode = target_mode, char_mode;
2605 enum insn_code icode = CODE_FOR_nothing;
2606 int align;
2608 /* If the length can be computed at compile-time, return it. */
2609 len = c_strlen (src, 0);
2610 if (len)
2611 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2613 /* If the length can be computed at compile-time and is constant
2614 integer, but there are side-effects in src, evaluate
2615 src for side-effects, then return len.
2616 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2617 can be optimized into: i++; x = 3; */
2618 len = c_strlen (src, 1);
2619 if (len && TREE_CODE (len) == INTEGER_CST)
2621 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2622 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2625 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2627 /* If SRC is not a pointer type, don't do this operation inline. */
2628 if (align == 0)
2629 return 0;
2631 /* Bail out if we can't compute strlen in the right mode. */
2632 while (insn_mode != VOIDmode)
2634 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2635 if (icode != CODE_FOR_nothing)
2636 break;
2638 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2640 if (insn_mode == VOIDmode)
2641 return 0;
2643 /* Make a place to write the result of the instruction. */
2644 result = target;
2645 if (! (result != 0
2646 && REG_P (result)
2647 && GET_MODE (result) == insn_mode
2648 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2649 result = gen_reg_rtx (insn_mode);
2651 /* Make a place to hold the source address. We will not expand
2652 the actual source until we are sure that the expansion will
2653 not fail -- there are trees that cannot be expanded twice. */
2654 src_reg = gen_reg_rtx (Pmode);
2656 /* Mark the beginning of the strlen sequence so we can emit the
2657 source operand later. */
2658 before_strlen = get_last_insn ();
2660 char_rtx = const0_rtx;
2661 char_mode = insn_data[(int) icode].operand[2].mode;
2662 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2663 char_mode))
2664 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2666 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2667 char_rtx, GEN_INT (align));
2668 if (! pat)
2669 return 0;
2670 emit_insn (pat);
2672 /* Now that we are assured of success, expand the source. */
2673 start_sequence ();
2674 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2675 if (pat != src_reg)
2676 emit_move_insn (src_reg, pat);
2677 pat = get_insns ();
2678 end_sequence ();
2680 if (before_strlen)
2681 emit_insn_after (pat, before_strlen);
2682 else
2683 emit_insn_before (pat, get_insns ());
2685 /* Return the value in the proper mode for this function. */
2686 if (GET_MODE (result) == target_mode)
2687 target = result;
2688 else if (target != 0)
2689 convert_move (target, result, 0);
2690 else
2691 target = convert_to_mode (target_mode, result, 0);
2693 return target;
2697 /* Expand a call to the strstr builtin. Return 0 if we failed the
2698 caller should emit a normal call, otherwise try to get the result
2699 in TARGET, if convenient (and in mode MODE if that's convenient). */
2701 static rtx
2702 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2704 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2706 tree result = fold_builtin_strstr (arglist, type);
2707 if (result)
2708 return expand_expr (result, target, mode, EXPAND_NORMAL);
2710 return 0;
2713 /* Expand a call to the strchr builtin. Return 0 if we failed the
2714 caller should emit a normal call, otherwise try to get the result
2715 in TARGET, if convenient (and in mode MODE if that's convenient). */
2717 static rtx
2718 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2720 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2722 tree result = fold_builtin_strchr (arglist, type);
2723 if (result)
2724 return expand_expr (result, target, mode, EXPAND_NORMAL);
2726 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2728 return 0;
2731 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2732 caller should emit a normal call, otherwise try to get the result
2733 in TARGET, if convenient (and in mode MODE if that's convenient). */
2735 static rtx
2736 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2738 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2740 tree result = fold_builtin_strrchr (arglist, type);
2741 if (result)
2742 return expand_expr (result, target, mode, EXPAND_NORMAL);
2744 return 0;
2747 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2748 caller should emit a normal call, otherwise try to get the result
2749 in TARGET, if convenient (and in mode MODE if that's convenient). */
2751 static rtx
2752 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2754 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2756 tree result = fold_builtin_strpbrk (arglist, type);
2757 if (result)
2758 return expand_expr (result, target, mode, EXPAND_NORMAL);
2760 return 0;
2763 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2764 bytes from constant string DATA + OFFSET and return it as target
2765 constant. */
2767 static rtx
2768 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2769 enum machine_mode mode)
2771 const char *str = (const char *) data;
2773 gcc_assert (offset >= 0
2774 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2775 <= strlen (str) + 1));
2777 return c_readstr (str + offset, mode);
2780 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2781 Return 0 if we failed, the caller should emit a normal call,
2782 otherwise try to get the result in TARGET, if convenient (and in
2783 mode MODE if that's convenient). */
2784 static rtx
2785 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2787 tree fndecl = get_callee_fndecl (exp);
2788 tree arglist = TREE_OPERAND (exp, 1);
2789 if (!validate_arglist (arglist,
2790 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2791 return 0;
2792 else
2794 tree dest = TREE_VALUE (arglist);
2795 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2796 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2797 const char *src_str;
2798 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2799 unsigned int dest_align
2800 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2801 rtx dest_mem, src_mem, dest_addr, len_rtx;
2802 tree result = fold_builtin_memcpy (fndecl, arglist);
2804 if (result)
2805 return expand_expr (result, target, mode, EXPAND_NORMAL);
2807 /* If DEST is not a pointer type, call the normal function. */
2808 if (dest_align == 0)
2809 return 0;
2811 /* If either SRC is not a pointer type, don't do this
2812 operation in-line. */
2813 if (src_align == 0)
2814 return 0;
2816 dest_mem = get_memory_rtx (dest, len);
2817 set_mem_align (dest_mem, dest_align);
2818 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2819 src_str = c_getstr (src);
2821 /* If SRC is a string constant and block move would be done
2822 by pieces, we can avoid loading the string from memory
2823 and only stored the computed constants. */
2824 if (src_str
2825 && GET_CODE (len_rtx) == CONST_INT
2826 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2827 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2828 (void *) src_str, dest_align))
2830 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2831 builtin_memcpy_read_str,
2832 (void *) src_str, dest_align, 0);
2833 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2834 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2835 return dest_mem;
2838 src_mem = get_memory_rtx (src, len);
2839 set_mem_align (src_mem, src_align);
2841 /* Copy word part most expediently. */
2842 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2843 CALL_EXPR_TAILCALL (exp)
2844 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2846 if (dest_addr == 0)
2848 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2849 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2851 return dest_addr;
2855 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2856 Return 0 if we failed; the caller should emit a normal call,
2857 otherwise try to get the result in TARGET, if convenient (and in
2858 mode MODE if that's convenient). If ENDP is 0 return the
2859 destination pointer, if ENDP is 1 return the end pointer ala
2860 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2861 stpcpy. */
2863 static rtx
2864 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2865 int endp)
2867 if (!validate_arglist (arglist,
2868 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2869 return 0;
2870 /* If return value is ignored, transform mempcpy into memcpy. */
2871 else if (target == const0_rtx)
2873 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2875 if (!fn)
2876 return 0;
2878 return expand_expr (build_function_call_expr (fn, arglist),
2879 target, mode, EXPAND_NORMAL);
2881 else
2883 tree dest = TREE_VALUE (arglist);
2884 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2885 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2886 const char *src_str;
2887 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2888 unsigned int dest_align
2889 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2890 rtx dest_mem, src_mem, len_rtx;
2891 tree result = fold_builtin_mempcpy (arglist, type, endp);
2893 if (result)
2894 return expand_expr (result, target, mode, EXPAND_NORMAL);
2896 /* If either SRC or DEST is not a pointer type, don't do this
2897 operation in-line. */
2898 if (dest_align == 0 || src_align == 0)
2899 return 0;
2901 /* If LEN is not constant, call the normal function. */
2902 if (! host_integerp (len, 1))
2903 return 0;
2905 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2906 src_str = c_getstr (src);
2908 /* If SRC is a string constant and block move would be done
2909 by pieces, we can avoid loading the string from memory
2910 and only stored the computed constants. */
2911 if (src_str
2912 && GET_CODE (len_rtx) == CONST_INT
2913 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2914 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2915 (void *) src_str, dest_align))
2917 dest_mem = get_memory_rtx (dest, len);
2918 set_mem_align (dest_mem, dest_align);
2919 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2920 builtin_memcpy_read_str,
2921 (void *) src_str, dest_align, endp);
2922 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2923 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2924 return dest_mem;
2927 if (GET_CODE (len_rtx) == CONST_INT
2928 && can_move_by_pieces (INTVAL (len_rtx),
2929 MIN (dest_align, src_align)))
2931 dest_mem = get_memory_rtx (dest, len);
2932 set_mem_align (dest_mem, dest_align);
2933 src_mem = get_memory_rtx (src, len);
2934 set_mem_align (src_mem, src_align);
2935 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2936 MIN (dest_align, src_align), endp);
2937 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2938 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2939 return dest_mem;
2942 return 0;
2946 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2947 if we failed; the caller should emit a normal call. */
2949 static rtx
2950 expand_builtin_memmove (tree arglist, tree type, rtx target,
2951 enum machine_mode mode, tree orig_exp)
2953 if (!validate_arglist (arglist,
2954 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2955 return 0;
2956 else
2958 tree dest = TREE_VALUE (arglist);
2959 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2960 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2962 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2963 unsigned int dest_align
2964 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2965 tree result = fold_builtin_memmove (arglist, type);
2967 if (result)
2968 return expand_expr (result, target, mode, EXPAND_NORMAL);
2970 /* If DEST is not a pointer type, call the normal function. */
2971 if (dest_align == 0)
2972 return 0;
2974 /* If either SRC is not a pointer type, don't do this
2975 operation in-line. */
2976 if (src_align == 0)
2977 return 0;
2979 /* If src is categorized for a readonly section we can use
2980 normal memcpy. */
2981 if (readonly_data_expr (src))
2983 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2984 if (!fn)
2985 return 0;
2986 fn = build_function_call_expr (fn, arglist);
2987 if (TREE_CODE (fn) == CALL_EXPR)
2988 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
2989 return expand_expr (fn, target, mode, EXPAND_NORMAL);
2992 /* If length is 1 and we can expand memcpy call inline,
2993 it is ok to use memcpy as well. */
2994 if (integer_onep (len))
2996 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
2997 /*endp=*/0);
2998 if (ret)
2999 return ret;
3002 /* Otherwise, call the normal function. */
3003 return 0;
3007 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3008 if we failed the caller should emit a normal call. */
3010 static rtx
3011 expand_builtin_bcopy (tree exp)
3013 tree arglist = TREE_OPERAND (exp, 1);
3014 tree type = TREE_TYPE (exp);
3015 tree src, dest, size, newarglist;
3017 if (!validate_arglist (arglist,
3018 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3019 return NULL_RTX;
3021 src = TREE_VALUE (arglist);
3022 dest = TREE_VALUE (TREE_CHAIN (arglist));
3023 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3025 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3026 memmove(ptr y, ptr x, size_t z). This is done this way
3027 so that if it isn't expanded inline, we fallback to
3028 calling bcopy instead of memmove. */
3030 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3031 newarglist = tree_cons (NULL_TREE, src, newarglist);
3032 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3034 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3037 #ifndef HAVE_movstr
3038 # define HAVE_movstr 0
3039 # define CODE_FOR_movstr CODE_FOR_nothing
3040 #endif
3042 /* Expand into a movstr instruction, if one is available. Return 0 if
3043 we failed, the caller should emit a normal call, otherwise try to
3044 get the result in TARGET, if convenient. If ENDP is 0 return the
3045 destination pointer, if ENDP is 1 return the end pointer ala
3046 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3047 stpcpy. */
3049 static rtx
3050 expand_movstr (tree dest, tree src, rtx target, int endp)
3052 rtx end;
3053 rtx dest_mem;
3054 rtx src_mem;
3055 rtx insn;
3056 const struct insn_data * data;
3058 if (!HAVE_movstr)
3059 return 0;
3061 dest_mem = get_memory_rtx (dest, NULL);
3062 src_mem = get_memory_rtx (src, NULL);
3063 if (!endp)
3065 target = force_reg (Pmode, XEXP (dest_mem, 0));
3066 dest_mem = replace_equiv_address (dest_mem, target);
3067 end = gen_reg_rtx (Pmode);
3069 else
3071 if (target == 0 || target == const0_rtx)
3073 end = gen_reg_rtx (Pmode);
3074 if (target == 0)
3075 target = end;
3077 else
3078 end = target;
3081 data = insn_data + CODE_FOR_movstr;
3083 if (data->operand[0].mode != VOIDmode)
3084 end = gen_lowpart (data->operand[0].mode, end);
3086 insn = data->genfun (end, dest_mem, src_mem);
3088 gcc_assert (insn);
3090 emit_insn (insn);
3092 /* movstr is supposed to set end to the address of the NUL
3093 terminator. If the caller requested a mempcpy-like return value,
3094 adjust it. */
3095 if (endp == 1 && target != const0_rtx)
3097 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3098 emit_move_insn (target, force_operand (tem, NULL_RTX));
3101 return target;
3104 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3105 if we failed the caller should emit a normal call, otherwise try to get
3106 the result in TARGET, if convenient (and in mode MODE if that's
3107 convenient). */
3109 static rtx
3110 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3112 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3114 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3115 if (result)
3116 return expand_expr (result, target, mode, EXPAND_NORMAL);
3118 return expand_movstr (TREE_VALUE (arglist),
3119 TREE_VALUE (TREE_CHAIN (arglist)),
3120 target, /*endp=*/0);
3122 return 0;
3125 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3126 Return 0 if we failed the caller should emit a normal call,
3127 otherwise try to get the result in TARGET, if convenient (and in
3128 mode MODE if that's convenient). */
3130 static rtx
3131 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3133 tree arglist = TREE_OPERAND (exp, 1);
3134 /* If return value is ignored, transform stpcpy into strcpy. */
3135 if (target == const0_rtx)
3137 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3138 if (!fn)
3139 return 0;
3141 return expand_expr (build_function_call_expr (fn, arglist),
3142 target, mode, EXPAND_NORMAL);
3145 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3146 return 0;
3147 else
3149 tree dst, src, len, lenp1;
3150 tree narglist;
3151 rtx ret;
3153 /* Ensure we get an actual string whose length can be evaluated at
3154 compile-time, not an expression containing a string. This is
3155 because the latter will potentially produce pessimized code
3156 when used to produce the return value. */
3157 src = TREE_VALUE (TREE_CHAIN (arglist));
3158 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3159 return expand_movstr (TREE_VALUE (arglist),
3160 TREE_VALUE (TREE_CHAIN (arglist)),
3161 target, /*endp=*/2);
3163 dst = TREE_VALUE (arglist);
3164 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3165 narglist = build_tree_list (NULL_TREE, lenp1);
3166 narglist = tree_cons (NULL_TREE, src, narglist);
3167 narglist = tree_cons (NULL_TREE, dst, narglist);
3168 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3169 target, mode, /*endp=*/2);
3171 if (ret)
3172 return ret;
3174 if (TREE_CODE (len) == INTEGER_CST)
3176 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3178 if (GET_CODE (len_rtx) == CONST_INT)
3180 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3181 arglist, target, mode);
3183 if (ret)
3185 if (! target)
3187 if (mode != VOIDmode)
3188 target = gen_reg_rtx (mode);
3189 else
3190 target = gen_reg_rtx (GET_MODE (ret));
3192 if (GET_MODE (target) != GET_MODE (ret))
3193 ret = gen_lowpart (GET_MODE (target), ret);
3195 ret = plus_constant (ret, INTVAL (len_rtx));
3196 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3197 gcc_assert (ret);
3199 return target;
3204 return expand_movstr (TREE_VALUE (arglist),
3205 TREE_VALUE (TREE_CHAIN (arglist)),
3206 target, /*endp=*/2);
3210 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3211 bytes from constant string DATA + OFFSET and return it as target
3212 constant. */
3214 static rtx
3215 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3216 enum machine_mode mode)
3218 const char *str = (const char *) data;
3220 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3221 return const0_rtx;
3223 return c_readstr (str + offset, mode);
3226 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3227 if we failed the caller should emit a normal call. */
3229 static rtx
3230 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3232 tree fndecl = get_callee_fndecl (exp);
3233 tree arglist = TREE_OPERAND (exp, 1);
3234 if (validate_arglist (arglist,
3235 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3237 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3238 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3239 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3241 if (result)
3242 return expand_expr (result, target, mode, EXPAND_NORMAL);
3244 /* We must be passed a constant len and src parameter. */
3245 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3246 return 0;
3248 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3250 /* We're required to pad with trailing zeros if the requested
3251 len is greater than strlen(s2)+1. In that case try to
3252 use store_by_pieces, if it fails, punt. */
3253 if (tree_int_cst_lt (slen, len))
3255 tree dest = TREE_VALUE (arglist);
3256 unsigned int dest_align
3257 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3258 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3259 rtx dest_mem;
3261 if (!p || dest_align == 0 || !host_integerp (len, 1)
3262 || !can_store_by_pieces (tree_low_cst (len, 1),
3263 builtin_strncpy_read_str,
3264 (void *) p, dest_align))
3265 return 0;
3267 dest_mem = get_memory_rtx (dest, len);
3268 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3269 builtin_strncpy_read_str,
3270 (void *) p, dest_align, 0);
3271 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3272 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3273 return dest_mem;
3276 return 0;
3279 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3280 bytes from constant string DATA + OFFSET and return it as target
3281 constant. */
3283 static rtx
3284 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3285 enum machine_mode mode)
3287 const char *c = (const char *) data;
3288 char *p = alloca (GET_MODE_SIZE (mode));
3290 memset (p, *c, GET_MODE_SIZE (mode));
3292 return c_readstr (p, mode);
3295 /* Callback routine for store_by_pieces. Return the RTL of a register
3296 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3297 char value given in the RTL register data. For example, if mode is
3298 4 bytes wide, return the RTL for 0x01010101*data. */
3300 static rtx
3301 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3302 enum machine_mode mode)
3304 rtx target, coeff;
3305 size_t size;
3306 char *p;
3308 size = GET_MODE_SIZE (mode);
3309 if (size == 1)
3310 return (rtx) data;
3312 p = alloca (size);
3313 memset (p, 1, size);
3314 coeff = c_readstr (p, mode);
3316 target = convert_to_mode (mode, (rtx) data, 1);
3317 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3318 return force_reg (mode, target);
3321 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3322 if we failed the caller should emit a normal call, otherwise try to get
3323 the result in TARGET, if convenient (and in mode MODE if that's
3324 convenient). */
3326 static rtx
3327 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3328 tree orig_exp)
3330 if (!validate_arglist (arglist,
3331 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3332 return 0;
3333 else
3335 tree dest = TREE_VALUE (arglist);
3336 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3337 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3338 char c;
3340 unsigned int dest_align
3341 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3342 rtx dest_mem, dest_addr, len_rtx;
3344 /* If DEST is not a pointer type, don't do this
3345 operation in-line. */
3346 if (dest_align == 0)
3347 return 0;
3349 /* If the LEN parameter is zero, return DEST. */
3350 if (integer_zerop (len))
3352 /* Evaluate and ignore VAL in case it has side-effects. */
3353 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3354 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3357 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3358 dest_mem = get_memory_rtx (dest, len);
3360 if (TREE_CODE (val) != INTEGER_CST)
3362 rtx val_rtx;
3364 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3365 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3367 /* Assume that we can memset by pieces if we can store the
3368 * the coefficients by pieces (in the required modes).
3369 * We can't pass builtin_memset_gen_str as that emits RTL. */
3370 c = 1;
3371 if (host_integerp (len, 1)
3372 && !(optimize_size && tree_low_cst (len, 1) > 1)
3373 && can_store_by_pieces (tree_low_cst (len, 1),
3374 builtin_memset_read_str, &c, dest_align))
3376 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3377 val_rtx);
3378 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3379 builtin_memset_gen_str, val_rtx, dest_align, 0);
3381 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3382 dest_align))
3383 return 0;
3385 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3386 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3387 return dest_mem;
3390 if (target_char_cast (val, &c))
3391 return 0;
3393 if (c)
3395 if (host_integerp (len, 1)
3396 && !(optimize_size && tree_low_cst (len, 1) > 1)
3397 && can_store_by_pieces (tree_low_cst (len, 1),
3398 builtin_memset_read_str, &c, dest_align))
3399 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3400 builtin_memset_read_str, &c, dest_align, 0);
3401 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3402 dest_align))
3403 return 0;
3405 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3406 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3407 return dest_mem;
3410 set_mem_align (dest_mem, dest_align);
3411 dest_addr = clear_storage (dest_mem, len_rtx,
3412 CALL_EXPR_TAILCALL (orig_exp)
3413 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3415 if (dest_addr == 0)
3417 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3418 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3421 return dest_addr;
3425 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3426 if we failed the caller should emit a normal call. */
3428 static rtx
3429 expand_builtin_bzero (tree exp)
3431 tree arglist = TREE_OPERAND (exp, 1);
3432 tree dest, size, newarglist;
3434 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3435 return NULL_RTX;
3437 dest = TREE_VALUE (arglist);
3438 size = TREE_VALUE (TREE_CHAIN (arglist));
3440 /* New argument list transforming bzero(ptr x, int y) to
3441 memset(ptr x, int 0, size_t y). This is done this way
3442 so that if it isn't expanded inline, we fallback to
3443 calling bzero instead of memset. */
3445 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3446 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3447 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3449 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3452 /* Expand expression EXP, which is a call to the memcmp built-in function.
3453 ARGLIST is the argument list for this call. Return 0 if we failed and the
3454 caller should emit a normal call, otherwise try to get the result in
3455 TARGET, if convenient (and in mode MODE, if that's convenient). */
3457 static rtx
3458 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3459 enum machine_mode mode)
3461 if (!validate_arglist (arglist,
3462 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3463 return 0;
3464 else
3466 tree result = fold_builtin_memcmp (arglist);
3467 if (result)
3468 return expand_expr (result, target, mode, EXPAND_NORMAL);
3471 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3473 tree arg1 = TREE_VALUE (arglist);
3474 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3475 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3476 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3477 rtx result;
3478 rtx insn;
3480 int arg1_align
3481 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3482 int arg2_align
3483 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3484 enum machine_mode insn_mode;
3486 #ifdef HAVE_cmpmemsi
3487 if (HAVE_cmpmemsi)
3488 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3489 else
3490 #endif
3491 #ifdef HAVE_cmpstrnsi
3492 if (HAVE_cmpstrnsi)
3493 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3494 else
3495 #endif
3496 return 0;
3498 /* If we don't have POINTER_TYPE, call the function. */
3499 if (arg1_align == 0 || arg2_align == 0)
3500 return 0;
3502 /* Make a place to write the result of the instruction. */
3503 result = target;
3504 if (! (result != 0
3505 && REG_P (result) && GET_MODE (result) == insn_mode
3506 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3507 result = gen_reg_rtx (insn_mode);
3509 arg1_rtx = get_memory_rtx (arg1, len);
3510 arg2_rtx = get_memory_rtx (arg2, len);
3511 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3513 /* Set MEM_SIZE as appropriate. */
3514 if (GET_CODE (arg3_rtx) == CONST_INT)
3516 set_mem_size (arg1_rtx, arg3_rtx);
3517 set_mem_size (arg2_rtx, arg3_rtx);
3520 #ifdef HAVE_cmpmemsi
3521 if (HAVE_cmpmemsi)
3522 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3523 GEN_INT (MIN (arg1_align, arg2_align)));
3524 else
3525 #endif
3526 #ifdef HAVE_cmpstrnsi
3527 if (HAVE_cmpstrnsi)
3528 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3529 GEN_INT (MIN (arg1_align, arg2_align)));
3530 else
3531 #endif
3532 gcc_unreachable ();
3534 if (insn)
3535 emit_insn (insn);
3536 else
3537 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3538 TYPE_MODE (integer_type_node), 3,
3539 XEXP (arg1_rtx, 0), Pmode,
3540 XEXP (arg2_rtx, 0), Pmode,
3541 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3542 TYPE_UNSIGNED (sizetype)),
3543 TYPE_MODE (sizetype));
3545 /* Return the value in the proper mode for this function. */
3546 mode = TYPE_MODE (TREE_TYPE (exp));
3547 if (GET_MODE (result) == mode)
3548 return result;
3549 else if (target != 0)
3551 convert_move (target, result, 0);
3552 return target;
3554 else
3555 return convert_to_mode (mode, result, 0);
3557 #endif
3559 return 0;
3562 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3563 if we failed the caller should emit a normal call, otherwise try to get
3564 the result in TARGET, if convenient. */
3566 static rtx
3567 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3569 tree arglist = TREE_OPERAND (exp, 1);
3571 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3572 return 0;
3573 else
3575 tree result = fold_builtin_strcmp (arglist);
3576 if (result)
3577 return expand_expr (result, target, mode, EXPAND_NORMAL);
3580 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3581 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3582 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3584 rtx arg1_rtx, arg2_rtx;
3585 rtx result, insn = NULL_RTX;
3586 tree fndecl, fn;
3588 tree arg1 = TREE_VALUE (arglist);
3589 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3590 int arg1_align
3591 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3592 int arg2_align
3593 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3595 /* If we don't have POINTER_TYPE, call the function. */
3596 if (arg1_align == 0 || arg2_align == 0)
3597 return 0;
3599 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3600 arg1 = builtin_save_expr (arg1);
3601 arg2 = builtin_save_expr (arg2);
3603 arg1_rtx = get_memory_rtx (arg1, NULL);
3604 arg2_rtx = get_memory_rtx (arg2, NULL);
3606 #ifdef HAVE_cmpstrsi
3607 /* Try to call cmpstrsi. */
3608 if (HAVE_cmpstrsi)
3610 enum machine_mode insn_mode
3611 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3613 /* Make a place to write the result of the instruction. */
3614 result = target;
3615 if (! (result != 0
3616 && REG_P (result) && GET_MODE (result) == insn_mode
3617 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3618 result = gen_reg_rtx (insn_mode);
3620 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3621 GEN_INT (MIN (arg1_align, arg2_align)));
3623 #endif
3624 #if HAVE_cmpstrnsi
3625 /* Try to determine at least one length and call cmpstrnsi. */
3626 if (!insn && HAVE_cmpstrnsi)
3628 tree len;
3629 rtx arg3_rtx;
3631 enum machine_mode insn_mode
3632 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3633 tree len1 = c_strlen (arg1, 1);
3634 tree len2 = c_strlen (arg2, 1);
3636 if (len1)
3637 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3638 if (len2)
3639 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3641 /* If we don't have a constant length for the first, use the length
3642 of the second, if we know it. We don't require a constant for
3643 this case; some cost analysis could be done if both are available
3644 but neither is constant. For now, assume they're equally cheap,
3645 unless one has side effects. If both strings have constant lengths,
3646 use the smaller. */
3648 if (!len1)
3649 len = len2;
3650 else if (!len2)
3651 len = len1;
3652 else if (TREE_SIDE_EFFECTS (len1))
3653 len = len2;
3654 else if (TREE_SIDE_EFFECTS (len2))
3655 len = len1;
3656 else if (TREE_CODE (len1) != INTEGER_CST)
3657 len = len2;
3658 else if (TREE_CODE (len2) != INTEGER_CST)
3659 len = len1;
3660 else if (tree_int_cst_lt (len1, len2))
3661 len = len1;
3662 else
3663 len = len2;
3665 /* If both arguments have side effects, we cannot optimize. */
3666 if (!len || TREE_SIDE_EFFECTS (len))
3667 return 0;
3669 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3670 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3672 /* Make a place to write the result of the instruction. */
3673 result = target;
3674 if (! (result != 0
3675 && REG_P (result) && GET_MODE (result) == insn_mode
3676 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3677 result = gen_reg_rtx (insn_mode);
3679 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3680 GEN_INT (MIN (arg1_align, arg2_align)));
3682 #endif
3684 if (insn)
3686 emit_insn (insn);
3688 /* Return the value in the proper mode for this function. */
3689 mode = TYPE_MODE (TREE_TYPE (exp));
3690 if (GET_MODE (result) == mode)
3691 return result;
3692 if (target == 0)
3693 return convert_to_mode (mode, result, 0);
3694 convert_move (target, result, 0);
3695 return target;
3698 /* Expand the library call ourselves using a stabilized argument
3699 list to avoid re-evaluating the function's arguments twice. */
3700 arglist = build_tree_list (NULL_TREE, arg2);
3701 arglist = tree_cons (NULL_TREE, arg1, arglist);
3702 fndecl = get_callee_fndecl (exp);
3703 fn = build_function_call_expr (fndecl, arglist);
3704 if (TREE_CODE (fn) == CALL_EXPR)
3705 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3706 return expand_call (fn, target, target == const0_rtx);
3708 #endif
3709 return 0;
3712 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3713 if we failed the caller should emit a normal call, otherwise try to get
3714 the result in TARGET, if convenient. */
3716 static rtx
3717 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3719 tree arglist = TREE_OPERAND (exp, 1);
3721 if (!validate_arglist (arglist,
3722 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3723 return 0;
3724 else
3726 tree result = fold_builtin_strncmp (arglist);
3727 if (result)
3728 return expand_expr (result, target, mode, EXPAND_NORMAL);
3731 /* If c_strlen can determine an expression for one of the string
3732 lengths, and it doesn't have side effects, then emit cmpstrnsi
3733 using length MIN(strlen(string)+1, arg3). */
3734 #ifdef HAVE_cmpstrnsi
3735 if (HAVE_cmpstrnsi)
3737 tree arg1 = TREE_VALUE (arglist);
3738 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3739 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3740 tree len, len1, len2;
3741 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3742 rtx result, insn;
3743 tree fndecl, fn;
3745 int arg1_align
3746 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3747 int arg2_align
3748 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3749 enum machine_mode insn_mode
3750 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3752 len1 = c_strlen (arg1, 1);
3753 len2 = c_strlen (arg2, 1);
3755 if (len1)
3756 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3757 if (len2)
3758 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3760 /* If we don't have a constant length for the first, use the length
3761 of the second, if we know it. We don't require a constant for
3762 this case; some cost analysis could be done if both are available
3763 but neither is constant. For now, assume they're equally cheap,
3764 unless one has side effects. If both strings have constant lengths,
3765 use the smaller. */
3767 if (!len1)
3768 len = len2;
3769 else if (!len2)
3770 len = len1;
3771 else if (TREE_SIDE_EFFECTS (len1))
3772 len = len2;
3773 else if (TREE_SIDE_EFFECTS (len2))
3774 len = len1;
3775 else if (TREE_CODE (len1) != INTEGER_CST)
3776 len = len2;
3777 else if (TREE_CODE (len2) != INTEGER_CST)
3778 len = len1;
3779 else if (tree_int_cst_lt (len1, len2))
3780 len = len1;
3781 else
3782 len = len2;
3784 /* If both arguments have side effects, we cannot optimize. */
3785 if (!len || TREE_SIDE_EFFECTS (len))
3786 return 0;
3788 /* The actual new length parameter is MIN(len,arg3). */
3789 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3790 fold_convert (TREE_TYPE (len), arg3));
3792 /* If we don't have POINTER_TYPE, call the function. */
3793 if (arg1_align == 0 || arg2_align == 0)
3794 return 0;
3796 /* Make a place to write the result of the instruction. */
3797 result = target;
3798 if (! (result != 0
3799 && REG_P (result) && GET_MODE (result) == insn_mode
3800 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3801 result = gen_reg_rtx (insn_mode);
3803 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3804 arg1 = builtin_save_expr (arg1);
3805 arg2 = builtin_save_expr (arg2);
3806 len = builtin_save_expr (len);
3808 arg1_rtx = get_memory_rtx (arg1, len);
3809 arg2_rtx = get_memory_rtx (arg2, len);
3810 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3811 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3812 GEN_INT (MIN (arg1_align, arg2_align)));
3813 if (insn)
3815 emit_insn (insn);
3817 /* Return the value in the proper mode for this function. */
3818 mode = TYPE_MODE (TREE_TYPE (exp));
3819 if (GET_MODE (result) == mode)
3820 return result;
3821 if (target == 0)
3822 return convert_to_mode (mode, result, 0);
3823 convert_move (target, result, 0);
3824 return target;
3827 /* Expand the library call ourselves using a stabilized argument
3828 list to avoid re-evaluating the function's arguments twice. */
3829 arglist = build_tree_list (NULL_TREE, len);
3830 arglist = tree_cons (NULL_TREE, arg2, arglist);
3831 arglist = tree_cons (NULL_TREE, arg1, arglist);
3832 fndecl = get_callee_fndecl (exp);
3833 fn = build_function_call_expr (fndecl, arglist);
3834 if (TREE_CODE (fn) == CALL_EXPR)
3835 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3836 return expand_call (fn, target, target == const0_rtx);
3838 #endif
3839 return 0;
3842 /* Expand expression EXP, which is a call to the strcat builtin.
3843 Return 0 if we failed the caller should emit a normal call,
3844 otherwise try to get the result in TARGET, if convenient. */
3846 static rtx
3847 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3849 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3850 return 0;
3851 else
3853 tree dst = TREE_VALUE (arglist),
3854 src = TREE_VALUE (TREE_CHAIN (arglist));
3855 const char *p = c_getstr (src);
3857 /* If the string length is zero, return the dst parameter. */
3858 if (p && *p == '\0')
3859 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3861 if (!optimize_size)
3863 /* See if we can store by pieces into (dst + strlen(dst)). */
3864 tree newsrc, newdst,
3865 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3866 rtx insns;
3868 /* Stabilize the argument list. */
3869 newsrc = builtin_save_expr (src);
3870 if (newsrc != src)
3871 arglist = build_tree_list (NULL_TREE, newsrc);
3872 else
3873 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3875 dst = builtin_save_expr (dst);
3877 start_sequence ();
3879 /* Create strlen (dst). */
3880 newdst =
3881 build_function_call_expr (strlen_fn,
3882 build_tree_list (NULL_TREE, dst));
3883 /* Create (dst + (cast) strlen (dst)). */
3884 newdst = fold_convert (TREE_TYPE (dst), newdst);
3885 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3887 newdst = builtin_save_expr (newdst);
3888 arglist = tree_cons (NULL_TREE, newdst, arglist);
3890 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3892 end_sequence (); /* Stop sequence. */
3893 return 0;
3896 /* Output the entire sequence. */
3897 insns = get_insns ();
3898 end_sequence ();
3899 emit_insn (insns);
3901 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3904 return 0;
3908 /* Expand expression EXP, which is a call to the strncat builtin.
3909 Return 0 if we failed the caller should emit a normal call,
3910 otherwise try to get the result in TARGET, if convenient. */
3912 static rtx
3913 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3915 if (validate_arglist (arglist,
3916 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3918 tree result = fold_builtin_strncat (arglist);
3919 if (result)
3920 return expand_expr (result, target, mode, EXPAND_NORMAL);
3922 return 0;
3925 /* Expand expression EXP, which is a call to the strspn builtin.
3926 Return 0 if we failed the caller should emit a normal call,
3927 otherwise try to get the result in TARGET, if convenient. */
3929 static rtx
3930 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3932 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3934 tree result = fold_builtin_strspn (arglist);
3935 if (result)
3936 return expand_expr (result, target, mode, EXPAND_NORMAL);
3938 return 0;
3941 /* Expand expression EXP, which is a call to the strcspn builtin.
3942 Return 0 if we failed the caller should emit a normal call,
3943 otherwise try to get the result in TARGET, if convenient. */
3945 static rtx
3946 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3948 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3950 tree result = fold_builtin_strcspn (arglist);
3951 if (result)
3952 return expand_expr (result, target, mode, EXPAND_NORMAL);
3954 return 0;
3957 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3958 if that's convenient. */
3961 expand_builtin_saveregs (void)
3963 rtx val, seq;
3965 /* Don't do __builtin_saveregs more than once in a function.
3966 Save the result of the first call and reuse it. */
3967 if (saveregs_value != 0)
3968 return saveregs_value;
3970 /* When this function is called, it means that registers must be
3971 saved on entry to this function. So we migrate the call to the
3972 first insn of this function. */
3974 start_sequence ();
3976 /* Do whatever the machine needs done in this case. */
3977 val = targetm.calls.expand_builtin_saveregs ();
3979 seq = get_insns ();
3980 end_sequence ();
3982 saveregs_value = val;
3984 /* Put the insns after the NOTE that starts the function. If this
3985 is inside a start_sequence, make the outer-level insn chain current, so
3986 the code is placed at the start of the function. */
3987 push_topmost_sequence ();
3988 emit_insn_after (seq, entry_of_function ());
3989 pop_topmost_sequence ();
3991 return val;
3994 /* __builtin_args_info (N) returns word N of the arg space info
3995 for the current function. The number and meanings of words
3996 is controlled by the definition of CUMULATIVE_ARGS. */
3998 static rtx
3999 expand_builtin_args_info (tree arglist)
4001 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4002 int *word_ptr = (int *) &current_function_args_info;
4004 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4006 if (arglist != 0)
4008 if (!host_integerp (TREE_VALUE (arglist), 0))
4009 error ("argument of %<__builtin_args_info%> must be constant");
4010 else
4012 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4014 if (wordnum < 0 || wordnum >= nwords)
4015 error ("argument of %<__builtin_args_info%> out of range");
4016 else
4017 return GEN_INT (word_ptr[wordnum]);
4020 else
4021 error ("missing argument in %<__builtin_args_info%>");
4023 return const0_rtx;
4026 /* Expand a call to __builtin_next_arg. */
4028 static rtx
4029 expand_builtin_next_arg (void)
4031 /* Checking arguments is already done in fold_builtin_next_arg
4032 that must be called before this function. */
4033 return expand_binop (Pmode, add_optab,
4034 current_function_internal_arg_pointer,
4035 current_function_arg_offset_rtx,
4036 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4039 /* Make it easier for the backends by protecting the valist argument
4040 from multiple evaluations. */
4042 static tree
4043 stabilize_va_list (tree valist, int needs_lvalue)
4045 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4047 if (TREE_SIDE_EFFECTS (valist))
4048 valist = save_expr (valist);
4050 /* For this case, the backends will be expecting a pointer to
4051 TREE_TYPE (va_list_type_node), but it's possible we've
4052 actually been given an array (an actual va_list_type_node).
4053 So fix it. */
4054 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4056 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4057 valist = build_fold_addr_expr_with_type (valist, p1);
4060 else
4062 tree pt;
4064 if (! needs_lvalue)
4066 if (! TREE_SIDE_EFFECTS (valist))
4067 return valist;
4069 pt = build_pointer_type (va_list_type_node);
4070 valist = fold_build1 (ADDR_EXPR, pt, valist);
4071 TREE_SIDE_EFFECTS (valist) = 1;
4074 if (TREE_SIDE_EFFECTS (valist))
4075 valist = save_expr (valist);
4076 valist = build_fold_indirect_ref (valist);
4079 return valist;
4082 /* The "standard" definition of va_list is void*. */
4084 tree
4085 std_build_builtin_va_list (void)
4087 return ptr_type_node;
4090 /* The "standard" implementation of va_start: just assign `nextarg' to
4091 the variable. */
4093 void
4094 std_expand_builtin_va_start (tree valist, rtx nextarg)
4096 tree t;
4098 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4099 make_tree (ptr_type_node, nextarg));
4100 TREE_SIDE_EFFECTS (t) = 1;
4102 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4105 /* Expand ARGLIST, from a call to __builtin_va_start. */
4107 static rtx
4108 expand_builtin_va_start (tree arglist)
4110 rtx nextarg;
4111 tree chain, valist;
4113 chain = TREE_CHAIN (arglist);
4115 if (!chain)
4117 error ("too few arguments to function %<va_start%>");
4118 return const0_rtx;
4121 if (fold_builtin_next_arg (chain))
4122 return const0_rtx;
4124 nextarg = expand_builtin_next_arg ();
4125 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4127 #ifdef EXPAND_BUILTIN_VA_START
4128 EXPAND_BUILTIN_VA_START (valist, nextarg);
4129 #else
4130 std_expand_builtin_va_start (valist, nextarg);
4131 #endif
4133 return const0_rtx;
4136 /* The "standard" implementation of va_arg: read the value from the
4137 current (padded) address and increment by the (padded) size. */
4139 tree
4140 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4142 tree addr, t, type_size, rounded_size, valist_tmp;
4143 unsigned HOST_WIDE_INT align, boundary;
4144 bool indirect;
4146 #ifdef ARGS_GROW_DOWNWARD
4147 /* All of the alignment and movement below is for args-grow-up machines.
4148 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4149 implement their own specialized gimplify_va_arg_expr routines. */
4150 gcc_unreachable ();
4151 #endif
4153 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4154 if (indirect)
4155 type = build_pointer_type (type);
4157 align = PARM_BOUNDARY / BITS_PER_UNIT;
4158 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4160 /* Hoist the valist value into a temporary for the moment. */
4161 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4163 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4164 requires greater alignment, we must perform dynamic alignment. */
4165 if (boundary > align
4166 && !integer_zerop (TYPE_SIZE (type)))
4168 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4169 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4170 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4171 gimplify_and_add (t, pre_p);
4173 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4174 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4175 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4176 gimplify_and_add (t, pre_p);
4178 else
4179 boundary = align;
4181 /* If the actual alignment is less than the alignment of the type,
4182 adjust the type accordingly so that we don't assume strict alignment
4183 when deferencing the pointer. */
4184 boundary *= BITS_PER_UNIT;
4185 if (boundary < TYPE_ALIGN (type))
4187 type = build_variant_type_copy (type);
4188 TYPE_ALIGN (type) = boundary;
4191 /* Compute the rounded size of the type. */
4192 type_size = size_in_bytes (type);
4193 rounded_size = round_up (type_size, align);
4195 /* Reduce rounded_size so it's sharable with the postqueue. */
4196 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4198 /* Get AP. */
4199 addr = valist_tmp;
4200 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4202 /* Small args are padded downward. */
4203 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4204 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4205 size_binop (MINUS_EXPR, rounded_size, type_size));
4206 t = fold_convert (TREE_TYPE (addr), t);
4207 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4210 /* Compute new value for AP. */
4211 t = fold_convert (TREE_TYPE (valist), rounded_size);
4212 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4213 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4214 gimplify_and_add (t, pre_p);
4216 addr = fold_convert (build_pointer_type (type), addr);
4218 if (indirect)
4219 addr = build_va_arg_indirect_ref (addr);
4221 return build_va_arg_indirect_ref (addr);
4224 /* Build an indirect-ref expression over the given TREE, which represents a
4225 piece of a va_arg() expansion. */
4226 tree
4227 build_va_arg_indirect_ref (tree addr)
4229 addr = build_fold_indirect_ref (addr);
4231 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4232 mf_mark (addr);
4234 return addr;
4237 /* Return a dummy expression of type TYPE in order to keep going after an
4238 error. */
4240 static tree
4241 dummy_object (tree type)
4243 tree t = convert (build_pointer_type (type), null_pointer_node);
4244 return build1 (INDIRECT_REF, type, t);
4247 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4248 builtin function, but a very special sort of operator. */
4250 enum gimplify_status
4251 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4253 tree promoted_type, want_va_type, have_va_type;
4254 tree valist = TREE_OPERAND (*expr_p, 0);
4255 tree type = TREE_TYPE (*expr_p);
4256 tree t;
4258 /* Verify that valist is of the proper type. */
4259 want_va_type = va_list_type_node;
4260 have_va_type = TREE_TYPE (valist);
4262 if (have_va_type == error_mark_node)
4263 return GS_ERROR;
4265 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4267 /* If va_list is an array type, the argument may have decayed
4268 to a pointer type, e.g. by being passed to another function.
4269 In that case, unwrap both types so that we can compare the
4270 underlying records. */
4271 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4272 || POINTER_TYPE_P (have_va_type))
4274 want_va_type = TREE_TYPE (want_va_type);
4275 have_va_type = TREE_TYPE (have_va_type);
4279 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4281 error ("first argument to %<va_arg%> not of type %<va_list%>");
4282 return GS_ERROR;
4285 /* Generate a diagnostic for requesting data of a type that cannot
4286 be passed through `...' due to type promotion at the call site. */
4287 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4288 != type)
4290 static bool gave_help;
4292 /* Unfortunately, this is merely undefined, rather than a constraint
4293 violation, so we cannot make this an error. If this call is never
4294 executed, the program is still strictly conforming. */
4295 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4296 type, promoted_type);
4297 if (! gave_help)
4299 gave_help = true;
4300 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4301 promoted_type, type);
4304 /* We can, however, treat "undefined" any way we please.
4305 Call abort to encourage the user to fix the program. */
4306 inform ("if this code is reached, the program will abort");
4307 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4308 NULL);
4309 append_to_statement_list (t, pre_p);
4311 /* This is dead code, but go ahead and finish so that the
4312 mode of the result comes out right. */
4313 *expr_p = dummy_object (type);
4314 return GS_ALL_DONE;
4316 else
4318 /* Make it easier for the backends by protecting the valist argument
4319 from multiple evaluations. */
4320 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4322 /* For this case, the backends will be expecting a pointer to
4323 TREE_TYPE (va_list_type_node), but it's possible we've
4324 actually been given an array (an actual va_list_type_node).
4325 So fix it. */
4326 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4328 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4329 valist = build_fold_addr_expr_with_type (valist, p1);
4331 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4333 else
4334 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4336 if (!targetm.gimplify_va_arg_expr)
4337 /* FIXME:Once most targets are converted we should merely
4338 assert this is non-null. */
4339 return GS_ALL_DONE;
4341 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4342 return GS_OK;
4346 /* Expand ARGLIST, from a call to __builtin_va_end. */
4348 static rtx
4349 expand_builtin_va_end (tree arglist)
4351 tree valist = TREE_VALUE (arglist);
4353 /* Evaluate for side effects, if needed. I hate macros that don't
4354 do that. */
4355 if (TREE_SIDE_EFFECTS (valist))
4356 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4358 return const0_rtx;
4361 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4362 builtin rather than just as an assignment in stdarg.h because of the
4363 nastiness of array-type va_list types. */
4365 static rtx
4366 expand_builtin_va_copy (tree arglist)
4368 tree dst, src, t;
4370 dst = TREE_VALUE (arglist);
4371 src = TREE_VALUE (TREE_CHAIN (arglist));
4373 dst = stabilize_va_list (dst, 1);
4374 src = stabilize_va_list (src, 0);
4376 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4378 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4379 TREE_SIDE_EFFECTS (t) = 1;
4380 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4382 else
4384 rtx dstb, srcb, size;
4386 /* Evaluate to pointers. */
4387 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4388 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4389 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4390 VOIDmode, EXPAND_NORMAL);
4392 dstb = convert_memory_address (Pmode, dstb);
4393 srcb = convert_memory_address (Pmode, srcb);
4395 /* "Dereference" to BLKmode memories. */
4396 dstb = gen_rtx_MEM (BLKmode, dstb);
4397 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4398 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4399 srcb = gen_rtx_MEM (BLKmode, srcb);
4400 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4401 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4403 /* Copy. */
4404 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4407 return const0_rtx;
4410 /* Expand a call to one of the builtin functions __builtin_frame_address or
4411 __builtin_return_address. */
4413 static rtx
4414 expand_builtin_frame_address (tree fndecl, tree arglist)
4416 /* The argument must be a nonnegative integer constant.
4417 It counts the number of frames to scan up the stack.
4418 The value is the return address saved in that frame. */
4419 if (arglist == 0)
4420 /* Warning about missing arg was already issued. */
4421 return const0_rtx;
4422 else if (! host_integerp (TREE_VALUE (arglist), 1))
4424 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4425 error ("invalid argument to %<__builtin_frame_address%>");
4426 else
4427 error ("invalid argument to %<__builtin_return_address%>");
4428 return const0_rtx;
4430 else
4432 rtx tem
4433 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4434 tree_low_cst (TREE_VALUE (arglist), 1));
4436 /* Some ports cannot access arbitrary stack frames. */
4437 if (tem == NULL)
4439 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4440 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4441 else
4442 warning (0, "unsupported argument to %<__builtin_return_address%>");
4443 return const0_rtx;
4446 /* For __builtin_frame_address, return what we've got. */
4447 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4448 return tem;
4450 if (!REG_P (tem)
4451 && ! CONSTANT_P (tem))
4452 tem = copy_to_mode_reg (Pmode, tem);
4453 return tem;
4457 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4458 we failed and the caller should emit a normal call, otherwise try to get
4459 the result in TARGET, if convenient. */
4461 static rtx
4462 expand_builtin_alloca (tree arglist, rtx target)
4464 rtx op0;
4465 rtx result;
4467 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4468 should always expand to function calls. These can be intercepted
4469 in libmudflap. */
4470 if (flag_mudflap)
4471 return 0;
4473 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4474 return 0;
4476 /* Compute the argument. */
4477 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4479 /* Allocate the desired space. */
4480 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4481 result = convert_memory_address (ptr_mode, result);
4483 return result;
4486 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4487 Return 0 if a normal call should be emitted rather than expanding the
4488 function in-line. If convenient, the result should be placed in TARGET.
4489 SUBTARGET may be used as the target for computing one of EXP's operands. */
4491 static rtx
4492 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4493 rtx subtarget, optab op_optab)
4495 rtx op0;
4496 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4497 return 0;
4499 /* Compute the argument. */
4500 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4501 /* Compute op, into TARGET if possible.
4502 Set TARGET to wherever the result comes back. */
4503 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4504 op_optab, op0, target, 1);
4505 gcc_assert (target);
4507 return convert_to_mode (target_mode, target, 0);
4510 /* If the string passed to fputs is a constant and is one character
4511 long, we attempt to transform this call into __builtin_fputc(). */
4513 static rtx
4514 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4516 /* Verify the arguments in the original call. */
4517 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4519 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4520 unlocked, NULL_TREE);
4521 if (result)
4522 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4524 return 0;
4527 /* Expand a call to __builtin_expect. We return our argument and emit a
4528 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4529 a non-jump context. */
4531 static rtx
4532 expand_builtin_expect (tree arglist, rtx target)
4534 tree exp, c;
4535 rtx note, rtx_c;
4537 if (arglist == NULL_TREE
4538 || TREE_CHAIN (arglist) == NULL_TREE)
4539 return const0_rtx;
4540 exp = TREE_VALUE (arglist);
4541 c = TREE_VALUE (TREE_CHAIN (arglist));
4543 if (TREE_CODE (c) != INTEGER_CST)
4545 error ("second argument to %<__builtin_expect%> must be a constant");
4546 c = integer_zero_node;
4549 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4551 /* Don't bother with expected value notes for integral constants. */
4552 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4554 /* We do need to force this into a register so that we can be
4555 moderately sure to be able to correctly interpret the branch
4556 condition later. */
4557 target = force_reg (GET_MODE (target), target);
4559 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4561 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4562 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4565 return target;
4568 /* Like expand_builtin_expect, except do this in a jump context. This is
4569 called from do_jump if the conditional is a __builtin_expect. Return either
4570 a list of insns to emit the jump or NULL if we cannot optimize
4571 __builtin_expect. We need to optimize this at jump time so that machines
4572 like the PowerPC don't turn the test into a SCC operation, and then jump
4573 based on the test being 0/1. */
4576 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4578 tree arglist = TREE_OPERAND (exp, 1);
4579 tree arg0 = TREE_VALUE (arglist);
4580 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4581 rtx ret = NULL_RTX;
4583 /* Only handle __builtin_expect (test, 0) and
4584 __builtin_expect (test, 1). */
4585 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4586 && (integer_zerop (arg1) || integer_onep (arg1)))
4588 rtx insn, drop_through_label, temp;
4590 /* Expand the jump insns. */
4591 start_sequence ();
4592 do_jump (arg0, if_false_label, if_true_label);
4593 ret = get_insns ();
4595 drop_through_label = get_last_insn ();
4596 if (drop_through_label && NOTE_P (drop_through_label))
4597 drop_through_label = prev_nonnote_insn (drop_through_label);
4598 if (drop_through_label && !LABEL_P (drop_through_label))
4599 drop_through_label = NULL_RTX;
4600 end_sequence ();
4602 if (! if_true_label)
4603 if_true_label = drop_through_label;
4604 if (! if_false_label)
4605 if_false_label = drop_through_label;
4607 /* Go through and add the expect's to each of the conditional jumps. */
4608 insn = ret;
4609 while (insn != NULL_RTX)
4611 rtx next = NEXT_INSN (insn);
4613 if (JUMP_P (insn) && any_condjump_p (insn))
4615 rtx ifelse = SET_SRC (pc_set (insn));
4616 rtx then_dest = XEXP (ifelse, 1);
4617 rtx else_dest = XEXP (ifelse, 2);
4618 int taken = -1;
4620 /* First check if we recognize any of the labels. */
4621 if (GET_CODE (then_dest) == LABEL_REF
4622 && XEXP (then_dest, 0) == if_true_label)
4623 taken = 1;
4624 else if (GET_CODE (then_dest) == LABEL_REF
4625 && XEXP (then_dest, 0) == if_false_label)
4626 taken = 0;
4627 else if (GET_CODE (else_dest) == LABEL_REF
4628 && XEXP (else_dest, 0) == if_false_label)
4629 taken = 1;
4630 else if (GET_CODE (else_dest) == LABEL_REF
4631 && XEXP (else_dest, 0) == if_true_label)
4632 taken = 0;
4633 /* Otherwise check where we drop through. */
4634 else if (else_dest == pc_rtx)
4636 if (next && NOTE_P (next))
4637 next = next_nonnote_insn (next);
4639 if (next && JUMP_P (next)
4640 && any_uncondjump_p (next))
4641 temp = XEXP (SET_SRC (pc_set (next)), 0);
4642 else
4643 temp = next;
4645 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4646 else that can't possibly match either target label. */
4647 if (temp == if_false_label)
4648 taken = 1;
4649 else if (temp == if_true_label)
4650 taken = 0;
4652 else if (then_dest == pc_rtx)
4654 if (next && NOTE_P (next))
4655 next = next_nonnote_insn (next);
4657 if (next && JUMP_P (next)
4658 && any_uncondjump_p (next))
4659 temp = XEXP (SET_SRC (pc_set (next)), 0);
4660 else
4661 temp = next;
4663 if (temp == if_false_label)
4664 taken = 0;
4665 else if (temp == if_true_label)
4666 taken = 1;
4669 if (taken != -1)
4671 /* If the test is expected to fail, reverse the
4672 probabilities. */
4673 if (integer_zerop (arg1))
4674 taken = 1 - taken;
4675 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4679 insn = next;
4683 return ret;
4686 void
4687 expand_builtin_trap (void)
4689 #ifdef HAVE_trap
4690 if (HAVE_trap)
4691 emit_insn (gen_trap ());
4692 else
4693 #endif
4694 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4695 emit_barrier ();
4698 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4699 Return 0 if a normal call should be emitted rather than expanding
4700 the function inline. If convenient, the result should be placed
4701 in TARGET. SUBTARGET may be used as the target for computing
4702 the operand. */
4704 static rtx
4705 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4707 enum machine_mode mode;
4708 tree arg;
4709 rtx op0;
4711 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4712 return 0;
4714 arg = TREE_VALUE (arglist);
4715 mode = TYPE_MODE (TREE_TYPE (arg));
4716 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4717 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4720 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4721 Return NULL is a normal call should be emitted rather than expanding the
4722 function inline. If convenient, the result should be placed in TARGET.
4723 SUBTARGET may be used as the target for computing the operand. */
4725 static rtx
4726 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4728 rtx op0, op1;
4729 tree arg;
4731 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4732 return 0;
4734 arg = TREE_VALUE (arglist);
4735 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4737 arg = TREE_VALUE (TREE_CHAIN (arglist));
4738 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4740 return expand_copysign (op0, op1, target);
4743 /* Create a new constant string literal and return a char* pointer to it.
4744 The STRING_CST value is the LEN characters at STR. */
4745 static tree
4746 build_string_literal (int len, const char *str)
4748 tree t, elem, index, type;
4750 t = build_string (len, str);
4751 elem = build_type_variant (char_type_node, 1, 0);
4752 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4753 type = build_array_type (elem, index);
4754 TREE_TYPE (t) = type;
4755 TREE_CONSTANT (t) = 1;
4756 TREE_INVARIANT (t) = 1;
4757 TREE_READONLY (t) = 1;
4758 TREE_STATIC (t) = 1;
4760 type = build_pointer_type (type);
4761 t = build1 (ADDR_EXPR, type, t);
4763 type = build_pointer_type (elem);
4764 t = build1 (NOP_EXPR, type, t);
4765 return t;
4768 /* Expand EXP, a call to printf or printf_unlocked.
4769 Return 0 if a normal call should be emitted rather than transforming
4770 the function inline. If convenient, the result should be placed in
4771 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4772 call. */
4773 static rtx
4774 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4775 bool unlocked)
4777 tree arglist = TREE_OPERAND (exp, 1);
4778 /* If we're using an unlocked function, assume the other unlocked
4779 functions exist explicitly. */
4780 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4781 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4782 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4783 : implicit_built_in_decls[BUILT_IN_PUTS];
4784 const char *fmt_str;
4785 tree fn, fmt, arg;
4787 /* If the return value is used, don't do the transformation. */
4788 if (target != const0_rtx)
4789 return 0;
4791 /* Verify the required arguments in the original call. */
4792 if (! arglist)
4793 return 0;
4794 fmt = TREE_VALUE (arglist);
4795 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4796 return 0;
4797 arglist = TREE_CHAIN (arglist);
4799 /* Check whether the format is a literal string constant. */
4800 fmt_str = c_getstr (fmt);
4801 if (fmt_str == NULL)
4802 return 0;
4804 if (!init_target_chars())
4805 return 0;
4807 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4808 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4810 if (! arglist
4811 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4812 || TREE_CHAIN (arglist))
4813 return 0;
4814 fn = fn_puts;
4816 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4817 else if (strcmp (fmt_str, target_percent_c) == 0)
4819 if (! arglist
4820 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4821 || TREE_CHAIN (arglist))
4822 return 0;
4823 fn = fn_putchar;
4825 else
4827 /* We can't handle anything else with % args or %% ... yet. */
4828 if (strchr (fmt_str, target_percent))
4829 return 0;
4831 if (arglist)
4832 return 0;
4834 /* If the format specifier was "", printf does nothing. */
4835 if (fmt_str[0] == '\0')
4836 return const0_rtx;
4837 /* If the format specifier has length of 1, call putchar. */
4838 if (fmt_str[1] == '\0')
4840 /* Given printf("c"), (where c is any one character,)
4841 convert "c"[0] to an int and pass that to the replacement
4842 function. */
4843 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4844 arglist = build_tree_list (NULL_TREE, arg);
4845 fn = fn_putchar;
4847 else
4849 /* If the format specifier was "string\n", call puts("string"). */
4850 size_t len = strlen (fmt_str);
4851 if ((unsigned char)fmt_str[len - 1] == target_newline)
4853 /* Create a NUL-terminated string that's one char shorter
4854 than the original, stripping off the trailing '\n'. */
4855 char *newstr = alloca (len);
4856 memcpy (newstr, fmt_str, len - 1);
4857 newstr[len - 1] = 0;
4859 arg = build_string_literal (len, newstr);
4860 arglist = build_tree_list (NULL_TREE, arg);
4861 fn = fn_puts;
4863 else
4864 /* We'd like to arrange to call fputs(string,stdout) here,
4865 but we need stdout and don't have a way to get it yet. */
4866 return 0;
4870 if (!fn)
4871 return 0;
4872 fn = build_function_call_expr (fn, arglist);
4873 if (TREE_CODE (fn) == CALL_EXPR)
4874 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4875 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4878 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4879 Return 0 if a normal call should be emitted rather than transforming
4880 the function inline. If convenient, the result should be placed in
4881 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4882 call. */
4883 static rtx
4884 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4885 bool unlocked)
4887 tree arglist = TREE_OPERAND (exp, 1);
4888 /* If we're using an unlocked function, assume the other unlocked
4889 functions exist explicitly. */
4890 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4891 : implicit_built_in_decls[BUILT_IN_FPUTC];
4892 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4893 : implicit_built_in_decls[BUILT_IN_FPUTS];
4894 const char *fmt_str;
4895 tree fn, fmt, fp, arg;
4897 /* If the return value is used, don't do the transformation. */
4898 if (target != const0_rtx)
4899 return 0;
4901 /* Verify the required arguments in the original call. */
4902 if (! arglist)
4903 return 0;
4904 fp = TREE_VALUE (arglist);
4905 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4906 return 0;
4907 arglist = TREE_CHAIN (arglist);
4908 if (! arglist)
4909 return 0;
4910 fmt = TREE_VALUE (arglist);
4911 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4912 return 0;
4913 arglist = TREE_CHAIN (arglist);
4915 /* Check whether the format is a literal string constant. */
4916 fmt_str = c_getstr (fmt);
4917 if (fmt_str == NULL)
4918 return 0;
4920 if (!init_target_chars())
4921 return 0;
4923 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4924 if (strcmp (fmt_str, target_percent_s) == 0)
4926 if (! arglist
4927 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4928 || TREE_CHAIN (arglist))
4929 return 0;
4930 arg = TREE_VALUE (arglist);
4931 arglist = build_tree_list (NULL_TREE, fp);
4932 arglist = tree_cons (NULL_TREE, arg, arglist);
4933 fn = fn_fputs;
4935 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4936 else if (strcmp (fmt_str, target_percent_c) == 0)
4938 if (! arglist
4939 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4940 || TREE_CHAIN (arglist))
4941 return 0;
4942 arg = TREE_VALUE (arglist);
4943 arglist = build_tree_list (NULL_TREE, fp);
4944 arglist = tree_cons (NULL_TREE, arg, arglist);
4945 fn = fn_fputc;
4947 else
4949 /* We can't handle anything else with % args or %% ... yet. */
4950 if (strchr (fmt_str, target_percent))
4951 return 0;
4953 if (arglist)
4954 return 0;
4956 /* If the format specifier was "", fprintf does nothing. */
4957 if (fmt_str[0] == '\0')
4959 /* Evaluate and ignore FILE* argument for side-effects. */
4960 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4961 return const0_rtx;
4964 /* When "string" doesn't contain %, replace all cases of
4965 fprintf(stream,string) with fputs(string,stream). The fputs
4966 builtin will take care of special cases like length == 1. */
4967 arglist = build_tree_list (NULL_TREE, fp);
4968 arglist = tree_cons (NULL_TREE, fmt, arglist);
4969 fn = fn_fputs;
4972 if (!fn)
4973 return 0;
4974 fn = build_function_call_expr (fn, arglist);
4975 if (TREE_CODE (fn) == CALL_EXPR)
4976 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4977 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4980 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4981 a normal call should be emitted rather than expanding the function
4982 inline. If convenient, the result should be placed in TARGET with
4983 mode MODE. */
4985 static rtx
4986 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4988 tree orig_arglist, dest, fmt;
4989 const char *fmt_str;
4991 orig_arglist = arglist;
4993 /* Verify the required arguments in the original call. */
4994 if (! arglist)
4995 return 0;
4996 dest = TREE_VALUE (arglist);
4997 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
4998 return 0;
4999 arglist = TREE_CHAIN (arglist);
5000 if (! arglist)
5001 return 0;
5002 fmt = TREE_VALUE (arglist);
5003 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5004 return 0;
5005 arglist = TREE_CHAIN (arglist);
5007 /* Check whether the format is a literal string constant. */
5008 fmt_str = c_getstr (fmt);
5009 if (fmt_str == NULL)
5010 return 0;
5012 if (!init_target_chars())
5013 return 0;
5015 /* If the format doesn't contain % args or %%, use strcpy. */
5016 if (strchr (fmt_str, target_percent) == 0)
5018 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5019 tree exp;
5021 if (arglist || ! fn)
5022 return 0;
5023 expand_expr (build_function_call_expr (fn, orig_arglist),
5024 const0_rtx, VOIDmode, EXPAND_NORMAL);
5025 if (target == const0_rtx)
5026 return const0_rtx;
5027 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5028 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5030 /* If the format is "%s", use strcpy if the result isn't used. */
5031 else if (strcmp (fmt_str, target_percent_s) == 0)
5033 tree fn, arg, len;
5034 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5036 if (! fn)
5037 return 0;
5039 if (! arglist || TREE_CHAIN (arglist))
5040 return 0;
5041 arg = TREE_VALUE (arglist);
5042 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5043 return 0;
5045 if (target != const0_rtx)
5047 len = c_strlen (arg, 1);
5048 if (! len || TREE_CODE (len) != INTEGER_CST)
5049 return 0;
5051 else
5052 len = NULL_TREE;
5054 arglist = build_tree_list (NULL_TREE, arg);
5055 arglist = tree_cons (NULL_TREE, dest, arglist);
5056 expand_expr (build_function_call_expr (fn, arglist),
5057 const0_rtx, VOIDmode, EXPAND_NORMAL);
5059 if (target == const0_rtx)
5060 return const0_rtx;
5061 return expand_expr (len, target, mode, EXPAND_NORMAL);
5064 return 0;
5067 /* Expand a call to either the entry or exit function profiler. */
5069 static rtx
5070 expand_builtin_profile_func (bool exitp)
5072 rtx this, which;
5074 this = DECL_RTL (current_function_decl);
5075 gcc_assert (MEM_P (this));
5076 this = XEXP (this, 0);
5078 if (exitp)
5079 which = profile_function_exit_libfunc;
5080 else
5081 which = profile_function_entry_libfunc;
5083 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5084 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5086 Pmode);
5088 return const0_rtx;
5091 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5093 static rtx
5094 round_trampoline_addr (rtx tramp)
5096 rtx temp, addend, mask;
5098 /* If we don't need too much alignment, we'll have been guaranteed
5099 proper alignment by get_trampoline_type. */
5100 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5101 return tramp;
5103 /* Round address up to desired boundary. */
5104 temp = gen_reg_rtx (Pmode);
5105 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5106 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5108 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5109 temp, 0, OPTAB_LIB_WIDEN);
5110 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5111 temp, 0, OPTAB_LIB_WIDEN);
5113 return tramp;
5116 static rtx
5117 expand_builtin_init_trampoline (tree arglist)
5119 tree t_tramp, t_func, t_chain;
5120 rtx r_tramp, r_func, r_chain;
5121 #ifdef TRAMPOLINE_TEMPLATE
5122 rtx blktramp;
5123 #endif
5125 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5126 POINTER_TYPE, VOID_TYPE))
5127 return NULL_RTX;
5129 t_tramp = TREE_VALUE (arglist);
5130 arglist = TREE_CHAIN (arglist);
5131 t_func = TREE_VALUE (arglist);
5132 arglist = TREE_CHAIN (arglist);
5133 t_chain = TREE_VALUE (arglist);
5135 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5136 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5137 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5139 /* Generate insns to initialize the trampoline. */
5140 r_tramp = round_trampoline_addr (r_tramp);
5141 #ifdef TRAMPOLINE_TEMPLATE
5142 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5143 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5144 emit_block_move (blktramp, assemble_trampoline_template (),
5145 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5146 #endif
5147 trampolines_created = 1;
5148 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5150 return const0_rtx;
5153 static rtx
5154 expand_builtin_adjust_trampoline (tree arglist)
5156 rtx tramp;
5158 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5159 return NULL_RTX;
5161 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5162 tramp = round_trampoline_addr (tramp);
5163 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5164 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5165 #endif
5167 return tramp;
5170 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5171 Return NULL_RTX if a normal call should be emitted rather than expanding
5172 the function in-line. EXP is the expression that is a call to the builtin
5173 function; if convenient, the result should be placed in TARGET. */
5175 static rtx
5176 expand_builtin_signbit (tree exp, rtx target)
5178 const struct real_format *fmt;
5179 enum machine_mode fmode, imode, rmode;
5180 HOST_WIDE_INT hi, lo;
5181 tree arg, arglist;
5182 int word, bitpos;
5183 rtx temp;
5185 arglist = TREE_OPERAND (exp, 1);
5186 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5187 return 0;
5189 arg = TREE_VALUE (arglist);
5190 fmode = TYPE_MODE (TREE_TYPE (arg));
5191 rmode = TYPE_MODE (TREE_TYPE (exp));
5192 fmt = REAL_MODE_FORMAT (fmode);
5194 /* For floating point formats without a sign bit, implement signbit
5195 as "ARG < 0.0". */
5196 bitpos = fmt->signbit_ro;
5197 if (bitpos < 0)
5199 /* But we can't do this if the format supports signed zero. */
5200 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5201 return 0;
5203 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5204 build_real (TREE_TYPE (arg), dconst0));
5205 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5208 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5209 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5211 imode = int_mode_for_mode (fmode);
5212 if (imode == BLKmode)
5213 return 0;
5214 temp = gen_lowpart (imode, temp);
5216 else
5218 imode = word_mode;
5219 /* Handle targets with different FP word orders. */
5220 if (FLOAT_WORDS_BIG_ENDIAN)
5221 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5222 else
5223 word = bitpos / BITS_PER_WORD;
5224 temp = operand_subword_force (temp, word, fmode);
5225 bitpos = bitpos % BITS_PER_WORD;
5228 /* Force the intermediate word_mode (or narrower) result into a
5229 register. This avoids attempting to create paradoxical SUBREGs
5230 of floating point modes below. */
5231 temp = force_reg (imode, temp);
5233 /* If the bitpos is within the "result mode" lowpart, the operation
5234 can be implement with a single bitwise AND. Otherwise, we need
5235 a right shift and an AND. */
5237 if (bitpos < GET_MODE_BITSIZE (rmode))
5239 if (bitpos < HOST_BITS_PER_WIDE_INT)
5241 hi = 0;
5242 lo = (HOST_WIDE_INT) 1 << bitpos;
5244 else
5246 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5247 lo = 0;
5250 if (imode != rmode)
5251 temp = gen_lowpart (rmode, temp);
5252 temp = expand_binop (rmode, and_optab, temp,
5253 immed_double_const (lo, hi, rmode),
5254 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5256 else
5258 /* Perform a logical right shift to place the signbit in the least
5259 significant bit, then truncate the result to the desired mode
5260 and mask just this bit. */
5261 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5262 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5263 temp = gen_lowpart (rmode, temp);
5264 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5265 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5268 return temp;
5271 /* Expand fork or exec calls. TARGET is the desired target of the
5272 call. ARGLIST is the list of arguments of the call. FN is the
5273 identificator of the actual function. IGNORE is nonzero if the
5274 value is to be ignored. */
5276 static rtx
5277 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5279 tree id, decl;
5280 tree call;
5282 /* If we are not profiling, just call the function. */
5283 if (!profile_arc_flag)
5284 return NULL_RTX;
5286 /* Otherwise call the wrapper. This should be equivalent for the rest of
5287 compiler, so the code does not diverge, and the wrapper may run the
5288 code necessary for keeping the profiling sane. */
5290 switch (DECL_FUNCTION_CODE (fn))
5292 case BUILT_IN_FORK:
5293 id = get_identifier ("__gcov_fork");
5294 break;
5296 case BUILT_IN_EXECL:
5297 id = get_identifier ("__gcov_execl");
5298 break;
5300 case BUILT_IN_EXECV:
5301 id = get_identifier ("__gcov_execv");
5302 break;
5304 case BUILT_IN_EXECLP:
5305 id = get_identifier ("__gcov_execlp");
5306 break;
5308 case BUILT_IN_EXECLE:
5309 id = get_identifier ("__gcov_execle");
5310 break;
5312 case BUILT_IN_EXECVP:
5313 id = get_identifier ("__gcov_execvp");
5314 break;
5316 case BUILT_IN_EXECVE:
5317 id = get_identifier ("__gcov_execve");
5318 break;
5320 default:
5321 gcc_unreachable ();
5324 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5325 DECL_EXTERNAL (decl) = 1;
5326 TREE_PUBLIC (decl) = 1;
5327 DECL_ARTIFICIAL (decl) = 1;
5328 TREE_NOTHROW (decl) = 1;
5329 call = build_function_call_expr (decl, arglist);
5331 return expand_call (call, target, ignore);
5335 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5336 the pointer in these functions is void*, the tree optimizers may remove
5337 casts. The mode computed in expand_builtin isn't reliable either, due
5338 to __sync_bool_compare_and_swap.
5340 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5341 group of builtins. This gives us log2 of the mode size. */
5343 static inline enum machine_mode
5344 get_builtin_sync_mode (int fcode_diff)
5346 /* The size is not negotiable, so ask not to get BLKmode in return
5347 if the target indicates that a smaller size would be better. */
5348 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5351 /* Expand the memory expression LOC and return the appropriate memory operand
5352 for the builtin_sync operations. */
5354 static rtx
5355 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5357 rtx addr, mem;
5359 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5361 /* Note that we explicitly do not want any alias information for this
5362 memory, so that we kill all other live memories. Otherwise we don't
5363 satisfy the full barrier semantics of the intrinsic. */
5364 mem = validize_mem (gen_rtx_MEM (mode, addr));
5366 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5367 MEM_VOLATILE_P (mem) = 1;
5369 return mem;
5372 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5373 ARGLIST is the operands list to the function. CODE is the rtx code
5374 that corresponds to the arithmetic or logical operation from the name;
5375 an exception here is that NOT actually means NAND. TARGET is an optional
5376 place for us to store the results; AFTER is true if this is the
5377 fetch_and_xxx form. IGNORE is true if we don't actually care about
5378 the result of the operation at all. */
5380 static rtx
5381 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5382 enum rtx_code code, bool after,
5383 rtx target, bool ignore)
5385 rtx val, mem;
5387 /* Expand the operands. */
5388 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5390 arglist = TREE_CHAIN (arglist);
5391 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5393 if (ignore)
5394 return expand_sync_operation (mem, val, code);
5395 else
5396 return expand_sync_fetch_operation (mem, val, code, after, target);
5399 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5400 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5401 true if this is the boolean form. TARGET is a place for us to store the
5402 results; this is NOT optional if IS_BOOL is true. */
5404 static rtx
5405 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5406 bool is_bool, rtx target)
5408 rtx old_val, new_val, mem;
5410 /* Expand the operands. */
5411 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5413 arglist = TREE_CHAIN (arglist);
5414 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5416 arglist = TREE_CHAIN (arglist);
5417 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5419 if (is_bool)
5420 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5421 else
5422 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5425 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5426 general form is actually an atomic exchange, and some targets only
5427 support a reduced form with the second argument being a constant 1.
5428 ARGLIST is the operands list to the function; TARGET is an optional
5429 place for us to store the results. */
5431 static rtx
5432 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5433 rtx target)
5435 rtx val, mem;
5437 /* Expand the operands. */
5438 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5440 arglist = TREE_CHAIN (arglist);
5441 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5443 return expand_sync_lock_test_and_set (mem, val, target);
5446 /* Expand the __sync_synchronize intrinsic. */
5448 static void
5449 expand_builtin_synchronize (void)
5451 tree x;
5453 #ifdef HAVE_memory_barrier
5454 if (HAVE_memory_barrier)
5456 emit_insn (gen_memory_barrier ());
5457 return;
5459 #endif
5461 /* If no explicit memory barrier instruction is available, create an
5462 empty asm stmt with a memory clobber. */
5463 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5464 tree_cons (NULL, build_string (6, "memory"), NULL));
5465 ASM_VOLATILE_P (x) = 1;
5466 expand_asm_expr (x);
5469 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5470 to the function. */
5472 static void
5473 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5475 enum insn_code icode;
5476 rtx mem, insn;
5477 rtx val = const0_rtx;
5479 /* Expand the operands. */
5480 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5482 /* If there is an explicit operation in the md file, use it. */
5483 icode = sync_lock_release[mode];
5484 if (icode != CODE_FOR_nothing)
5486 if (!insn_data[icode].operand[1].predicate (val, mode))
5487 val = force_reg (mode, val);
5489 insn = GEN_FCN (icode) (mem, val);
5490 if (insn)
5492 emit_insn (insn);
5493 return;
5497 /* Otherwise we can implement this operation by emitting a barrier
5498 followed by a store of zero. */
5499 expand_builtin_synchronize ();
5500 emit_move_insn (mem, val);
5503 /* Expand an expression EXP that calls a built-in function,
5504 with result going to TARGET if that's convenient
5505 (and in mode MODE if that's convenient).
5506 SUBTARGET may be used as the target for computing one of EXP's operands.
5507 IGNORE is nonzero if the value is to be ignored. */
5510 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5511 int ignore)
5513 tree fndecl = get_callee_fndecl (exp);
5514 tree arglist = TREE_OPERAND (exp, 1);
5515 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5516 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5518 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5519 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5521 /* When not optimizing, generate calls to library functions for a certain
5522 set of builtins. */
5523 if (!optimize
5524 && !called_as_built_in (fndecl)
5525 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5526 && fcode != BUILT_IN_ALLOCA)
5527 return expand_call (exp, target, ignore);
5529 /* The built-in function expanders test for target == const0_rtx
5530 to determine whether the function's result will be ignored. */
5531 if (ignore)
5532 target = const0_rtx;
5534 /* If the result of a pure or const built-in function is ignored, and
5535 none of its arguments are volatile, we can avoid expanding the
5536 built-in call and just evaluate the arguments for side-effects. */
5537 if (target == const0_rtx
5538 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5540 bool volatilep = false;
5541 tree arg;
5543 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5544 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5546 volatilep = true;
5547 break;
5550 if (! volatilep)
5552 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5553 expand_expr (TREE_VALUE (arg), const0_rtx,
5554 VOIDmode, EXPAND_NORMAL);
5555 return const0_rtx;
5559 switch (fcode)
5561 CASE_FLT_FN (BUILT_IN_FABS):
5562 target = expand_builtin_fabs (arglist, target, subtarget);
5563 if (target)
5564 return target;
5565 break;
5567 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5568 target = expand_builtin_copysign (arglist, target, subtarget);
5569 if (target)
5570 return target;
5571 break;
5573 /* Just do a normal library call if we were unable to fold
5574 the values. */
5575 CASE_FLT_FN (BUILT_IN_CABS):
5576 break;
5578 CASE_FLT_FN (BUILT_IN_EXP):
5579 CASE_FLT_FN (BUILT_IN_EXP10):
5580 CASE_FLT_FN (BUILT_IN_POW10):
5581 CASE_FLT_FN (BUILT_IN_EXP2):
5582 CASE_FLT_FN (BUILT_IN_EXPM1):
5583 CASE_FLT_FN (BUILT_IN_LOGB):
5584 CASE_FLT_FN (BUILT_IN_ILOGB):
5585 CASE_FLT_FN (BUILT_IN_LOG):
5586 CASE_FLT_FN (BUILT_IN_LOG10):
5587 CASE_FLT_FN (BUILT_IN_LOG2):
5588 CASE_FLT_FN (BUILT_IN_LOG1P):
5589 CASE_FLT_FN (BUILT_IN_TAN):
5590 CASE_FLT_FN (BUILT_IN_ASIN):
5591 CASE_FLT_FN (BUILT_IN_ACOS):
5592 CASE_FLT_FN (BUILT_IN_ATAN):
5593 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5594 because of possible accuracy problems. */
5595 if (! flag_unsafe_math_optimizations)
5596 break;
5597 CASE_FLT_FN (BUILT_IN_SQRT):
5598 CASE_FLT_FN (BUILT_IN_FLOOR):
5599 CASE_FLT_FN (BUILT_IN_CEIL):
5600 CASE_FLT_FN (BUILT_IN_TRUNC):
5601 CASE_FLT_FN (BUILT_IN_ROUND):
5602 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5603 CASE_FLT_FN (BUILT_IN_RINT):
5604 CASE_FLT_FN (BUILT_IN_LRINT):
5605 CASE_FLT_FN (BUILT_IN_LLRINT):
5606 target = expand_builtin_mathfn (exp, target, subtarget);
5607 if (target)
5608 return target;
5609 break;
5611 CASE_FLT_FN (BUILT_IN_LCEIL):
5612 CASE_FLT_FN (BUILT_IN_LLCEIL):
5613 CASE_FLT_FN (BUILT_IN_LFLOOR):
5614 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5615 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5616 if (target)
5617 return target;
5618 break;
5620 CASE_FLT_FN (BUILT_IN_POW):
5621 target = expand_builtin_pow (exp, target, subtarget);
5622 if (target)
5623 return target;
5624 break;
5626 CASE_FLT_FN (BUILT_IN_POWI):
5627 target = expand_builtin_powi (exp, target, subtarget);
5628 if (target)
5629 return target;
5630 break;
5632 CASE_FLT_FN (BUILT_IN_ATAN2):
5633 CASE_FLT_FN (BUILT_IN_LDEXP):
5634 CASE_FLT_FN (BUILT_IN_FMOD):
5635 CASE_FLT_FN (BUILT_IN_DREM):
5636 if (! flag_unsafe_math_optimizations)
5637 break;
5638 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5639 if (target)
5640 return target;
5641 break;
5643 CASE_FLT_FN (BUILT_IN_SIN):
5644 CASE_FLT_FN (BUILT_IN_COS):
5645 if (! flag_unsafe_math_optimizations)
5646 break;
5647 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5648 if (target)
5649 return target;
5650 break;
5652 case BUILT_IN_APPLY_ARGS:
5653 return expand_builtin_apply_args ();
5655 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5656 FUNCTION with a copy of the parameters described by
5657 ARGUMENTS, and ARGSIZE. It returns a block of memory
5658 allocated on the stack into which is stored all the registers
5659 that might possibly be used for returning the result of a
5660 function. ARGUMENTS is the value returned by
5661 __builtin_apply_args. ARGSIZE is the number of bytes of
5662 arguments that must be copied. ??? How should this value be
5663 computed? We'll also need a safe worst case value for varargs
5664 functions. */
5665 case BUILT_IN_APPLY:
5666 if (!validate_arglist (arglist, POINTER_TYPE,
5667 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5668 && !validate_arglist (arglist, REFERENCE_TYPE,
5669 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5670 return const0_rtx;
5671 else
5673 int i;
5674 tree t;
5675 rtx ops[3];
5677 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5678 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5680 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5683 /* __builtin_return (RESULT) causes the function to return the
5684 value described by RESULT. RESULT is address of the block of
5685 memory returned by __builtin_apply. */
5686 case BUILT_IN_RETURN:
5687 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5688 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5689 NULL_RTX, VOIDmode, 0));
5690 return const0_rtx;
5692 case BUILT_IN_SAVEREGS:
5693 return expand_builtin_saveregs ();
5695 case BUILT_IN_ARGS_INFO:
5696 return expand_builtin_args_info (arglist);
5698 /* Return the address of the first anonymous stack arg. */
5699 case BUILT_IN_NEXT_ARG:
5700 if (fold_builtin_next_arg (arglist))
5701 return const0_rtx;
5702 return expand_builtin_next_arg ();
5704 case BUILT_IN_CLASSIFY_TYPE:
5705 return expand_builtin_classify_type (arglist);
5707 case BUILT_IN_CONSTANT_P:
5708 return const0_rtx;
5710 case BUILT_IN_FRAME_ADDRESS:
5711 case BUILT_IN_RETURN_ADDRESS:
5712 return expand_builtin_frame_address (fndecl, arglist);
5714 /* Returns the address of the area where the structure is returned.
5715 0 otherwise. */
5716 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5717 if (arglist != 0
5718 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5719 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5720 return const0_rtx;
5721 else
5722 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5724 case BUILT_IN_ALLOCA:
5725 target = expand_builtin_alloca (arglist, target);
5726 if (target)
5727 return target;
5728 break;
5730 case BUILT_IN_STACK_SAVE:
5731 return expand_stack_save ();
5733 case BUILT_IN_STACK_RESTORE:
5734 expand_stack_restore (TREE_VALUE (arglist));
5735 return const0_rtx;
5737 CASE_INT_FN (BUILT_IN_FFS):
5738 case BUILT_IN_FFSIMAX:
5739 target = expand_builtin_unop (target_mode, arglist, target,
5740 subtarget, ffs_optab);
5741 if (target)
5742 return target;
5743 break;
5745 CASE_INT_FN (BUILT_IN_CLZ):
5746 case BUILT_IN_CLZIMAX:
5747 target = expand_builtin_unop (target_mode, arglist, target,
5748 subtarget, clz_optab);
5749 if (target)
5750 return target;
5751 break;
5753 CASE_INT_FN (BUILT_IN_CTZ):
5754 case BUILT_IN_CTZIMAX:
5755 target = expand_builtin_unop (target_mode, arglist, target,
5756 subtarget, ctz_optab);
5757 if (target)
5758 return target;
5759 break;
5761 CASE_INT_FN (BUILT_IN_POPCOUNT):
5762 case BUILT_IN_POPCOUNTIMAX:
5763 target = expand_builtin_unop (target_mode, arglist, target,
5764 subtarget, popcount_optab);
5765 if (target)
5766 return target;
5767 break;
5769 CASE_INT_FN (BUILT_IN_PARITY):
5770 case BUILT_IN_PARITYIMAX:
5771 target = expand_builtin_unop (target_mode, arglist, target,
5772 subtarget, parity_optab);
5773 if (target)
5774 return target;
5775 break;
5777 case BUILT_IN_STRLEN:
5778 target = expand_builtin_strlen (arglist, target, target_mode);
5779 if (target)
5780 return target;
5781 break;
5783 case BUILT_IN_STRCPY:
5784 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5785 if (target)
5786 return target;
5787 break;
5789 case BUILT_IN_STRNCPY:
5790 target = expand_builtin_strncpy (exp, target, mode);
5791 if (target)
5792 return target;
5793 break;
5795 case BUILT_IN_STPCPY:
5796 target = expand_builtin_stpcpy (exp, target, mode);
5797 if (target)
5798 return target;
5799 break;
5801 case BUILT_IN_STRCAT:
5802 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5803 if (target)
5804 return target;
5805 break;
5807 case BUILT_IN_STRNCAT:
5808 target = expand_builtin_strncat (arglist, target, mode);
5809 if (target)
5810 return target;
5811 break;
5813 case BUILT_IN_STRSPN:
5814 target = expand_builtin_strspn (arglist, target, mode);
5815 if (target)
5816 return target;
5817 break;
5819 case BUILT_IN_STRCSPN:
5820 target = expand_builtin_strcspn (arglist, target, mode);
5821 if (target)
5822 return target;
5823 break;
5825 case BUILT_IN_STRSTR:
5826 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5827 if (target)
5828 return target;
5829 break;
5831 case BUILT_IN_STRPBRK:
5832 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5833 if (target)
5834 return target;
5835 break;
5837 case BUILT_IN_INDEX:
5838 case BUILT_IN_STRCHR:
5839 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5840 if (target)
5841 return target;
5842 break;
5844 case BUILT_IN_RINDEX:
5845 case BUILT_IN_STRRCHR:
5846 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5847 if (target)
5848 return target;
5849 break;
5851 case BUILT_IN_MEMCPY:
5852 target = expand_builtin_memcpy (exp, target, mode);
5853 if (target)
5854 return target;
5855 break;
5857 case BUILT_IN_MEMPCPY:
5858 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5859 if (target)
5860 return target;
5861 break;
5863 case BUILT_IN_MEMMOVE:
5864 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5865 mode, exp);
5866 if (target)
5867 return target;
5868 break;
5870 case BUILT_IN_BCOPY:
5871 target = expand_builtin_bcopy (exp);
5872 if (target)
5873 return target;
5874 break;
5876 case BUILT_IN_MEMSET:
5877 target = expand_builtin_memset (arglist, target, mode, exp);
5878 if (target)
5879 return target;
5880 break;
5882 case BUILT_IN_BZERO:
5883 target = expand_builtin_bzero (exp);
5884 if (target)
5885 return target;
5886 break;
5888 case BUILT_IN_STRCMP:
5889 target = expand_builtin_strcmp (exp, target, mode);
5890 if (target)
5891 return target;
5892 break;
5894 case BUILT_IN_STRNCMP:
5895 target = expand_builtin_strncmp (exp, target, mode);
5896 if (target)
5897 return target;
5898 break;
5900 case BUILT_IN_BCMP:
5901 case BUILT_IN_MEMCMP:
5902 target = expand_builtin_memcmp (exp, arglist, target, mode);
5903 if (target)
5904 return target;
5905 break;
5907 case BUILT_IN_SETJMP:
5908 target = expand_builtin_setjmp (arglist, target);
5909 if (target)
5910 return target;
5911 break;
5913 /* __builtin_longjmp is passed a pointer to an array of five words.
5914 It's similar to the C library longjmp function but works with
5915 __builtin_setjmp above. */
5916 case BUILT_IN_LONGJMP:
5917 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5918 break;
5919 else
5921 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5922 VOIDmode, 0);
5923 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5924 NULL_RTX, VOIDmode, 0);
5926 if (value != const1_rtx)
5928 error ("%<__builtin_longjmp%> second argument must be 1");
5929 return const0_rtx;
5932 expand_builtin_longjmp (buf_addr, value);
5933 return const0_rtx;
5936 case BUILT_IN_NONLOCAL_GOTO:
5937 target = expand_builtin_nonlocal_goto (arglist);
5938 if (target)
5939 return target;
5940 break;
5942 /* This updates the setjmp buffer that is its argument with the value
5943 of the current stack pointer. */
5944 case BUILT_IN_UPDATE_SETJMP_BUF:
5945 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5947 rtx buf_addr
5948 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5950 expand_builtin_update_setjmp_buf (buf_addr);
5951 return const0_rtx;
5953 break;
5955 case BUILT_IN_TRAP:
5956 expand_builtin_trap ();
5957 return const0_rtx;
5959 case BUILT_IN_PRINTF:
5960 target = expand_builtin_printf (exp, target, mode, false);
5961 if (target)
5962 return target;
5963 break;
5965 case BUILT_IN_PRINTF_UNLOCKED:
5966 target = expand_builtin_printf (exp, target, mode, true);
5967 if (target)
5968 return target;
5969 break;
5971 case BUILT_IN_FPUTS:
5972 target = expand_builtin_fputs (arglist, target, false);
5973 if (target)
5974 return target;
5975 break;
5976 case BUILT_IN_FPUTS_UNLOCKED:
5977 target = expand_builtin_fputs (arglist, target, true);
5978 if (target)
5979 return target;
5980 break;
5982 case BUILT_IN_FPRINTF:
5983 target = expand_builtin_fprintf (exp, target, mode, false);
5984 if (target)
5985 return target;
5986 break;
5988 case BUILT_IN_FPRINTF_UNLOCKED:
5989 target = expand_builtin_fprintf (exp, target, mode, true);
5990 if (target)
5991 return target;
5992 break;
5994 case BUILT_IN_SPRINTF:
5995 target = expand_builtin_sprintf (arglist, target, mode);
5996 if (target)
5997 return target;
5998 break;
6000 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6001 target = expand_builtin_signbit (exp, target);
6002 if (target)
6003 return target;
6004 break;
6006 /* Various hooks for the DWARF 2 __throw routine. */
6007 case BUILT_IN_UNWIND_INIT:
6008 expand_builtin_unwind_init ();
6009 return const0_rtx;
6010 case BUILT_IN_DWARF_CFA:
6011 return virtual_cfa_rtx;
6012 #ifdef DWARF2_UNWIND_INFO
6013 case BUILT_IN_DWARF_SP_COLUMN:
6014 return expand_builtin_dwarf_sp_column ();
6015 case BUILT_IN_INIT_DWARF_REG_SIZES:
6016 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6017 return const0_rtx;
6018 #endif
6019 case BUILT_IN_FROB_RETURN_ADDR:
6020 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6021 case BUILT_IN_EXTRACT_RETURN_ADDR:
6022 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6023 case BUILT_IN_EH_RETURN:
6024 expand_builtin_eh_return (TREE_VALUE (arglist),
6025 TREE_VALUE (TREE_CHAIN (arglist)));
6026 return const0_rtx;
6027 #ifdef EH_RETURN_DATA_REGNO
6028 case BUILT_IN_EH_RETURN_DATA_REGNO:
6029 return expand_builtin_eh_return_data_regno (arglist);
6030 #endif
6031 case BUILT_IN_EXTEND_POINTER:
6032 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6034 case BUILT_IN_VA_START:
6035 case BUILT_IN_STDARG_START:
6036 return expand_builtin_va_start (arglist);
6037 case BUILT_IN_VA_END:
6038 return expand_builtin_va_end (arglist);
6039 case BUILT_IN_VA_COPY:
6040 return expand_builtin_va_copy (arglist);
6041 case BUILT_IN_EXPECT:
6042 return expand_builtin_expect (arglist, target);
6043 case BUILT_IN_PREFETCH:
6044 expand_builtin_prefetch (arglist);
6045 return const0_rtx;
6047 case BUILT_IN_PROFILE_FUNC_ENTER:
6048 return expand_builtin_profile_func (false);
6049 case BUILT_IN_PROFILE_FUNC_EXIT:
6050 return expand_builtin_profile_func (true);
6052 case BUILT_IN_INIT_TRAMPOLINE:
6053 return expand_builtin_init_trampoline (arglist);
6054 case BUILT_IN_ADJUST_TRAMPOLINE:
6055 return expand_builtin_adjust_trampoline (arglist);
6057 case BUILT_IN_FORK:
6058 case BUILT_IN_EXECL:
6059 case BUILT_IN_EXECV:
6060 case BUILT_IN_EXECLP:
6061 case BUILT_IN_EXECLE:
6062 case BUILT_IN_EXECVP:
6063 case BUILT_IN_EXECVE:
6064 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6065 if (target)
6066 return target;
6067 break;
6069 case BUILT_IN_FETCH_AND_ADD_1:
6070 case BUILT_IN_FETCH_AND_ADD_2:
6071 case BUILT_IN_FETCH_AND_ADD_4:
6072 case BUILT_IN_FETCH_AND_ADD_8:
6073 case BUILT_IN_FETCH_AND_ADD_16:
6074 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6075 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6076 false, target, ignore);
6077 if (target)
6078 return target;
6079 break;
6081 case BUILT_IN_FETCH_AND_SUB_1:
6082 case BUILT_IN_FETCH_AND_SUB_2:
6083 case BUILT_IN_FETCH_AND_SUB_4:
6084 case BUILT_IN_FETCH_AND_SUB_8:
6085 case BUILT_IN_FETCH_AND_SUB_16:
6086 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6087 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6088 false, target, ignore);
6089 if (target)
6090 return target;
6091 break;
6093 case BUILT_IN_FETCH_AND_OR_1:
6094 case BUILT_IN_FETCH_AND_OR_2:
6095 case BUILT_IN_FETCH_AND_OR_4:
6096 case BUILT_IN_FETCH_AND_OR_8:
6097 case BUILT_IN_FETCH_AND_OR_16:
6098 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6099 target = expand_builtin_sync_operation (mode, arglist, IOR,
6100 false, target, ignore);
6101 if (target)
6102 return target;
6103 break;
6105 case BUILT_IN_FETCH_AND_AND_1:
6106 case BUILT_IN_FETCH_AND_AND_2:
6107 case BUILT_IN_FETCH_AND_AND_4:
6108 case BUILT_IN_FETCH_AND_AND_8:
6109 case BUILT_IN_FETCH_AND_AND_16:
6110 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6111 target = expand_builtin_sync_operation (mode, arglist, AND,
6112 false, target, ignore);
6113 if (target)
6114 return target;
6115 break;
6117 case BUILT_IN_FETCH_AND_XOR_1:
6118 case BUILT_IN_FETCH_AND_XOR_2:
6119 case BUILT_IN_FETCH_AND_XOR_4:
6120 case BUILT_IN_FETCH_AND_XOR_8:
6121 case BUILT_IN_FETCH_AND_XOR_16:
6122 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6123 target = expand_builtin_sync_operation (mode, arglist, XOR,
6124 false, target, ignore);
6125 if (target)
6126 return target;
6127 break;
6129 case BUILT_IN_FETCH_AND_NAND_1:
6130 case BUILT_IN_FETCH_AND_NAND_2:
6131 case BUILT_IN_FETCH_AND_NAND_4:
6132 case BUILT_IN_FETCH_AND_NAND_8:
6133 case BUILT_IN_FETCH_AND_NAND_16:
6134 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6135 target = expand_builtin_sync_operation (mode, arglist, NOT,
6136 false, target, ignore);
6137 if (target)
6138 return target;
6139 break;
6141 case BUILT_IN_ADD_AND_FETCH_1:
6142 case BUILT_IN_ADD_AND_FETCH_2:
6143 case BUILT_IN_ADD_AND_FETCH_4:
6144 case BUILT_IN_ADD_AND_FETCH_8:
6145 case BUILT_IN_ADD_AND_FETCH_16:
6146 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6147 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6148 true, target, ignore);
6149 if (target)
6150 return target;
6151 break;
6153 case BUILT_IN_SUB_AND_FETCH_1:
6154 case BUILT_IN_SUB_AND_FETCH_2:
6155 case BUILT_IN_SUB_AND_FETCH_4:
6156 case BUILT_IN_SUB_AND_FETCH_8:
6157 case BUILT_IN_SUB_AND_FETCH_16:
6158 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6159 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6160 true, target, ignore);
6161 if (target)
6162 return target;
6163 break;
6165 case BUILT_IN_OR_AND_FETCH_1:
6166 case BUILT_IN_OR_AND_FETCH_2:
6167 case BUILT_IN_OR_AND_FETCH_4:
6168 case BUILT_IN_OR_AND_FETCH_8:
6169 case BUILT_IN_OR_AND_FETCH_16:
6170 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6171 target = expand_builtin_sync_operation (mode, arglist, IOR,
6172 true, target, ignore);
6173 if (target)
6174 return target;
6175 break;
6177 case BUILT_IN_AND_AND_FETCH_1:
6178 case BUILT_IN_AND_AND_FETCH_2:
6179 case BUILT_IN_AND_AND_FETCH_4:
6180 case BUILT_IN_AND_AND_FETCH_8:
6181 case BUILT_IN_AND_AND_FETCH_16:
6182 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6183 target = expand_builtin_sync_operation (mode, arglist, AND,
6184 true, target, ignore);
6185 if (target)
6186 return target;
6187 break;
6189 case BUILT_IN_XOR_AND_FETCH_1:
6190 case BUILT_IN_XOR_AND_FETCH_2:
6191 case BUILT_IN_XOR_AND_FETCH_4:
6192 case BUILT_IN_XOR_AND_FETCH_8:
6193 case BUILT_IN_XOR_AND_FETCH_16:
6194 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6195 target = expand_builtin_sync_operation (mode, arglist, XOR,
6196 true, target, ignore);
6197 if (target)
6198 return target;
6199 break;
6201 case BUILT_IN_NAND_AND_FETCH_1:
6202 case BUILT_IN_NAND_AND_FETCH_2:
6203 case BUILT_IN_NAND_AND_FETCH_4:
6204 case BUILT_IN_NAND_AND_FETCH_8:
6205 case BUILT_IN_NAND_AND_FETCH_16:
6206 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6207 target = expand_builtin_sync_operation (mode, arglist, NOT,
6208 true, target, ignore);
6209 if (target)
6210 return target;
6211 break;
6213 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6214 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6215 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6216 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6217 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6218 if (mode == VOIDmode)
6219 mode = TYPE_MODE (boolean_type_node);
6220 if (!target || !register_operand (target, mode))
6221 target = gen_reg_rtx (mode);
6223 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6224 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6225 if (target)
6226 return target;
6227 break;
6229 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6230 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6231 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6232 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6233 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6234 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6235 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6236 if (target)
6237 return target;
6238 break;
6240 case BUILT_IN_LOCK_TEST_AND_SET_1:
6241 case BUILT_IN_LOCK_TEST_AND_SET_2:
6242 case BUILT_IN_LOCK_TEST_AND_SET_4:
6243 case BUILT_IN_LOCK_TEST_AND_SET_8:
6244 case BUILT_IN_LOCK_TEST_AND_SET_16:
6245 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6246 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6247 if (target)
6248 return target;
6249 break;
6251 case BUILT_IN_LOCK_RELEASE_1:
6252 case BUILT_IN_LOCK_RELEASE_2:
6253 case BUILT_IN_LOCK_RELEASE_4:
6254 case BUILT_IN_LOCK_RELEASE_8:
6255 case BUILT_IN_LOCK_RELEASE_16:
6256 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6257 expand_builtin_lock_release (mode, arglist);
6258 return const0_rtx;
6260 case BUILT_IN_SYNCHRONIZE:
6261 expand_builtin_synchronize ();
6262 return const0_rtx;
6264 case BUILT_IN_OBJECT_SIZE:
6265 return expand_builtin_object_size (exp);
6267 case BUILT_IN_MEMCPY_CHK:
6268 case BUILT_IN_MEMPCPY_CHK:
6269 case BUILT_IN_MEMMOVE_CHK:
6270 case BUILT_IN_MEMSET_CHK:
6271 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6272 if (target)
6273 return target;
6274 break;
6276 case BUILT_IN_STRCPY_CHK:
6277 case BUILT_IN_STPCPY_CHK:
6278 case BUILT_IN_STRNCPY_CHK:
6279 case BUILT_IN_STRCAT_CHK:
6280 case BUILT_IN_SNPRINTF_CHK:
6281 case BUILT_IN_VSNPRINTF_CHK:
6282 maybe_emit_chk_warning (exp, fcode);
6283 break;
6285 case BUILT_IN_SPRINTF_CHK:
6286 case BUILT_IN_VSPRINTF_CHK:
6287 maybe_emit_sprintf_chk_warning (exp, fcode);
6288 break;
6290 default: /* just do library call, if unknown builtin */
6291 break;
6294 /* The switch statement above can drop through to cause the function
6295 to be called normally. */
6296 return expand_call (exp, target, ignore);
6299 /* Determine whether a tree node represents a call to a built-in
6300 function. If the tree T is a call to a built-in function with
6301 the right number of arguments of the appropriate types, return
6302 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6303 Otherwise the return value is END_BUILTINS. */
6305 enum built_in_function
6306 builtin_mathfn_code (tree t)
6308 tree fndecl, arglist, parmlist;
6309 tree argtype, parmtype;
6311 if (TREE_CODE (t) != CALL_EXPR
6312 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6313 return END_BUILTINS;
6315 fndecl = get_callee_fndecl (t);
6316 if (fndecl == NULL_TREE
6317 || TREE_CODE (fndecl) != FUNCTION_DECL
6318 || ! DECL_BUILT_IN (fndecl)
6319 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6320 return END_BUILTINS;
6322 arglist = TREE_OPERAND (t, 1);
6323 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6324 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6326 /* If a function doesn't take a variable number of arguments,
6327 the last element in the list will have type `void'. */
6328 parmtype = TREE_VALUE (parmlist);
6329 if (VOID_TYPE_P (parmtype))
6331 if (arglist)
6332 return END_BUILTINS;
6333 return DECL_FUNCTION_CODE (fndecl);
6336 if (! arglist)
6337 return END_BUILTINS;
6339 argtype = TREE_TYPE (TREE_VALUE (arglist));
6341 if (SCALAR_FLOAT_TYPE_P (parmtype))
6343 if (! SCALAR_FLOAT_TYPE_P (argtype))
6344 return END_BUILTINS;
6346 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6348 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6349 return END_BUILTINS;
6351 else if (POINTER_TYPE_P (parmtype))
6353 if (! POINTER_TYPE_P (argtype))
6354 return END_BUILTINS;
6356 else if (INTEGRAL_TYPE_P (parmtype))
6358 if (! INTEGRAL_TYPE_P (argtype))
6359 return END_BUILTINS;
6361 else
6362 return END_BUILTINS;
6364 arglist = TREE_CHAIN (arglist);
6367 /* Variable-length argument list. */
6368 return DECL_FUNCTION_CODE (fndecl);
6371 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6372 constant. ARGLIST is the argument list of the call. */
6374 static tree
6375 fold_builtin_constant_p (tree arglist)
6377 if (arglist == 0)
6378 return 0;
6380 arglist = TREE_VALUE (arglist);
6382 /* We return 1 for a numeric type that's known to be a constant
6383 value at compile-time or for an aggregate type that's a
6384 literal constant. */
6385 STRIP_NOPS (arglist);
6387 /* If we know this is a constant, emit the constant of one. */
6388 if (CONSTANT_CLASS_P (arglist)
6389 || (TREE_CODE (arglist) == CONSTRUCTOR
6390 && TREE_CONSTANT (arglist)))
6391 return integer_one_node;
6392 if (TREE_CODE (arglist) == ADDR_EXPR)
6394 tree op = TREE_OPERAND (arglist, 0);
6395 if (TREE_CODE (op) == STRING_CST
6396 || (TREE_CODE (op) == ARRAY_REF
6397 && integer_zerop (TREE_OPERAND (op, 1))
6398 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6399 return integer_one_node;
6402 /* If this expression has side effects, show we don't know it to be a
6403 constant. Likewise if it's a pointer or aggregate type since in
6404 those case we only want literals, since those are only optimized
6405 when generating RTL, not later.
6406 And finally, if we are compiling an initializer, not code, we
6407 need to return a definite result now; there's not going to be any
6408 more optimization done. */
6409 if (TREE_SIDE_EFFECTS (arglist)
6410 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6411 || POINTER_TYPE_P (TREE_TYPE (arglist))
6412 || cfun == 0)
6413 return integer_zero_node;
6415 return 0;
6418 /* Fold a call to __builtin_expect, if we expect that a comparison against
6419 the argument will fold to a constant. In practice, this means a true
6420 constant or the address of a non-weak symbol. ARGLIST is the argument
6421 list of the call. */
6423 static tree
6424 fold_builtin_expect (tree arglist)
6426 tree arg, inner;
6428 if (arglist == 0)
6429 return 0;
6431 arg = TREE_VALUE (arglist);
6433 /* If the argument isn't invariant, then there's nothing we can do. */
6434 if (!TREE_INVARIANT (arg))
6435 return 0;
6437 /* If we're looking at an address of a weak decl, then do not fold. */
6438 inner = arg;
6439 STRIP_NOPS (inner);
6440 if (TREE_CODE (inner) == ADDR_EXPR)
6444 inner = TREE_OPERAND (inner, 0);
6446 while (TREE_CODE (inner) == COMPONENT_REF
6447 || TREE_CODE (inner) == ARRAY_REF);
6448 if (DECL_P (inner) && DECL_WEAK (inner))
6449 return 0;
6452 /* Otherwise, ARG already has the proper type for the return value. */
6453 return arg;
6456 /* Fold a call to __builtin_classify_type. */
6458 static tree
6459 fold_builtin_classify_type (tree arglist)
6461 if (arglist == 0)
6462 return build_int_cst (NULL_TREE, no_type_class);
6464 return build_int_cst (NULL_TREE,
6465 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6468 /* Fold a call to __builtin_strlen. */
6470 static tree
6471 fold_builtin_strlen (tree arglist)
6473 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6474 return NULL_TREE;
6475 else
6477 tree len = c_strlen (TREE_VALUE (arglist), 0);
6479 if (len)
6481 /* Convert from the internal "sizetype" type to "size_t". */
6482 if (size_type_node)
6483 len = fold_convert (size_type_node, len);
6484 return len;
6487 return NULL_TREE;
6491 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6493 static tree
6494 fold_builtin_inf (tree type, int warn)
6496 REAL_VALUE_TYPE real;
6498 /* __builtin_inff is intended to be usable to define INFINITY on all
6499 targets. If an infinity is not available, INFINITY expands "to a
6500 positive constant of type float that overflows at translation
6501 time", footnote "In this case, using INFINITY will violate the
6502 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6503 Thus we pedwarn to ensure this constraint violation is
6504 diagnosed. */
6505 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6506 pedwarn ("target format does not support infinity");
6508 real_inf (&real);
6509 return build_real (type, real);
6512 /* Fold a call to __builtin_nan or __builtin_nans. */
6514 static tree
6515 fold_builtin_nan (tree arglist, tree type, int quiet)
6517 REAL_VALUE_TYPE real;
6518 const char *str;
6520 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6521 return 0;
6522 str = c_getstr (TREE_VALUE (arglist));
6523 if (!str)
6524 return 0;
6526 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6527 return 0;
6529 return build_real (type, real);
6532 /* Return true if the floating point expression T has an integer value.
6533 We also allow +Inf, -Inf and NaN to be considered integer values. */
6535 static bool
6536 integer_valued_real_p (tree t)
6538 switch (TREE_CODE (t))
6540 case FLOAT_EXPR:
6541 return true;
6543 case ABS_EXPR:
6544 case SAVE_EXPR:
6545 case NON_LVALUE_EXPR:
6546 return integer_valued_real_p (TREE_OPERAND (t, 0));
6548 case COMPOUND_EXPR:
6549 case MODIFY_EXPR:
6550 case BIND_EXPR:
6551 return integer_valued_real_p (TREE_OPERAND (t, 1));
6553 case PLUS_EXPR:
6554 case MINUS_EXPR:
6555 case MULT_EXPR:
6556 case MIN_EXPR:
6557 case MAX_EXPR:
6558 return integer_valued_real_p (TREE_OPERAND (t, 0))
6559 && integer_valued_real_p (TREE_OPERAND (t, 1));
6561 case COND_EXPR:
6562 return integer_valued_real_p (TREE_OPERAND (t, 1))
6563 && integer_valued_real_p (TREE_OPERAND (t, 2));
6565 case REAL_CST:
6566 if (! TREE_CONSTANT_OVERFLOW (t))
6568 REAL_VALUE_TYPE c, cint;
6570 c = TREE_REAL_CST (t);
6571 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6572 return real_identical (&c, &cint);
6574 break;
6576 case NOP_EXPR:
6578 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6579 if (TREE_CODE (type) == INTEGER_TYPE)
6580 return true;
6581 if (TREE_CODE (type) == REAL_TYPE)
6582 return integer_valued_real_p (TREE_OPERAND (t, 0));
6583 break;
6586 case CALL_EXPR:
6587 switch (builtin_mathfn_code (t))
6589 CASE_FLT_FN (BUILT_IN_CEIL):
6590 CASE_FLT_FN (BUILT_IN_FLOOR):
6591 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6592 CASE_FLT_FN (BUILT_IN_RINT):
6593 CASE_FLT_FN (BUILT_IN_ROUND):
6594 CASE_FLT_FN (BUILT_IN_TRUNC):
6595 return true;
6597 default:
6598 break;
6600 break;
6602 default:
6603 break;
6605 return false;
6608 /* EXP is assumed to be builtin call where truncation can be propagated
6609 across (for instance floor((double)f) == (double)floorf (f).
6610 Do the transformation. */
6612 static tree
6613 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6615 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6616 tree arg;
6618 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6619 return 0;
6621 arg = TREE_VALUE (arglist);
6622 /* Integer rounding functions are idempotent. */
6623 if (fcode == builtin_mathfn_code (arg))
6624 return arg;
6626 /* If argument is already integer valued, and we don't need to worry
6627 about setting errno, there's no need to perform rounding. */
6628 if (! flag_errno_math && integer_valued_real_p (arg))
6629 return arg;
6631 if (optimize)
6633 tree arg0 = strip_float_extensions (arg);
6634 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6635 tree newtype = TREE_TYPE (arg0);
6636 tree decl;
6638 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6639 && (decl = mathfn_built_in (newtype, fcode)))
6641 arglist =
6642 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6643 return fold_convert (ftype,
6644 build_function_call_expr (decl, arglist));
6647 return 0;
6650 /* EXP is assumed to be builtin call which can narrow the FP type of
6651 the argument, for instance lround((double)f) -> lroundf (f). */
6653 static tree
6654 fold_fixed_mathfn (tree fndecl, tree arglist)
6656 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6657 tree arg;
6659 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6660 return 0;
6662 arg = TREE_VALUE (arglist);
6664 /* If argument is already integer valued, and we don't need to worry
6665 about setting errno, there's no need to perform rounding. */
6666 if (! flag_errno_math && integer_valued_real_p (arg))
6667 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6669 if (optimize)
6671 tree ftype = TREE_TYPE (arg);
6672 tree arg0 = strip_float_extensions (arg);
6673 tree newtype = TREE_TYPE (arg0);
6674 tree decl;
6676 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6677 && (decl = mathfn_built_in (newtype, fcode)))
6679 arglist =
6680 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6681 return build_function_call_expr (decl, arglist);
6684 return 0;
6687 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6688 is the argument list and TYPE is the return type. Return
6689 NULL_TREE if no if no simplification can be made. */
6691 static tree
6692 fold_builtin_cabs (tree arglist, tree type)
6694 tree arg;
6696 if (!arglist || TREE_CHAIN (arglist))
6697 return NULL_TREE;
6699 arg = TREE_VALUE (arglist);
6700 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6701 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6702 return NULL_TREE;
6704 /* Evaluate cabs of a constant at compile-time. */
6705 if (flag_unsafe_math_optimizations
6706 && TREE_CODE (arg) == COMPLEX_CST
6707 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6708 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6709 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6710 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6712 REAL_VALUE_TYPE r, i;
6714 r = TREE_REAL_CST (TREE_REALPART (arg));
6715 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6717 real_arithmetic (&r, MULT_EXPR, &r, &r);
6718 real_arithmetic (&i, MULT_EXPR, &i, &i);
6719 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6720 if (real_sqrt (&r, TYPE_MODE (type), &r)
6721 || ! flag_trapping_math)
6722 return build_real (type, r);
6725 /* If either part is zero, cabs is fabs of the other. */
6726 if (TREE_CODE (arg) == COMPLEX_EXPR
6727 && real_zerop (TREE_OPERAND (arg, 0)))
6728 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6729 if (TREE_CODE (arg) == COMPLEX_EXPR
6730 && real_zerop (TREE_OPERAND (arg, 1)))
6731 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6733 /* Don't do this when optimizing for size. */
6734 if (flag_unsafe_math_optimizations
6735 && optimize && !optimize_size)
6737 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6739 if (sqrtfn != NULL_TREE)
6741 tree rpart, ipart, result, arglist;
6743 arg = builtin_save_expr (arg);
6745 rpart = fold_build1 (REALPART_EXPR, type, arg);
6746 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6748 rpart = builtin_save_expr (rpart);
6749 ipart = builtin_save_expr (ipart);
6751 result = fold_build2 (PLUS_EXPR, type,
6752 fold_build2 (MULT_EXPR, type,
6753 rpart, rpart),
6754 fold_build2 (MULT_EXPR, type,
6755 ipart, ipart));
6757 arglist = build_tree_list (NULL_TREE, result);
6758 return build_function_call_expr (sqrtfn, arglist);
6762 return NULL_TREE;
6765 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6766 NULL_TREE if no simplification can be made. */
6768 static tree
6769 fold_builtin_sqrt (tree arglist, tree type)
6772 enum built_in_function fcode;
6773 tree arg = TREE_VALUE (arglist);
6775 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6776 return NULL_TREE;
6778 /* Optimize sqrt of constant value. */
6779 if (TREE_CODE (arg) == REAL_CST
6780 && ! TREE_CONSTANT_OVERFLOW (arg))
6782 REAL_VALUE_TYPE r, x;
6784 x = TREE_REAL_CST (arg);
6785 if (real_sqrt (&r, TYPE_MODE (type), &x)
6786 || (!flag_trapping_math && !flag_errno_math))
6787 return build_real (type, r);
6790 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6791 fcode = builtin_mathfn_code (arg);
6792 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6794 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6795 arg = fold_build2 (MULT_EXPR, type,
6796 TREE_VALUE (TREE_OPERAND (arg, 1)),
6797 build_real (type, dconsthalf));
6798 arglist = build_tree_list (NULL_TREE, arg);
6799 return build_function_call_expr (expfn, arglist);
6802 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6803 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6805 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6807 if (powfn)
6809 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6810 tree tree_root;
6811 /* The inner root was either sqrt or cbrt. */
6812 REAL_VALUE_TYPE dconstroot =
6813 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6815 /* Adjust for the outer root. */
6816 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6817 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6818 tree_root = build_real (type, dconstroot);
6819 arglist = tree_cons (NULL_TREE, arg0,
6820 build_tree_list (NULL_TREE, tree_root));
6821 return build_function_call_expr (powfn, arglist);
6825 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6826 if (flag_unsafe_math_optimizations
6827 && (fcode == BUILT_IN_POW
6828 || fcode == BUILT_IN_POWF
6829 || fcode == BUILT_IN_POWL))
6831 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6832 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6833 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6834 tree narg1;
6835 if (!tree_expr_nonnegative_p (arg0))
6836 arg0 = build1 (ABS_EXPR, type, arg0);
6837 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6838 build_real (type, dconsthalf));
6839 arglist = tree_cons (NULL_TREE, arg0,
6840 build_tree_list (NULL_TREE, narg1));
6841 return build_function_call_expr (powfn, arglist);
6844 return NULL_TREE;
6847 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6848 NULL_TREE if no simplification can be made. */
6849 static tree
6850 fold_builtin_cbrt (tree arglist, tree type)
6852 tree arg = TREE_VALUE (arglist);
6853 const enum built_in_function fcode = builtin_mathfn_code (arg);
6855 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6856 return NULL_TREE;
6858 /* Optimize cbrt of constant value. */
6859 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6860 return arg;
6862 if (flag_unsafe_math_optimizations)
6864 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6865 if (BUILTIN_EXPONENT_P (fcode))
6867 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6868 const REAL_VALUE_TYPE third_trunc =
6869 real_value_truncate (TYPE_MODE (type), dconstthird);
6870 arg = fold_build2 (MULT_EXPR, type,
6871 TREE_VALUE (TREE_OPERAND (arg, 1)),
6872 build_real (type, third_trunc));
6873 arglist = build_tree_list (NULL_TREE, arg);
6874 return build_function_call_expr (expfn, arglist);
6877 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6878 if (BUILTIN_SQRT_P (fcode))
6880 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6882 if (powfn)
6884 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6885 tree tree_root;
6886 REAL_VALUE_TYPE dconstroot = dconstthird;
6888 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6889 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6890 tree_root = build_real (type, dconstroot);
6891 arglist = tree_cons (NULL_TREE, arg0,
6892 build_tree_list (NULL_TREE, tree_root));
6893 return build_function_call_expr (powfn, arglist);
6897 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6898 if (BUILTIN_CBRT_P (fcode))
6900 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6901 if (tree_expr_nonnegative_p (arg0))
6903 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6905 if (powfn)
6907 tree tree_root;
6908 REAL_VALUE_TYPE dconstroot;
6910 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6911 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6912 tree_root = build_real (type, dconstroot);
6913 arglist = tree_cons (NULL_TREE, arg0,
6914 build_tree_list (NULL_TREE, tree_root));
6915 return build_function_call_expr (powfn, arglist);
6920 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6921 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6922 || fcode == BUILT_IN_POWL)
6924 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6925 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6926 if (tree_expr_nonnegative_p (arg00))
6928 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6929 const REAL_VALUE_TYPE dconstroot
6930 = real_value_truncate (TYPE_MODE (type), dconstthird);
6931 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6932 build_real (type, dconstroot));
6933 arglist = tree_cons (NULL_TREE, arg00,
6934 build_tree_list (NULL_TREE, narg01));
6935 return build_function_call_expr (powfn, arglist);
6939 return NULL_TREE;
6942 /* Fold function call to builtin sin, sinf, or sinl. Return
6943 NULL_TREE if no simplification can be made. */
6944 static tree
6945 fold_builtin_sin (tree arglist)
6947 tree arg = TREE_VALUE (arglist);
6949 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6950 return NULL_TREE;
6952 /* Optimize sin (0.0) = 0.0. */
6953 if (real_zerop (arg))
6954 return arg;
6956 return NULL_TREE;
6959 /* Fold function call to builtin cos, cosf, or cosl. Return
6960 NULL_TREE if no simplification can be made. */
6961 static tree
6962 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6964 tree arg = TREE_VALUE (arglist);
6966 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6967 return NULL_TREE;
6969 /* Optimize cos (0.0) = 1.0. */
6970 if (real_zerop (arg))
6971 return build_real (type, dconst1);
6973 /* Optimize cos(-x) into cos (x). */
6974 if (TREE_CODE (arg) == NEGATE_EXPR)
6976 tree args = build_tree_list (NULL_TREE,
6977 TREE_OPERAND (arg, 0));
6978 return build_function_call_expr (fndecl, args);
6981 return NULL_TREE;
6984 /* Fold function call to builtin tan, tanf, or tanl. Return
6985 NULL_TREE if no simplification can be made. */
6986 static tree
6987 fold_builtin_tan (tree arglist)
6989 enum built_in_function fcode;
6990 tree arg = TREE_VALUE (arglist);
6992 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6993 return NULL_TREE;
6995 /* Optimize tan(0.0) = 0.0. */
6996 if (real_zerop (arg))
6997 return arg;
6999 /* Optimize tan(atan(x)) = x. */
7000 fcode = builtin_mathfn_code (arg);
7001 if (flag_unsafe_math_optimizations
7002 && (fcode == BUILT_IN_ATAN
7003 || fcode == BUILT_IN_ATANF
7004 || fcode == BUILT_IN_ATANL))
7005 return TREE_VALUE (TREE_OPERAND (arg, 1));
7007 return NULL_TREE;
7010 /* Fold function call to builtin atan, atanf, or atanl. Return
7011 NULL_TREE if no simplification can be made. */
7013 static tree
7014 fold_builtin_atan (tree arglist, tree type)
7017 tree arg = TREE_VALUE (arglist);
7019 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7020 return NULL_TREE;
7022 /* Optimize atan(0.0) = 0.0. */
7023 if (real_zerop (arg))
7024 return arg;
7026 /* Optimize atan(1.0) = pi/4. */
7027 if (real_onep (arg))
7029 REAL_VALUE_TYPE cst;
7031 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7032 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7033 return build_real (type, cst);
7036 return NULL_TREE;
7039 /* Fold function call to builtin trunc, truncf or truncl. Return
7040 NULL_TREE if no simplification can be made. */
7042 static tree
7043 fold_builtin_trunc (tree fndecl, tree arglist)
7045 tree arg;
7047 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7048 return 0;
7050 /* Optimize trunc of constant value. */
7051 arg = TREE_VALUE (arglist);
7052 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7054 REAL_VALUE_TYPE r, x;
7055 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7057 x = TREE_REAL_CST (arg);
7058 real_trunc (&r, TYPE_MODE (type), &x);
7059 return build_real (type, r);
7062 return fold_trunc_transparent_mathfn (fndecl, arglist);
7065 /* Fold function call to builtin floor, floorf or floorl. Return
7066 NULL_TREE if no simplification can be made. */
7068 static tree
7069 fold_builtin_floor (tree fndecl, tree arglist)
7071 tree arg;
7073 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7074 return 0;
7076 /* Optimize floor of constant value. */
7077 arg = TREE_VALUE (arglist);
7078 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7080 REAL_VALUE_TYPE x;
7082 x = TREE_REAL_CST (arg);
7083 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7085 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7086 REAL_VALUE_TYPE r;
7088 real_floor (&r, TYPE_MODE (type), &x);
7089 return build_real (type, r);
7093 return fold_trunc_transparent_mathfn (fndecl, arglist);
7096 /* Fold function call to builtin ceil, ceilf or ceill. Return
7097 NULL_TREE if no simplification can be made. */
7099 static tree
7100 fold_builtin_ceil (tree fndecl, tree arglist)
7102 tree arg;
7104 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7105 return 0;
7107 /* Optimize ceil of constant value. */
7108 arg = TREE_VALUE (arglist);
7109 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7111 REAL_VALUE_TYPE x;
7113 x = TREE_REAL_CST (arg);
7114 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7116 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7117 REAL_VALUE_TYPE r;
7119 real_ceil (&r, TYPE_MODE (type), &x);
7120 return build_real (type, r);
7124 return fold_trunc_transparent_mathfn (fndecl, arglist);
7127 /* Fold function call to builtin round, roundf or roundl. Return
7128 NULL_TREE if no simplification can be made. */
7130 static tree
7131 fold_builtin_round (tree fndecl, tree arglist)
7133 tree arg;
7135 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7136 return 0;
7138 /* Optimize round of constant value. */
7139 arg = TREE_VALUE (arglist);
7140 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7142 REAL_VALUE_TYPE x;
7144 x = TREE_REAL_CST (arg);
7145 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7147 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7148 REAL_VALUE_TYPE r;
7150 real_round (&r, TYPE_MODE (type), &x);
7151 return build_real (type, r);
7155 return fold_trunc_transparent_mathfn (fndecl, arglist);
7158 /* Fold function call to builtin lround, lroundf or lroundl (or the
7159 corresponding long long versions) and other rounding functions.
7160 Return NULL_TREE if no simplification can be made. */
7162 static tree
7163 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7165 tree arg;
7167 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7168 return 0;
7170 /* Optimize lround of constant value. */
7171 arg = TREE_VALUE (arglist);
7172 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7174 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7176 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7178 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7179 tree ftype = TREE_TYPE (arg), result;
7180 HOST_WIDE_INT hi, lo;
7181 REAL_VALUE_TYPE r;
7183 switch (DECL_FUNCTION_CODE (fndecl))
7185 CASE_FLT_FN (BUILT_IN_LFLOOR):
7186 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7187 real_floor (&r, TYPE_MODE (ftype), &x);
7188 break;
7190 CASE_FLT_FN (BUILT_IN_LCEIL):
7191 CASE_FLT_FN (BUILT_IN_LLCEIL):
7192 real_ceil (&r, TYPE_MODE (ftype), &x);
7193 break;
7195 CASE_FLT_FN (BUILT_IN_LROUND):
7196 CASE_FLT_FN (BUILT_IN_LLROUND):
7197 real_round (&r, TYPE_MODE (ftype), &x);
7198 break;
7200 default:
7201 gcc_unreachable ();
7204 REAL_VALUE_TO_INT (&lo, &hi, r);
7205 result = build_int_cst_wide (NULL_TREE, lo, hi);
7206 if (int_fits_type_p (result, itype))
7207 return fold_convert (itype, result);
7211 return fold_fixed_mathfn (fndecl, arglist);
7214 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7215 and their long and long long variants (i.e. ffsl and ffsll).
7216 Return NULL_TREE if no simplification can be made. */
7218 static tree
7219 fold_builtin_bitop (tree fndecl, tree arglist)
7221 tree arg;
7223 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7224 return NULL_TREE;
7226 /* Optimize for constant argument. */
7227 arg = TREE_VALUE (arglist);
7228 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7230 HOST_WIDE_INT hi, width, result;
7231 unsigned HOST_WIDE_INT lo;
7232 tree type;
7234 type = TREE_TYPE (arg);
7235 width = TYPE_PRECISION (type);
7236 lo = TREE_INT_CST_LOW (arg);
7238 /* Clear all the bits that are beyond the type's precision. */
7239 if (width > HOST_BITS_PER_WIDE_INT)
7241 hi = TREE_INT_CST_HIGH (arg);
7242 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7243 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7245 else
7247 hi = 0;
7248 if (width < HOST_BITS_PER_WIDE_INT)
7249 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7252 switch (DECL_FUNCTION_CODE (fndecl))
7254 CASE_INT_FN (BUILT_IN_FFS):
7255 if (lo != 0)
7256 result = exact_log2 (lo & -lo) + 1;
7257 else if (hi != 0)
7258 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7259 else
7260 result = 0;
7261 break;
7263 CASE_INT_FN (BUILT_IN_CLZ):
7264 if (hi != 0)
7265 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7266 else if (lo != 0)
7267 result = width - floor_log2 (lo) - 1;
7268 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7269 result = width;
7270 break;
7272 CASE_INT_FN (BUILT_IN_CTZ):
7273 if (lo != 0)
7274 result = exact_log2 (lo & -lo);
7275 else if (hi != 0)
7276 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7277 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7278 result = width;
7279 break;
7281 CASE_INT_FN (BUILT_IN_POPCOUNT):
7282 result = 0;
7283 while (lo)
7284 result++, lo &= lo - 1;
7285 while (hi)
7286 result++, hi &= hi - 1;
7287 break;
7289 CASE_INT_FN (BUILT_IN_PARITY):
7290 result = 0;
7291 while (lo)
7292 result++, lo &= lo - 1;
7293 while (hi)
7294 result++, hi &= hi - 1;
7295 result &= 1;
7296 break;
7298 default:
7299 gcc_unreachable ();
7302 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7305 return NULL_TREE;
7308 /* Return true if EXPR is the real constant contained in VALUE. */
7310 static bool
7311 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7313 STRIP_NOPS (expr);
7315 return ((TREE_CODE (expr) == REAL_CST
7316 && ! TREE_CONSTANT_OVERFLOW (expr)
7317 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7318 || (TREE_CODE (expr) == COMPLEX_CST
7319 && real_dconstp (TREE_REALPART (expr), value)
7320 && real_zerop (TREE_IMAGPART (expr))));
7323 /* A subroutine of fold_builtin to fold the various logarithmic
7324 functions. EXP is the CALL_EXPR of a call to a builtin logN
7325 function. VALUE is the base of the logN function. */
7327 static tree
7328 fold_builtin_logarithm (tree fndecl, tree arglist,
7329 const REAL_VALUE_TYPE *value)
7331 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7333 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7334 tree arg = TREE_VALUE (arglist);
7335 const enum built_in_function fcode = builtin_mathfn_code (arg);
7337 /* Optimize logN(1.0) = 0.0. */
7338 if (real_onep (arg))
7339 return build_real (type, dconst0);
7341 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7342 exactly, then only do this if flag_unsafe_math_optimizations. */
7343 if (exact_real_truncate (TYPE_MODE (type), value)
7344 || flag_unsafe_math_optimizations)
7346 const REAL_VALUE_TYPE value_truncate =
7347 real_value_truncate (TYPE_MODE (type), *value);
7348 if (real_dconstp (arg, &value_truncate))
7349 return build_real (type, dconst1);
7352 /* Special case, optimize logN(expN(x)) = x. */
7353 if (flag_unsafe_math_optimizations
7354 && ((value == &dconste
7355 && (fcode == BUILT_IN_EXP
7356 || fcode == BUILT_IN_EXPF
7357 || fcode == BUILT_IN_EXPL))
7358 || (value == &dconst2
7359 && (fcode == BUILT_IN_EXP2
7360 || fcode == BUILT_IN_EXP2F
7361 || fcode == BUILT_IN_EXP2L))
7362 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7363 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7365 /* Optimize logN(func()) for various exponential functions. We
7366 want to determine the value "x" and the power "exponent" in
7367 order to transform logN(x**exponent) into exponent*logN(x). */
7368 if (flag_unsafe_math_optimizations)
7370 tree exponent = 0, x = 0;
7372 switch (fcode)
7374 CASE_FLT_FN (BUILT_IN_EXP):
7375 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7376 x = build_real (type,
7377 real_value_truncate (TYPE_MODE (type), dconste));
7378 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7379 break;
7380 CASE_FLT_FN (BUILT_IN_EXP2):
7381 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7382 x = build_real (type, dconst2);
7383 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7384 break;
7385 CASE_FLT_FN (BUILT_IN_EXP10):
7386 CASE_FLT_FN (BUILT_IN_POW10):
7387 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7388 x = build_real (type, dconst10);
7389 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7390 break;
7391 CASE_FLT_FN (BUILT_IN_SQRT):
7392 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7393 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7394 exponent = build_real (type, dconsthalf);
7395 break;
7396 CASE_FLT_FN (BUILT_IN_CBRT):
7397 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7398 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7399 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7400 dconstthird));
7401 break;
7402 CASE_FLT_FN (BUILT_IN_POW):
7403 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7404 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7405 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7406 break;
7407 default:
7408 break;
7411 /* Now perform the optimization. */
7412 if (x && exponent)
7414 tree logfn;
7415 arglist = build_tree_list (NULL_TREE, x);
7416 logfn = build_function_call_expr (fndecl, arglist);
7417 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7422 return 0;
7425 /* Fold a builtin function call to pow, powf, or powl. Return
7426 NULL_TREE if no simplification can be made. */
7427 static tree
7428 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7430 tree arg0 = TREE_VALUE (arglist);
7431 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7433 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7434 return NULL_TREE;
7436 /* Optimize pow(1.0,y) = 1.0. */
7437 if (real_onep (arg0))
7438 return omit_one_operand (type, build_real (type, dconst1), arg1);
7440 if (TREE_CODE (arg1) == REAL_CST
7441 && ! TREE_CONSTANT_OVERFLOW (arg1))
7443 REAL_VALUE_TYPE cint;
7444 REAL_VALUE_TYPE c;
7445 HOST_WIDE_INT n;
7447 c = TREE_REAL_CST (arg1);
7449 /* Optimize pow(x,0.0) = 1.0. */
7450 if (REAL_VALUES_EQUAL (c, dconst0))
7451 return omit_one_operand (type, build_real (type, dconst1),
7452 arg0);
7454 /* Optimize pow(x,1.0) = x. */
7455 if (REAL_VALUES_EQUAL (c, dconst1))
7456 return arg0;
7458 /* Optimize pow(x,-1.0) = 1.0/x. */
7459 if (REAL_VALUES_EQUAL (c, dconstm1))
7460 return fold_build2 (RDIV_EXPR, type,
7461 build_real (type, dconst1), arg0);
7463 /* Optimize pow(x,0.5) = sqrt(x). */
7464 if (flag_unsafe_math_optimizations
7465 && REAL_VALUES_EQUAL (c, dconsthalf))
7467 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7469 if (sqrtfn != NULL_TREE)
7471 tree arglist = build_tree_list (NULL_TREE, arg0);
7472 return build_function_call_expr (sqrtfn, arglist);
7476 /* Check for an integer exponent. */
7477 n = real_to_integer (&c);
7478 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7479 if (real_identical (&c, &cint))
7481 /* Attempt to evaluate pow at compile-time. */
7482 if (TREE_CODE (arg0) == REAL_CST
7483 && ! TREE_CONSTANT_OVERFLOW (arg0))
7485 REAL_VALUE_TYPE x;
7486 bool inexact;
7488 x = TREE_REAL_CST (arg0);
7489 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7490 if (flag_unsafe_math_optimizations || !inexact)
7491 return build_real (type, x);
7494 /* Strip sign ops from even integer powers. */
7495 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7497 tree narg0 = fold_strip_sign_ops (arg0);
7498 if (narg0)
7500 arglist = build_tree_list (NULL_TREE, arg1);
7501 arglist = tree_cons (NULL_TREE, narg0, arglist);
7502 return build_function_call_expr (fndecl, arglist);
7508 if (flag_unsafe_math_optimizations)
7510 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7512 /* Optimize pow(expN(x),y) = expN(x*y). */
7513 if (BUILTIN_EXPONENT_P (fcode))
7515 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7516 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7517 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7518 arglist = build_tree_list (NULL_TREE, arg);
7519 return build_function_call_expr (expfn, arglist);
7522 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7523 if (BUILTIN_SQRT_P (fcode))
7525 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7526 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7527 build_real (type, dconsthalf));
7529 arglist = tree_cons (NULL_TREE, narg0,
7530 build_tree_list (NULL_TREE, narg1));
7531 return build_function_call_expr (fndecl, arglist);
7534 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7535 if (BUILTIN_CBRT_P (fcode))
7537 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7538 if (tree_expr_nonnegative_p (arg))
7540 const REAL_VALUE_TYPE dconstroot
7541 = real_value_truncate (TYPE_MODE (type), dconstthird);
7542 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7543 build_real (type, dconstroot));
7544 arglist = tree_cons (NULL_TREE, arg,
7545 build_tree_list (NULL_TREE, narg1));
7546 return build_function_call_expr (fndecl, arglist);
7550 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7551 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7552 || fcode == BUILT_IN_POWL)
7554 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7555 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7556 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7557 arglist = tree_cons (NULL_TREE, arg00,
7558 build_tree_list (NULL_TREE, narg1));
7559 return build_function_call_expr (fndecl, arglist);
7563 return NULL_TREE;
7566 /* Fold a builtin function call to powi, powif, or powil. Return
7567 NULL_TREE if no simplification can be made. */
7568 static tree
7569 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7571 tree arg0 = TREE_VALUE (arglist);
7572 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7574 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7575 return NULL_TREE;
7577 /* Optimize pow(1.0,y) = 1.0. */
7578 if (real_onep (arg0))
7579 return omit_one_operand (type, build_real (type, dconst1), arg1);
7581 if (host_integerp (arg1, 0))
7583 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7585 /* Evaluate powi at compile-time. */
7586 if (TREE_CODE (arg0) == REAL_CST
7587 && ! TREE_CONSTANT_OVERFLOW (arg0))
7589 REAL_VALUE_TYPE x;
7590 x = TREE_REAL_CST (arg0);
7591 real_powi (&x, TYPE_MODE (type), &x, c);
7592 return build_real (type, x);
7595 /* Optimize pow(x,0) = 1.0. */
7596 if (c == 0)
7597 return omit_one_operand (type, build_real (type, dconst1),
7598 arg0);
7600 /* Optimize pow(x,1) = x. */
7601 if (c == 1)
7602 return arg0;
7604 /* Optimize pow(x,-1) = 1.0/x. */
7605 if (c == -1)
7606 return fold_build2 (RDIV_EXPR, type,
7607 build_real (type, dconst1), arg0);
7610 return NULL_TREE;
7613 /* A subroutine of fold_builtin to fold the various exponent
7614 functions. EXP is the CALL_EXPR of a call to a builtin function.
7615 VALUE is the value which will be raised to a power. */
7617 static tree
7618 fold_builtin_exponent (tree fndecl, tree arglist,
7619 const REAL_VALUE_TYPE *value)
7621 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7623 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7624 tree arg = TREE_VALUE (arglist);
7626 /* Optimize exp*(0.0) = 1.0. */
7627 if (real_zerop (arg))
7628 return build_real (type, dconst1);
7630 /* Optimize expN(1.0) = N. */
7631 if (real_onep (arg))
7633 REAL_VALUE_TYPE cst;
7635 real_convert (&cst, TYPE_MODE (type), value);
7636 return build_real (type, cst);
7639 /* Attempt to evaluate expN(integer) at compile-time. */
7640 if (flag_unsafe_math_optimizations
7641 && TREE_CODE (arg) == REAL_CST
7642 && ! TREE_CONSTANT_OVERFLOW (arg))
7644 REAL_VALUE_TYPE cint;
7645 REAL_VALUE_TYPE c;
7646 HOST_WIDE_INT n;
7648 c = TREE_REAL_CST (arg);
7649 n = real_to_integer (&c);
7650 real_from_integer (&cint, VOIDmode, n,
7651 n < 0 ? -1 : 0, 0);
7652 if (real_identical (&c, &cint))
7654 REAL_VALUE_TYPE x;
7656 real_powi (&x, TYPE_MODE (type), value, n);
7657 return build_real (type, x);
7661 /* Optimize expN(logN(x)) = x. */
7662 if (flag_unsafe_math_optimizations)
7664 const enum built_in_function fcode = builtin_mathfn_code (arg);
7666 if ((value == &dconste
7667 && (fcode == BUILT_IN_LOG
7668 || fcode == BUILT_IN_LOGF
7669 || fcode == BUILT_IN_LOGL))
7670 || (value == &dconst2
7671 && (fcode == BUILT_IN_LOG2
7672 || fcode == BUILT_IN_LOG2F
7673 || fcode == BUILT_IN_LOG2L))
7674 || (value == &dconst10
7675 && (fcode == BUILT_IN_LOG10
7676 || fcode == BUILT_IN_LOG10F
7677 || fcode == BUILT_IN_LOG10L)))
7678 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7682 return 0;
7685 /* Fold function call to builtin memcpy. Return
7686 NULL_TREE if no simplification can be made. */
7688 static tree
7689 fold_builtin_memcpy (tree fndecl, tree arglist)
7691 tree dest, src, len;
7693 if (!validate_arglist (arglist,
7694 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7695 return 0;
7697 dest = TREE_VALUE (arglist);
7698 src = TREE_VALUE (TREE_CHAIN (arglist));
7699 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7701 /* If the LEN parameter is zero, return DEST. */
7702 if (integer_zerop (len))
7703 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7705 /* If SRC and DEST are the same (and not volatile), return DEST. */
7706 if (operand_equal_p (src, dest, 0))
7707 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7709 return 0;
7712 /* Fold function call to builtin mempcpy. Return
7713 NULL_TREE if no simplification can be made. */
7715 static tree
7716 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7718 if (validate_arglist (arglist,
7719 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7721 tree dest = TREE_VALUE (arglist);
7722 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7723 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7725 /* If the LEN parameter is zero, return DEST. */
7726 if (integer_zerop (len))
7727 return omit_one_operand (type, dest, src);
7729 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7730 if (operand_equal_p (src, dest, 0))
7732 if (endp == 0)
7733 return omit_one_operand (type, dest, len);
7735 if (endp == 2)
7736 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7737 ssize_int (1));
7739 len = fold_convert (TREE_TYPE (dest), len);
7740 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7741 return fold_convert (type, len);
7744 return 0;
7747 /* Fold function call to builtin memmove. Return
7748 NULL_TREE if no simplification can be made. */
7750 static tree
7751 fold_builtin_memmove (tree arglist, tree type)
7753 tree dest, src, len;
7755 if (!validate_arglist (arglist,
7756 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7757 return 0;
7759 dest = TREE_VALUE (arglist);
7760 src = TREE_VALUE (TREE_CHAIN (arglist));
7761 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7763 /* If the LEN parameter is zero, return DEST. */
7764 if (integer_zerop (len))
7765 return omit_one_operand (type, dest, src);
7767 /* If SRC and DEST are the same (and not volatile), return DEST. */
7768 if (operand_equal_p (src, dest, 0))
7769 return omit_one_operand (type, dest, len);
7771 return 0;
7774 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7775 the length of the string to be copied. Return NULL_TREE if no
7776 simplification can be made. */
7778 tree
7779 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7781 tree dest, src, fn;
7783 if (!validate_arglist (arglist,
7784 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7785 return 0;
7787 dest = TREE_VALUE (arglist);
7788 src = TREE_VALUE (TREE_CHAIN (arglist));
7790 /* If SRC and DEST are the same (and not volatile), return DEST. */
7791 if (operand_equal_p (src, dest, 0))
7792 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7794 if (optimize_size)
7795 return 0;
7797 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7798 if (!fn)
7799 return 0;
7801 if (!len)
7803 len = c_strlen (src, 1);
7804 if (! len || TREE_SIDE_EFFECTS (len))
7805 return 0;
7808 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7809 arglist = build_tree_list (NULL_TREE, len);
7810 arglist = tree_cons (NULL_TREE, src, arglist);
7811 arglist = tree_cons (NULL_TREE, dest, arglist);
7812 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7813 build_function_call_expr (fn, arglist));
7816 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7817 the length of the source string. Return NULL_TREE if no simplification
7818 can be made. */
7820 tree
7821 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7823 tree dest, src, len, fn;
7825 if (!validate_arglist (arglist,
7826 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7827 return 0;
7829 dest = TREE_VALUE (arglist);
7830 src = TREE_VALUE (TREE_CHAIN (arglist));
7831 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7833 /* If the LEN parameter is zero, return DEST. */
7834 if (integer_zerop (len))
7835 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7837 /* We can't compare slen with len as constants below if len is not a
7838 constant. */
7839 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7840 return 0;
7842 if (!slen)
7843 slen = c_strlen (src, 1);
7845 /* Now, we must be passed a constant src ptr parameter. */
7846 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7847 return 0;
7849 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7851 /* We do not support simplification of this case, though we do
7852 support it when expanding trees into RTL. */
7853 /* FIXME: generate a call to __builtin_memset. */
7854 if (tree_int_cst_lt (slen, len))
7855 return 0;
7857 /* OK transform into builtin memcpy. */
7858 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7859 if (!fn)
7860 return 0;
7861 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7862 build_function_call_expr (fn, arglist));
7865 /* Fold function call to builtin memcmp. Return
7866 NULL_TREE if no simplification can be made. */
7868 static tree
7869 fold_builtin_memcmp (tree arglist)
7871 tree arg1, arg2, len;
7872 const char *p1, *p2;
7874 if (!validate_arglist (arglist,
7875 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7876 return 0;
7878 arg1 = TREE_VALUE (arglist);
7879 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7880 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7882 /* If the LEN parameter is zero, return zero. */
7883 if (integer_zerop (len))
7884 return omit_two_operands (integer_type_node, integer_zero_node,
7885 arg1, arg2);
7887 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7888 if (operand_equal_p (arg1, arg2, 0))
7889 return omit_one_operand (integer_type_node, integer_zero_node, len);
7891 p1 = c_getstr (arg1);
7892 p2 = c_getstr (arg2);
7894 /* If all arguments are constant, and the value of len is not greater
7895 than the lengths of arg1 and arg2, evaluate at compile-time. */
7896 if (host_integerp (len, 1) && p1 && p2
7897 && compare_tree_int (len, strlen (p1) + 1) <= 0
7898 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7900 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7902 if (r > 0)
7903 return integer_one_node;
7904 else if (r < 0)
7905 return integer_minus_one_node;
7906 else
7907 return integer_zero_node;
7910 /* If len parameter is one, return an expression corresponding to
7911 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7912 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7914 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7915 tree cst_uchar_ptr_node
7916 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7918 tree ind1 = fold_convert (integer_type_node,
7919 build1 (INDIRECT_REF, cst_uchar_node,
7920 fold_convert (cst_uchar_ptr_node,
7921 arg1)));
7922 tree ind2 = fold_convert (integer_type_node,
7923 build1 (INDIRECT_REF, cst_uchar_node,
7924 fold_convert (cst_uchar_ptr_node,
7925 arg2)));
7926 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7929 return 0;
7932 /* Fold function call to builtin strcmp. Return
7933 NULL_TREE if no simplification can be made. */
7935 static tree
7936 fold_builtin_strcmp (tree arglist)
7938 tree arg1, arg2;
7939 const char *p1, *p2;
7941 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7942 return 0;
7944 arg1 = TREE_VALUE (arglist);
7945 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7947 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7948 if (operand_equal_p (arg1, arg2, 0))
7949 return integer_zero_node;
7951 p1 = c_getstr (arg1);
7952 p2 = c_getstr (arg2);
7954 if (p1 && p2)
7956 const int i = strcmp (p1, p2);
7957 if (i < 0)
7958 return integer_minus_one_node;
7959 else if (i > 0)
7960 return integer_one_node;
7961 else
7962 return integer_zero_node;
7965 /* If the second arg is "", return *(const unsigned char*)arg1. */
7966 if (p2 && *p2 == '\0')
7968 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7969 tree cst_uchar_ptr_node
7970 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7972 return fold_convert (integer_type_node,
7973 build1 (INDIRECT_REF, cst_uchar_node,
7974 fold_convert (cst_uchar_ptr_node,
7975 arg1)));
7978 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7979 if (p1 && *p1 == '\0')
7981 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7982 tree cst_uchar_ptr_node
7983 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7985 tree temp = fold_convert (integer_type_node,
7986 build1 (INDIRECT_REF, cst_uchar_node,
7987 fold_convert (cst_uchar_ptr_node,
7988 arg2)));
7989 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
7992 return 0;
7995 /* Fold function call to builtin strncmp. Return
7996 NULL_TREE if no simplification can be made. */
7998 static tree
7999 fold_builtin_strncmp (tree arglist)
8001 tree arg1, arg2, len;
8002 const char *p1, *p2;
8004 if (!validate_arglist (arglist,
8005 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8006 return 0;
8008 arg1 = TREE_VALUE (arglist);
8009 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8010 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8012 /* If the LEN parameter is zero, return zero. */
8013 if (integer_zerop (len))
8014 return omit_two_operands (integer_type_node, integer_zero_node,
8015 arg1, arg2);
8017 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8018 if (operand_equal_p (arg1, arg2, 0))
8019 return omit_one_operand (integer_type_node, integer_zero_node, len);
8021 p1 = c_getstr (arg1);
8022 p2 = c_getstr (arg2);
8024 if (host_integerp (len, 1) && p1 && p2)
8026 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8027 if (i > 0)
8028 return integer_one_node;
8029 else if (i < 0)
8030 return integer_minus_one_node;
8031 else
8032 return integer_zero_node;
8035 /* If the second arg is "", and the length is greater than zero,
8036 return *(const unsigned char*)arg1. */
8037 if (p2 && *p2 == '\0'
8038 && TREE_CODE (len) == INTEGER_CST
8039 && tree_int_cst_sgn (len) == 1)
8041 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8042 tree cst_uchar_ptr_node
8043 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8045 return fold_convert (integer_type_node,
8046 build1 (INDIRECT_REF, cst_uchar_node,
8047 fold_convert (cst_uchar_ptr_node,
8048 arg1)));
8051 /* If the first arg is "", and the length is greater than zero,
8052 return -*(const unsigned char*)arg2. */
8053 if (p1 && *p1 == '\0'
8054 && TREE_CODE (len) == INTEGER_CST
8055 && tree_int_cst_sgn (len) == 1)
8057 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8058 tree cst_uchar_ptr_node
8059 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8061 tree temp = fold_convert (integer_type_node,
8062 build1 (INDIRECT_REF, cst_uchar_node,
8063 fold_convert (cst_uchar_ptr_node,
8064 arg2)));
8065 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8068 /* If len parameter is one, return an expression corresponding to
8069 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8070 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8072 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8073 tree cst_uchar_ptr_node
8074 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8076 tree ind1 = fold_convert (integer_type_node,
8077 build1 (INDIRECT_REF, cst_uchar_node,
8078 fold_convert (cst_uchar_ptr_node,
8079 arg1)));
8080 tree ind2 = fold_convert (integer_type_node,
8081 build1 (INDIRECT_REF, cst_uchar_node,
8082 fold_convert (cst_uchar_ptr_node,
8083 arg2)));
8084 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8087 return 0;
8090 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8091 NULL_TREE if no simplification can be made. */
8093 static tree
8094 fold_builtin_signbit (tree fndecl, tree arglist)
8096 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8097 tree arg, temp;
8099 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8100 return NULL_TREE;
8102 arg = TREE_VALUE (arglist);
8104 /* If ARG is a compile-time constant, determine the result. */
8105 if (TREE_CODE (arg) == REAL_CST
8106 && !TREE_CONSTANT_OVERFLOW (arg))
8108 REAL_VALUE_TYPE c;
8110 c = TREE_REAL_CST (arg);
8111 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8112 return fold_convert (type, temp);
8115 /* If ARG is non-negative, the result is always zero. */
8116 if (tree_expr_nonnegative_p (arg))
8117 return omit_one_operand (type, integer_zero_node, arg);
8119 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8120 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8121 return fold_build2 (LT_EXPR, type, arg,
8122 build_real (TREE_TYPE (arg), dconst0));
8124 return NULL_TREE;
8127 /* Fold function call to builtin copysign, copysignf or copysignl.
8128 Return NULL_TREE if no simplification can be made. */
8130 static tree
8131 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8133 tree arg1, arg2, tem;
8135 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8136 return NULL_TREE;
8138 arg1 = TREE_VALUE (arglist);
8139 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8141 /* copysign(X,X) is X. */
8142 if (operand_equal_p (arg1, arg2, 0))
8143 return fold_convert (type, arg1);
8145 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8146 if (TREE_CODE (arg1) == REAL_CST
8147 && TREE_CODE (arg2) == REAL_CST
8148 && !TREE_CONSTANT_OVERFLOW (arg1)
8149 && !TREE_CONSTANT_OVERFLOW (arg2))
8151 REAL_VALUE_TYPE c1, c2;
8153 c1 = TREE_REAL_CST (arg1);
8154 c2 = TREE_REAL_CST (arg2);
8155 real_copysign (&c1, &c2);
8156 return build_real (type, c1);
8157 c1.sign = c2.sign;
8160 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8161 Remember to evaluate Y for side-effects. */
8162 if (tree_expr_nonnegative_p (arg2))
8163 return omit_one_operand (type,
8164 fold_build1 (ABS_EXPR, type, arg1),
8165 arg2);
8167 /* Strip sign changing operations for the first argument. */
8168 tem = fold_strip_sign_ops (arg1);
8169 if (tem)
8171 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8172 return build_function_call_expr (fndecl, arglist);
8175 return NULL_TREE;
8178 /* Fold a call to builtin isascii. */
8180 static tree
8181 fold_builtin_isascii (tree arglist)
8183 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8184 return 0;
8185 else
8187 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8188 tree arg = TREE_VALUE (arglist);
8190 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8191 build_int_cst (NULL_TREE,
8192 ~ (unsigned HOST_WIDE_INT) 0x7f));
8193 arg = fold_build2 (EQ_EXPR, integer_type_node,
8194 arg, integer_zero_node);
8196 if (in_gimple_form && !TREE_CONSTANT (arg))
8197 return NULL_TREE;
8198 else
8199 return arg;
8203 /* Fold a call to builtin toascii. */
8205 static tree
8206 fold_builtin_toascii (tree arglist)
8208 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8209 return 0;
8210 else
8212 /* Transform toascii(c) -> (c & 0x7f). */
8213 tree arg = TREE_VALUE (arglist);
8215 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8216 build_int_cst (NULL_TREE, 0x7f));
8220 /* Fold a call to builtin isdigit. */
8222 static tree
8223 fold_builtin_isdigit (tree arglist)
8225 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8226 return 0;
8227 else
8229 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8230 /* According to the C standard, isdigit is unaffected by locale.
8231 However, it definitely is affected by the target character set. */
8232 tree arg;
8233 unsigned HOST_WIDE_INT target_digit0
8234 = lang_hooks.to_target_charset ('0');
8236 if (target_digit0 == 0)
8237 return NULL_TREE;
8239 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8240 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8241 build_int_cst (unsigned_type_node, target_digit0));
8242 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8243 build_int_cst (unsigned_type_node, 9));
8244 if (in_gimple_form && !TREE_CONSTANT (arg))
8245 return NULL_TREE;
8246 else
8247 return arg;
8251 /* Fold a call to fabs, fabsf or fabsl. */
8253 static tree
8254 fold_builtin_fabs (tree arglist, tree type)
8256 tree arg;
8258 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8259 return 0;
8261 arg = TREE_VALUE (arglist);
8262 arg = fold_convert (type, arg);
8263 if (TREE_CODE (arg) == REAL_CST)
8264 return fold_abs_const (arg, type);
8265 return fold_build1 (ABS_EXPR, type, arg);
8268 /* Fold a call to abs, labs, llabs or imaxabs. */
8270 static tree
8271 fold_builtin_abs (tree arglist, tree type)
8273 tree arg;
8275 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8276 return 0;
8278 arg = TREE_VALUE (arglist);
8279 arg = fold_convert (type, arg);
8280 if (TREE_CODE (arg) == INTEGER_CST)
8281 return fold_abs_const (arg, type);
8282 return fold_build1 (ABS_EXPR, type, arg);
8285 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8286 EXP is the CALL_EXPR for the call. */
8288 static tree
8289 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8291 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8292 tree arg;
8293 REAL_VALUE_TYPE r;
8295 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8297 /* Check that we have exactly one argument. */
8298 if (arglist == 0)
8300 error ("too few arguments to function %qs",
8301 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8302 return error_mark_node;
8304 else if (TREE_CHAIN (arglist) != 0)
8306 error ("too many arguments to function %qs",
8307 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8308 return error_mark_node;
8310 else
8312 error ("non-floating-point argument to function %qs",
8313 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8314 return error_mark_node;
8318 arg = TREE_VALUE (arglist);
8319 switch (builtin_index)
8321 case BUILT_IN_ISINF:
8322 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8323 return omit_one_operand (type, integer_zero_node, arg);
8325 if (TREE_CODE (arg) == REAL_CST)
8327 r = TREE_REAL_CST (arg);
8328 if (real_isinf (&r))
8329 return real_compare (GT_EXPR, &r, &dconst0)
8330 ? integer_one_node : integer_minus_one_node;
8331 else
8332 return integer_zero_node;
8335 return NULL_TREE;
8337 case BUILT_IN_FINITE:
8338 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8339 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8340 return omit_one_operand (type, integer_zero_node, arg);
8342 if (TREE_CODE (arg) == REAL_CST)
8344 r = TREE_REAL_CST (arg);
8345 return real_isinf (&r) || real_isnan (&r)
8346 ? integer_zero_node : integer_one_node;
8349 return NULL_TREE;
8351 case BUILT_IN_ISNAN:
8352 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8353 return omit_one_operand (type, integer_zero_node, arg);
8355 if (TREE_CODE (arg) == REAL_CST)
8357 r = TREE_REAL_CST (arg);
8358 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8361 arg = builtin_save_expr (arg);
8362 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8364 default:
8365 gcc_unreachable ();
8369 /* Fold a call to an unordered comparison function such as
8370 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8371 being called and ARGLIST is the argument list for the call.
8372 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8373 the opposite of the desired result. UNORDERED_CODE is used
8374 for modes that can hold NaNs and ORDERED_CODE is used for
8375 the rest. */
8377 static tree
8378 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8379 enum tree_code unordered_code,
8380 enum tree_code ordered_code)
8382 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8383 enum tree_code code;
8384 tree arg0, arg1;
8385 tree type0, type1;
8386 enum tree_code code0, code1;
8387 tree cmp_type = NULL_TREE;
8389 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8391 /* Check that we have exactly two arguments. */
8392 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8394 error ("too few arguments to function %qs",
8395 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8396 return error_mark_node;
8398 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8400 error ("too many arguments to function %qs",
8401 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8402 return error_mark_node;
8406 arg0 = TREE_VALUE (arglist);
8407 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8409 type0 = TREE_TYPE (arg0);
8410 type1 = TREE_TYPE (arg1);
8412 code0 = TREE_CODE (type0);
8413 code1 = TREE_CODE (type1);
8415 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8416 /* Choose the wider of two real types. */
8417 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8418 ? type0 : type1;
8419 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8420 cmp_type = type0;
8421 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8422 cmp_type = type1;
8423 else
8425 error ("non-floating-point argument to function %qs",
8426 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8427 return error_mark_node;
8430 arg0 = fold_convert (cmp_type, arg0);
8431 arg1 = fold_convert (cmp_type, arg1);
8433 if (unordered_code == UNORDERED_EXPR)
8435 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8436 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8437 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8440 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8441 : ordered_code;
8442 return fold_build1 (TRUTH_NOT_EXPR, type,
8443 fold_build2 (code, type, arg0, arg1));
8446 /* Used by constant folding to simplify calls to builtin functions. EXP is
8447 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8448 result of the function call is ignored. This function returns NULL_TREE
8449 if no simplification was possible. */
8451 static tree
8452 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8454 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8455 enum built_in_function fcode;
8457 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8458 return targetm.fold_builtin (fndecl, arglist, ignore);
8460 fcode = DECL_FUNCTION_CODE (fndecl);
8461 switch (fcode)
8463 case BUILT_IN_FPUTS:
8464 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8466 case BUILT_IN_FPUTS_UNLOCKED:
8467 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8469 case BUILT_IN_STRSTR:
8470 return fold_builtin_strstr (arglist, type);
8472 case BUILT_IN_STRCAT:
8473 return fold_builtin_strcat (arglist);
8475 case BUILT_IN_STRNCAT:
8476 return fold_builtin_strncat (arglist);
8478 case BUILT_IN_STRSPN:
8479 return fold_builtin_strspn (arglist);
8481 case BUILT_IN_STRCSPN:
8482 return fold_builtin_strcspn (arglist);
8484 case BUILT_IN_STRCHR:
8485 case BUILT_IN_INDEX:
8486 return fold_builtin_strchr (arglist, type);
8488 case BUILT_IN_STRRCHR:
8489 case BUILT_IN_RINDEX:
8490 return fold_builtin_strrchr (arglist, type);
8492 case BUILT_IN_STRCPY:
8493 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8495 case BUILT_IN_STRNCPY:
8496 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8498 case BUILT_IN_STRCMP:
8499 return fold_builtin_strcmp (arglist);
8501 case BUILT_IN_STRNCMP:
8502 return fold_builtin_strncmp (arglist);
8504 case BUILT_IN_STRPBRK:
8505 return fold_builtin_strpbrk (arglist, type);
8507 case BUILT_IN_BCMP:
8508 case BUILT_IN_MEMCMP:
8509 return fold_builtin_memcmp (arglist);
8511 case BUILT_IN_SPRINTF:
8512 return fold_builtin_sprintf (arglist, ignore);
8514 case BUILT_IN_CONSTANT_P:
8516 tree val;
8518 val = fold_builtin_constant_p (arglist);
8519 /* Gimplification will pull the CALL_EXPR for the builtin out of
8520 an if condition. When not optimizing, we'll not CSE it back.
8521 To avoid link error types of regressions, return false now. */
8522 if (!val && !optimize)
8523 val = integer_zero_node;
8525 return val;
8528 case BUILT_IN_EXPECT:
8529 return fold_builtin_expect (arglist);
8531 case BUILT_IN_CLASSIFY_TYPE:
8532 return fold_builtin_classify_type (arglist);
8534 case BUILT_IN_STRLEN:
8535 return fold_builtin_strlen (arglist);
8537 CASE_FLT_FN (BUILT_IN_FABS):
8538 return fold_builtin_fabs (arglist, type);
8540 case BUILT_IN_ABS:
8541 case BUILT_IN_LABS:
8542 case BUILT_IN_LLABS:
8543 case BUILT_IN_IMAXABS:
8544 return fold_builtin_abs (arglist, type);
8546 CASE_FLT_FN (BUILT_IN_CONJ):
8547 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8548 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8549 break;
8551 CASE_FLT_FN (BUILT_IN_CREAL):
8552 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8553 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8554 TREE_VALUE (arglist)));
8555 break;
8557 CASE_FLT_FN (BUILT_IN_CIMAG):
8558 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8559 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8560 TREE_VALUE (arglist)));
8561 break;
8563 CASE_FLT_FN (BUILT_IN_CABS):
8564 return fold_builtin_cabs (arglist, type);
8566 CASE_FLT_FN (BUILT_IN_SQRT):
8567 return fold_builtin_sqrt (arglist, type);
8569 CASE_FLT_FN (BUILT_IN_CBRT):
8570 return fold_builtin_cbrt (arglist, type);
8572 CASE_FLT_FN (BUILT_IN_SIN):
8573 return fold_builtin_sin (arglist);
8575 CASE_FLT_FN (BUILT_IN_COS):
8576 return fold_builtin_cos (arglist, type, fndecl);
8578 CASE_FLT_FN (BUILT_IN_EXP):
8579 return fold_builtin_exponent (fndecl, arglist, &dconste);
8581 CASE_FLT_FN (BUILT_IN_EXP2):
8582 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8584 CASE_FLT_FN (BUILT_IN_EXP10):
8585 CASE_FLT_FN (BUILT_IN_POW10):
8586 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8588 CASE_FLT_FN (BUILT_IN_LOG):
8589 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8591 CASE_FLT_FN (BUILT_IN_LOG2):
8592 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8594 CASE_FLT_FN (BUILT_IN_LOG10):
8595 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8597 CASE_FLT_FN (BUILT_IN_TAN):
8598 return fold_builtin_tan (arglist);
8600 CASE_FLT_FN (BUILT_IN_ATAN):
8601 return fold_builtin_atan (arglist, type);
8603 CASE_FLT_FN (BUILT_IN_POW):
8604 return fold_builtin_pow (fndecl, arglist, type);
8606 CASE_FLT_FN (BUILT_IN_POWI):
8607 return fold_builtin_powi (fndecl, arglist, type);
8609 CASE_FLT_FN (BUILT_IN_INF):
8610 case BUILT_IN_INFD32:
8611 case BUILT_IN_INFD64:
8612 case BUILT_IN_INFD128:
8613 return fold_builtin_inf (type, true);
8615 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8616 return fold_builtin_inf (type, false);
8618 CASE_FLT_FN (BUILT_IN_NAN):
8619 case BUILT_IN_NAND32:
8620 case BUILT_IN_NAND64:
8621 case BUILT_IN_NAND128:
8622 return fold_builtin_nan (arglist, type, true);
8624 CASE_FLT_FN (BUILT_IN_NANS):
8625 return fold_builtin_nan (arglist, type, false);
8627 CASE_FLT_FN (BUILT_IN_FLOOR):
8628 return fold_builtin_floor (fndecl, arglist);
8630 CASE_FLT_FN (BUILT_IN_CEIL):
8631 return fold_builtin_ceil (fndecl, arglist);
8633 CASE_FLT_FN (BUILT_IN_TRUNC):
8634 return fold_builtin_trunc (fndecl, arglist);
8636 CASE_FLT_FN (BUILT_IN_ROUND):
8637 return fold_builtin_round (fndecl, arglist);
8639 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8640 CASE_FLT_FN (BUILT_IN_RINT):
8641 return fold_trunc_transparent_mathfn (fndecl, arglist);
8643 CASE_FLT_FN (BUILT_IN_LCEIL):
8644 CASE_FLT_FN (BUILT_IN_LLCEIL):
8645 CASE_FLT_FN (BUILT_IN_LFLOOR):
8646 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8647 CASE_FLT_FN (BUILT_IN_LROUND):
8648 CASE_FLT_FN (BUILT_IN_LLROUND):
8649 return fold_builtin_int_roundingfn (fndecl, arglist);
8651 CASE_FLT_FN (BUILT_IN_LRINT):
8652 CASE_FLT_FN (BUILT_IN_LLRINT):
8653 return fold_fixed_mathfn (fndecl, arglist);
8655 CASE_INT_FN (BUILT_IN_FFS):
8656 CASE_INT_FN (BUILT_IN_CLZ):
8657 CASE_INT_FN (BUILT_IN_CTZ):
8658 CASE_INT_FN (BUILT_IN_POPCOUNT):
8659 CASE_INT_FN (BUILT_IN_PARITY):
8660 return fold_builtin_bitop (fndecl, arglist);
8662 case BUILT_IN_MEMCPY:
8663 return fold_builtin_memcpy (fndecl, arglist);
8665 case BUILT_IN_MEMPCPY:
8666 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8668 case BUILT_IN_MEMMOVE:
8669 return fold_builtin_memmove (arglist, type);
8671 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8672 return fold_builtin_signbit (fndecl, arglist);
8674 case BUILT_IN_ISASCII:
8675 return fold_builtin_isascii (arglist);
8677 case BUILT_IN_TOASCII:
8678 return fold_builtin_toascii (arglist);
8680 case BUILT_IN_ISDIGIT:
8681 return fold_builtin_isdigit (arglist);
8683 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8684 return fold_builtin_copysign (fndecl, arglist, type);
8686 CASE_FLT_FN (BUILT_IN_FINITE):
8687 case BUILT_IN_FINITED32:
8688 case BUILT_IN_FINITED64:
8689 case BUILT_IN_FINITED128:
8690 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8692 CASE_FLT_FN (BUILT_IN_ISINF):
8693 case BUILT_IN_ISINFD32:
8694 case BUILT_IN_ISINFD64:
8695 case BUILT_IN_ISINFD128:
8696 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8698 CASE_FLT_FN (BUILT_IN_ISNAN):
8699 case BUILT_IN_ISNAND32:
8700 case BUILT_IN_ISNAND64:
8701 case BUILT_IN_ISNAND128:
8702 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8704 case BUILT_IN_ISGREATER:
8705 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8706 case BUILT_IN_ISGREATEREQUAL:
8707 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8708 case BUILT_IN_ISLESS:
8709 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8710 case BUILT_IN_ISLESSEQUAL:
8711 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8712 case BUILT_IN_ISLESSGREATER:
8713 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8714 case BUILT_IN_ISUNORDERED:
8715 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8716 NOP_EXPR);
8718 /* We do the folding for va_start in the expander. */
8719 case BUILT_IN_VA_START:
8720 break;
8722 case BUILT_IN_OBJECT_SIZE:
8723 return fold_builtin_object_size (arglist);
8724 case BUILT_IN_MEMCPY_CHK:
8725 case BUILT_IN_MEMPCPY_CHK:
8726 case BUILT_IN_MEMMOVE_CHK:
8727 case BUILT_IN_MEMSET_CHK:
8728 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8729 DECL_FUNCTION_CODE (fndecl));
8730 case BUILT_IN_STRCPY_CHK:
8731 case BUILT_IN_STPCPY_CHK:
8732 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8733 DECL_FUNCTION_CODE (fndecl));
8734 case BUILT_IN_STRNCPY_CHK:
8735 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8736 case BUILT_IN_STRCAT_CHK:
8737 return fold_builtin_strcat_chk (fndecl, arglist);
8738 case BUILT_IN_STRNCAT_CHK:
8739 return fold_builtin_strncat_chk (fndecl, arglist);
8740 case BUILT_IN_SPRINTF_CHK:
8741 case BUILT_IN_VSPRINTF_CHK:
8742 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8743 case BUILT_IN_SNPRINTF_CHK:
8744 case BUILT_IN_VSNPRINTF_CHK:
8745 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8746 DECL_FUNCTION_CODE (fndecl));
8748 case BUILT_IN_PRINTF:
8749 case BUILT_IN_PRINTF_UNLOCKED:
8750 case BUILT_IN_VPRINTF:
8751 case BUILT_IN_PRINTF_CHK:
8752 case BUILT_IN_VPRINTF_CHK:
8753 return fold_builtin_printf (fndecl, arglist, ignore,
8754 DECL_FUNCTION_CODE (fndecl));
8756 case BUILT_IN_FPRINTF:
8757 case BUILT_IN_FPRINTF_UNLOCKED:
8758 case BUILT_IN_VFPRINTF:
8759 case BUILT_IN_FPRINTF_CHK:
8760 case BUILT_IN_VFPRINTF_CHK:
8761 return fold_builtin_fprintf (fndecl, arglist, ignore,
8762 DECL_FUNCTION_CODE (fndecl));
8764 default:
8765 break;
8768 return 0;
8771 /* A wrapper function for builtin folding that prevents warnings for
8772 "statement without effect" and the like, caused by removing the
8773 call node earlier than the warning is generated. */
8775 tree
8776 fold_builtin (tree fndecl, tree arglist, bool ignore)
8778 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8779 if (exp)
8781 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8782 TREE_NO_WARNING (exp) = 1;
8785 return exp;
8788 /* Conveniently construct a function call expression. */
8790 tree
8791 build_function_call_expr (tree fn, tree arglist)
8793 tree call_expr;
8795 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8796 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8797 call_expr, arglist, NULL_TREE);
8800 /* This function validates the types of a function call argument list
8801 represented as a tree chain of parameters against a specified list
8802 of tree_codes. If the last specifier is a 0, that represents an
8803 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8805 static int
8806 validate_arglist (tree arglist, ...)
8808 enum tree_code code;
8809 int res = 0;
8810 va_list ap;
8812 va_start (ap, arglist);
8816 code = va_arg (ap, enum tree_code);
8817 switch (code)
8819 case 0:
8820 /* This signifies an ellipses, any further arguments are all ok. */
8821 res = 1;
8822 goto end;
8823 case VOID_TYPE:
8824 /* This signifies an endlink, if no arguments remain, return
8825 true, otherwise return false. */
8826 res = arglist == 0;
8827 goto end;
8828 default:
8829 /* If no parameters remain or the parameter's code does not
8830 match the specified code, return false. Otherwise continue
8831 checking any remaining arguments. */
8832 if (arglist == 0)
8833 goto end;
8834 if (code == POINTER_TYPE)
8836 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8837 goto end;
8839 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8840 goto end;
8841 break;
8843 arglist = TREE_CHAIN (arglist);
8845 while (1);
8847 /* We need gotos here since we can only have one VA_CLOSE in a
8848 function. */
8849 end: ;
8850 va_end (ap);
8852 return res;
8855 /* Default target-specific builtin expander that does nothing. */
8858 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8859 rtx target ATTRIBUTE_UNUSED,
8860 rtx subtarget ATTRIBUTE_UNUSED,
8861 enum machine_mode mode ATTRIBUTE_UNUSED,
8862 int ignore ATTRIBUTE_UNUSED)
8864 return NULL_RTX;
8867 /* Returns true is EXP represents data that would potentially reside
8868 in a readonly section. */
8870 static bool
8871 readonly_data_expr (tree exp)
8873 STRIP_NOPS (exp);
8875 if (TREE_CODE (exp) != ADDR_EXPR)
8876 return false;
8878 exp = get_base_address (TREE_OPERAND (exp, 0));
8879 if (!exp)
8880 return false;
8882 /* Make sure we call decl_readonly_section only for trees it
8883 can handle (since it returns true for everything it doesn't
8884 understand). */
8885 if (TREE_CODE (exp) == STRING_CST
8886 || TREE_CODE (exp) == CONSTRUCTOR
8887 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8888 return decl_readonly_section (exp, 0);
8889 else
8890 return false;
8893 /* Simplify a call to the strstr builtin.
8895 Return 0 if no simplification was possible, otherwise return the
8896 simplified form of the call as a tree.
8898 The simplified form may be a constant or other expression which
8899 computes the same value, but in a more efficient manner (including
8900 calls to other builtin functions).
8902 The call may contain arguments which need to be evaluated, but
8903 which are not useful to determine the result of the call. In
8904 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8905 COMPOUND_EXPR will be an argument which must be evaluated.
8906 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8907 COMPOUND_EXPR in the chain will contain the tree for the simplified
8908 form of the builtin function call. */
8910 static tree
8911 fold_builtin_strstr (tree arglist, tree type)
8913 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8914 return 0;
8915 else
8917 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8918 tree fn;
8919 const char *p1, *p2;
8921 p2 = c_getstr (s2);
8922 if (p2 == NULL)
8923 return 0;
8925 p1 = c_getstr (s1);
8926 if (p1 != NULL)
8928 const char *r = strstr (p1, p2);
8929 tree tem;
8931 if (r == NULL)
8932 return build_int_cst (TREE_TYPE (s1), 0);
8934 /* Return an offset into the constant string argument. */
8935 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8936 s1, build_int_cst (TREE_TYPE (s1), r - p1));
8937 return fold_convert (type, tem);
8940 /* The argument is const char *, and the result is char *, so we need
8941 a type conversion here to avoid a warning. */
8942 if (p2[0] == '\0')
8943 return fold_convert (type, s1);
8945 if (p2[1] != '\0')
8946 return 0;
8948 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8949 if (!fn)
8950 return 0;
8952 /* New argument list transforming strstr(s1, s2) to
8953 strchr(s1, s2[0]). */
8954 arglist = build_tree_list (NULL_TREE,
8955 build_int_cst (NULL_TREE, p2[0]));
8956 arglist = tree_cons (NULL_TREE, s1, arglist);
8957 return build_function_call_expr (fn, arglist);
8961 /* Simplify a call to the strchr builtin.
8963 Return 0 if no simplification was possible, otherwise return the
8964 simplified form of the call as a tree.
8966 The simplified form may be a constant or other expression which
8967 computes the same value, but in a more efficient manner (including
8968 calls to other builtin functions).
8970 The call may contain arguments which need to be evaluated, but
8971 which are not useful to determine the result of the call. In
8972 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8973 COMPOUND_EXPR will be an argument which must be evaluated.
8974 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8975 COMPOUND_EXPR in the chain will contain the tree for the simplified
8976 form of the builtin function call. */
8978 static tree
8979 fold_builtin_strchr (tree arglist, tree type)
8981 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8982 return 0;
8983 else
8985 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8986 const char *p1;
8988 if (TREE_CODE (s2) != INTEGER_CST)
8989 return 0;
8991 p1 = c_getstr (s1);
8992 if (p1 != NULL)
8994 char c;
8995 const char *r;
8996 tree tem;
8998 if (target_char_cast (s2, &c))
8999 return 0;
9001 r = strchr (p1, c);
9003 if (r == NULL)
9004 return build_int_cst (TREE_TYPE (s1), 0);
9006 /* Return an offset into the constant string argument. */
9007 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9008 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9009 return fold_convert (type, tem);
9011 return 0;
9015 /* Simplify a call to the strrchr builtin.
9017 Return 0 if no simplification was possible, otherwise return the
9018 simplified form of the call as a tree.
9020 The simplified form may be a constant or other expression which
9021 computes the same value, but in a more efficient manner (including
9022 calls to other builtin functions).
9024 The call may contain arguments which need to be evaluated, but
9025 which are not useful to determine the result of the call. In
9026 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9027 COMPOUND_EXPR will be an argument which must be evaluated.
9028 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9029 COMPOUND_EXPR in the chain will contain the tree for the simplified
9030 form of the builtin function call. */
9032 static tree
9033 fold_builtin_strrchr (tree arglist, tree type)
9035 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9036 return 0;
9037 else
9039 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9040 tree fn;
9041 const char *p1;
9043 if (TREE_CODE (s2) != INTEGER_CST)
9044 return 0;
9046 p1 = c_getstr (s1);
9047 if (p1 != NULL)
9049 char c;
9050 const char *r;
9051 tree tem;
9053 if (target_char_cast (s2, &c))
9054 return 0;
9056 r = strrchr (p1, c);
9058 if (r == NULL)
9059 return build_int_cst (TREE_TYPE (s1), 0);
9061 /* Return an offset into the constant string argument. */
9062 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9063 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9064 return fold_convert (type, tem);
9067 if (! integer_zerop (s2))
9068 return 0;
9070 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9071 if (!fn)
9072 return 0;
9074 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9075 return build_function_call_expr (fn, arglist);
9079 /* Simplify a call to the strpbrk builtin.
9081 Return 0 if no simplification was possible, otherwise return the
9082 simplified form of the call as a tree.
9084 The simplified form may be a constant or other expression which
9085 computes the same value, but in a more efficient manner (including
9086 calls to other builtin functions).
9088 The call may contain arguments which need to be evaluated, but
9089 which are not useful to determine the result of the call. In
9090 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9091 COMPOUND_EXPR will be an argument which must be evaluated.
9092 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9093 COMPOUND_EXPR in the chain will contain the tree for the simplified
9094 form of the builtin function call. */
9096 static tree
9097 fold_builtin_strpbrk (tree arglist, tree type)
9099 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9100 return 0;
9101 else
9103 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9104 tree fn;
9105 const char *p1, *p2;
9107 p2 = c_getstr (s2);
9108 if (p2 == NULL)
9109 return 0;
9111 p1 = c_getstr (s1);
9112 if (p1 != NULL)
9114 const char *r = strpbrk (p1, p2);
9115 tree tem;
9117 if (r == NULL)
9118 return build_int_cst (TREE_TYPE (s1), 0);
9120 /* Return an offset into the constant string argument. */
9121 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9122 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9123 return fold_convert (type, tem);
9126 if (p2[0] == '\0')
9127 /* strpbrk(x, "") == NULL.
9128 Evaluate and ignore s1 in case it had side-effects. */
9129 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9131 if (p2[1] != '\0')
9132 return 0; /* Really call strpbrk. */
9134 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9135 if (!fn)
9136 return 0;
9138 /* New argument list transforming strpbrk(s1, s2) to
9139 strchr(s1, s2[0]). */
9140 arglist = build_tree_list (NULL_TREE,
9141 build_int_cst (NULL_TREE, p2[0]));
9142 arglist = tree_cons (NULL_TREE, s1, arglist);
9143 return build_function_call_expr (fn, arglist);
9147 /* Simplify a call to the strcat builtin.
9149 Return 0 if no simplification was possible, otherwise return the
9150 simplified form of the call as a tree.
9152 The simplified form may be a constant or other expression which
9153 computes the same value, but in a more efficient manner (including
9154 calls to other builtin functions).
9156 The call may contain arguments which need to be evaluated, but
9157 which are not useful to determine the result of the call. In
9158 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9159 COMPOUND_EXPR will be an argument which must be evaluated.
9160 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9161 COMPOUND_EXPR in the chain will contain the tree for the simplified
9162 form of the builtin function call. */
9164 static tree
9165 fold_builtin_strcat (tree arglist)
9167 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9168 return 0;
9169 else
9171 tree dst = TREE_VALUE (arglist),
9172 src = TREE_VALUE (TREE_CHAIN (arglist));
9173 const char *p = c_getstr (src);
9175 /* If the string length is zero, return the dst parameter. */
9176 if (p && *p == '\0')
9177 return dst;
9179 return 0;
9183 /* Simplify a call to the strncat builtin.
9185 Return 0 if no simplification was possible, otherwise return the
9186 simplified form of the call as a tree.
9188 The simplified form may be a constant or other expression which
9189 computes the same value, but in a more efficient manner (including
9190 calls to other builtin functions).
9192 The call may contain arguments which need to be evaluated, but
9193 which are not useful to determine the result of the call. In
9194 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9195 COMPOUND_EXPR will be an argument which must be evaluated.
9196 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9197 COMPOUND_EXPR in the chain will contain the tree for the simplified
9198 form of the builtin function call. */
9200 static tree
9201 fold_builtin_strncat (tree arglist)
9203 if (!validate_arglist (arglist,
9204 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9205 return 0;
9206 else
9208 tree dst = TREE_VALUE (arglist);
9209 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9210 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9211 const char *p = c_getstr (src);
9213 /* If the requested length is zero, or the src parameter string
9214 length is zero, return the dst parameter. */
9215 if (integer_zerop (len) || (p && *p == '\0'))
9216 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9218 /* If the requested len is greater than or equal to the string
9219 length, call strcat. */
9220 if (TREE_CODE (len) == INTEGER_CST && p
9221 && compare_tree_int (len, strlen (p)) >= 0)
9223 tree newarglist
9224 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9225 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9227 /* If the replacement _DECL isn't initialized, don't do the
9228 transformation. */
9229 if (!fn)
9230 return 0;
9232 return build_function_call_expr (fn, newarglist);
9234 return 0;
9238 /* Simplify a call to the strspn builtin.
9240 Return 0 if no simplification was possible, otherwise return the
9241 simplified form of the call as a tree.
9243 The simplified form may be a constant or other expression which
9244 computes the same value, but in a more efficient manner (including
9245 calls to other builtin functions).
9247 The call may contain arguments which need to be evaluated, but
9248 which are not useful to determine the result of the call. In
9249 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9250 COMPOUND_EXPR will be an argument which must be evaluated.
9251 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9252 COMPOUND_EXPR in the chain will contain the tree for the simplified
9253 form of the builtin function call. */
9255 static tree
9256 fold_builtin_strspn (tree arglist)
9258 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9259 return 0;
9260 else
9262 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9263 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9265 /* If both arguments are constants, evaluate at compile-time. */
9266 if (p1 && p2)
9268 const size_t r = strspn (p1, p2);
9269 return size_int (r);
9272 /* If either argument is "", return 0. */
9273 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9274 /* Evaluate and ignore both arguments in case either one has
9275 side-effects. */
9276 return omit_two_operands (integer_type_node, integer_zero_node,
9277 s1, s2);
9278 return 0;
9282 /* Simplify a call to the strcspn builtin.
9284 Return 0 if no simplification was possible, otherwise return the
9285 simplified form of the call as a tree.
9287 The simplified form may be a constant or other expression which
9288 computes the same value, but in a more efficient manner (including
9289 calls to other builtin functions).
9291 The call may contain arguments which need to be evaluated, but
9292 which are not useful to determine the result of the call. In
9293 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9294 COMPOUND_EXPR will be an argument which must be evaluated.
9295 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9296 COMPOUND_EXPR in the chain will contain the tree for the simplified
9297 form of the builtin function call. */
9299 static tree
9300 fold_builtin_strcspn (tree arglist)
9302 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9303 return 0;
9304 else
9306 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9307 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9309 /* If both arguments are constants, evaluate at compile-time. */
9310 if (p1 && p2)
9312 const size_t r = strcspn (p1, p2);
9313 return size_int (r);
9316 /* If the first argument is "", return 0. */
9317 if (p1 && *p1 == '\0')
9319 /* Evaluate and ignore argument s2 in case it has
9320 side-effects. */
9321 return omit_one_operand (integer_type_node,
9322 integer_zero_node, s2);
9325 /* If the second argument is "", return __builtin_strlen(s1). */
9326 if (p2 && *p2 == '\0')
9328 tree newarglist = build_tree_list (NULL_TREE, s1),
9329 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9331 /* If the replacement _DECL isn't initialized, don't do the
9332 transformation. */
9333 if (!fn)
9334 return 0;
9336 return build_function_call_expr (fn, newarglist);
9338 return 0;
9342 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9343 by the builtin will be ignored. UNLOCKED is true is true if this
9344 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9345 the known length of the string. Return NULL_TREE if no simplification
9346 was possible. */
9348 tree
9349 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9351 tree fn;
9352 /* If we're using an unlocked function, assume the other unlocked
9353 functions exist explicitly. */
9354 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9355 : implicit_built_in_decls[BUILT_IN_FPUTC];
9356 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9357 : implicit_built_in_decls[BUILT_IN_FWRITE];
9359 /* If the return value is used, don't do the transformation. */
9360 if (!ignore)
9361 return 0;
9363 /* Verify the arguments in the original call. */
9364 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9365 return 0;
9367 if (! len)
9368 len = c_strlen (TREE_VALUE (arglist), 0);
9370 /* Get the length of the string passed to fputs. If the length
9371 can't be determined, punt. */
9372 if (!len
9373 || TREE_CODE (len) != INTEGER_CST)
9374 return 0;
9376 switch (compare_tree_int (len, 1))
9378 case -1: /* length is 0, delete the call entirely . */
9379 return omit_one_operand (integer_type_node, integer_zero_node,
9380 TREE_VALUE (TREE_CHAIN (arglist)));
9382 case 0: /* length is 1, call fputc. */
9384 const char *p = c_getstr (TREE_VALUE (arglist));
9386 if (p != NULL)
9388 /* New argument list transforming fputs(string, stream) to
9389 fputc(string[0], stream). */
9390 arglist = build_tree_list (NULL_TREE,
9391 TREE_VALUE (TREE_CHAIN (arglist)));
9392 arglist = tree_cons (NULL_TREE,
9393 build_int_cst (NULL_TREE, p[0]),
9394 arglist);
9395 fn = fn_fputc;
9396 break;
9399 /* FALLTHROUGH */
9400 case 1: /* length is greater than 1, call fwrite. */
9402 tree string_arg;
9404 /* If optimizing for size keep fputs. */
9405 if (optimize_size)
9406 return 0;
9407 string_arg = TREE_VALUE (arglist);
9408 /* New argument list transforming fputs(string, stream) to
9409 fwrite(string, 1, len, stream). */
9410 arglist = build_tree_list (NULL_TREE,
9411 TREE_VALUE (TREE_CHAIN (arglist)));
9412 arglist = tree_cons (NULL_TREE, len, arglist);
9413 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9414 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9415 fn = fn_fwrite;
9416 break;
9418 default:
9419 gcc_unreachable ();
9422 /* If the replacement _DECL isn't initialized, don't do the
9423 transformation. */
9424 if (!fn)
9425 return 0;
9427 /* These optimizations are only performed when the result is ignored,
9428 hence there's no need to cast the result to integer_type_node. */
9429 return build_function_call_expr (fn, arglist);
9432 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9433 produced. False otherwise. This is done so that we don't output the error
9434 or warning twice or three times. */
9435 bool
9436 fold_builtin_next_arg (tree arglist)
9438 tree fntype = TREE_TYPE (current_function_decl);
9440 if (TYPE_ARG_TYPES (fntype) == 0
9441 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9442 == void_type_node))
9444 error ("%<va_start%> used in function with fixed args");
9445 return true;
9447 else if (!arglist)
9449 /* Evidently an out of date version of <stdarg.h>; can't validate
9450 va_start's second argument, but can still work as intended. */
9451 warning (0, "%<__builtin_next_arg%> called without an argument");
9452 return true;
9454 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9455 when we checked the arguments and if needed issued a warning. */
9456 else if (!TREE_CHAIN (arglist)
9457 || !integer_zerop (TREE_VALUE (arglist))
9458 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9459 || TREE_CHAIN (TREE_CHAIN (arglist)))
9461 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9462 tree arg = TREE_VALUE (arglist);
9464 if (TREE_CHAIN (arglist))
9466 error ("%<va_start%> used with too many arguments");
9467 return true;
9470 /* Strip off all nops for the sake of the comparison. This
9471 is not quite the same as STRIP_NOPS. It does more.
9472 We must also strip off INDIRECT_EXPR for C++ reference
9473 parameters. */
9474 while (TREE_CODE (arg) == NOP_EXPR
9475 || TREE_CODE (arg) == CONVERT_EXPR
9476 || TREE_CODE (arg) == NON_LVALUE_EXPR
9477 || TREE_CODE (arg) == INDIRECT_REF)
9478 arg = TREE_OPERAND (arg, 0);
9479 if (arg != last_parm)
9481 /* FIXME: Sometimes with the tree optimizers we can get the
9482 not the last argument even though the user used the last
9483 argument. We just warn and set the arg to be the last
9484 argument so that we will get wrong-code because of
9485 it. */
9486 warning (0, "second parameter of %<va_start%> not last named argument");
9488 /* We want to verify the second parameter just once before the tree
9489 optimizers are run and then avoid keeping it in the tree,
9490 as otherwise we could warn even for correct code like:
9491 void foo (int i, ...)
9492 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9493 TREE_VALUE (arglist) = integer_zero_node;
9494 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9496 return false;
9500 /* Simplify a call to the sprintf builtin.
9502 Return 0 if no simplification was possible, otherwise return the
9503 simplified form of the call as a tree. If IGNORED is true, it means that
9504 the caller does not use the returned value of the function. */
9506 static tree
9507 fold_builtin_sprintf (tree arglist, int ignored)
9509 tree call, retval, dest, fmt;
9510 const char *fmt_str = NULL;
9512 /* Verify the required arguments in the original call. We deal with two
9513 types of sprintf() calls: 'sprintf (str, fmt)' and
9514 'sprintf (dest, "%s", orig)'. */
9515 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9516 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9517 VOID_TYPE))
9518 return NULL_TREE;
9520 /* Get the destination string and the format specifier. */
9521 dest = TREE_VALUE (arglist);
9522 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9524 /* Check whether the format is a literal string constant. */
9525 fmt_str = c_getstr (fmt);
9526 if (fmt_str == NULL)
9527 return NULL_TREE;
9529 call = NULL_TREE;
9530 retval = NULL_TREE;
9532 if (!init_target_chars())
9533 return 0;
9535 /* If the format doesn't contain % args or %%, use strcpy. */
9536 if (strchr (fmt_str, target_percent) == NULL)
9538 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9540 if (!fn)
9541 return NULL_TREE;
9543 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9544 'format' is known to contain no % formats. */
9545 arglist = build_tree_list (NULL_TREE, fmt);
9546 arglist = tree_cons (NULL_TREE, dest, arglist);
9547 call = build_function_call_expr (fn, arglist);
9548 if (!ignored)
9549 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9552 /* If the format is "%s", use strcpy if the result isn't used. */
9553 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9555 tree fn, orig;
9556 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9558 if (!fn)
9559 return NULL_TREE;
9561 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9562 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9563 arglist = build_tree_list (NULL_TREE, orig);
9564 arglist = tree_cons (NULL_TREE, dest, arglist);
9565 if (!ignored)
9567 retval = c_strlen (orig, 1);
9568 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9569 return NULL_TREE;
9571 call = build_function_call_expr (fn, arglist);
9574 if (call && retval)
9576 retval = convert
9577 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9578 retval);
9579 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9581 else
9582 return call;
9585 /* Expand a call to __builtin_object_size. */
9588 expand_builtin_object_size (tree exp)
9590 tree ost;
9591 int object_size_type;
9592 tree fndecl = get_callee_fndecl (exp);
9593 tree arglist = TREE_OPERAND (exp, 1);
9594 location_t locus = EXPR_LOCATION (exp);
9596 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9598 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9599 &locus, fndecl);
9600 expand_builtin_trap ();
9601 return const0_rtx;
9604 ost = TREE_VALUE (TREE_CHAIN (arglist));
9605 STRIP_NOPS (ost);
9607 if (TREE_CODE (ost) != INTEGER_CST
9608 || tree_int_cst_sgn (ost) < 0
9609 || compare_tree_int (ost, 3) > 0)
9611 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9612 &locus, fndecl);
9613 expand_builtin_trap ();
9614 return const0_rtx;
9617 object_size_type = tree_low_cst (ost, 0);
9619 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9622 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9623 FCODE is the BUILT_IN_* to use.
9624 Return 0 if we failed; the caller should emit a normal call,
9625 otherwise try to get the result in TARGET, if convenient (and in
9626 mode MODE if that's convenient). */
9628 static rtx
9629 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9630 enum built_in_function fcode)
9632 tree arglist = TREE_OPERAND (exp, 1);
9633 tree dest, src, len, size;
9635 if (!validate_arglist (arglist,
9636 POINTER_TYPE,
9637 fcode == BUILT_IN_MEMSET_CHK
9638 ? INTEGER_TYPE : POINTER_TYPE,
9639 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9640 return 0;
9642 dest = TREE_VALUE (arglist);
9643 src = TREE_VALUE (TREE_CHAIN (arglist));
9644 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9645 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9647 if (! host_integerp (size, 1))
9648 return 0;
9650 if (host_integerp (len, 1) || integer_all_onesp (size))
9652 tree fn;
9654 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9656 location_t locus = EXPR_LOCATION (exp);
9657 warning (0, "%Hcall to %D will always overflow destination buffer",
9658 &locus, get_callee_fndecl (exp));
9659 return 0;
9662 arglist = build_tree_list (NULL_TREE, len);
9663 arglist = tree_cons (NULL_TREE, src, arglist);
9664 arglist = tree_cons (NULL_TREE, dest, arglist);
9666 fn = NULL_TREE;
9667 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9668 mem{cpy,pcpy,move,set} is available. */
9669 switch (fcode)
9671 case BUILT_IN_MEMCPY_CHK:
9672 fn = built_in_decls[BUILT_IN_MEMCPY];
9673 break;
9674 case BUILT_IN_MEMPCPY_CHK:
9675 fn = built_in_decls[BUILT_IN_MEMPCPY];
9676 break;
9677 case BUILT_IN_MEMMOVE_CHK:
9678 fn = built_in_decls[BUILT_IN_MEMMOVE];
9679 break;
9680 case BUILT_IN_MEMSET_CHK:
9681 fn = built_in_decls[BUILT_IN_MEMSET];
9682 break;
9683 default:
9684 break;
9687 if (! fn)
9688 return 0;
9690 fn = build_function_call_expr (fn, arglist);
9691 if (TREE_CODE (fn) == CALL_EXPR)
9692 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9693 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9695 else if (fcode == BUILT_IN_MEMSET_CHK)
9696 return 0;
9697 else
9699 unsigned int dest_align
9700 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9702 /* If DEST is not a pointer type, call the normal function. */
9703 if (dest_align == 0)
9704 return 0;
9706 /* If SRC and DEST are the same (and not volatile), do nothing. */
9707 if (operand_equal_p (src, dest, 0))
9709 tree expr;
9711 if (fcode != BUILT_IN_MEMPCPY_CHK)
9713 /* Evaluate and ignore LEN in case it has side-effects. */
9714 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9715 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9718 len = fold_convert (TREE_TYPE (dest), len);
9719 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9720 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9723 /* __memmove_chk special case. */
9724 if (fcode == BUILT_IN_MEMMOVE_CHK)
9726 unsigned int src_align
9727 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9729 if (src_align == 0)
9730 return 0;
9732 /* If src is categorized for a readonly section we can use
9733 normal __memcpy_chk. */
9734 if (readonly_data_expr (src))
9736 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9737 if (!fn)
9738 return 0;
9739 fn = build_function_call_expr (fn, arglist);
9740 if (TREE_CODE (fn) == CALL_EXPR)
9741 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9742 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9745 return 0;
9749 /* Emit warning if a buffer overflow is detected at compile time. */
9751 static void
9752 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9754 int arg_mask, is_strlen = 0;
9755 tree arglist = TREE_OPERAND (exp, 1), a;
9756 tree len, size;
9757 location_t locus;
9759 switch (fcode)
9761 case BUILT_IN_STRCPY_CHK:
9762 case BUILT_IN_STPCPY_CHK:
9763 /* For __strcat_chk the warning will be emitted only if overflowing
9764 by at least strlen (dest) + 1 bytes. */
9765 case BUILT_IN_STRCAT_CHK:
9766 arg_mask = 6;
9767 is_strlen = 1;
9768 break;
9769 case BUILT_IN_STRNCPY_CHK:
9770 arg_mask = 12;
9771 break;
9772 case BUILT_IN_SNPRINTF_CHK:
9773 case BUILT_IN_VSNPRINTF_CHK:
9774 arg_mask = 10;
9775 break;
9776 default:
9777 gcc_unreachable ();
9780 len = NULL_TREE;
9781 size = NULL_TREE;
9782 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9783 if (arg_mask & 1)
9785 if (len)
9786 size = a;
9787 else
9788 len = a;
9791 if (!len || !size)
9792 return;
9794 len = TREE_VALUE (len);
9795 size = TREE_VALUE (size);
9797 if (! host_integerp (size, 1) || integer_all_onesp (size))
9798 return;
9800 if (is_strlen)
9802 len = c_strlen (len, 1);
9803 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9804 return;
9806 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9807 return;
9809 locus = EXPR_LOCATION (exp);
9810 warning (0, "%Hcall to %D will always overflow destination buffer",
9811 &locus, get_callee_fndecl (exp));
9814 /* Emit warning if a buffer overflow is detected at compile time
9815 in __sprintf_chk/__vsprintf_chk calls. */
9817 static void
9818 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9820 tree arglist = TREE_OPERAND (exp, 1);
9821 tree dest, size, len, fmt, flag;
9822 const char *fmt_str;
9824 /* Verify the required arguments in the original call. */
9825 if (! arglist)
9826 return;
9827 dest = TREE_VALUE (arglist);
9828 arglist = TREE_CHAIN (arglist);
9829 if (! arglist)
9830 return;
9831 flag = TREE_VALUE (arglist);
9832 arglist = TREE_CHAIN (arglist);
9833 if (! arglist)
9834 return;
9835 size = TREE_VALUE (arglist);
9836 arglist = TREE_CHAIN (arglist);
9837 if (! arglist)
9838 return;
9839 fmt = TREE_VALUE (arglist);
9840 arglist = TREE_CHAIN (arglist);
9842 if (! host_integerp (size, 1) || integer_all_onesp (size))
9843 return;
9845 /* Check whether the format is a literal string constant. */
9846 fmt_str = c_getstr (fmt);
9847 if (fmt_str == NULL)
9848 return;
9850 if (!init_target_chars())
9851 return;
9853 /* If the format doesn't contain % args or %%, we know its size. */
9854 if (strchr (fmt_str, target_percent) == 0)
9855 len = build_int_cstu (size_type_node, strlen (fmt_str));
9856 /* If the format is "%s" and first ... argument is a string literal,
9857 we know it too. */
9858 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9860 tree arg;
9862 if (! arglist)
9863 return;
9864 arg = TREE_VALUE (arglist);
9865 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9866 return;
9868 len = c_strlen (arg, 1);
9869 if (!len || ! host_integerp (len, 1))
9870 return;
9872 else
9873 return;
9875 if (! tree_int_cst_lt (len, size))
9877 location_t locus = EXPR_LOCATION (exp);
9878 warning (0, "%Hcall to %D will always overflow destination buffer",
9879 &locus, get_callee_fndecl (exp));
9883 /* Fold a call to __builtin_object_size, if possible. */
9885 tree
9886 fold_builtin_object_size (tree arglist)
9888 tree ptr, ost, ret = 0;
9889 int object_size_type;
9891 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9892 return 0;
9894 ptr = TREE_VALUE (arglist);
9895 ost = TREE_VALUE (TREE_CHAIN (arglist));
9896 STRIP_NOPS (ost);
9898 if (TREE_CODE (ost) != INTEGER_CST
9899 || tree_int_cst_sgn (ost) < 0
9900 || compare_tree_int (ost, 3) > 0)
9901 return 0;
9903 object_size_type = tree_low_cst (ost, 0);
9905 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9906 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9907 and (size_t) 0 for types 2 and 3. */
9908 if (TREE_SIDE_EFFECTS (ptr))
9909 return fold_convert (size_type_node,
9910 object_size_type < 2
9911 ? integer_minus_one_node : integer_zero_node);
9913 if (TREE_CODE (ptr) == ADDR_EXPR)
9914 ret = build_int_cstu (size_type_node,
9915 compute_builtin_object_size (ptr, object_size_type));
9917 else if (TREE_CODE (ptr) == SSA_NAME)
9919 unsigned HOST_WIDE_INT bytes;
9921 /* If object size is not known yet, delay folding until
9922 later. Maybe subsequent passes will help determining
9923 it. */
9924 bytes = compute_builtin_object_size (ptr, object_size_type);
9925 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
9926 ? -1 : 0))
9927 ret = build_int_cstu (size_type_node, bytes);
9930 if (ret)
9932 ret = force_fit_type (ret, -1, false, false);
9933 if (TREE_CONSTANT_OVERFLOW (ret))
9934 ret = 0;
9937 return ret;
9940 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9941 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
9942 code of the builtin. If MAXLEN is not NULL, it is maximum length
9943 passed as third argument. */
9945 tree
9946 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
9947 enum built_in_function fcode)
9949 tree dest, src, len, size, fn;
9951 if (!validate_arglist (arglist,
9952 POINTER_TYPE,
9953 fcode == BUILT_IN_MEMSET_CHK
9954 ? INTEGER_TYPE : POINTER_TYPE,
9955 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9956 return 0;
9958 dest = TREE_VALUE (arglist);
9959 /* Actually val for __memset_chk, but it doesn't matter. */
9960 src = TREE_VALUE (TREE_CHAIN (arglist));
9961 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9962 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9964 /* If SRC and DEST are the same (and not volatile), return DEST
9965 (resp. DEST+LEN for __mempcpy_chk). */
9966 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
9968 if (fcode != BUILT_IN_MEMPCPY_CHK)
9969 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
9970 else
9972 tree temp = fold_convert (TREE_TYPE (dest), len);
9973 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
9974 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
9978 if (! host_integerp (size, 1))
9979 return 0;
9981 if (! integer_all_onesp (size))
9983 if (! host_integerp (len, 1))
9985 /* If LEN is not constant, try MAXLEN too.
9986 For MAXLEN only allow optimizing into non-_ocs function
9987 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
9988 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
9990 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
9992 /* (void) __mempcpy_chk () can be optimized into
9993 (void) __memcpy_chk (). */
9994 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9995 if (!fn)
9996 return 0;
9998 return build_function_call_expr (fn, arglist);
10000 return 0;
10003 else
10004 maxlen = len;
10006 if (tree_int_cst_lt (size, maxlen))
10007 return 0;
10010 arglist = build_tree_list (NULL_TREE, len);
10011 arglist = tree_cons (NULL_TREE, src, arglist);
10012 arglist = tree_cons (NULL_TREE, dest, arglist);
10014 fn = NULL_TREE;
10015 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10016 mem{cpy,pcpy,move,set} is available. */
10017 switch (fcode)
10019 case BUILT_IN_MEMCPY_CHK:
10020 fn = built_in_decls[BUILT_IN_MEMCPY];
10021 break;
10022 case BUILT_IN_MEMPCPY_CHK:
10023 fn = built_in_decls[BUILT_IN_MEMPCPY];
10024 break;
10025 case BUILT_IN_MEMMOVE_CHK:
10026 fn = built_in_decls[BUILT_IN_MEMMOVE];
10027 break;
10028 case BUILT_IN_MEMSET_CHK:
10029 fn = built_in_decls[BUILT_IN_MEMSET];
10030 break;
10031 default:
10032 break;
10035 if (!fn)
10036 return 0;
10038 return build_function_call_expr (fn, arglist);
10041 /* Fold a call to the __st[rp]cpy_chk builtin.
10042 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10043 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10044 strings passed as second argument. */
10046 tree
10047 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10048 enum built_in_function fcode)
10050 tree dest, src, size, len, fn;
10052 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10053 VOID_TYPE))
10054 return 0;
10056 dest = TREE_VALUE (arglist);
10057 src = TREE_VALUE (TREE_CHAIN (arglist));
10058 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10060 /* If SRC and DEST are the same (and not volatile), return DEST. */
10061 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10062 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10064 if (! host_integerp (size, 1))
10065 return 0;
10067 if (! integer_all_onesp (size))
10069 len = c_strlen (src, 1);
10070 if (! len || ! host_integerp (len, 1))
10072 /* If LEN is not constant, try MAXLEN too.
10073 For MAXLEN only allow optimizing into non-_ocs function
10074 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10075 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10077 if (fcode == BUILT_IN_STPCPY_CHK)
10079 if (! ignore)
10080 return 0;
10082 /* If return value of __stpcpy_chk is ignored,
10083 optimize into __strcpy_chk. */
10084 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10085 if (!fn)
10086 return 0;
10088 return build_function_call_expr (fn, arglist);
10091 if (! len || TREE_SIDE_EFFECTS (len))
10092 return 0;
10094 /* If c_strlen returned something, but not a constant,
10095 transform __strcpy_chk into __memcpy_chk. */
10096 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10097 if (!fn)
10098 return 0;
10100 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10101 arglist = build_tree_list (NULL_TREE, size);
10102 arglist = tree_cons (NULL_TREE, len, arglist);
10103 arglist = tree_cons (NULL_TREE, src, arglist);
10104 arglist = tree_cons (NULL_TREE, dest, arglist);
10105 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10106 build_function_call_expr (fn, arglist));
10109 else
10110 maxlen = len;
10112 if (! tree_int_cst_lt (maxlen, size))
10113 return 0;
10116 arglist = build_tree_list (NULL_TREE, src);
10117 arglist = tree_cons (NULL_TREE, dest, arglist);
10119 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10120 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10121 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10122 if (!fn)
10123 return 0;
10125 return build_function_call_expr (fn, arglist);
10128 /* Fold a call to the __strncpy_chk builtin.
10129 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10131 tree
10132 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10134 tree dest, src, size, len, fn;
10136 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10137 INTEGER_TYPE, VOID_TYPE))
10138 return 0;
10140 dest = TREE_VALUE (arglist);
10141 src = TREE_VALUE (TREE_CHAIN (arglist));
10142 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10143 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10145 if (! host_integerp (size, 1))
10146 return 0;
10148 if (! integer_all_onesp (size))
10150 if (! host_integerp (len, 1))
10152 /* If LEN is not constant, try MAXLEN too.
10153 For MAXLEN only allow optimizing into non-_ocs function
10154 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10155 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10156 return 0;
10158 else
10159 maxlen = len;
10161 if (tree_int_cst_lt (size, maxlen))
10162 return 0;
10165 arglist = build_tree_list (NULL_TREE, len);
10166 arglist = tree_cons (NULL_TREE, src, arglist);
10167 arglist = tree_cons (NULL_TREE, dest, arglist);
10169 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10170 fn = built_in_decls[BUILT_IN_STRNCPY];
10171 if (!fn)
10172 return 0;
10174 return build_function_call_expr (fn, arglist);
10177 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10179 static tree
10180 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10182 tree dest, src, size, fn;
10183 const char *p;
10185 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10186 VOID_TYPE))
10187 return 0;
10189 dest = TREE_VALUE (arglist);
10190 src = TREE_VALUE (TREE_CHAIN (arglist));
10191 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10193 p = c_getstr (src);
10194 /* If the SRC parameter is "", return DEST. */
10195 if (p && *p == '\0')
10196 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10198 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10199 return 0;
10201 arglist = build_tree_list (NULL_TREE, src);
10202 arglist = tree_cons (NULL_TREE, dest, arglist);
10204 /* If __builtin_strcat_chk is used, assume strcat is available. */
10205 fn = built_in_decls[BUILT_IN_STRCAT];
10206 if (!fn)
10207 return 0;
10209 return build_function_call_expr (fn, arglist);
10212 /* Fold a call to the __strncat_chk builtin EXP. */
10214 static tree
10215 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10217 tree dest, src, size, len, fn;
10218 const char *p;
10220 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10221 INTEGER_TYPE, VOID_TYPE))
10222 return 0;
10224 dest = TREE_VALUE (arglist);
10225 src = TREE_VALUE (TREE_CHAIN (arglist));
10226 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10227 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10229 p = c_getstr (src);
10230 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10231 if (p && *p == '\0')
10232 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10233 else if (integer_zerop (len))
10234 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10236 if (! host_integerp (size, 1))
10237 return 0;
10239 if (! integer_all_onesp (size))
10241 tree src_len = c_strlen (src, 1);
10242 if (src_len
10243 && host_integerp (src_len, 1)
10244 && host_integerp (len, 1)
10245 && ! tree_int_cst_lt (len, src_len))
10247 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10248 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10249 if (!fn)
10250 return 0;
10252 arglist = build_tree_list (NULL_TREE, size);
10253 arglist = tree_cons (NULL_TREE, src, arglist);
10254 arglist = tree_cons (NULL_TREE, dest, arglist);
10255 return build_function_call_expr (fn, arglist);
10257 return 0;
10260 arglist = build_tree_list (NULL_TREE, len);
10261 arglist = tree_cons (NULL_TREE, src, arglist);
10262 arglist = tree_cons (NULL_TREE, dest, arglist);
10264 /* If __builtin_strncat_chk is used, assume strncat is available. */
10265 fn = built_in_decls[BUILT_IN_STRNCAT];
10266 if (!fn)
10267 return 0;
10269 return build_function_call_expr (fn, arglist);
10272 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10273 a normal call should be emitted rather than expanding the function
10274 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10276 static tree
10277 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10279 tree dest, size, len, fn, fmt, flag;
10280 const char *fmt_str;
10282 /* Verify the required arguments in the original call. */
10283 if (! arglist)
10284 return 0;
10285 dest = TREE_VALUE (arglist);
10286 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10287 return 0;
10288 arglist = TREE_CHAIN (arglist);
10289 if (! arglist)
10290 return 0;
10291 flag = TREE_VALUE (arglist);
10292 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10293 return 0;
10294 arglist = TREE_CHAIN (arglist);
10295 if (! arglist)
10296 return 0;
10297 size = TREE_VALUE (arglist);
10298 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10299 return 0;
10300 arglist = TREE_CHAIN (arglist);
10301 if (! arglist)
10302 return 0;
10303 fmt = TREE_VALUE (arglist);
10304 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10305 return 0;
10306 arglist = TREE_CHAIN (arglist);
10308 if (! host_integerp (size, 1))
10309 return 0;
10311 len = NULL_TREE;
10313 if (!init_target_chars())
10314 return 0;
10316 /* Check whether the format is a literal string constant. */
10317 fmt_str = c_getstr (fmt);
10318 if (fmt_str != NULL)
10320 /* If the format doesn't contain % args or %%, we know the size. */
10321 if (strchr (fmt_str, target_percent) == 0)
10323 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10324 len = build_int_cstu (size_type_node, strlen (fmt_str));
10326 /* If the format is "%s" and first ... argument is a string literal,
10327 we know the size too. */
10328 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10330 tree arg;
10332 if (arglist && !TREE_CHAIN (arglist))
10334 arg = TREE_VALUE (arglist);
10335 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10337 len = c_strlen (arg, 1);
10338 if (! len || ! host_integerp (len, 1))
10339 len = NULL_TREE;
10345 if (! integer_all_onesp (size))
10347 if (! len || ! tree_int_cst_lt (len, size))
10348 return 0;
10351 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10352 or if format doesn't contain % chars or is "%s". */
10353 if (! integer_zerop (flag))
10355 if (fmt_str == NULL)
10356 return 0;
10357 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10358 return 0;
10361 arglist = tree_cons (NULL_TREE, fmt, arglist);
10362 arglist = tree_cons (NULL_TREE, dest, arglist);
10364 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10365 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10366 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10367 if (!fn)
10368 return 0;
10370 return build_function_call_expr (fn, arglist);
10373 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10374 a normal call should be emitted rather than expanding the function
10375 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10376 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10377 passed as second argument. */
10379 tree
10380 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10381 enum built_in_function fcode)
10383 tree dest, size, len, fn, fmt, flag;
10384 const char *fmt_str;
10386 /* Verify the required arguments in the original call. */
10387 if (! arglist)
10388 return 0;
10389 dest = TREE_VALUE (arglist);
10390 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10391 return 0;
10392 arglist = TREE_CHAIN (arglist);
10393 if (! arglist)
10394 return 0;
10395 len = TREE_VALUE (arglist);
10396 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10397 return 0;
10398 arglist = TREE_CHAIN (arglist);
10399 if (! arglist)
10400 return 0;
10401 flag = TREE_VALUE (arglist);
10402 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10403 return 0;
10404 arglist = TREE_CHAIN (arglist);
10405 if (! arglist)
10406 return 0;
10407 size = TREE_VALUE (arglist);
10408 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10409 return 0;
10410 arglist = TREE_CHAIN (arglist);
10411 if (! arglist)
10412 return 0;
10413 fmt = TREE_VALUE (arglist);
10414 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10415 return 0;
10416 arglist = TREE_CHAIN (arglist);
10418 if (! host_integerp (size, 1))
10419 return 0;
10421 if (! integer_all_onesp (size))
10423 if (! host_integerp (len, 1))
10425 /* If LEN is not constant, try MAXLEN too.
10426 For MAXLEN only allow optimizing into non-_ocs function
10427 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10428 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10429 return 0;
10431 else
10432 maxlen = len;
10434 if (tree_int_cst_lt (size, maxlen))
10435 return 0;
10438 if (!init_target_chars())
10439 return 0;
10441 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10442 or if format doesn't contain % chars or is "%s". */
10443 if (! integer_zerop (flag))
10445 fmt_str = c_getstr (fmt);
10446 if (fmt_str == NULL)
10447 return 0;
10448 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10449 return 0;
10452 arglist = tree_cons (NULL_TREE, fmt, arglist);
10453 arglist = tree_cons (NULL_TREE, len, arglist);
10454 arglist = tree_cons (NULL_TREE, dest, arglist);
10456 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10457 available. */
10458 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10459 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10460 if (!fn)
10461 return 0;
10463 return build_function_call_expr (fn, arglist);
10466 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10468 Return 0 if no simplification was possible, otherwise return the
10469 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10470 code of the function to be simplified. */
10472 static tree
10473 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10474 enum built_in_function fcode)
10476 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10477 const char *fmt_str = NULL;
10479 /* If the return value is used, don't do the transformation. */
10480 if (! ignore)
10481 return 0;
10483 /* Verify the required arguments in the original call. */
10484 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10486 tree flag;
10488 if (! arglist)
10489 return 0;
10490 flag = TREE_VALUE (arglist);
10491 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10492 || TREE_SIDE_EFFECTS (flag))
10493 return 0;
10494 arglist = TREE_CHAIN (arglist);
10497 if (! arglist)
10498 return 0;
10499 fmt = TREE_VALUE (arglist);
10500 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10501 return 0;
10502 arglist = TREE_CHAIN (arglist);
10504 /* Check whether the format is a literal string constant. */
10505 fmt_str = c_getstr (fmt);
10506 if (fmt_str == NULL)
10507 return NULL_TREE;
10509 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10511 /* If we're using an unlocked function, assume the other
10512 unlocked functions exist explicitly. */
10513 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10514 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10516 else
10518 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10519 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10522 if (!init_target_chars())
10523 return 0;
10525 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10527 const char *str;
10529 if (strcmp (fmt_str, target_percent_s) == 0)
10531 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10532 return 0;
10534 if (! arglist
10535 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10536 || TREE_CHAIN (arglist))
10537 return 0;
10539 str = c_getstr (TREE_VALUE (arglist));
10540 if (str == NULL)
10541 return 0;
10543 else
10545 /* The format specifier doesn't contain any '%' characters. */
10546 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10547 && arglist)
10548 return 0;
10549 str = fmt_str;
10552 /* If the string was "", printf does nothing. */
10553 if (str[0] == '\0')
10554 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10556 /* If the string has length of 1, call putchar. */
10557 if (str[1] == '\0')
10559 /* Given printf("c"), (where c is any one character,)
10560 convert "c"[0] to an int and pass that to the replacement
10561 function. */
10562 arg = build_int_cst (NULL_TREE, str[0]);
10563 arglist = build_tree_list (NULL_TREE, arg);
10564 fn = fn_putchar;
10566 else
10568 /* If the string was "string\n", call puts("string"). */
10569 size_t len = strlen (str);
10570 if ((unsigned char)str[len - 1] == target_newline)
10572 /* Create a NUL-terminated string that's one char shorter
10573 than the original, stripping off the trailing '\n'. */
10574 char *newstr = alloca (len);
10575 memcpy (newstr, str, len - 1);
10576 newstr[len - 1] = 0;
10578 arg = build_string_literal (len, newstr);
10579 arglist = build_tree_list (NULL_TREE, arg);
10580 fn = fn_puts;
10582 else
10583 /* We'd like to arrange to call fputs(string,stdout) here,
10584 but we need stdout and don't have a way to get it yet. */
10585 return 0;
10589 /* The other optimizations can be done only on the non-va_list variants. */
10590 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10591 return 0;
10593 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10594 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10596 if (! arglist
10597 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10598 || TREE_CHAIN (arglist))
10599 return 0;
10600 fn = fn_puts;
10603 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10604 else if (strcmp (fmt_str, target_percent_c) == 0)
10606 if (! arglist
10607 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10608 || TREE_CHAIN (arglist))
10609 return 0;
10610 fn = fn_putchar;
10613 if (!fn)
10614 return 0;
10616 call = build_function_call_expr (fn, arglist);
10617 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10620 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10622 Return 0 if no simplification was possible, otherwise return the
10623 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10624 code of the function to be simplified. */
10626 static tree
10627 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10628 enum built_in_function fcode)
10630 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10631 const char *fmt_str = NULL;
10633 /* If the return value is used, don't do the transformation. */
10634 if (! ignore)
10635 return 0;
10637 /* Verify the required arguments in the original call. */
10638 if (! arglist)
10639 return 0;
10640 fp = TREE_VALUE (arglist);
10641 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10642 return 0;
10643 arglist = TREE_CHAIN (arglist);
10645 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10647 tree flag;
10649 if (! arglist)
10650 return 0;
10651 flag = TREE_VALUE (arglist);
10652 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10653 || TREE_SIDE_EFFECTS (flag))
10654 return 0;
10655 arglist = TREE_CHAIN (arglist);
10658 if (! arglist)
10659 return 0;
10660 fmt = TREE_VALUE (arglist);
10661 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10662 return 0;
10663 arglist = TREE_CHAIN (arglist);
10665 /* Check whether the format is a literal string constant. */
10666 fmt_str = c_getstr (fmt);
10667 if (fmt_str == NULL)
10668 return NULL_TREE;
10670 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10672 /* If we're using an unlocked function, assume the other
10673 unlocked functions exist explicitly. */
10674 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10675 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10677 else
10679 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10680 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10683 if (!init_target_chars())
10684 return 0;
10686 /* If the format doesn't contain % args or %%, use strcpy. */
10687 if (strchr (fmt_str, target_percent) == NULL)
10689 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10690 && arglist)
10691 return 0;
10693 /* If the format specifier was "", fprintf does nothing. */
10694 if (fmt_str[0] == '\0')
10696 /* If FP has side-effects, just wait until gimplification is
10697 done. */
10698 if (TREE_SIDE_EFFECTS (fp))
10699 return 0;
10701 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10704 /* When "string" doesn't contain %, replace all cases of
10705 fprintf (fp, string) with fputs (string, fp). The fputs
10706 builtin will take care of special cases like length == 1. */
10707 arglist = build_tree_list (NULL_TREE, fp);
10708 arglist = tree_cons (NULL_TREE, fmt, arglist);
10709 fn = fn_fputs;
10712 /* The other optimizations can be done only on the non-va_list variants. */
10713 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10714 return 0;
10716 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10717 else if (strcmp (fmt_str, target_percent_s) == 0)
10719 if (! arglist
10720 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10721 || TREE_CHAIN (arglist))
10722 return 0;
10723 arg = TREE_VALUE (arglist);
10724 arglist = build_tree_list (NULL_TREE, fp);
10725 arglist = tree_cons (NULL_TREE, arg, arglist);
10726 fn = fn_fputs;
10729 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10730 else if (strcmp (fmt_str, target_percent_c) == 0)
10732 if (! arglist
10733 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10734 || TREE_CHAIN (arglist))
10735 return 0;
10736 arg = TREE_VALUE (arglist);
10737 arglist = build_tree_list (NULL_TREE, fp);
10738 arglist = tree_cons (NULL_TREE, arg, arglist);
10739 fn = fn_fputc;
10742 if (!fn)
10743 return 0;
10745 call = build_function_call_expr (fn, arglist);
10746 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10749 /* Initialize format string characters in the target charset. */
10751 static bool
10752 init_target_chars (void)
10754 static bool init;
10755 if (!init)
10757 target_newline = lang_hooks.to_target_charset ('\n');
10758 target_percent = lang_hooks.to_target_charset ('%');
10759 target_c = lang_hooks.to_target_charset ('c');
10760 target_s = lang_hooks.to_target_charset ('s');
10761 if (target_newline == 0 || target_percent == 0 || target_c == 0
10762 || target_s == 0)
10763 return false;
10765 target_percent_c[0] = target_percent;
10766 target_percent_c[1] = target_c;
10767 target_percent_c[2] = '\0';
10769 target_percent_s[0] = target_percent;
10770 target_percent_s[1] = target_s;
10771 target_percent_s[2] = '\0';
10773 target_percent_s_newline[0] = target_percent;
10774 target_percent_s_newline[1] = target_s;
10775 target_percent_s_newline[2] = target_newline;
10776 target_percent_s_newline[3] = '\0';
10778 init = true;
10780 return true;