2004-10-07 J"orn Rennecke <joern.rennecke@st.com>
[official-gcc.git] / gcc / builtins.c
blob11fd5687a0efac265db33a5ebf24ec13331fd814
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, 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 #define CALLED_AS_BUILT_IN(NODE) \
52 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
54 #ifndef PAD_VARARGS_DOWN
55 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 #endif
58 /* Define the names of the builtin function types and codes. */
59 const char *const built_in_class_names[4]
60 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
62 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
63 const char *const built_in_names[(int) END_BUILTINS] =
65 #include "builtins.def"
67 #undef DEF_BUILTIN
69 /* Setup an array of _DECL trees, make sure each element is
70 initialized to NULL_TREE. */
71 tree built_in_decls[(int) END_BUILTINS];
72 /* Declarations used when constructing the builtin implicitly in the compiler.
73 It may be NULL_TREE when this is invalid (for instance runtime is not
74 required to implement the function call in all cases). */
75 tree implicit_built_in_decls[(int) END_BUILTINS];
77 static int get_pointer_alignment (tree, unsigned int);
78 static const char *c_getstr (tree);
79 static rtx c_readstr (const char *, enum machine_mode);
80 static int target_char_cast (tree, char *);
81 static rtx get_memory_rtx (tree);
82 static tree build_string_literal (int, const char *);
83 static int apply_args_size (void);
84 static int apply_result_size (void);
85 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
86 static rtx result_vector (int, rtx);
87 #endif
88 static rtx expand_builtin_setjmp (tree, rtx);
89 static void expand_builtin_update_setjmp_buf (rtx);
90 static void expand_builtin_prefetch (tree);
91 static rtx expand_builtin_apply_args (void);
92 static rtx expand_builtin_apply_args_1 (void);
93 static rtx expand_builtin_apply (rtx, rtx, rtx);
94 static void expand_builtin_return (rtx);
95 static enum type_class type_to_class (tree);
96 static rtx expand_builtin_classify_type (tree);
97 static void expand_errno_check (tree, rtx);
98 static rtx expand_builtin_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
101 static rtx expand_builtin_args_info (tree);
102 static rtx expand_builtin_next_arg (tree);
103 static rtx expand_builtin_va_start (tree);
104 static rtx expand_builtin_va_end (tree);
105 static rtx expand_builtin_va_copy (tree);
106 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
109 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
110 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
116 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_bcopy (tree, tree);
118 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
120 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
122 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_bzero (tree);
126 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
131 static rtx expand_builtin_alloca (tree, rtx);
132 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
133 static rtx expand_builtin_frame_address (tree, tree);
134 static rtx expand_builtin_fputs (tree, rtx, bool);
135 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
137 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
138 static tree stabilize_va_list (tree, int);
139 static rtx expand_builtin_expect (tree, rtx);
140 static tree fold_builtin_constant_p (tree);
141 static tree fold_builtin_classify_type (tree);
142 static tree fold_builtin_strlen (tree);
143 static tree fold_builtin_inf (tree, int);
144 static tree fold_builtin_nan (tree, tree, int);
145 static int validate_arglist (tree, ...);
146 static bool integer_valued_real_p (tree);
147 static tree fold_trunc_transparent_mathfn (tree);
148 static bool readonly_data_expr (tree);
149 static rtx expand_builtin_fabs (tree, rtx, rtx);
150 static rtx expand_builtin_signbit (tree, rtx);
151 static tree fold_builtin_cabs (tree, tree);
152 static tree fold_builtin_sqrt (tree, tree);
153 static tree fold_builtin_cbrt (tree, tree);
154 static tree fold_builtin_pow (tree, tree, tree);
155 static tree fold_builtin_sin (tree);
156 static tree fold_builtin_cos (tree, tree, tree);
157 static tree fold_builtin_tan (tree);
158 static tree fold_builtin_atan (tree, tree);
159 static tree fold_builtin_trunc (tree);
160 static tree fold_builtin_floor (tree);
161 static tree fold_builtin_ceil (tree);
162 static tree fold_builtin_round (tree);
163 static tree fold_builtin_bitop (tree);
164 static tree fold_builtin_memcpy (tree);
165 static tree fold_builtin_mempcpy (tree);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (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);
172 static tree fold_builtin_copysign (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, enum tree_code, enum tree_code);
179 static tree fold_builtin_1 (tree, bool);
181 static tree fold_builtin_strpbrk (tree);
182 static tree fold_builtin_strstr (tree);
183 static tree fold_builtin_strrchr (tree);
184 static tree fold_builtin_strcat (tree);
185 static tree fold_builtin_strncat (tree);
186 static tree fold_builtin_strspn (tree);
187 static tree fold_builtin_strcspn (tree);
188 static void fold_builtin_next_arg (tree);
189 static tree fold_builtin_sprintf (tree, int);
192 /* Return the alignment in bits of EXP, a pointer valued expression.
193 But don't return more than MAX_ALIGN no matter what.
194 The alignment returned is, by default, the alignment of the thing that
195 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
197 Otherwise, look at the expression to see if we can do better, i.e., if the
198 expression is actually pointing at an object whose alignment is tighter. */
200 static int
201 get_pointer_alignment (tree exp, unsigned int max_align)
203 unsigned int align, inner;
205 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
206 return 0;
208 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
209 align = MIN (align, max_align);
211 while (1)
213 switch (TREE_CODE (exp))
215 case NOP_EXPR:
216 case CONVERT_EXPR:
217 case NON_LVALUE_EXPR:
218 exp = TREE_OPERAND (exp, 0);
219 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
220 return align;
222 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
223 align = MIN (inner, max_align);
224 break;
226 case PLUS_EXPR:
227 /* If sum of pointer + int, restrict our maximum alignment to that
228 imposed by the integer. If not, we can't do any better than
229 ALIGN. */
230 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
231 return align;
233 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
234 & (max_align / BITS_PER_UNIT - 1))
235 != 0)
236 max_align >>= 1;
238 exp = TREE_OPERAND (exp, 0);
239 break;
241 case ADDR_EXPR:
242 /* See what we are pointing at and look at its alignment. */
243 exp = TREE_OPERAND (exp, 0);
244 if (TREE_CODE (exp) == FUNCTION_DECL)
245 align = FUNCTION_BOUNDARY;
246 else if (DECL_P (exp))
247 align = DECL_ALIGN (exp);
248 #ifdef CONSTANT_ALIGNMENT
249 else if (CONSTANT_CLASS_P (exp))
250 align = CONSTANT_ALIGNMENT (exp, align);
251 #endif
252 return MIN (align, max_align);
254 default:
255 return align;
260 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
261 way, because it could contain a zero byte in the middle.
262 TREE_STRING_LENGTH is the size of the character array, not the string.
264 ONLY_VALUE should be nonzero if the result is not going to be emitted
265 into the instruction stream and zero if it is going to be expanded.
266 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
267 is returned, otherwise NULL, since
268 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
269 evaluate the side-effects.
271 The value returned is of type `ssizetype'.
273 Unfortunately, string_constant can't access the values of const char
274 arrays with initializers, so neither can we do so here. */
276 tree
277 c_strlen (tree src, int only_value)
279 tree offset_node;
280 HOST_WIDE_INT offset;
281 int max;
282 const char *ptr;
284 STRIP_NOPS (src);
285 if (TREE_CODE (src) == COND_EXPR
286 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
288 tree len1, len2;
290 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
291 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
292 if (tree_int_cst_equal (len1, len2))
293 return len1;
296 if (TREE_CODE (src) == COMPOUND_EXPR
297 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
298 return c_strlen (TREE_OPERAND (src, 1), only_value);
300 src = string_constant (src, &offset_node);
301 if (src == 0)
302 return 0;
304 max = TREE_STRING_LENGTH (src) - 1;
305 ptr = TREE_STRING_POINTER (src);
307 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
309 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
310 compute the offset to the following null if we don't know where to
311 start searching for it. */
312 int i;
314 for (i = 0; i < max; i++)
315 if (ptr[i] == 0)
316 return 0;
318 /* We don't know the starting offset, but we do know that the string
319 has no internal zero bytes. We can assume that the offset falls
320 within the bounds of the string; otherwise, the programmer deserves
321 what he gets. Subtract the offset from the length of the string,
322 and return that. This would perhaps not be valid if we were dealing
323 with named arrays in addition to literal string constants. */
325 return size_diffop (size_int (max), offset_node);
328 /* We have a known offset into the string. Start searching there for
329 a null character if we can represent it as a single HOST_WIDE_INT. */
330 if (offset_node == 0)
331 offset = 0;
332 else if (! host_integerp (offset_node, 0))
333 offset = -1;
334 else
335 offset = tree_low_cst (offset_node, 0);
337 /* If the offset is known to be out of bounds, warn, and call strlen at
338 runtime. */
339 if (offset < 0 || offset > max)
341 warning ("offset outside bounds of constant string");
342 return 0;
345 /* Use strlen to search for the first zero byte. Since any strings
346 constructed with build_string will have nulls appended, we win even
347 if we get handed something like (char[4])"abcd".
349 Since OFFSET is our starting index into the string, no further
350 calculation is needed. */
351 return ssize_int (strlen (ptr + offset));
354 /* Return a char pointer for a C string if it is a string constant
355 or sum of string constant and integer constant. */
357 static const char *
358 c_getstr (tree src)
360 tree offset_node;
362 src = string_constant (src, &offset_node);
363 if (src == 0)
364 return 0;
366 if (offset_node == 0)
367 return TREE_STRING_POINTER (src);
368 else if (!host_integerp (offset_node, 1)
369 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
370 return 0;
372 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
375 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
376 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
378 static rtx
379 c_readstr (const char *str, enum machine_mode mode)
381 HOST_WIDE_INT c[2];
382 HOST_WIDE_INT ch;
383 unsigned int i, j;
385 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
387 c[0] = 0;
388 c[1] = 0;
389 ch = 1;
390 for (i = 0; i < GET_MODE_SIZE (mode); i++)
392 j = i;
393 if (WORDS_BIG_ENDIAN)
394 j = GET_MODE_SIZE (mode) - i - 1;
395 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
396 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
397 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
398 j *= BITS_PER_UNIT;
399 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
401 if (ch)
402 ch = (unsigned char) str[i];
403 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
405 return immed_double_const (c[0], c[1], mode);
408 /* Cast a target constant CST to target CHAR and if that value fits into
409 host char type, return zero and put that value into variable pointed by
410 P. */
412 static int
413 target_char_cast (tree cst, char *p)
415 unsigned HOST_WIDE_INT val, hostval;
417 if (!host_integerp (cst, 1)
418 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
419 return 1;
421 val = tree_low_cst (cst, 1);
422 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
423 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
425 hostval = val;
426 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
427 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
429 if (val != hostval)
430 return 1;
432 *p = hostval;
433 return 0;
436 /* Similar to save_expr, but assumes that arbitrary code is not executed
437 in between the multiple evaluations. In particular, we assume that a
438 non-addressable local variable will not be modified. */
440 static tree
441 builtin_save_expr (tree exp)
443 if (TREE_ADDRESSABLE (exp) == 0
444 && (TREE_CODE (exp) == PARM_DECL
445 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
446 return exp;
448 return save_expr (exp);
451 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
452 times to get the address of either a higher stack frame, or a return
453 address located within it (depending on FNDECL_CODE). */
456 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
457 rtx tem)
459 int i;
461 /* Some machines need special handling before we can access
462 arbitrary frames. For example, on the sparc, we must first flush
463 all register windows to the stack. */
464 #ifdef SETUP_FRAME_ADDRESSES
465 if (count > 0)
466 SETUP_FRAME_ADDRESSES ();
467 #endif
469 /* On the sparc, the return address is not in the frame, it is in a
470 register. There is no way to access it off of the current frame
471 pointer, but it can be accessed off the previous frame pointer by
472 reading the value from the register window save area. */
473 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
474 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
475 count--;
476 #endif
478 /* Scan back COUNT frames to the specified frame. */
479 for (i = 0; i < count; i++)
481 /* Assume the dynamic chain pointer is in the word that the
482 frame address points to, unless otherwise specified. */
483 #ifdef DYNAMIC_CHAIN_ADDRESS
484 tem = DYNAMIC_CHAIN_ADDRESS (tem);
485 #endif
486 tem = memory_address (Pmode, tem);
487 tem = gen_rtx_MEM (Pmode, tem);
488 set_mem_alias_set (tem, get_frame_alias_set ());
489 tem = copy_to_reg (tem);
492 /* For __builtin_frame_address, return what we've got. */
493 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
494 return tem;
496 /* For __builtin_return_address, Get the return address from that
497 frame. */
498 #ifdef RETURN_ADDR_RTX
499 tem = RETURN_ADDR_RTX (count, tem);
500 #else
501 tem = memory_address (Pmode,
502 plus_constant (tem, GET_MODE_SIZE (Pmode)));
503 tem = gen_rtx_MEM (Pmode, tem);
504 set_mem_alias_set (tem, get_frame_alias_set ());
505 #endif
506 return tem;
509 /* Alias set used for setjmp buffer. */
510 static HOST_WIDE_INT setjmp_alias_set = -1;
512 /* Construct the leading half of a __builtin_setjmp call. Control will
513 return to RECEIVER_LABEL. This is used directly by sjlj exception
514 handling code. */
516 void
517 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
519 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
520 rtx stack_save;
521 rtx mem;
523 if (setjmp_alias_set == -1)
524 setjmp_alias_set = new_alias_set ();
526 buf_addr = convert_memory_address (Pmode, buf_addr);
528 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
530 /* We store the frame pointer and the address of receiver_label in
531 the buffer and use the rest of it for the stack save area, which
532 is machine-dependent. */
534 mem = gen_rtx_MEM (Pmode, buf_addr);
535 set_mem_alias_set (mem, setjmp_alias_set);
536 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
538 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
539 set_mem_alias_set (mem, setjmp_alias_set);
541 emit_move_insn (validize_mem (mem),
542 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
544 stack_save = gen_rtx_MEM (sa_mode,
545 plus_constant (buf_addr,
546 2 * GET_MODE_SIZE (Pmode)));
547 set_mem_alias_set (stack_save, setjmp_alias_set);
548 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
550 /* If there is further processing to do, do it. */
551 #ifdef HAVE_builtin_setjmp_setup
552 if (HAVE_builtin_setjmp_setup)
553 emit_insn (gen_builtin_setjmp_setup (buf_addr));
554 #endif
556 /* Tell optimize_save_area_alloca that extra work is going to
557 need to go on during alloca. */
558 current_function_calls_setjmp = 1;
560 /* Set this so all the registers get saved in our frame; we need to be
561 able to copy the saved values for any registers from frames we unwind. */
562 current_function_has_nonlocal_label = 1;
565 /* Construct the trailing part of a __builtin_setjmp call.
566 This is used directly by sjlj exception handling code. */
568 void
569 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
571 /* Clobber the FP when we get here, so we have to make sure it's
572 marked as used by this function. */
573 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
575 /* Mark the static chain as clobbered here so life information
576 doesn't get messed up for it. */
577 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
579 /* Now put in the code to restore the frame pointer, and argument
580 pointer, if needed. */
581 #ifdef HAVE_nonlocal_goto
582 if (! HAVE_nonlocal_goto)
583 #endif
584 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
586 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
587 if (fixed_regs[ARG_POINTER_REGNUM])
589 #ifdef ELIMINABLE_REGS
590 size_t i;
591 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
593 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
594 if (elim_regs[i].from == ARG_POINTER_REGNUM
595 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
596 break;
598 if (i == ARRAY_SIZE (elim_regs))
599 #endif
601 /* Now restore our arg pointer from the address at which it
602 was saved in our stack frame. */
603 emit_move_insn (virtual_incoming_args_rtx,
604 copy_to_reg (get_arg_pointer_save_area (cfun)));
607 #endif
609 #ifdef HAVE_builtin_setjmp_receiver
610 if (HAVE_builtin_setjmp_receiver)
611 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
612 else
613 #endif
614 #ifdef HAVE_nonlocal_goto_receiver
615 if (HAVE_nonlocal_goto_receiver)
616 emit_insn (gen_nonlocal_goto_receiver ());
617 else
618 #endif
619 { /* Nothing */ }
621 /* @@@ This is a kludge. Not all machine descriptions define a blockage
622 insn, but we must not allow the code we just generated to be reordered
623 by scheduling. Specifically, the update of the frame pointer must
624 happen immediately, not later. So emit an ASM_INPUT to act as blockage
625 insn. */
626 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
629 /* __builtin_setjmp is passed a pointer to an array of five words (not
630 all will be used on all machines). It operates similarly to the C
631 library function of the same name, but is more efficient. Much of
632 the code below (and for longjmp) is copied from the handling of
633 non-local gotos.
635 NOTE: This is intended for use by GNAT and the exception handling
636 scheme in the compiler and will only work in the method used by
637 them. */
639 static rtx
640 expand_builtin_setjmp (tree arglist, rtx target)
642 rtx buf_addr, next_lab, cont_lab;
644 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
645 return NULL_RTX;
647 if (target == 0 || !REG_P (target)
648 || REGNO (target) < FIRST_PSEUDO_REGISTER)
649 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
651 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
653 next_lab = gen_label_rtx ();
654 cont_lab = gen_label_rtx ();
656 expand_builtin_setjmp_setup (buf_addr, next_lab);
658 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
659 ensure that pending stack adjustments are flushed. */
660 emit_move_insn (target, const0_rtx);
661 emit_jump (cont_lab);
663 emit_label (next_lab);
665 expand_builtin_setjmp_receiver (next_lab);
667 /* Set TARGET to one. */
668 emit_move_insn (target, const1_rtx);
669 emit_label (cont_lab);
671 /* Tell flow about the strange goings on. Putting `next_lab' on
672 `nonlocal_goto_handler_labels' to indicates that function
673 calls may traverse the arc back to this label. */
675 current_function_has_nonlocal_label = 1;
676 nonlocal_goto_handler_labels
677 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
679 return target;
682 /* __builtin_longjmp is passed a pointer to an array of five words (not
683 all will be used on all machines). It operates similarly to the C
684 library function of the same name, but is more efficient. Much of
685 the code below is copied from the handling of 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 void
692 expand_builtin_longjmp (rtx buf_addr, rtx value)
694 rtx fp, lab, stack, insn, last;
695 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
697 if (setjmp_alias_set == -1)
698 setjmp_alias_set = new_alias_set ();
700 buf_addr = convert_memory_address (Pmode, buf_addr);
702 buf_addr = force_reg (Pmode, buf_addr);
704 /* We used to store value in static_chain_rtx, but that fails if pointers
705 are smaller than integers. We instead require that the user must pass
706 a second argument of 1, because that is what builtin_setjmp will
707 return. This also makes EH slightly more efficient, since we are no
708 longer copying around a value that we don't care about. */
709 gcc_assert (value == const1_rtx);
711 current_function_calls_longjmp = 1;
713 last = get_last_insn ();
714 #ifdef HAVE_builtin_longjmp
715 if (HAVE_builtin_longjmp)
716 emit_insn (gen_builtin_longjmp (buf_addr));
717 else
718 #endif
720 fp = gen_rtx_MEM (Pmode, buf_addr);
721 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
722 GET_MODE_SIZE (Pmode)));
724 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
725 2 * GET_MODE_SIZE (Pmode)));
726 set_mem_alias_set (fp, setjmp_alias_set);
727 set_mem_alias_set (lab, setjmp_alias_set);
728 set_mem_alias_set (stack, setjmp_alias_set);
730 /* Pick up FP, label, and SP from the block and jump. This code is
731 from expand_goto in stmt.c; see there for detailed comments. */
732 #if HAVE_nonlocal_goto
733 if (HAVE_nonlocal_goto)
734 /* We have to pass a value to the nonlocal_goto pattern that will
735 get copied into the static_chain pointer, but it does not matter
736 what that value is, because builtin_setjmp does not use it. */
737 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
738 else
739 #endif
741 lab = copy_to_reg (lab);
743 emit_insn (gen_rtx_CLOBBER (VOIDmode,
744 gen_rtx_MEM (BLKmode,
745 gen_rtx_SCRATCH (VOIDmode))));
746 emit_insn (gen_rtx_CLOBBER (VOIDmode,
747 gen_rtx_MEM (BLKmode,
748 hard_frame_pointer_rtx)));
750 emit_move_insn (hard_frame_pointer_rtx, fp);
751 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
753 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
754 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
755 emit_indirect_jump (lab);
759 /* Search backwards and mark the jump insn as a non-local goto.
760 Note that this precludes the use of __builtin_longjmp to a
761 __builtin_setjmp target in the same function. However, we've
762 already cautioned the user that these functions are for
763 internal exception handling use only. */
764 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
766 gcc_assert (insn != last);
768 if (JUMP_P (insn))
770 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
771 REG_NOTES (insn));
772 break;
774 else if (CALL_P (insn))
775 break;
779 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
780 and the address of the save area. */
782 static rtx
783 expand_builtin_nonlocal_goto (tree arglist)
785 tree t_label, t_save_area;
786 rtx r_label, r_save_area, r_fp, r_sp, insn;
788 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
789 return NULL_RTX;
791 t_label = TREE_VALUE (arglist);
792 arglist = TREE_CHAIN (arglist);
793 t_save_area = TREE_VALUE (arglist);
795 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
796 r_label = convert_memory_address (Pmode, r_label);
797 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
798 r_save_area = convert_memory_address (Pmode, r_save_area);
799 r_fp = gen_rtx_MEM (Pmode, r_save_area);
800 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
801 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
803 current_function_has_nonlocal_goto = 1;
805 #if HAVE_nonlocal_goto
806 /* ??? We no longer need to pass the static chain value, afaik. */
807 if (HAVE_nonlocal_goto)
808 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
809 else
810 #endif
812 r_label = copy_to_reg (r_label);
814 emit_insn (gen_rtx_CLOBBER (VOIDmode,
815 gen_rtx_MEM (BLKmode,
816 gen_rtx_SCRATCH (VOIDmode))));
818 emit_insn (gen_rtx_CLOBBER (VOIDmode,
819 gen_rtx_MEM (BLKmode,
820 hard_frame_pointer_rtx)));
822 /* Restore frame pointer for containing function.
823 This sets the actual hard register used for the frame pointer
824 to the location of the function's incoming static chain info.
825 The non-local goto handler will then adjust it to contain the
826 proper value and reload the argument pointer, if needed. */
827 emit_move_insn (hard_frame_pointer_rtx, r_fp);
828 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
830 /* USE of hard_frame_pointer_rtx added for consistency;
831 not clear if really needed. */
832 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
833 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
834 emit_indirect_jump (r_label);
837 /* Search backwards to the jump insn and mark it as a
838 non-local goto. */
839 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
841 if (JUMP_P (insn))
843 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
844 const0_rtx, REG_NOTES (insn));
845 break;
847 else if (CALL_P (insn))
848 break;
851 return const0_rtx;
854 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
855 (not all will be used on all machines) that was passed to __builtin_setjmp.
856 It updates the stack pointer in that block to correspond to the current
857 stack pointer. */
859 static void
860 expand_builtin_update_setjmp_buf (rtx buf_addr)
862 enum machine_mode sa_mode = Pmode;
863 rtx stack_save;
866 #ifdef HAVE_save_stack_nonlocal
867 if (HAVE_save_stack_nonlocal)
868 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
869 #endif
870 #ifdef STACK_SAVEAREA_MODE
871 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
872 #endif
874 stack_save
875 = gen_rtx_MEM (sa_mode,
876 memory_address
877 (sa_mode,
878 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
880 #ifdef HAVE_setjmp
881 if (HAVE_setjmp)
882 emit_insn (gen_setjmp ());
883 #endif
885 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
888 /* Expand a call to __builtin_prefetch. For a target that does not support
889 data prefetch, evaluate the memory address argument in case it has side
890 effects. */
892 static void
893 expand_builtin_prefetch (tree arglist)
895 tree arg0, arg1, arg2;
896 rtx op0, op1, op2;
898 if (!validate_arglist (arglist, POINTER_TYPE, 0))
899 return;
901 arg0 = TREE_VALUE (arglist);
902 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
903 zero (read) and argument 2 (locality) defaults to 3 (high degree of
904 locality). */
905 if (TREE_CHAIN (arglist))
907 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
908 if (TREE_CHAIN (TREE_CHAIN (arglist)))
909 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
910 else
911 arg2 = build_int_cst (NULL_TREE, 3);
913 else
915 arg1 = integer_zero_node;
916 arg2 = build_int_cst (NULL_TREE, 3);
919 /* Argument 0 is an address. */
920 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
922 /* Argument 1 (read/write flag) must be a compile-time constant int. */
923 if (TREE_CODE (arg1) != INTEGER_CST)
925 error ("second arg to %<__builtin_prefetch%> must be a constant");
926 arg1 = integer_zero_node;
928 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
929 /* Argument 1 must be either zero or one. */
930 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
932 warning ("invalid second arg to __builtin_prefetch; using zero");
933 op1 = const0_rtx;
936 /* Argument 2 (locality) must be a compile-time constant int. */
937 if (TREE_CODE (arg2) != INTEGER_CST)
939 error ("third arg to %<__builtin_prefetch%> must be a constant");
940 arg2 = integer_zero_node;
942 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
943 /* Argument 2 must be 0, 1, 2, or 3. */
944 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
946 warning ("invalid third arg to __builtin_prefetch; using zero");
947 op2 = const0_rtx;
950 #ifdef HAVE_prefetch
951 if (HAVE_prefetch)
953 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
954 (op0,
955 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
956 || (GET_MODE (op0) != Pmode))
958 op0 = convert_memory_address (Pmode, op0);
959 op0 = force_reg (Pmode, op0);
961 emit_insn (gen_prefetch (op0, op1, op2));
963 #endif
965 /* Don't do anything with direct references to volatile memory, but
966 generate code to handle other side effects. */
967 if (!MEM_P (op0) && side_effects_p (op0))
968 emit_insn (op0);
971 /* Get a MEM rtx for expression EXP which is the address of an operand
972 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
974 static rtx
975 get_memory_rtx (tree exp)
977 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
978 rtx mem;
980 addr = convert_memory_address (Pmode, addr);
982 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
984 /* Get an expression we can use to find the attributes to assign to MEM.
985 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
986 we can. First remove any nops. */
987 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
988 || TREE_CODE (exp) == NON_LVALUE_EXPR)
989 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
990 exp = TREE_OPERAND (exp, 0);
992 if (TREE_CODE (exp) == ADDR_EXPR)
993 exp = TREE_OPERAND (exp, 0);
994 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
995 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
996 else
997 exp = NULL;
999 /* Honor attributes derived from exp, except for the alias set
1000 (as builtin stringops may alias with anything) and the size
1001 (as stringops may access multiple array elements). */
1002 if (exp)
1004 set_mem_attributes (mem, exp, 0);
1005 set_mem_alias_set (mem, 0);
1006 set_mem_size (mem, NULL_RTX);
1009 return mem;
1012 /* Built-in functions to perform an untyped call and return. */
1014 /* For each register that may be used for calling a function, this
1015 gives a mode used to copy the register's value. VOIDmode indicates
1016 the register is not used for calling a function. If the machine
1017 has register windows, this gives only the outbound registers.
1018 INCOMING_REGNO gives the corresponding inbound register. */
1019 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1021 /* For each register that may be used for returning values, this gives
1022 a mode used to copy the register's value. VOIDmode indicates the
1023 register is not used for returning values. If the machine has
1024 register windows, this gives only the outbound registers.
1025 INCOMING_REGNO gives the corresponding inbound register. */
1026 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1028 /* For each register that may be used for calling a function, this
1029 gives the offset of that register into the block returned by
1030 __builtin_apply_args. 0 indicates that the register is not
1031 used for calling a function. */
1032 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1034 /* Return the size required for the block returned by __builtin_apply_args,
1035 and initialize apply_args_mode. */
1037 static int
1038 apply_args_size (void)
1040 static int size = -1;
1041 int align;
1042 unsigned int regno;
1043 enum machine_mode mode;
1045 /* The values computed by this function never change. */
1046 if (size < 0)
1048 /* The first value is the incoming arg-pointer. */
1049 size = GET_MODE_SIZE (Pmode);
1051 /* The second value is the structure value address unless this is
1052 passed as an "invisible" first argument. */
1053 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1054 size += GET_MODE_SIZE (Pmode);
1056 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1057 if (FUNCTION_ARG_REGNO_P (regno))
1059 mode = reg_raw_mode[regno];
1061 gcc_assert (mode != VOIDmode);
1063 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1064 if (size % align != 0)
1065 size = CEIL (size, align) * align;
1066 apply_args_reg_offset[regno] = size;
1067 size += GET_MODE_SIZE (mode);
1068 apply_args_mode[regno] = mode;
1070 else
1072 apply_args_mode[regno] = VOIDmode;
1073 apply_args_reg_offset[regno] = 0;
1076 return size;
1079 /* Return the size required for the block returned by __builtin_apply,
1080 and initialize apply_result_mode. */
1082 static int
1083 apply_result_size (void)
1085 static int size = -1;
1086 int align, regno;
1087 enum machine_mode mode;
1089 /* The values computed by this function never change. */
1090 if (size < 0)
1092 size = 0;
1094 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1095 if (FUNCTION_VALUE_REGNO_P (regno))
1097 mode = reg_raw_mode[regno];
1099 gcc_assert (mode != VOIDmode);
1101 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1102 if (size % align != 0)
1103 size = CEIL (size, align) * align;
1104 size += GET_MODE_SIZE (mode);
1105 apply_result_mode[regno] = mode;
1107 else
1108 apply_result_mode[regno] = VOIDmode;
1110 /* Allow targets that use untyped_call and untyped_return to override
1111 the size so that machine-specific information can be stored here. */
1112 #ifdef APPLY_RESULT_SIZE
1113 size = APPLY_RESULT_SIZE;
1114 #endif
1116 return size;
1119 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1120 /* Create a vector describing the result block RESULT. If SAVEP is true,
1121 the result block is used to save the values; otherwise it is used to
1122 restore the values. */
1124 static rtx
1125 result_vector (int savep, rtx result)
1127 int regno, size, align, nelts;
1128 enum machine_mode mode;
1129 rtx reg, mem;
1130 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1132 size = nelts = 0;
1133 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1134 if ((mode = apply_result_mode[regno]) != VOIDmode)
1136 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1137 if (size % align != 0)
1138 size = CEIL (size, align) * align;
1139 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1140 mem = adjust_address (result, mode, size);
1141 savevec[nelts++] = (savep
1142 ? gen_rtx_SET (VOIDmode, mem, reg)
1143 : gen_rtx_SET (VOIDmode, reg, mem));
1144 size += GET_MODE_SIZE (mode);
1146 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1148 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1150 /* Save the state required to perform an untyped call with the same
1151 arguments as were passed to the current function. */
1153 static rtx
1154 expand_builtin_apply_args_1 (void)
1156 rtx registers, tem;
1157 int size, align, regno;
1158 enum machine_mode mode;
1159 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1161 /* Create a block where the arg-pointer, structure value address,
1162 and argument registers can be saved. */
1163 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1165 /* Walk past the arg-pointer and structure value address. */
1166 size = GET_MODE_SIZE (Pmode);
1167 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1168 size += GET_MODE_SIZE (Pmode);
1170 /* Save each register used in calling a function to the block. */
1171 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1172 if ((mode = apply_args_mode[regno]) != VOIDmode)
1174 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1175 if (size % align != 0)
1176 size = CEIL (size, align) * align;
1178 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1180 emit_move_insn (adjust_address (registers, mode, size), tem);
1181 size += GET_MODE_SIZE (mode);
1184 /* Save the arg pointer to the block. */
1185 tem = copy_to_reg (virtual_incoming_args_rtx);
1186 #ifdef STACK_GROWS_DOWNWARD
1187 /* We need the pointer as the caller actually passed them to us, not
1188 as we might have pretended they were passed. Make sure it's a valid
1189 operand, as emit_move_insn isn't expected to handle a PLUS. */
1191 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1192 NULL_RTX);
1193 #endif
1194 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1196 size = GET_MODE_SIZE (Pmode);
1198 /* Save the structure value address unless this is passed as an
1199 "invisible" first argument. */
1200 if (struct_incoming_value)
1202 emit_move_insn (adjust_address (registers, Pmode, size),
1203 copy_to_reg (struct_incoming_value));
1204 size += GET_MODE_SIZE (Pmode);
1207 /* Return the address of the block. */
1208 return copy_addr_to_reg (XEXP (registers, 0));
1211 /* __builtin_apply_args returns block of memory allocated on
1212 the stack into which is stored the arg pointer, structure
1213 value address, static chain, and all the registers that might
1214 possibly be used in performing a function call. The code is
1215 moved to the start of the function so the incoming values are
1216 saved. */
1218 static rtx
1219 expand_builtin_apply_args (void)
1221 /* Don't do __builtin_apply_args more than once in a function.
1222 Save the result of the first call and reuse it. */
1223 if (apply_args_value != 0)
1224 return apply_args_value;
1226 /* When this function is called, it means that registers must be
1227 saved on entry to this function. So we migrate the
1228 call to the first insn of this function. */
1229 rtx temp;
1230 rtx seq;
1232 start_sequence ();
1233 temp = expand_builtin_apply_args_1 ();
1234 seq = get_insns ();
1235 end_sequence ();
1237 apply_args_value = temp;
1239 /* Put the insns after the NOTE that starts the function.
1240 If this is inside a start_sequence, make the outer-level insn
1241 chain current, so the code is placed at the start of the
1242 function. */
1243 push_topmost_sequence ();
1244 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1245 pop_topmost_sequence ();
1246 return temp;
1250 /* Perform an untyped call and save the state required to perform an
1251 untyped return of whatever value was returned by the given function. */
1253 static rtx
1254 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1256 int size, align, regno;
1257 enum machine_mode mode;
1258 rtx incoming_args, result, reg, dest, src, call_insn;
1259 rtx old_stack_level = 0;
1260 rtx call_fusage = 0;
1261 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1263 arguments = convert_memory_address (Pmode, arguments);
1265 /* Create a block where the return registers can be saved. */
1266 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1268 /* Fetch the arg pointer from the ARGUMENTS block. */
1269 incoming_args = gen_reg_rtx (Pmode);
1270 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1271 #ifndef STACK_GROWS_DOWNWARD
1272 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1273 incoming_args, 0, OPTAB_LIB_WIDEN);
1274 #endif
1276 /* Push a new argument block and copy the arguments. Do not allow
1277 the (potential) memcpy call below to interfere with our stack
1278 manipulations. */
1279 do_pending_stack_adjust ();
1280 NO_DEFER_POP;
1282 /* Save the stack with nonlocal if available. */
1283 #ifdef HAVE_save_stack_nonlocal
1284 if (HAVE_save_stack_nonlocal)
1285 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1286 else
1287 #endif
1288 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1290 /* Allocate a block of memory onto the stack and copy the memory
1291 arguments to the outgoing arguments address. */
1292 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1293 dest = virtual_outgoing_args_rtx;
1294 #ifndef STACK_GROWS_DOWNWARD
1295 if (GET_CODE (argsize) == CONST_INT)
1296 dest = plus_constant (dest, -INTVAL (argsize));
1297 else
1298 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1299 #endif
1300 dest = gen_rtx_MEM (BLKmode, dest);
1301 set_mem_align (dest, PARM_BOUNDARY);
1302 src = gen_rtx_MEM (BLKmode, incoming_args);
1303 set_mem_align (src, PARM_BOUNDARY);
1304 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1306 /* Refer to the argument block. */
1307 apply_args_size ();
1308 arguments = gen_rtx_MEM (BLKmode, arguments);
1309 set_mem_align (arguments, PARM_BOUNDARY);
1311 /* Walk past the arg-pointer and structure value address. */
1312 size = GET_MODE_SIZE (Pmode);
1313 if (struct_value)
1314 size += GET_MODE_SIZE (Pmode);
1316 /* Restore each of the registers previously saved. Make USE insns
1317 for each of these registers for use in making the call. */
1318 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1319 if ((mode = apply_args_mode[regno]) != VOIDmode)
1321 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1322 if (size % align != 0)
1323 size = CEIL (size, align) * align;
1324 reg = gen_rtx_REG (mode, regno);
1325 emit_move_insn (reg, adjust_address (arguments, mode, size));
1326 use_reg (&call_fusage, reg);
1327 size += GET_MODE_SIZE (mode);
1330 /* Restore the structure value address unless this is passed as an
1331 "invisible" first argument. */
1332 size = GET_MODE_SIZE (Pmode);
1333 if (struct_value)
1335 rtx value = gen_reg_rtx (Pmode);
1336 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1337 emit_move_insn (struct_value, value);
1338 if (REG_P (struct_value))
1339 use_reg (&call_fusage, struct_value);
1340 size += GET_MODE_SIZE (Pmode);
1343 /* All arguments and registers used for the call are set up by now! */
1344 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1346 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1347 and we don't want to load it into a register as an optimization,
1348 because prepare_call_address already did it if it should be done. */
1349 if (GET_CODE (function) != SYMBOL_REF)
1350 function = memory_address (FUNCTION_MODE, function);
1352 /* Generate the actual call instruction and save the return value. */
1353 #ifdef HAVE_untyped_call
1354 if (HAVE_untyped_call)
1355 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1356 result, result_vector (1, result)));
1357 else
1358 #endif
1359 #ifdef HAVE_call_value
1360 if (HAVE_call_value)
1362 rtx valreg = 0;
1364 /* Locate the unique return register. It is not possible to
1365 express a call that sets more than one return register using
1366 call_value; use untyped_call for that. In fact, untyped_call
1367 only needs to save the return registers in the given block. */
1368 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1369 if ((mode = apply_result_mode[regno]) != VOIDmode)
1371 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1373 valreg = gen_rtx_REG (mode, regno);
1376 emit_call_insn (GEN_CALL_VALUE (valreg,
1377 gen_rtx_MEM (FUNCTION_MODE, function),
1378 const0_rtx, NULL_RTX, const0_rtx));
1380 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1382 else
1383 #endif
1384 gcc_unreachable ();
1386 /* Find the CALL insn we just emitted, and attach the register usage
1387 information. */
1388 call_insn = last_call_insn ();
1389 add_function_usage_to (call_insn, call_fusage);
1391 /* Restore the stack. */
1392 #ifdef HAVE_save_stack_nonlocal
1393 if (HAVE_save_stack_nonlocal)
1394 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1395 else
1396 #endif
1397 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1399 OK_DEFER_POP;
1401 /* Return the address of the result block. */
1402 result = copy_addr_to_reg (XEXP (result, 0));
1403 return convert_memory_address (ptr_mode, result);
1406 /* Perform an untyped return. */
1408 static void
1409 expand_builtin_return (rtx result)
1411 int size, align, regno;
1412 enum machine_mode mode;
1413 rtx reg;
1414 rtx call_fusage = 0;
1416 result = convert_memory_address (Pmode, result);
1418 apply_result_size ();
1419 result = gen_rtx_MEM (BLKmode, result);
1421 #ifdef HAVE_untyped_return
1422 if (HAVE_untyped_return)
1424 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1425 emit_barrier ();
1426 return;
1428 #endif
1430 /* Restore the return value and note that each value is used. */
1431 size = 0;
1432 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1433 if ((mode = apply_result_mode[regno]) != VOIDmode)
1435 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1436 if (size % align != 0)
1437 size = CEIL (size, align) * align;
1438 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1439 emit_move_insn (reg, adjust_address (result, mode, size));
1441 push_to_sequence (call_fusage);
1442 emit_insn (gen_rtx_USE (VOIDmode, reg));
1443 call_fusage = get_insns ();
1444 end_sequence ();
1445 size += GET_MODE_SIZE (mode);
1448 /* Put the USE insns before the return. */
1449 emit_insn (call_fusage);
1451 /* Return whatever values was restored by jumping directly to the end
1452 of the function. */
1453 expand_naked_return ();
1456 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1458 static enum type_class
1459 type_to_class (tree type)
1461 switch (TREE_CODE (type))
1463 case VOID_TYPE: return void_type_class;
1464 case INTEGER_TYPE: return integer_type_class;
1465 case CHAR_TYPE: return char_type_class;
1466 case ENUMERAL_TYPE: return enumeral_type_class;
1467 case BOOLEAN_TYPE: return boolean_type_class;
1468 case POINTER_TYPE: return pointer_type_class;
1469 case REFERENCE_TYPE: return reference_type_class;
1470 case OFFSET_TYPE: return offset_type_class;
1471 case REAL_TYPE: return real_type_class;
1472 case COMPLEX_TYPE: return complex_type_class;
1473 case FUNCTION_TYPE: return function_type_class;
1474 case METHOD_TYPE: return method_type_class;
1475 case RECORD_TYPE: return record_type_class;
1476 case UNION_TYPE:
1477 case QUAL_UNION_TYPE: return union_type_class;
1478 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1479 ? string_type_class : array_type_class);
1480 case SET_TYPE: return set_type_class;
1481 case FILE_TYPE: return file_type_class;
1482 case LANG_TYPE: return lang_type_class;
1483 default: return no_type_class;
1487 /* Expand a call to __builtin_classify_type with arguments found in
1488 ARGLIST. */
1490 static rtx
1491 expand_builtin_classify_type (tree arglist)
1493 if (arglist != 0)
1494 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1495 return GEN_INT (no_type_class);
1498 /* This helper macro, meant to be used in mathfn_built_in below,
1499 determines which among a set of three builtin math functions is
1500 appropriate for a given type mode. The `F' and `L' cases are
1501 automatically generated from the `double' case. */
1502 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1503 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1504 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1505 fcodel = BUILT_IN_MATHFN##L ; break;
1507 /* Return mathematic function equivalent to FN but operating directly
1508 on TYPE, if available. If we can't do the conversion, return zero. */
1509 tree
1510 mathfn_built_in (tree type, enum built_in_function fn)
1512 enum built_in_function fcode, fcodef, fcodel;
1514 switch (fn)
1516 CASE_MATHFN (BUILT_IN_ACOS)
1517 CASE_MATHFN (BUILT_IN_ACOSH)
1518 CASE_MATHFN (BUILT_IN_ASIN)
1519 CASE_MATHFN (BUILT_IN_ASINH)
1520 CASE_MATHFN (BUILT_IN_ATAN)
1521 CASE_MATHFN (BUILT_IN_ATAN2)
1522 CASE_MATHFN (BUILT_IN_ATANH)
1523 CASE_MATHFN (BUILT_IN_CBRT)
1524 CASE_MATHFN (BUILT_IN_CEIL)
1525 CASE_MATHFN (BUILT_IN_COPYSIGN)
1526 CASE_MATHFN (BUILT_IN_COS)
1527 CASE_MATHFN (BUILT_IN_COSH)
1528 CASE_MATHFN (BUILT_IN_DREM)
1529 CASE_MATHFN (BUILT_IN_ERF)
1530 CASE_MATHFN (BUILT_IN_ERFC)
1531 CASE_MATHFN (BUILT_IN_EXP)
1532 CASE_MATHFN (BUILT_IN_EXP10)
1533 CASE_MATHFN (BUILT_IN_EXP2)
1534 CASE_MATHFN (BUILT_IN_EXPM1)
1535 CASE_MATHFN (BUILT_IN_FABS)
1536 CASE_MATHFN (BUILT_IN_FDIM)
1537 CASE_MATHFN (BUILT_IN_FLOOR)
1538 CASE_MATHFN (BUILT_IN_FMA)
1539 CASE_MATHFN (BUILT_IN_FMAX)
1540 CASE_MATHFN (BUILT_IN_FMIN)
1541 CASE_MATHFN (BUILT_IN_FMOD)
1542 CASE_MATHFN (BUILT_IN_FREXP)
1543 CASE_MATHFN (BUILT_IN_GAMMA)
1544 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1545 CASE_MATHFN (BUILT_IN_HYPOT)
1546 CASE_MATHFN (BUILT_IN_ILOGB)
1547 CASE_MATHFN (BUILT_IN_INF)
1548 CASE_MATHFN (BUILT_IN_J0)
1549 CASE_MATHFN (BUILT_IN_J1)
1550 CASE_MATHFN (BUILT_IN_JN)
1551 CASE_MATHFN (BUILT_IN_LDEXP)
1552 CASE_MATHFN (BUILT_IN_LGAMMA)
1553 CASE_MATHFN (BUILT_IN_LLRINT)
1554 CASE_MATHFN (BUILT_IN_LLROUND)
1555 CASE_MATHFN (BUILT_IN_LOG)
1556 CASE_MATHFN (BUILT_IN_LOG10)
1557 CASE_MATHFN (BUILT_IN_LOG1P)
1558 CASE_MATHFN (BUILT_IN_LOG2)
1559 CASE_MATHFN (BUILT_IN_LOGB)
1560 CASE_MATHFN (BUILT_IN_LRINT)
1561 CASE_MATHFN (BUILT_IN_LROUND)
1562 CASE_MATHFN (BUILT_IN_MODF)
1563 CASE_MATHFN (BUILT_IN_NAN)
1564 CASE_MATHFN (BUILT_IN_NANS)
1565 CASE_MATHFN (BUILT_IN_NEARBYINT)
1566 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1567 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1568 CASE_MATHFN (BUILT_IN_POW)
1569 CASE_MATHFN (BUILT_IN_POW10)
1570 CASE_MATHFN (BUILT_IN_REMAINDER)
1571 CASE_MATHFN (BUILT_IN_REMQUO)
1572 CASE_MATHFN (BUILT_IN_RINT)
1573 CASE_MATHFN (BUILT_IN_ROUND)
1574 CASE_MATHFN (BUILT_IN_SCALB)
1575 CASE_MATHFN (BUILT_IN_SCALBLN)
1576 CASE_MATHFN (BUILT_IN_SCALBN)
1577 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1578 CASE_MATHFN (BUILT_IN_SIN)
1579 CASE_MATHFN (BUILT_IN_SINCOS)
1580 CASE_MATHFN (BUILT_IN_SINH)
1581 CASE_MATHFN (BUILT_IN_SQRT)
1582 CASE_MATHFN (BUILT_IN_TAN)
1583 CASE_MATHFN (BUILT_IN_TANH)
1584 CASE_MATHFN (BUILT_IN_TGAMMA)
1585 CASE_MATHFN (BUILT_IN_TRUNC)
1586 CASE_MATHFN (BUILT_IN_Y0)
1587 CASE_MATHFN (BUILT_IN_Y1)
1588 CASE_MATHFN (BUILT_IN_YN)
1590 default:
1591 return 0;
1594 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1595 return implicit_built_in_decls[fcode];
1596 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1597 return implicit_built_in_decls[fcodef];
1598 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1599 return implicit_built_in_decls[fcodel];
1600 else
1601 return 0;
1604 /* If errno must be maintained, expand the RTL to check if the result,
1605 TARGET, of a built-in function call, EXP, is NaN, and if so set
1606 errno to EDOM. */
1608 static void
1609 expand_errno_check (tree exp, rtx target)
1611 rtx lab = gen_label_rtx ();
1613 /* Test the result; if it is NaN, set errno=EDOM because
1614 the argument was not in the domain. */
1615 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1616 0, lab);
1618 #ifdef TARGET_EDOM
1619 /* If this built-in doesn't throw an exception, set errno directly. */
1620 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1622 #ifdef GEN_ERRNO_RTX
1623 rtx errno_rtx = GEN_ERRNO_RTX;
1624 #else
1625 rtx errno_rtx
1626 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1627 #endif
1628 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1629 emit_label (lab);
1630 return;
1632 #endif
1634 /* We can't set errno=EDOM directly; let the library call do it.
1635 Pop the arguments right away in case the call gets deleted. */
1636 NO_DEFER_POP;
1637 expand_call (exp, target, 0);
1638 OK_DEFER_POP;
1639 emit_label (lab);
1643 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1644 Return 0 if a normal call should be emitted rather than expanding the
1645 function in-line. EXP is the expression that is a call to the builtin
1646 function; if convenient, the result should be placed in TARGET.
1647 SUBTARGET may be used as the target for computing one of EXP's operands. */
1649 static rtx
1650 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1652 optab builtin_optab;
1653 rtx op0, insns, before_call;
1654 tree fndecl = get_callee_fndecl (exp);
1655 tree arglist = TREE_OPERAND (exp, 1);
1656 enum machine_mode mode;
1657 bool errno_set = false;
1658 tree arg, narg;
1660 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1661 return 0;
1663 arg = TREE_VALUE (arglist);
1665 switch (DECL_FUNCTION_CODE (fndecl))
1667 case BUILT_IN_SQRT:
1668 case BUILT_IN_SQRTF:
1669 case BUILT_IN_SQRTL:
1670 errno_set = ! tree_expr_nonnegative_p (arg);
1671 builtin_optab = sqrt_optab;
1672 break;
1673 case BUILT_IN_EXP:
1674 case BUILT_IN_EXPF:
1675 case BUILT_IN_EXPL:
1676 errno_set = true; builtin_optab = exp_optab; break;
1677 case BUILT_IN_EXP10:
1678 case BUILT_IN_EXP10F:
1679 case BUILT_IN_EXP10L:
1680 case BUILT_IN_POW10:
1681 case BUILT_IN_POW10F:
1682 case BUILT_IN_POW10L:
1683 errno_set = true; builtin_optab = exp10_optab; break;
1684 case BUILT_IN_EXP2:
1685 case BUILT_IN_EXP2F:
1686 case BUILT_IN_EXP2L:
1687 errno_set = true; builtin_optab = exp2_optab; break;
1688 case BUILT_IN_EXPM1:
1689 case BUILT_IN_EXPM1F:
1690 case BUILT_IN_EXPM1L:
1691 errno_set = true; builtin_optab = expm1_optab; break;
1692 case BUILT_IN_LOGB:
1693 case BUILT_IN_LOGBF:
1694 case BUILT_IN_LOGBL:
1695 errno_set = true; builtin_optab = logb_optab; break;
1696 case BUILT_IN_ILOGB:
1697 case BUILT_IN_ILOGBF:
1698 case BUILT_IN_ILOGBL:
1699 errno_set = true; builtin_optab = ilogb_optab; break;
1700 case BUILT_IN_LOG:
1701 case BUILT_IN_LOGF:
1702 case BUILT_IN_LOGL:
1703 errno_set = true; builtin_optab = log_optab; break;
1704 case BUILT_IN_LOG10:
1705 case BUILT_IN_LOG10F:
1706 case BUILT_IN_LOG10L:
1707 errno_set = true; builtin_optab = log10_optab; break;
1708 case BUILT_IN_LOG2:
1709 case BUILT_IN_LOG2F:
1710 case BUILT_IN_LOG2L:
1711 errno_set = true; builtin_optab = log2_optab; break;
1712 case BUILT_IN_LOG1P:
1713 case BUILT_IN_LOG1PF:
1714 case BUILT_IN_LOG1PL:
1715 errno_set = true; builtin_optab = log1p_optab; break;
1716 case BUILT_IN_ASIN:
1717 case BUILT_IN_ASINF:
1718 case BUILT_IN_ASINL:
1719 builtin_optab = asin_optab; break;
1720 case BUILT_IN_ACOS:
1721 case BUILT_IN_ACOSF:
1722 case BUILT_IN_ACOSL:
1723 builtin_optab = acos_optab; break;
1724 case BUILT_IN_TAN:
1725 case BUILT_IN_TANF:
1726 case BUILT_IN_TANL:
1727 builtin_optab = tan_optab; break;
1728 case BUILT_IN_ATAN:
1729 case BUILT_IN_ATANF:
1730 case BUILT_IN_ATANL:
1731 builtin_optab = atan_optab; break;
1732 case BUILT_IN_FLOOR:
1733 case BUILT_IN_FLOORF:
1734 case BUILT_IN_FLOORL:
1735 builtin_optab = floor_optab; break;
1736 case BUILT_IN_CEIL:
1737 case BUILT_IN_CEILF:
1738 case BUILT_IN_CEILL:
1739 builtin_optab = ceil_optab; break;
1740 case BUILT_IN_TRUNC:
1741 case BUILT_IN_TRUNCF:
1742 case BUILT_IN_TRUNCL:
1743 builtin_optab = btrunc_optab; break;
1744 case BUILT_IN_ROUND:
1745 case BUILT_IN_ROUNDF:
1746 case BUILT_IN_ROUNDL:
1747 builtin_optab = round_optab; break;
1748 case BUILT_IN_NEARBYINT:
1749 case BUILT_IN_NEARBYINTF:
1750 case BUILT_IN_NEARBYINTL:
1751 builtin_optab = nearbyint_optab; break;
1752 case BUILT_IN_RINT:
1753 case BUILT_IN_RINTF:
1754 case BUILT_IN_RINTL:
1755 builtin_optab = rint_optab; break;
1756 default:
1757 gcc_unreachable ();
1760 /* Make a suitable register to place result in. */
1761 mode = TYPE_MODE (TREE_TYPE (exp));
1763 if (! flag_errno_math || ! HONOR_NANS (mode))
1764 errno_set = false;
1766 /* Before working hard, check whether the instruction is available. */
1767 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1769 target = gen_reg_rtx (mode);
1771 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1772 need to expand the argument again. This way, we will not perform
1773 side-effects more the once. */
1774 narg = builtin_save_expr (arg);
1775 if (narg != arg)
1777 arglist = build_tree_list (NULL_TREE, arg);
1778 exp = build_function_call_expr (fndecl, arglist);
1781 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1783 start_sequence ();
1785 /* Compute into TARGET.
1786 Set TARGET to wherever the result comes back. */
1787 target = expand_unop (mode, builtin_optab, op0, target, 0);
1789 if (target != 0)
1791 if (errno_set)
1792 expand_errno_check (exp, target);
1794 /* Output the entire sequence. */
1795 insns = get_insns ();
1796 end_sequence ();
1797 emit_insn (insns);
1798 return target;
1801 /* If we were unable to expand via the builtin, stop the sequence
1802 (without outputting the insns) and call to the library function
1803 with the stabilized argument list. */
1804 end_sequence ();
1807 before_call = get_last_insn ();
1809 target = expand_call (exp, target, target == const0_rtx);
1811 /* If this is a sqrt operation and we don't care about errno, try to
1812 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1813 This allows the semantics of the libcall to be visible to the RTL
1814 optimizers. */
1815 if (builtin_optab == sqrt_optab && !errno_set)
1817 /* Search backwards through the insns emitted by expand_call looking
1818 for the instruction with the REG_RETVAL note. */
1819 rtx last = get_last_insn ();
1820 while (last != before_call)
1822 if (find_reg_note (last, REG_RETVAL, NULL))
1824 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1825 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1826 two elements, i.e. symbol_ref(sqrt) and the operand. */
1827 if (note
1828 && GET_CODE (note) == EXPR_LIST
1829 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1830 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1831 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1833 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1834 /* Check operand is a register with expected mode. */
1835 if (operand
1836 && REG_P (operand)
1837 && GET_MODE (operand) == mode)
1839 /* Replace the REG_EQUAL note with a SQRT rtx. */
1840 rtx equiv = gen_rtx_SQRT (mode, operand);
1841 set_unique_reg_note (last, REG_EQUAL, equiv);
1844 break;
1846 last = PREV_INSN (last);
1850 return target;
1853 /* Expand a call to the builtin binary math functions (pow and atan2).
1854 Return 0 if a normal call should be emitted rather than expanding the
1855 function in-line. EXP is the expression that is a call to the builtin
1856 function; if convenient, the result should be placed in TARGET.
1857 SUBTARGET may be used as the target for computing one of EXP's
1858 operands. */
1860 static rtx
1861 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1863 optab builtin_optab;
1864 rtx op0, op1, insns;
1865 tree fndecl = get_callee_fndecl (exp);
1866 tree arglist = TREE_OPERAND (exp, 1);
1867 tree arg0, arg1, temp, narg;
1868 enum machine_mode mode;
1869 bool errno_set = true;
1870 bool stable = true;
1872 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1873 return 0;
1875 arg0 = TREE_VALUE (arglist);
1876 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1878 switch (DECL_FUNCTION_CODE (fndecl))
1880 case BUILT_IN_POW:
1881 case BUILT_IN_POWF:
1882 case BUILT_IN_POWL:
1883 builtin_optab = pow_optab; break;
1884 case BUILT_IN_ATAN2:
1885 case BUILT_IN_ATAN2F:
1886 case BUILT_IN_ATAN2L:
1887 builtin_optab = atan2_optab; break;
1888 case BUILT_IN_FMOD:
1889 case BUILT_IN_FMODF:
1890 case BUILT_IN_FMODL:
1891 builtin_optab = fmod_optab; break;
1892 case BUILT_IN_DREM:
1893 case BUILT_IN_DREMF:
1894 case BUILT_IN_DREML:
1895 builtin_optab = drem_optab; break;
1896 default:
1897 gcc_unreachable ();
1900 /* Make a suitable register to place result in. */
1901 mode = TYPE_MODE (TREE_TYPE (exp));
1903 /* Before working hard, check whether the instruction is available. */
1904 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1905 return 0;
1907 target = gen_reg_rtx (mode);
1909 if (! flag_errno_math || ! HONOR_NANS (mode))
1910 errno_set = false;
1912 /* Always stabilize the argument list. */
1913 narg = builtin_save_expr (arg1);
1914 if (narg != arg1)
1916 temp = build_tree_list (NULL_TREE, narg);
1917 stable = false;
1919 else
1920 temp = TREE_CHAIN (arglist);
1922 narg = builtin_save_expr (arg0);
1923 if (narg != arg0)
1925 arglist = tree_cons (NULL_TREE, narg, temp);
1926 stable = false;
1928 else if (! stable)
1929 arglist = tree_cons (NULL_TREE, arg0, temp);
1931 if (! stable)
1932 exp = build_function_call_expr (fndecl, arglist);
1934 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1935 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1937 start_sequence ();
1939 /* Compute into TARGET.
1940 Set TARGET to wherever the result comes back. */
1941 target = expand_binop (mode, builtin_optab, op0, op1,
1942 target, 0, OPTAB_DIRECT);
1944 /* If we were unable to expand via the builtin, stop the sequence
1945 (without outputting the insns) and call to the library function
1946 with the stabilized argument list. */
1947 if (target == 0)
1949 end_sequence ();
1950 return expand_call (exp, target, target == const0_rtx);
1953 if (errno_set)
1954 expand_errno_check (exp, target);
1956 /* Output the entire sequence. */
1957 insns = get_insns ();
1958 end_sequence ();
1959 emit_insn (insns);
1961 return target;
1964 /* Expand a call to the builtin sin and cos math functions.
1965 Return 0 if a normal call should be emitted rather than expanding the
1966 function in-line. EXP is the expression that is a call to the builtin
1967 function; if convenient, the result should be placed in TARGET.
1968 SUBTARGET may be used as the target for computing one of EXP's
1969 operands. */
1971 static rtx
1972 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1974 optab builtin_optab;
1975 rtx op0, insns, before_call;
1976 tree fndecl = get_callee_fndecl (exp);
1977 tree arglist = TREE_OPERAND (exp, 1);
1978 enum machine_mode mode;
1979 bool errno_set = false;
1980 tree arg, narg;
1982 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1983 return 0;
1985 arg = TREE_VALUE (arglist);
1987 switch (DECL_FUNCTION_CODE (fndecl))
1989 case BUILT_IN_SIN:
1990 case BUILT_IN_SINF:
1991 case BUILT_IN_SINL:
1992 case BUILT_IN_COS:
1993 case BUILT_IN_COSF:
1994 case BUILT_IN_COSL:
1995 builtin_optab = sincos_optab; break;
1996 default:
1997 gcc_unreachable ();
2000 /* Make a suitable register to place result in. */
2001 mode = TYPE_MODE (TREE_TYPE (exp));
2003 if (! flag_errno_math || ! HONOR_NANS (mode))
2004 errno_set = false;
2006 /* Check if sincos insn is available, otherwise fallback
2007 to sin or cos insn. */
2008 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2009 switch (DECL_FUNCTION_CODE (fndecl))
2011 case BUILT_IN_SIN:
2012 case BUILT_IN_SINF:
2013 case BUILT_IN_SINL:
2014 builtin_optab = sin_optab; break;
2015 case BUILT_IN_COS:
2016 case BUILT_IN_COSF:
2017 case BUILT_IN_COSL:
2018 builtin_optab = cos_optab; break;
2019 default:
2020 gcc_unreachable ();
2024 /* Before working hard, check whether the instruction is available. */
2025 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2027 target = gen_reg_rtx (mode);
2029 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2030 need to expand the argument again. This way, we will not perform
2031 side-effects more the once. */
2032 narg = save_expr (arg);
2033 if (narg != arg)
2035 arglist = build_tree_list (NULL_TREE, arg);
2036 exp = build_function_call_expr (fndecl, arglist);
2039 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2041 start_sequence ();
2043 /* Compute into TARGET.
2044 Set TARGET to wherever the result comes back. */
2045 if (builtin_optab == sincos_optab)
2047 int result;
2049 switch (DECL_FUNCTION_CODE (fndecl))
2051 case BUILT_IN_SIN:
2052 case BUILT_IN_SINF:
2053 case BUILT_IN_SINL:
2054 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2055 break;
2056 case BUILT_IN_COS:
2057 case BUILT_IN_COSF:
2058 case BUILT_IN_COSL:
2059 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2060 break;
2061 default:
2062 gcc_unreachable ();
2064 gcc_assert (result);
2066 else
2068 target = expand_unop (mode, builtin_optab, op0, target, 0);
2071 if (target != 0)
2073 if (errno_set)
2074 expand_errno_check (exp, target);
2076 /* Output the entire sequence. */
2077 insns = get_insns ();
2078 end_sequence ();
2079 emit_insn (insns);
2080 return target;
2083 /* If we were unable to expand via the builtin, stop the sequence
2084 (without outputting the insns) and call to the library function
2085 with the stabilized argument list. */
2086 end_sequence ();
2089 before_call = get_last_insn ();
2091 target = expand_call (exp, target, target == const0_rtx);
2093 return target;
2096 /* To evaluate powi(x,n), the floating point value x raised to the
2097 constant integer exponent n, we use a hybrid algorithm that
2098 combines the "window method" with look-up tables. For an
2099 introduction to exponentiation algorithms and "addition chains",
2100 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2101 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2102 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2103 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2105 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2106 multiplications to inline before calling the system library's pow
2107 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2108 so this default never requires calling pow, powf or powl. */
2110 #ifndef POWI_MAX_MULTS
2111 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2112 #endif
2114 /* The size of the "optimal power tree" lookup table. All
2115 exponents less than this value are simply looked up in the
2116 powi_table below. This threshold is also used to size the
2117 cache of pseudo registers that hold intermediate results. */
2118 #define POWI_TABLE_SIZE 256
2120 /* The size, in bits of the window, used in the "window method"
2121 exponentiation algorithm. This is equivalent to a radix of
2122 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2123 #define POWI_WINDOW_SIZE 3
2125 /* The following table is an efficient representation of an
2126 "optimal power tree". For each value, i, the corresponding
2127 value, j, in the table states than an optimal evaluation
2128 sequence for calculating pow(x,i) can be found by evaluating
2129 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2130 100 integers is given in Knuth's "Seminumerical algorithms". */
2132 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2134 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2135 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2136 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2137 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2138 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2139 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2140 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2141 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2142 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2143 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2144 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2145 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2146 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2147 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2148 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2149 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2150 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2151 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2152 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2153 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2154 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2155 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2156 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2157 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2158 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2159 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2160 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2161 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2162 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2163 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2164 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2165 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2169 /* Return the number of multiplications required to calculate
2170 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2171 subroutine of powi_cost. CACHE is an array indicating
2172 which exponents have already been calculated. */
2174 static int
2175 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2177 /* If we've already calculated this exponent, then this evaluation
2178 doesn't require any additional multiplications. */
2179 if (cache[n])
2180 return 0;
2182 cache[n] = true;
2183 return powi_lookup_cost (n - powi_table[n], cache)
2184 + powi_lookup_cost (powi_table[n], cache) + 1;
2187 /* Return the number of multiplications required to calculate
2188 powi(x,n) for an arbitrary x, given the exponent N. This
2189 function needs to be kept in sync with expand_powi below. */
2191 static int
2192 powi_cost (HOST_WIDE_INT n)
2194 bool cache[POWI_TABLE_SIZE];
2195 unsigned HOST_WIDE_INT digit;
2196 unsigned HOST_WIDE_INT val;
2197 int result;
2199 if (n == 0)
2200 return 0;
2202 /* Ignore the reciprocal when calculating the cost. */
2203 val = (n < 0) ? -n : n;
2205 /* Initialize the exponent cache. */
2206 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2207 cache[1] = true;
2209 result = 0;
2211 while (val >= POWI_TABLE_SIZE)
2213 if (val & 1)
2215 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2216 result += powi_lookup_cost (digit, cache)
2217 + POWI_WINDOW_SIZE + 1;
2218 val >>= POWI_WINDOW_SIZE;
2220 else
2222 val >>= 1;
2223 result++;
2227 return result + powi_lookup_cost (val, cache);
2230 /* Recursive subroutine of expand_powi. This function takes the array,
2231 CACHE, of already calculated exponents and an exponent N and returns
2232 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2234 static rtx
2235 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2237 unsigned HOST_WIDE_INT digit;
2238 rtx target, result;
2239 rtx op0, op1;
2241 if (n < POWI_TABLE_SIZE)
2243 if (cache[n])
2244 return cache[n];
2246 target = gen_reg_rtx (mode);
2247 cache[n] = target;
2249 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2250 op1 = expand_powi_1 (mode, powi_table[n], cache);
2252 else if (n & 1)
2254 target = gen_reg_rtx (mode);
2255 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2256 op0 = expand_powi_1 (mode, n - digit, cache);
2257 op1 = expand_powi_1 (mode, digit, cache);
2259 else
2261 target = gen_reg_rtx (mode);
2262 op0 = expand_powi_1 (mode, n >> 1, cache);
2263 op1 = op0;
2266 result = expand_mult (mode, op0, op1, target, 0);
2267 if (result != target)
2268 emit_move_insn (target, result);
2269 return target;
2272 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2273 floating point operand in mode MODE, and N is the exponent. This
2274 function needs to be kept in sync with powi_cost above. */
2276 static rtx
2277 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2279 unsigned HOST_WIDE_INT val;
2280 rtx cache[POWI_TABLE_SIZE];
2281 rtx result;
2283 if (n == 0)
2284 return CONST1_RTX (mode);
2286 val = (n < 0) ? -n : n;
2288 memset (cache, 0, sizeof (cache));
2289 cache[1] = x;
2291 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2293 /* If the original exponent was negative, reciprocate the result. */
2294 if (n < 0)
2295 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2296 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2298 return result;
2301 /* Expand a call to the pow built-in mathematical function. Return 0 if
2302 a normal call should be emitted rather than expanding the function
2303 in-line. EXP is the expression that is a call to the builtin
2304 function; if convenient, the result should be placed in TARGET. */
2306 static rtx
2307 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2309 tree arglist = TREE_OPERAND (exp, 1);
2310 tree arg0, arg1;
2312 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2313 return 0;
2315 arg0 = TREE_VALUE (arglist);
2316 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2318 if (TREE_CODE (arg1) == REAL_CST
2319 && ! TREE_CONSTANT_OVERFLOW (arg1))
2321 REAL_VALUE_TYPE cint;
2322 REAL_VALUE_TYPE c;
2323 HOST_WIDE_INT n;
2325 c = TREE_REAL_CST (arg1);
2326 n = real_to_integer (&c);
2327 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2328 if (real_identical (&c, &cint))
2330 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2331 Otherwise, check the number of multiplications required.
2332 Note that pow never sets errno for an integer exponent. */
2333 if ((n >= -1 && n <= 2)
2334 || (flag_unsafe_math_optimizations
2335 && ! optimize_size
2336 && powi_cost (n) <= POWI_MAX_MULTS))
2338 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2339 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2340 op = force_reg (mode, op);
2341 return expand_powi (op, mode, n);
2346 if (! flag_unsafe_math_optimizations)
2347 return NULL_RTX;
2348 return expand_builtin_mathfn_2 (exp, target, subtarget);
2351 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2352 if we failed the caller should emit a normal call, otherwise
2353 try to get the result in TARGET, if convenient. */
2355 static rtx
2356 expand_builtin_strlen (tree arglist, rtx target,
2357 enum machine_mode target_mode)
2359 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2360 return 0;
2361 else
2363 rtx pat;
2364 tree len, src = TREE_VALUE (arglist);
2365 rtx result, src_reg, char_rtx, before_strlen;
2366 enum machine_mode insn_mode = target_mode, char_mode;
2367 enum insn_code icode = CODE_FOR_nothing;
2368 int align;
2370 /* If the length can be computed at compile-time, return it. */
2371 len = c_strlen (src, 0);
2372 if (len)
2373 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2375 /* If the length can be computed at compile-time and is constant
2376 integer, but there are side-effects in src, evaluate
2377 src for side-effects, then return len.
2378 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2379 can be optimized into: i++; x = 3; */
2380 len = c_strlen (src, 1);
2381 if (len && TREE_CODE (len) == INTEGER_CST)
2383 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2384 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2387 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2389 /* If SRC is not a pointer type, don't do this operation inline. */
2390 if (align == 0)
2391 return 0;
2393 /* Bail out if we can't compute strlen in the right mode. */
2394 while (insn_mode != VOIDmode)
2396 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2397 if (icode != CODE_FOR_nothing)
2398 break;
2400 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2402 if (insn_mode == VOIDmode)
2403 return 0;
2405 /* Make a place to write the result of the instruction. */
2406 result = target;
2407 if (! (result != 0
2408 && REG_P (result)
2409 && GET_MODE (result) == insn_mode
2410 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2411 result = gen_reg_rtx (insn_mode);
2413 /* Make a place to hold the source address. We will not expand
2414 the actual source until we are sure that the expansion will
2415 not fail -- there are trees that cannot be expanded twice. */
2416 src_reg = gen_reg_rtx (Pmode);
2418 /* Mark the beginning of the strlen sequence so we can emit the
2419 source operand later. */
2420 before_strlen = get_last_insn ();
2422 char_rtx = const0_rtx;
2423 char_mode = insn_data[(int) icode].operand[2].mode;
2424 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2425 char_mode))
2426 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2428 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2429 char_rtx, GEN_INT (align));
2430 if (! pat)
2431 return 0;
2432 emit_insn (pat);
2434 /* Now that we are assured of success, expand the source. */
2435 start_sequence ();
2436 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2437 if (pat != src_reg)
2438 emit_move_insn (src_reg, pat);
2439 pat = get_insns ();
2440 end_sequence ();
2442 if (before_strlen)
2443 emit_insn_after (pat, before_strlen);
2444 else
2445 emit_insn_before (pat, get_insns ());
2447 /* Return the value in the proper mode for this function. */
2448 if (GET_MODE (result) == target_mode)
2449 target = result;
2450 else if (target != 0)
2451 convert_move (target, result, 0);
2452 else
2453 target = convert_to_mode (target_mode, result, 0);
2455 return target;
2459 /* Expand a call to the strstr builtin. Return 0 if we failed the
2460 caller should emit a normal call, otherwise try to get the result
2461 in TARGET, if convenient (and in mode MODE if that's convenient). */
2463 static rtx
2464 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2466 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2468 tree result = fold_builtin_strstr (arglist);
2469 if (result)
2470 return expand_expr (result, target, mode, EXPAND_NORMAL);
2472 return 0;
2475 /* Expand a call to the strchr builtin. Return 0 if we failed the
2476 caller should emit a normal call, otherwise try to get the result
2477 in TARGET, if convenient (and in mode MODE if that's convenient). */
2479 static rtx
2480 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2482 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2484 tree result = fold_builtin_strchr (arglist);
2485 if (result)
2486 return expand_expr (result, target, mode, EXPAND_NORMAL);
2488 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2490 return 0;
2493 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2494 caller should emit a normal call, otherwise try to get the result
2495 in TARGET, if convenient (and in mode MODE if that's convenient). */
2497 static rtx
2498 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2500 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2502 tree result = fold_builtin_strrchr (arglist);
2503 if (result)
2504 return expand_expr (result, target, mode, EXPAND_NORMAL);
2506 return 0;
2509 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2510 caller should emit a normal call, otherwise try to get the result
2511 in TARGET, if convenient (and in mode MODE if that's convenient). */
2513 static rtx
2514 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2516 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2518 tree result = fold_builtin_strpbrk (arglist);
2519 if (result)
2520 return expand_expr (result, target, mode, EXPAND_NORMAL);
2522 return 0;
2525 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2526 bytes from constant string DATA + OFFSET and return it as target
2527 constant. */
2529 static rtx
2530 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2531 enum machine_mode mode)
2533 const char *str = (const char *) data;
2535 gcc_assert (offset >= 0
2536 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2537 <= strlen (str) + 1));
2539 return c_readstr (str + offset, mode);
2542 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2543 Return 0 if we failed, the caller should emit a normal call,
2544 otherwise try to get the result in TARGET, if convenient (and in
2545 mode MODE if that's convenient). */
2546 static rtx
2547 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2549 tree arglist = TREE_OPERAND (exp, 1);
2550 if (!validate_arglist (arglist,
2551 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2552 return 0;
2553 else
2555 tree dest = TREE_VALUE (arglist);
2556 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2557 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2558 const char *src_str;
2559 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2560 unsigned int dest_align
2561 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2562 rtx dest_mem, src_mem, dest_addr, len_rtx;
2563 tree result = fold_builtin_memcpy (exp);
2565 if (result)
2566 return expand_expr (result, target, mode, EXPAND_NORMAL);
2568 /* If DEST is not a pointer type, call the normal function. */
2569 if (dest_align == 0)
2570 return 0;
2572 /* If either SRC is not a pointer type, don't do this
2573 operation in-line. */
2574 if (src_align == 0)
2575 return 0;
2577 dest_mem = get_memory_rtx (dest);
2578 set_mem_align (dest_mem, dest_align);
2579 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2580 src_str = c_getstr (src);
2582 /* If SRC is a string constant and block move would be done
2583 by pieces, we can avoid loading the string from memory
2584 and only stored the computed constants. */
2585 if (src_str
2586 && GET_CODE (len_rtx) == CONST_INT
2587 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2588 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2589 (void *) src_str, dest_align))
2591 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2592 builtin_memcpy_read_str,
2593 (void *) src_str, dest_align, 0);
2594 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2595 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2596 return dest_mem;
2599 src_mem = get_memory_rtx (src);
2600 set_mem_align (src_mem, src_align);
2602 /* Copy word part most expediently. */
2603 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2604 BLOCK_OP_NORMAL);
2606 if (dest_addr == 0)
2608 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2609 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2611 return dest_addr;
2615 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2616 Return 0 if we failed the caller should emit a normal call,
2617 otherwise try to get the result in TARGET, if convenient (and in
2618 mode MODE if that's convenient). If ENDP is 0 return the
2619 destination pointer, if ENDP is 1 return the end pointer ala
2620 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2621 stpcpy. */
2623 static rtx
2624 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2625 int endp)
2627 if (!validate_arglist (arglist,
2628 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2629 return 0;
2630 /* If return value is ignored, transform mempcpy into memcpy. */
2631 else if (target == const0_rtx)
2633 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2635 if (!fn)
2636 return 0;
2638 return expand_expr (build_function_call_expr (fn, arglist),
2639 target, mode, EXPAND_NORMAL);
2641 else
2643 tree dest = TREE_VALUE (arglist);
2644 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2645 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2646 const char *src_str;
2647 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2648 unsigned int dest_align
2649 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2650 rtx dest_mem, src_mem, len_rtx;
2652 /* If DEST is not a pointer type, call the normal function. */
2653 if (dest_align == 0)
2654 return 0;
2656 /* If SRC and DEST are the same (and not volatile), do nothing. */
2657 if (operand_equal_p (src, dest, 0))
2659 tree expr;
2661 if (endp == 0)
2663 /* Evaluate and ignore LEN in case it has side-effects. */
2664 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2665 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2668 if (endp == 2)
2669 len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2670 integer_one_node));
2671 len = fold_convert (TREE_TYPE (dest), len);
2672 expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2673 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2676 /* If LEN is not constant, call the normal function. */
2677 if (! host_integerp (len, 1))
2678 return 0;
2680 /* If the LEN parameter is zero, return DEST. */
2681 if (tree_low_cst (len, 1) == 0)
2683 /* Evaluate and ignore SRC in case it has side-effects. */
2684 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2685 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2688 /* If either SRC is not a pointer type, don't do this
2689 operation in-line. */
2690 if (src_align == 0)
2691 return 0;
2693 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2694 src_str = c_getstr (src);
2696 /* If SRC is a string constant and block move would be done
2697 by pieces, we can avoid loading the string from memory
2698 and only stored the computed constants. */
2699 if (src_str
2700 && GET_CODE (len_rtx) == CONST_INT
2701 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2702 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2703 (void *) src_str, dest_align))
2705 dest_mem = get_memory_rtx (dest);
2706 set_mem_align (dest_mem, dest_align);
2707 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2708 builtin_memcpy_read_str,
2709 (void *) src_str, dest_align, endp);
2710 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2711 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2712 return dest_mem;
2715 if (GET_CODE (len_rtx) == CONST_INT
2716 && can_move_by_pieces (INTVAL (len_rtx),
2717 MIN (dest_align, src_align)))
2719 dest_mem = get_memory_rtx (dest);
2720 set_mem_align (dest_mem, dest_align);
2721 src_mem = get_memory_rtx (src);
2722 set_mem_align (src_mem, src_align);
2723 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2724 MIN (dest_align, src_align), endp);
2725 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2726 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2727 return dest_mem;
2730 return 0;
2734 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2735 if we failed the caller should emit a normal call. */
2737 static rtx
2738 expand_builtin_memmove (tree arglist, tree type, rtx target,
2739 enum machine_mode mode)
2741 if (!validate_arglist (arglist,
2742 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2743 return 0;
2744 else
2746 tree dest = TREE_VALUE (arglist);
2747 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2748 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2750 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2751 unsigned int dest_align
2752 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2753 tree result = fold_builtin_memmove (arglist, type);
2755 if (result)
2756 expand_expr (result, target, mode, EXPAND_NORMAL);
2758 /* If DEST is not a pointer type, call the normal function. */
2759 if (dest_align == 0)
2760 return 0;
2762 /* If either SRC is not a pointer type, don't do this
2763 operation in-line. */
2764 if (src_align == 0)
2765 return 0;
2767 /* If src is categorized for a readonly section we can use
2768 normal memcpy. */
2769 if (readonly_data_expr (src))
2771 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2772 if (!fn)
2773 return 0;
2774 return expand_expr (build_function_call_expr (fn, arglist),
2775 target, mode, EXPAND_NORMAL);
2778 /* If length is 1 and we can expand memcpy call inline,
2779 it is ok to use memcpy as well. */
2780 if (integer_onep (len))
2782 rtx ret = expand_builtin_mempcpy (arglist, target, mode,
2783 /*endp=*/0);
2784 if (ret)
2785 return ret;
2788 /* Otherwise, call the normal function. */
2789 return 0;
2793 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2794 if we failed the caller should emit a normal call. */
2796 static rtx
2797 expand_builtin_bcopy (tree arglist, tree type)
2799 tree src, dest, size, newarglist;
2801 if (!validate_arglist (arglist,
2802 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2803 return NULL_RTX;
2805 src = TREE_VALUE (arglist);
2806 dest = TREE_VALUE (TREE_CHAIN (arglist));
2807 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2809 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2810 memmove(ptr y, ptr x, size_t z). This is done this way
2811 so that if it isn't expanded inline, we fallback to
2812 calling bcopy instead of memmove. */
2814 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2815 newarglist = tree_cons (NULL_TREE, src, newarglist);
2816 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2818 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
2821 #ifndef HAVE_movstr
2822 # define HAVE_movstr 0
2823 # define CODE_FOR_movstr CODE_FOR_nothing
2824 #endif
2826 /* Expand into a movstr instruction, if one is available. Return 0 if
2827 we failed, the caller should emit a normal call, otherwise try to
2828 get the result in TARGET, if convenient. If ENDP is 0 return the
2829 destination pointer, if ENDP is 1 return the end pointer ala
2830 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2831 stpcpy. */
2833 static rtx
2834 expand_movstr (tree dest, tree src, rtx target, int endp)
2836 rtx end;
2837 rtx dest_mem;
2838 rtx src_mem;
2839 rtx insn;
2840 const struct insn_data * data;
2842 if (!HAVE_movstr)
2843 return 0;
2845 dest_mem = get_memory_rtx (dest);
2846 src_mem = get_memory_rtx (src);
2847 if (!endp)
2849 target = force_reg (Pmode, XEXP (dest_mem, 0));
2850 dest_mem = replace_equiv_address (dest_mem, target);
2851 end = gen_reg_rtx (Pmode);
2853 else
2855 if (target == 0 || target == const0_rtx)
2857 end = gen_reg_rtx (Pmode);
2858 if (target == 0)
2859 target = end;
2861 else
2862 end = target;
2865 data = insn_data + CODE_FOR_movstr;
2867 if (data->operand[0].mode != VOIDmode)
2868 end = gen_lowpart (data->operand[0].mode, end);
2870 insn = data->genfun (end, dest_mem, src_mem);
2872 gcc_assert (insn);
2874 emit_insn (insn);
2876 /* movstr is supposed to set end to the address of the NUL
2877 terminator. If the caller requested a mempcpy-like return value,
2878 adjust it. */
2879 if (endp == 1 && target != const0_rtx)
2881 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
2882 emit_move_insn (target, force_operand (tem, NULL_RTX));
2885 return target;
2888 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2889 if we failed the caller should emit a normal call, otherwise try to get
2890 the result in TARGET, if convenient (and in mode MODE if that's
2891 convenient). */
2893 static rtx
2894 expand_builtin_strcpy (tree exp, rtx target, enum machine_mode mode)
2896 tree arglist = TREE_OPERAND (exp, 1);
2897 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2899 tree result = fold_builtin_strcpy (exp, 0);
2900 if (result)
2901 return expand_expr (result, target, mode, EXPAND_NORMAL);
2903 return expand_movstr (TREE_VALUE (arglist),
2904 TREE_VALUE (TREE_CHAIN (arglist)),
2905 target, /*endp=*/0);
2907 return 0;
2910 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2911 Return 0 if we failed the caller should emit a normal call,
2912 otherwise try to get the result in TARGET, if convenient (and in
2913 mode MODE if that's convenient). */
2915 static rtx
2916 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
2918 tree arglist = TREE_OPERAND (exp, 1);
2919 /* If return value is ignored, transform stpcpy into strcpy. */
2920 if (target == const0_rtx)
2922 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2923 if (!fn)
2924 return 0;
2926 return expand_expr (build_function_call_expr (fn, arglist),
2927 target, mode, EXPAND_NORMAL);
2930 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2931 return 0;
2932 else
2934 tree dst, src, len, lenp1;
2935 tree narglist;
2936 rtx ret;
2938 /* Ensure we get an actual string whose length can be evaluated at
2939 compile-time, not an expression containing a string. This is
2940 because the latter will potentially produce pessimized code
2941 when used to produce the return value. */
2942 src = TREE_VALUE (TREE_CHAIN (arglist));
2943 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2944 return expand_movstr (TREE_VALUE (arglist),
2945 TREE_VALUE (TREE_CHAIN (arglist)),
2946 target, /*endp=*/2);
2948 dst = TREE_VALUE (arglist);
2949 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
2950 narglist = build_tree_list (NULL_TREE, lenp1);
2951 narglist = tree_cons (NULL_TREE, src, narglist);
2952 narglist = tree_cons (NULL_TREE, dst, narglist);
2953 ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
2955 if (ret)
2956 return ret;
2958 if (TREE_CODE (len) == INTEGER_CST)
2960 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2962 if (GET_CODE (len_rtx) == CONST_INT)
2964 ret = expand_builtin_strcpy (exp, target, mode);
2966 if (ret)
2968 if (! target)
2970 if (mode != VOIDmode)
2971 target = gen_reg_rtx (mode);
2972 else
2973 target = gen_reg_rtx (GET_MODE (ret));
2975 if (GET_MODE (target) != GET_MODE (ret))
2976 ret = gen_lowpart (GET_MODE (target), ret);
2978 ret = plus_constant (ret, INTVAL (len_rtx));
2979 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
2980 gcc_assert (ret);
2982 return target;
2987 return expand_movstr (TREE_VALUE (arglist),
2988 TREE_VALUE (TREE_CHAIN (arglist)),
2989 target, /*endp=*/2);
2993 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2994 bytes from constant string DATA + OFFSET and return it as target
2995 constant. */
2997 static rtx
2998 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2999 enum machine_mode mode)
3001 const char *str = (const char *) data;
3003 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3004 return const0_rtx;
3006 return c_readstr (str + offset, mode);
3009 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3010 if we failed the caller should emit a normal call. */
3012 static rtx
3013 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3015 if (!validate_arglist (arglist,
3016 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3017 return 0;
3018 else
3020 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3021 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3022 tree fn;
3024 /* We must be passed a constant len parameter. */
3025 if (TREE_CODE (len) != INTEGER_CST)
3026 return 0;
3028 /* If the len parameter is zero, return the dst parameter. */
3029 if (integer_zerop (len))
3031 /* Evaluate and ignore the src argument in case it has
3032 side-effects. */
3033 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3034 VOIDmode, EXPAND_NORMAL);
3035 /* Return the dst parameter. */
3036 return expand_expr (TREE_VALUE (arglist), target, mode,
3037 EXPAND_NORMAL);
3040 /* Now, we must be passed a constant src ptr parameter. */
3041 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3042 return 0;
3044 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3046 /* We're required to pad with trailing zeros if the requested
3047 len is greater than strlen(s2)+1. In that case try to
3048 use store_by_pieces, if it fails, punt. */
3049 if (tree_int_cst_lt (slen, len))
3051 tree dest = TREE_VALUE (arglist);
3052 unsigned int dest_align
3053 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3054 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3055 rtx dest_mem;
3057 if (!p || dest_align == 0 || !host_integerp (len, 1)
3058 || !can_store_by_pieces (tree_low_cst (len, 1),
3059 builtin_strncpy_read_str,
3060 (void *) p, dest_align))
3061 return 0;
3063 dest_mem = get_memory_rtx (dest);
3064 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3065 builtin_strncpy_read_str,
3066 (void *) p, dest_align, 0);
3067 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3068 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3069 return dest_mem;
3072 /* OK transform into builtin memcpy. */
3073 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3074 if (!fn)
3075 return 0;
3076 return expand_expr (build_function_call_expr (fn, arglist),
3077 target, mode, EXPAND_NORMAL);
3081 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3082 bytes from constant string DATA + OFFSET and return it as target
3083 constant. */
3085 static rtx
3086 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3087 enum machine_mode mode)
3089 const char *c = (const char *) data;
3090 char *p = alloca (GET_MODE_SIZE (mode));
3092 memset (p, *c, GET_MODE_SIZE (mode));
3094 return c_readstr (p, mode);
3097 /* Callback routine for store_by_pieces. Return the RTL of a register
3098 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3099 char value given in the RTL register data. For example, if mode is
3100 4 bytes wide, return the RTL for 0x01010101*data. */
3102 static rtx
3103 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3104 enum machine_mode mode)
3106 rtx target, coeff;
3107 size_t size;
3108 char *p;
3110 size = GET_MODE_SIZE (mode);
3111 if (size == 1)
3112 return (rtx) data;
3114 p = alloca (size);
3115 memset (p, 1, size);
3116 coeff = c_readstr (p, mode);
3118 target = convert_to_mode (mode, (rtx) data, 1);
3119 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3120 return force_reg (mode, target);
3123 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3124 if we failed the caller should emit a normal call, otherwise try to get
3125 the result in TARGET, if convenient (and in mode MODE if that's
3126 convenient). */
3128 static rtx
3129 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3131 if (!validate_arglist (arglist,
3132 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3133 return 0;
3134 else
3136 tree dest = TREE_VALUE (arglist);
3137 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3138 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3139 char c;
3141 unsigned int dest_align
3142 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3143 rtx dest_mem, dest_addr, len_rtx;
3145 /* If DEST is not a pointer type, don't do this
3146 operation in-line. */
3147 if (dest_align == 0)
3148 return 0;
3150 /* If the LEN parameter is zero, return DEST. */
3151 if (integer_zerop (len))
3153 /* Evaluate and ignore VAL in case it has side-effects. */
3154 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3155 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3158 if (TREE_CODE (val) != INTEGER_CST)
3160 rtx val_rtx;
3162 if (!host_integerp (len, 1))
3163 return 0;
3165 if (optimize_size && tree_low_cst (len, 1) > 1)
3166 return 0;
3168 /* Assume that we can memset by pieces if we can store the
3169 * the coefficients by pieces (in the required modes).
3170 * We can't pass builtin_memset_gen_str as that emits RTL. */
3171 c = 1;
3172 if (!can_store_by_pieces (tree_low_cst (len, 1),
3173 builtin_memset_read_str,
3174 &c, dest_align))
3175 return 0;
3177 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3178 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3179 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3180 val_rtx);
3181 dest_mem = get_memory_rtx (dest);
3182 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3183 builtin_memset_gen_str,
3184 val_rtx, dest_align, 0);
3185 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3186 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3187 return dest_mem;
3190 if (target_char_cast (val, &c))
3191 return 0;
3193 if (c)
3195 if (!host_integerp (len, 1))
3196 return 0;
3197 if (!can_store_by_pieces (tree_low_cst (len, 1),
3198 builtin_memset_read_str, &c,
3199 dest_align))
3200 return 0;
3202 dest_mem = get_memory_rtx (dest);
3203 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3204 builtin_memset_read_str,
3205 &c, dest_align, 0);
3206 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3207 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3208 return dest_mem;
3211 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3213 dest_mem = get_memory_rtx (dest);
3214 set_mem_align (dest_mem, dest_align);
3215 dest_addr = clear_storage (dest_mem, len_rtx);
3217 if (dest_addr == 0)
3219 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3220 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3223 return dest_addr;
3227 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3228 if we failed the caller should emit a normal call. */
3230 static rtx
3231 expand_builtin_bzero (tree arglist)
3233 tree dest, size, newarglist;
3235 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3236 return NULL_RTX;
3238 dest = TREE_VALUE (arglist);
3239 size = TREE_VALUE (TREE_CHAIN (arglist));
3241 /* New argument list transforming bzero(ptr x, int y) to
3242 memset(ptr x, int 0, size_t y). This is done this way
3243 so that if it isn't expanded inline, we fallback to
3244 calling bzero instead of memset. */
3246 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3247 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3248 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3250 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3253 /* Expand expression EXP, which is a call to the memcmp built-in function.
3254 ARGLIST is the argument list for this call. Return 0 if we failed and the
3255 caller should emit a normal call, otherwise try to get the result in
3256 TARGET, if convenient (and in mode MODE, if that's convenient). */
3258 static rtx
3259 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3260 enum machine_mode mode)
3262 if (!validate_arglist (arglist,
3263 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3264 return 0;
3265 else
3267 tree result = fold_builtin_memcmp (arglist);
3268 if (result)
3269 return expand_expr (result, target, mode, EXPAND_NORMAL);
3272 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3274 tree arg1 = TREE_VALUE (arglist);
3275 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3276 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3277 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3278 rtx result;
3279 rtx insn;
3281 int arg1_align
3282 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3283 int arg2_align
3284 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3285 enum machine_mode insn_mode;
3287 #ifdef HAVE_cmpmemsi
3288 if (HAVE_cmpmemsi)
3289 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3290 else
3291 #endif
3292 #ifdef HAVE_cmpstrsi
3293 if (HAVE_cmpstrsi)
3294 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3295 else
3296 #endif
3297 return 0;
3299 /* If we don't have POINTER_TYPE, call the function. */
3300 if (arg1_align == 0 || arg2_align == 0)
3301 return 0;
3303 /* Make a place to write the result of the instruction. */
3304 result = target;
3305 if (! (result != 0
3306 && REG_P (result) && GET_MODE (result) == insn_mode
3307 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3308 result = gen_reg_rtx (insn_mode);
3310 arg1_rtx = get_memory_rtx (arg1);
3311 arg2_rtx = get_memory_rtx (arg2);
3312 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3314 /* Set MEM_SIZE as appropriate. */
3315 if (GET_CODE (arg3_rtx) == CONST_INT)
3317 set_mem_size (arg1_rtx, arg3_rtx);
3318 set_mem_size (arg2_rtx, arg3_rtx);
3321 #ifdef HAVE_cmpmemsi
3322 if (HAVE_cmpmemsi)
3323 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3324 GEN_INT (MIN (arg1_align, arg2_align)));
3325 else
3326 #endif
3327 #ifdef HAVE_cmpstrsi
3328 if (HAVE_cmpstrsi)
3329 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3330 GEN_INT (MIN (arg1_align, arg2_align)));
3331 else
3332 #endif
3333 gcc_unreachable ();
3335 if (insn)
3336 emit_insn (insn);
3337 else
3338 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3339 TYPE_MODE (integer_type_node), 3,
3340 XEXP (arg1_rtx, 0), Pmode,
3341 XEXP (arg2_rtx, 0), Pmode,
3342 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3343 TYPE_UNSIGNED (sizetype)),
3344 TYPE_MODE (sizetype));
3346 /* Return the value in the proper mode for this function. */
3347 mode = TYPE_MODE (TREE_TYPE (exp));
3348 if (GET_MODE (result) == mode)
3349 return result;
3350 else if (target != 0)
3352 convert_move (target, result, 0);
3353 return target;
3355 else
3356 return convert_to_mode (mode, result, 0);
3358 #endif
3360 return 0;
3363 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3364 if we failed the caller should emit a normal call, otherwise try to get
3365 the result in TARGET, if convenient. */
3367 static rtx
3368 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3370 tree arglist = TREE_OPERAND (exp, 1);
3372 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3373 return 0;
3374 else
3376 tree result = fold_builtin_strcmp (arglist);
3377 if (result)
3378 return expand_expr (result, target, mode, EXPAND_NORMAL);
3381 #ifdef HAVE_cmpstrsi
3382 if (HAVE_cmpstrsi)
3384 tree arg1 = TREE_VALUE (arglist);
3385 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3386 tree len, len1, len2;
3387 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3388 rtx result, insn;
3389 tree fndecl;
3391 int arg1_align
3392 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3393 int arg2_align
3394 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3395 enum machine_mode insn_mode
3396 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3398 len1 = c_strlen (arg1, 1);
3399 len2 = c_strlen (arg2, 1);
3401 if (len1)
3402 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3403 if (len2)
3404 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3406 /* If we don't have a constant length for the first, use the length
3407 of the second, if we know it. We don't require a constant for
3408 this case; some cost analysis could be done if both are available
3409 but neither is constant. For now, assume they're equally cheap,
3410 unless one has side effects. If both strings have constant lengths,
3411 use the smaller. */
3413 if (!len1)
3414 len = len2;
3415 else if (!len2)
3416 len = len1;
3417 else if (TREE_SIDE_EFFECTS (len1))
3418 len = len2;
3419 else if (TREE_SIDE_EFFECTS (len2))
3420 len = len1;
3421 else if (TREE_CODE (len1) != INTEGER_CST)
3422 len = len2;
3423 else if (TREE_CODE (len2) != INTEGER_CST)
3424 len = len1;
3425 else if (tree_int_cst_lt (len1, len2))
3426 len = len1;
3427 else
3428 len = len2;
3430 /* If both arguments have side effects, we cannot optimize. */
3431 if (!len || TREE_SIDE_EFFECTS (len))
3432 return 0;
3434 /* If we don't have POINTER_TYPE, call the function. */
3435 if (arg1_align == 0 || arg2_align == 0)
3436 return 0;
3438 /* Make a place to write the result of the instruction. */
3439 result = target;
3440 if (! (result != 0
3441 && REG_P (result) && GET_MODE (result) == insn_mode
3442 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3443 result = gen_reg_rtx (insn_mode);
3445 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3446 arg1 = builtin_save_expr (arg1);
3447 arg2 = builtin_save_expr (arg2);
3449 arg1_rtx = get_memory_rtx (arg1);
3450 arg2_rtx = get_memory_rtx (arg2);
3451 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3452 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3453 GEN_INT (MIN (arg1_align, arg2_align)));
3454 if (insn)
3456 emit_insn (insn);
3458 /* Return the value in the proper mode for this function. */
3459 mode = TYPE_MODE (TREE_TYPE (exp));
3460 if (GET_MODE (result) == mode)
3461 return result;
3462 if (target == 0)
3463 return convert_to_mode (mode, result, 0);
3464 convert_move (target, result, 0);
3465 return target;
3468 /* Expand the library call ourselves using a stabilized argument
3469 list to avoid re-evaluating the function's arguments twice. */
3470 arglist = build_tree_list (NULL_TREE, arg2);
3471 arglist = tree_cons (NULL_TREE, arg1, arglist);
3472 fndecl = get_callee_fndecl (exp);
3473 exp = build_function_call_expr (fndecl, arglist);
3474 return expand_call (exp, target, target == const0_rtx);
3476 #endif
3477 return 0;
3480 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3481 if we failed the caller should emit a normal call, otherwise try to get
3482 the result in TARGET, if convenient. */
3484 static rtx
3485 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3487 tree arglist = TREE_OPERAND (exp, 1);
3489 if (!validate_arglist (arglist,
3490 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3491 return 0;
3492 else
3494 tree result = fold_builtin_strncmp (arglist);
3495 if (result)
3496 return expand_expr (result, target, mode, EXPAND_NORMAL);
3499 /* If c_strlen can determine an expression for one of the string
3500 lengths, and it doesn't have side effects, then emit cmpstrsi
3501 using length MIN(strlen(string)+1, arg3). */
3502 #ifdef HAVE_cmpstrsi
3503 if (HAVE_cmpstrsi)
3505 tree arg1 = TREE_VALUE (arglist);
3506 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3507 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3508 tree len, len1, len2;
3509 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3510 rtx result, insn;
3511 tree fndecl;
3513 int arg1_align
3514 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3515 int arg2_align
3516 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3517 enum machine_mode insn_mode
3518 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3520 len1 = c_strlen (arg1, 1);
3521 len2 = c_strlen (arg2, 1);
3523 if (len1)
3524 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3525 if (len2)
3526 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3528 /* If we don't have a constant length for the first, use the length
3529 of the second, if we know it. We don't require a constant for
3530 this case; some cost analysis could be done if both are available
3531 but neither is constant. For now, assume they're equally cheap,
3532 unless one has side effects. If both strings have constant lengths,
3533 use the smaller. */
3535 if (!len1)
3536 len = len2;
3537 else if (!len2)
3538 len = len1;
3539 else if (TREE_SIDE_EFFECTS (len1))
3540 len = len2;
3541 else if (TREE_SIDE_EFFECTS (len2))
3542 len = len1;
3543 else if (TREE_CODE (len1) != INTEGER_CST)
3544 len = len2;
3545 else if (TREE_CODE (len2) != INTEGER_CST)
3546 len = len1;
3547 else if (tree_int_cst_lt (len1, len2))
3548 len = len1;
3549 else
3550 len = len2;
3552 /* If both arguments have side effects, we cannot optimize. */
3553 if (!len || TREE_SIDE_EFFECTS (len))
3554 return 0;
3556 /* The actual new length parameter is MIN(len,arg3). */
3557 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len,
3558 fold_convert (TREE_TYPE (len), arg3)));
3560 /* If we don't have POINTER_TYPE, call the function. */
3561 if (arg1_align == 0 || arg2_align == 0)
3562 return 0;
3564 /* Make a place to write the result of the instruction. */
3565 result = target;
3566 if (! (result != 0
3567 && REG_P (result) && GET_MODE (result) == insn_mode
3568 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3569 result = gen_reg_rtx (insn_mode);
3571 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3572 arg1 = builtin_save_expr (arg1);
3573 arg2 = builtin_save_expr (arg2);
3574 len = builtin_save_expr (len);
3576 arg1_rtx = get_memory_rtx (arg1);
3577 arg2_rtx = get_memory_rtx (arg2);
3578 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3579 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3580 GEN_INT (MIN (arg1_align, arg2_align)));
3581 if (insn)
3583 emit_insn (insn);
3585 /* Return the value in the proper mode for this function. */
3586 mode = TYPE_MODE (TREE_TYPE (exp));
3587 if (GET_MODE (result) == mode)
3588 return result;
3589 if (target == 0)
3590 return convert_to_mode (mode, result, 0);
3591 convert_move (target, result, 0);
3592 return target;
3595 /* Expand the library call ourselves using a stabilized argument
3596 list to avoid re-evaluating the function's arguments twice. */
3597 arglist = build_tree_list (NULL_TREE, len);
3598 arglist = tree_cons (NULL_TREE, arg2, arglist);
3599 arglist = tree_cons (NULL_TREE, arg1, arglist);
3600 fndecl = get_callee_fndecl (exp);
3601 exp = build_function_call_expr (fndecl, arglist);
3602 return expand_call (exp, target, target == const0_rtx);
3604 #endif
3605 return 0;
3608 /* Expand expression EXP, which is a call to the strcat builtin.
3609 Return 0 if we failed the caller should emit a normal call,
3610 otherwise try to get the result in TARGET, if convenient. */
3612 static rtx
3613 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3615 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3616 return 0;
3617 else
3619 tree dst = TREE_VALUE (arglist),
3620 src = TREE_VALUE (TREE_CHAIN (arglist));
3621 const char *p = c_getstr (src);
3623 if (p)
3625 /* If the string length is zero, return the dst parameter. */
3626 if (*p == '\0')
3627 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3628 else if (!optimize_size)
3630 /* Otherwise if !optimize_size, see if we can store by
3631 pieces into (dst + strlen(dst)). */
3632 tree newdst, arglist,
3633 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3635 /* This is the length argument. */
3636 arglist = build_tree_list (NULL_TREE,
3637 fold (size_binop (PLUS_EXPR,
3638 c_strlen (src, 0),
3639 ssize_int (1))));
3640 /* Prepend src argument. */
3641 arglist = tree_cons (NULL_TREE, src, arglist);
3643 /* We're going to use dst more than once. */
3644 dst = builtin_save_expr (dst);
3646 /* Create strlen (dst). */
3647 newdst =
3648 fold (build_function_call_expr (strlen_fn,
3649 build_tree_list (NULL_TREE,
3650 dst)));
3651 /* Create (dst + strlen (dst)). */
3652 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3654 /* Prepend the new dst argument. */
3655 arglist = tree_cons (NULL_TREE, newdst, arglist);
3657 /* We don't want to get turned into a memcpy if the
3658 target is const0_rtx, i.e. when the return value
3659 isn't used. That would produce pessimized code so
3660 pass in a target of zero, it should never actually be
3661 used. If this was successful return the original
3662 dst, not the result of mempcpy. */
3663 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3664 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3665 else
3666 return 0;
3670 return 0;
3674 /* Expand expression EXP, which is a call to the strncat builtin.
3675 Return 0 if we failed the caller should emit a normal call,
3676 otherwise try to get the result in TARGET, if convenient. */
3678 static rtx
3679 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3681 if (validate_arglist (arglist,
3682 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3684 tree result = fold_builtin_strncat (arglist);
3685 if (result)
3686 return expand_expr (result, target, mode, EXPAND_NORMAL);
3688 return 0;
3691 /* Expand expression EXP, which is a call to the strspn builtin.
3692 Return 0 if we failed the caller should emit a normal call,
3693 otherwise try to get the result in TARGET, if convenient. */
3695 static rtx
3696 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3698 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3700 tree result = fold_builtin_strspn (arglist);
3701 if (result)
3702 return expand_expr (result, target, mode, EXPAND_NORMAL);
3704 return 0;
3707 /* Expand expression EXP, which is a call to the strcspn builtin.
3708 Return 0 if we failed the caller should emit a normal call,
3709 otherwise try to get the result in TARGET, if convenient. */
3711 static rtx
3712 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3714 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3716 tree result = fold_builtin_strcspn (arglist);
3717 if (result)
3718 return expand_expr (result, target, mode, EXPAND_NORMAL);
3720 return 0;
3723 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3724 if that's convenient. */
3727 expand_builtin_saveregs (void)
3729 rtx val, seq;
3731 /* Don't do __builtin_saveregs more than once in a function.
3732 Save the result of the first call and reuse it. */
3733 if (saveregs_value != 0)
3734 return saveregs_value;
3736 /* When this function is called, it means that registers must be
3737 saved on entry to this function. So we migrate the call to the
3738 first insn of this function. */
3740 start_sequence ();
3742 /* Do whatever the machine needs done in this case. */
3743 val = targetm.calls.expand_builtin_saveregs ();
3745 seq = get_insns ();
3746 end_sequence ();
3748 saveregs_value = val;
3750 /* Put the insns after the NOTE that starts the function. If this
3751 is inside a start_sequence, make the outer-level insn chain current, so
3752 the code is placed at the start of the function. */
3753 push_topmost_sequence ();
3754 emit_insn_after (seq, entry_of_function ());
3755 pop_topmost_sequence ();
3757 return val;
3760 /* __builtin_args_info (N) returns word N of the arg space info
3761 for the current function. The number and meanings of words
3762 is controlled by the definition of CUMULATIVE_ARGS. */
3764 static rtx
3765 expand_builtin_args_info (tree arglist)
3767 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3768 int *word_ptr = (int *) &current_function_args_info;
3770 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
3772 if (arglist != 0)
3774 if (!host_integerp (TREE_VALUE (arglist), 0))
3775 error ("argument of %<__builtin_args_info%> must be constant");
3776 else
3778 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3780 if (wordnum < 0 || wordnum >= nwords)
3781 error ("argument of %<__builtin_args_info%> out of range");
3782 else
3783 return GEN_INT (word_ptr[wordnum]);
3786 else
3787 error ("missing argument in %<__builtin_args_info%>");
3789 return const0_rtx;
3792 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3794 static rtx
3795 expand_builtin_next_arg (tree arglist)
3797 tree fntype = TREE_TYPE (current_function_decl);
3799 if (TYPE_ARG_TYPES (fntype) == 0
3800 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3801 == void_type_node))
3803 error ("%<va_start%> used in function with fixed args");
3804 return const0_rtx;
3807 if (arglist)
3809 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3810 tree arg = TREE_VALUE (arglist);
3812 /* Strip off all nops for the sake of the comparison. This
3813 is not quite the same as STRIP_NOPS. It does more.
3814 We must also strip off INDIRECT_EXPR for C++ reference
3815 parameters. */
3816 while (TREE_CODE (arg) == NOP_EXPR
3817 || TREE_CODE (arg) == CONVERT_EXPR
3818 || TREE_CODE (arg) == NON_LVALUE_EXPR
3819 || TREE_CODE (arg) == INDIRECT_REF)
3820 arg = TREE_OPERAND (arg, 0);
3821 if (arg != last_parm)
3822 warning ("second parameter of %<va_start%> not last named argument");
3824 else
3825 /* Evidently an out of date version of <stdarg.h>; can't validate
3826 va_start's second argument, but can still work as intended. */
3827 warning ("%<__builtin_next_arg%> called without an argument");
3829 return expand_binop (Pmode, add_optab,
3830 current_function_internal_arg_pointer,
3831 current_function_arg_offset_rtx,
3832 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3835 /* Make it easier for the backends by protecting the valist argument
3836 from multiple evaluations. */
3838 static tree
3839 stabilize_va_list (tree valist, int needs_lvalue)
3841 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3843 if (TREE_SIDE_EFFECTS (valist))
3844 valist = save_expr (valist);
3846 /* For this case, the backends will be expecting a pointer to
3847 TREE_TYPE (va_list_type_node), but it's possible we've
3848 actually been given an array (an actual va_list_type_node).
3849 So fix it. */
3850 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3852 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3853 valist = build_fold_addr_expr_with_type (valist, p1);
3856 else
3858 tree pt;
3860 if (! needs_lvalue)
3862 if (! TREE_SIDE_EFFECTS (valist))
3863 return valist;
3865 pt = build_pointer_type (va_list_type_node);
3866 valist = fold (build1 (ADDR_EXPR, pt, valist));
3867 TREE_SIDE_EFFECTS (valist) = 1;
3870 if (TREE_SIDE_EFFECTS (valist))
3871 valist = save_expr (valist);
3872 valist = build_fold_indirect_ref (valist);
3875 return valist;
3878 /* The "standard" definition of va_list is void*. */
3880 tree
3881 std_build_builtin_va_list (void)
3883 return ptr_type_node;
3886 /* The "standard" implementation of va_start: just assign `nextarg' to
3887 the variable. */
3889 void
3890 std_expand_builtin_va_start (tree valist, rtx nextarg)
3892 tree t;
3894 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
3895 make_tree (ptr_type_node, nextarg));
3896 TREE_SIDE_EFFECTS (t) = 1;
3898 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3901 /* Expand ARGLIST, from a call to __builtin_va_start. */
3903 static rtx
3904 expand_builtin_va_start (tree arglist)
3906 rtx nextarg;
3907 tree chain, valist;
3909 chain = TREE_CHAIN (arglist);
3911 if (TREE_CHAIN (chain))
3912 error ("too many arguments to function %<va_start%>");
3914 fold_builtin_next_arg (chain);
3916 nextarg = expand_builtin_next_arg (chain);
3917 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3919 #ifdef EXPAND_BUILTIN_VA_START
3920 EXPAND_BUILTIN_VA_START (valist, nextarg);
3921 #else
3922 std_expand_builtin_va_start (valist, nextarg);
3923 #endif
3925 return const0_rtx;
3928 /* The "standard" implementation of va_arg: read the value from the
3929 current (padded) address and increment by the (padded) size. */
3931 tree
3932 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3934 tree addr, t, type_size, rounded_size, valist_tmp;
3935 unsigned HOST_WIDE_INT align, boundary;
3936 bool indirect;
3938 #ifdef ARGS_GROW_DOWNWARD
3939 /* All of the alignment and movement below is for args-grow-up machines.
3940 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
3941 implement their own specialized gimplify_va_arg_expr routines. */
3942 gcc_unreachable ();
3943 #endif
3945 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
3946 if (indirect)
3947 type = build_pointer_type (type);
3949 align = PARM_BOUNDARY / BITS_PER_UNIT;
3950 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
3952 /* Hoist the valist value into a temporary for the moment. */
3953 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
3955 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
3956 requires greater alignment, we must perform dynamic alignment. */
3957 if (boundary > align)
3959 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
3960 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3961 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
3962 gimplify_and_add (t, pre_p);
3964 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
3965 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3966 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
3967 gimplify_and_add (t, pre_p);
3970 /* Compute the rounded size of the type. */
3971 type_size = size_in_bytes (type);
3972 rounded_size = round_up (type_size, align);
3974 /* Reduce rounded_size so it's sharable with the postqueue. */
3975 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
3977 /* Get AP. */
3978 addr = valist_tmp;
3979 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
3981 /* Small args are padded downward. */
3982 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
3983 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
3984 size_binop (MINUS_EXPR, rounded_size, type_size)));
3985 t = fold_convert (TREE_TYPE (addr), t);
3986 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
3989 /* Compute new value for AP. */
3990 t = fold_convert (TREE_TYPE (valist), rounded_size);
3991 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
3992 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
3993 gimplify_and_add (t, pre_p);
3995 addr = fold_convert (build_pointer_type (type), addr);
3997 if (indirect)
3998 addr = build_va_arg_indirect_ref (addr);
4000 return build_va_arg_indirect_ref (addr);
4003 /* Build an indirect-ref expression over the given TREE, which represents a
4004 piece of a va_arg() expansion. */
4005 tree
4006 build_va_arg_indirect_ref (tree addr)
4008 addr = build_fold_indirect_ref (addr);
4010 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4011 mf_mark (addr);
4013 return addr;
4016 /* Return a dummy expression of type TYPE in order to keep going after an
4017 error. */
4019 static tree
4020 dummy_object (tree type)
4022 tree t = convert (build_pointer_type (type), null_pointer_node);
4023 return build1 (INDIRECT_REF, type, t);
4026 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4027 builtin function, but a very special sort of operator. */
4029 enum gimplify_status
4030 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4032 tree promoted_type, want_va_type, have_va_type;
4033 tree valist = TREE_OPERAND (*expr_p, 0);
4034 tree type = TREE_TYPE (*expr_p);
4035 tree t;
4037 /* Verify that valist is of the proper type. */
4038 want_va_type = va_list_type_node;
4039 have_va_type = TREE_TYPE (valist);
4041 if (have_va_type == error_mark_node)
4042 return GS_ERROR;
4044 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4046 /* If va_list is an array type, the argument may have decayed
4047 to a pointer type, e.g. by being passed to another function.
4048 In that case, unwrap both types so that we can compare the
4049 underlying records. */
4050 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4051 || TREE_CODE (have_va_type) == POINTER_TYPE)
4053 want_va_type = TREE_TYPE (want_va_type);
4054 have_va_type = TREE_TYPE (have_va_type);
4058 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4060 error ("first argument to %<va_arg%> not of type %<va_list%>");
4061 return GS_ERROR;
4064 /* Generate a diagnostic for requesting data of a type that cannot
4065 be passed through `...' due to type promotion at the call site. */
4066 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4067 != type)
4069 static bool gave_help;
4071 /* Unfortunately, this is merely undefined, rather than a constraint
4072 violation, so we cannot make this an error. If this call is never
4073 executed, the program is still strictly conforming. */
4074 warning ("%qT is promoted to %qT when passed through %<...%>",
4075 type, promoted_type);
4076 if (! gave_help)
4078 gave_help = true;
4079 warning ("(so you should pass %qT not %qT to %<va_arg%>)",
4080 promoted_type, type);
4083 /* We can, however, treat "undefined" any way we please.
4084 Call abort to encourage the user to fix the program. */
4085 inform ("if this code is reached, the program will abort");
4086 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4087 NULL);
4088 append_to_statement_list (t, pre_p);
4090 /* This is dead code, but go ahead and finish so that the
4091 mode of the result comes out right. */
4092 *expr_p = dummy_object (type);
4093 return GS_ALL_DONE;
4095 else
4097 /* Make it easier for the backends by protecting the valist argument
4098 from multiple evaluations. */
4099 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4101 /* For this case, the backends will be expecting a pointer to
4102 TREE_TYPE (va_list_type_node), but it's possible we've
4103 actually been given an array (an actual va_list_type_node).
4104 So fix it. */
4105 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4107 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4108 valist = build_fold_addr_expr_with_type (valist, p1);
4110 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4112 else
4113 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4115 if (!targetm.gimplify_va_arg_expr)
4116 /* Once most targets are converted this should abort. */
4117 return GS_ALL_DONE;
4119 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4120 return GS_OK;
4124 /* Expand ARGLIST, from a call to __builtin_va_end. */
4126 static rtx
4127 expand_builtin_va_end (tree arglist)
4129 tree valist = TREE_VALUE (arglist);
4131 /* Evaluate for side effects, if needed. I hate macros that don't
4132 do that. */
4133 if (TREE_SIDE_EFFECTS (valist))
4134 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4136 return const0_rtx;
4139 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4140 builtin rather than just as an assignment in stdarg.h because of the
4141 nastiness of array-type va_list types. */
4143 static rtx
4144 expand_builtin_va_copy (tree arglist)
4146 tree dst, src, t;
4148 dst = TREE_VALUE (arglist);
4149 src = TREE_VALUE (TREE_CHAIN (arglist));
4151 dst = stabilize_va_list (dst, 1);
4152 src = stabilize_va_list (src, 0);
4154 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4156 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4157 TREE_SIDE_EFFECTS (t) = 1;
4158 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4160 else
4162 rtx dstb, srcb, size;
4164 /* Evaluate to pointers. */
4165 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4166 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4167 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4168 VOIDmode, EXPAND_NORMAL);
4170 dstb = convert_memory_address (Pmode, dstb);
4171 srcb = convert_memory_address (Pmode, srcb);
4173 /* "Dereference" to BLKmode memories. */
4174 dstb = gen_rtx_MEM (BLKmode, dstb);
4175 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4176 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4177 srcb = gen_rtx_MEM (BLKmode, srcb);
4178 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4179 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4181 /* Copy. */
4182 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4185 return const0_rtx;
4188 /* Expand a call to one of the builtin functions __builtin_frame_address or
4189 __builtin_return_address. */
4191 static rtx
4192 expand_builtin_frame_address (tree fndecl, tree arglist)
4194 /* The argument must be a nonnegative integer constant.
4195 It counts the number of frames to scan up the stack.
4196 The value is the return address saved in that frame. */
4197 if (arglist == 0)
4198 /* Warning about missing arg was already issued. */
4199 return const0_rtx;
4200 else if (! host_integerp (TREE_VALUE (arglist), 1))
4202 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4203 error ("invalid arg to %<__builtin_frame_address%>");
4204 else
4205 error ("invalid arg to %<__builtin_return_address%>");
4206 return const0_rtx;
4208 else
4210 rtx tem
4211 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4212 tree_low_cst (TREE_VALUE (arglist), 1),
4213 hard_frame_pointer_rtx);
4215 /* Some ports cannot access arbitrary stack frames. */
4216 if (tem == NULL)
4218 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4219 warning ("unsupported arg to %<__builtin_frame_address%>");
4220 else
4221 warning ("unsupported arg to %<__builtin_return_address%>");
4222 return const0_rtx;
4225 /* For __builtin_frame_address, return what we've got. */
4226 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4227 return tem;
4229 if (!REG_P (tem)
4230 && ! CONSTANT_P (tem))
4231 tem = copy_to_mode_reg (Pmode, tem);
4232 return tem;
4236 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4237 we failed and the caller should emit a normal call, otherwise try to get
4238 the result in TARGET, if convenient. */
4240 static rtx
4241 expand_builtin_alloca (tree arglist, rtx target)
4243 rtx op0;
4244 rtx result;
4246 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4247 should always expand to function calls. These can be intercepted
4248 in libmudflap. */
4249 if (flag_mudflap)
4250 return 0;
4252 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4253 return 0;
4255 /* Compute the argument. */
4256 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4258 /* Allocate the desired space. */
4259 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4260 result = convert_memory_address (ptr_mode, result);
4262 return result;
4265 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4266 Return 0 if a normal call should be emitted rather than expanding the
4267 function in-line. If convenient, the result should be placed in TARGET.
4268 SUBTARGET may be used as the target for computing one of EXP's operands. */
4270 static rtx
4271 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4272 rtx subtarget, optab op_optab)
4274 rtx op0;
4275 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4276 return 0;
4278 /* Compute the argument. */
4279 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4280 /* Compute op, into TARGET if possible.
4281 Set TARGET to wherever the result comes back. */
4282 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4283 op_optab, op0, target, 1);
4284 gcc_assert (target);
4286 return convert_to_mode (target_mode, target, 0);
4289 /* If the string passed to fputs is a constant and is one character
4290 long, we attempt to transform this call into __builtin_fputc(). */
4292 static rtx
4293 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4295 /* Verify the arguments in the original call. */
4296 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4298 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4299 unlocked, NULL_TREE);
4300 if (result)
4301 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4303 return 0;
4306 /* Expand a call to __builtin_expect. We return our argument and emit a
4307 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4308 a non-jump context. */
4310 static rtx
4311 expand_builtin_expect (tree arglist, rtx target)
4313 tree exp, c;
4314 rtx note, rtx_c;
4316 if (arglist == NULL_TREE
4317 || TREE_CHAIN (arglist) == NULL_TREE)
4318 return const0_rtx;
4319 exp = TREE_VALUE (arglist);
4320 c = TREE_VALUE (TREE_CHAIN (arglist));
4322 if (TREE_CODE (c) != INTEGER_CST)
4324 error ("second arg to %<__builtin_expect%> must be a constant");
4325 c = integer_zero_node;
4328 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4330 /* Don't bother with expected value notes for integral constants. */
4331 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4333 /* We do need to force this into a register so that we can be
4334 moderately sure to be able to correctly interpret the branch
4335 condition later. */
4336 target = force_reg (GET_MODE (target), target);
4338 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4340 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4341 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4344 return target;
4347 /* Like expand_builtin_expect, except do this in a jump context. This is
4348 called from do_jump if the conditional is a __builtin_expect. Return either
4349 a list of insns to emit the jump or NULL if we cannot optimize
4350 __builtin_expect. We need to optimize this at jump time so that machines
4351 like the PowerPC don't turn the test into a SCC operation, and then jump
4352 based on the test being 0/1. */
4355 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4357 tree arglist = TREE_OPERAND (exp, 1);
4358 tree arg0 = TREE_VALUE (arglist);
4359 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4360 rtx ret = NULL_RTX;
4362 /* Only handle __builtin_expect (test, 0) and
4363 __builtin_expect (test, 1). */
4364 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4365 && (integer_zerop (arg1) || integer_onep (arg1)))
4367 rtx insn, drop_through_label, temp;
4369 /* Expand the jump insns. */
4370 start_sequence ();
4371 do_jump (arg0, if_false_label, if_true_label);
4372 ret = get_insns ();
4374 drop_through_label = get_last_insn ();
4375 if (drop_through_label && NOTE_P (drop_through_label))
4376 drop_through_label = prev_nonnote_insn (drop_through_label);
4377 if (drop_through_label && !LABEL_P (drop_through_label))
4378 drop_through_label = NULL_RTX;
4379 end_sequence ();
4381 if (! if_true_label)
4382 if_true_label = drop_through_label;
4383 if (! if_false_label)
4384 if_false_label = drop_through_label;
4386 /* Go through and add the expect's to each of the conditional jumps. */
4387 insn = ret;
4388 while (insn != NULL_RTX)
4390 rtx next = NEXT_INSN (insn);
4392 if (JUMP_P (insn) && any_condjump_p (insn))
4394 rtx ifelse = SET_SRC (pc_set (insn));
4395 rtx then_dest = XEXP (ifelse, 1);
4396 rtx else_dest = XEXP (ifelse, 2);
4397 int taken = -1;
4399 /* First check if we recognize any of the labels. */
4400 if (GET_CODE (then_dest) == LABEL_REF
4401 && XEXP (then_dest, 0) == if_true_label)
4402 taken = 1;
4403 else if (GET_CODE (then_dest) == LABEL_REF
4404 && XEXP (then_dest, 0) == if_false_label)
4405 taken = 0;
4406 else if (GET_CODE (else_dest) == LABEL_REF
4407 && XEXP (else_dest, 0) == if_false_label)
4408 taken = 1;
4409 else if (GET_CODE (else_dest) == LABEL_REF
4410 && XEXP (else_dest, 0) == if_true_label)
4411 taken = 0;
4412 /* Otherwise check where we drop through. */
4413 else if (else_dest == pc_rtx)
4415 if (next && NOTE_P (next))
4416 next = next_nonnote_insn (next);
4418 if (next && JUMP_P (next)
4419 && any_uncondjump_p (next))
4420 temp = XEXP (SET_SRC (pc_set (next)), 0);
4421 else
4422 temp = next;
4424 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4425 else that can't possibly match either target label. */
4426 if (temp == if_false_label)
4427 taken = 1;
4428 else if (temp == if_true_label)
4429 taken = 0;
4431 else if (then_dest == pc_rtx)
4433 if (next && NOTE_P (next))
4434 next = next_nonnote_insn (next);
4436 if (next && JUMP_P (next)
4437 && any_uncondjump_p (next))
4438 temp = XEXP (SET_SRC (pc_set (next)), 0);
4439 else
4440 temp = next;
4442 if (temp == if_false_label)
4443 taken = 0;
4444 else if (temp == if_true_label)
4445 taken = 1;
4448 if (taken != -1)
4450 /* If the test is expected to fail, reverse the
4451 probabilities. */
4452 if (integer_zerop (arg1))
4453 taken = 1 - taken;
4454 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4458 insn = next;
4462 return ret;
4465 void
4466 expand_builtin_trap (void)
4468 #ifdef HAVE_trap
4469 if (HAVE_trap)
4470 emit_insn (gen_trap ());
4471 else
4472 #endif
4473 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4474 emit_barrier ();
4477 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4478 Return 0 if a normal call should be emitted rather than expanding
4479 the function inline. If convenient, the result should be placed
4480 in TARGET. SUBTARGET may be used as the target for computing
4481 the operand. */
4483 static rtx
4484 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4486 enum machine_mode mode;
4487 tree arg;
4488 rtx op0;
4490 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4491 return 0;
4493 arg = TREE_VALUE (arglist);
4494 mode = TYPE_MODE (TREE_TYPE (arg));
4495 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4496 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4499 /* Create a new constant string literal and return a char* pointer to it.
4500 The STRING_CST value is the LEN characters at STR. */
4501 static tree
4502 build_string_literal (int len, const char *str)
4504 tree t, elem, index, type;
4506 t = build_string (len, str);
4507 elem = build_type_variant (char_type_node, 1, 0);
4508 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4509 type = build_array_type (elem, index);
4510 TREE_TYPE (t) = type;
4511 TREE_CONSTANT (t) = 1;
4512 TREE_INVARIANT (t) = 1;
4513 TREE_READONLY (t) = 1;
4514 TREE_STATIC (t) = 1;
4516 type = build_pointer_type (type);
4517 t = build1 (ADDR_EXPR, type, t);
4519 type = build_pointer_type (elem);
4520 t = build1 (NOP_EXPR, type, t);
4521 return t;
4524 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4525 Return 0 if a normal call should be emitted rather than transforming
4526 the function inline. If convenient, the result should be placed in
4527 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4528 call. */
4529 static rtx
4530 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4531 bool unlocked)
4533 tree fn_putchar = unlocked
4534 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4535 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4536 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4537 : implicit_built_in_decls[BUILT_IN_PUTS];
4538 const char *fmt_str;
4539 tree fn, fmt, arg;
4541 /* If the return value is used, don't do the transformation. */
4542 if (target != const0_rtx)
4543 return 0;
4545 /* Verify the required arguments in the original call. */
4546 if (! arglist)
4547 return 0;
4548 fmt = TREE_VALUE (arglist);
4549 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4550 return 0;
4551 arglist = TREE_CHAIN (arglist);
4553 /* Check whether the format is a literal string constant. */
4554 fmt_str = c_getstr (fmt);
4555 if (fmt_str == NULL)
4556 return 0;
4558 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4559 if (strcmp (fmt_str, "%s\n") == 0)
4561 if (! arglist
4562 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4563 || TREE_CHAIN (arglist))
4564 return 0;
4565 fn = fn_puts;
4567 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4568 else if (strcmp (fmt_str, "%c") == 0)
4570 if (! arglist
4571 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4572 || TREE_CHAIN (arglist))
4573 return 0;
4574 fn = fn_putchar;
4576 else
4578 /* We can't handle anything else with % args or %% ... yet. */
4579 if (strchr (fmt_str, '%'))
4580 return 0;
4582 if (arglist)
4583 return 0;
4585 /* If the format specifier was "", printf does nothing. */
4586 if (fmt_str[0] == '\0')
4587 return const0_rtx;
4588 /* If the format specifier has length of 1, call putchar. */
4589 if (fmt_str[1] == '\0')
4591 /* Given printf("c"), (where c is any one character,)
4592 convert "c"[0] to an int and pass that to the replacement
4593 function. */
4594 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4595 arglist = build_tree_list (NULL_TREE, arg);
4596 fn = fn_putchar;
4598 else
4600 /* If the format specifier was "string\n", call puts("string"). */
4601 size_t len = strlen (fmt_str);
4602 if (fmt_str[len - 1] == '\n')
4604 /* Create a NUL-terminated string that's one char shorter
4605 than the original, stripping off the trailing '\n'. */
4606 char *newstr = alloca (len);
4607 memcpy (newstr, fmt_str, len - 1);
4608 newstr[len - 1] = 0;
4610 arg = build_string_literal (len, newstr);
4611 arglist = build_tree_list (NULL_TREE, arg);
4612 fn = fn_puts;
4614 else
4615 /* We'd like to arrange to call fputs(string,stdout) here,
4616 but we need stdout and don't have a way to get it yet. */
4617 return 0;
4621 if (!fn)
4622 return 0;
4623 return expand_expr (build_function_call_expr (fn, arglist),
4624 target, mode, EXPAND_NORMAL);
4627 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4628 Return 0 if a normal call should be emitted rather than transforming
4629 the function inline. If convenient, the result should be placed in
4630 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4631 call. */
4632 static rtx
4633 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4634 bool unlocked)
4636 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4637 : implicit_built_in_decls[BUILT_IN_FPUTC];
4638 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4639 : implicit_built_in_decls[BUILT_IN_FPUTS];
4640 const char *fmt_str;
4641 tree fn, fmt, fp, arg;
4643 /* If the return value is used, don't do the transformation. */
4644 if (target != const0_rtx)
4645 return 0;
4647 /* Verify the required arguments in the original call. */
4648 if (! arglist)
4649 return 0;
4650 fp = TREE_VALUE (arglist);
4651 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4652 return 0;
4653 arglist = TREE_CHAIN (arglist);
4654 if (! arglist)
4655 return 0;
4656 fmt = TREE_VALUE (arglist);
4657 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4658 return 0;
4659 arglist = TREE_CHAIN (arglist);
4661 /* Check whether the format is a literal string constant. */
4662 fmt_str = c_getstr (fmt);
4663 if (fmt_str == NULL)
4664 return 0;
4666 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4667 if (strcmp (fmt_str, "%s") == 0)
4669 if (! arglist
4670 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4671 || TREE_CHAIN (arglist))
4672 return 0;
4673 arg = TREE_VALUE (arglist);
4674 arglist = build_tree_list (NULL_TREE, fp);
4675 arglist = tree_cons (NULL_TREE, arg, arglist);
4676 fn = fn_fputs;
4678 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4679 else if (strcmp (fmt_str, "%c") == 0)
4681 if (! arglist
4682 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4683 || TREE_CHAIN (arglist))
4684 return 0;
4685 arg = TREE_VALUE (arglist);
4686 arglist = build_tree_list (NULL_TREE, fp);
4687 arglist = tree_cons (NULL_TREE, arg, arglist);
4688 fn = fn_fputc;
4690 else
4692 /* We can't handle anything else with % args or %% ... yet. */
4693 if (strchr (fmt_str, '%'))
4694 return 0;
4696 if (arglist)
4697 return 0;
4699 /* If the format specifier was "", fprintf does nothing. */
4700 if (fmt_str[0] == '\0')
4702 /* Evaluate and ignore FILE* argument for side-effects. */
4703 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4704 return const0_rtx;
4707 /* When "string" doesn't contain %, replace all cases of
4708 fprintf(stream,string) with fputs(string,stream). The fputs
4709 builtin will take care of special cases like length == 1. */
4710 arglist = build_tree_list (NULL_TREE, fp);
4711 arglist = tree_cons (NULL_TREE, fmt, arglist);
4712 fn = fn_fputs;
4715 if (!fn)
4716 return 0;
4717 return expand_expr (build_function_call_expr (fn, arglist),
4718 target, mode, EXPAND_NORMAL);
4721 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4722 a normal call should be emitted rather than expanding the function
4723 inline. If convenient, the result should be placed in TARGET with
4724 mode MODE. */
4726 static rtx
4727 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4729 tree orig_arglist, dest, fmt;
4730 const char *fmt_str;
4732 orig_arglist = arglist;
4734 /* Verify the required arguments in the original call. */
4735 if (! arglist)
4736 return 0;
4737 dest = TREE_VALUE (arglist);
4738 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4739 return 0;
4740 arglist = TREE_CHAIN (arglist);
4741 if (! arglist)
4742 return 0;
4743 fmt = TREE_VALUE (arglist);
4744 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4745 return 0;
4746 arglist = TREE_CHAIN (arglist);
4748 /* Check whether the format is a literal string constant. */
4749 fmt_str = c_getstr (fmt);
4750 if (fmt_str == NULL)
4751 return 0;
4753 /* If the format doesn't contain % args or %%, use strcpy. */
4754 if (strchr (fmt_str, '%') == 0)
4756 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4757 tree exp;
4759 if (arglist || ! fn)
4760 return 0;
4761 expand_expr (build_function_call_expr (fn, orig_arglist),
4762 const0_rtx, VOIDmode, EXPAND_NORMAL);
4763 if (target == const0_rtx)
4764 return const0_rtx;
4765 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
4766 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4768 /* If the format is "%s", use strcpy if the result isn't used. */
4769 else if (strcmp (fmt_str, "%s") == 0)
4771 tree fn, arg, len;
4772 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4774 if (! fn)
4775 return 0;
4777 if (! arglist || TREE_CHAIN (arglist))
4778 return 0;
4779 arg = TREE_VALUE (arglist);
4780 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4781 return 0;
4783 if (target != const0_rtx)
4785 len = c_strlen (arg, 1);
4786 if (! len || TREE_CODE (len) != INTEGER_CST)
4787 return 0;
4789 else
4790 len = NULL_TREE;
4792 arglist = build_tree_list (NULL_TREE, arg);
4793 arglist = tree_cons (NULL_TREE, dest, arglist);
4794 expand_expr (build_function_call_expr (fn, arglist),
4795 const0_rtx, VOIDmode, EXPAND_NORMAL);
4797 if (target == const0_rtx)
4798 return const0_rtx;
4799 return expand_expr (len, target, mode, EXPAND_NORMAL);
4802 return 0;
4805 /* Expand a call to either the entry or exit function profiler. */
4807 static rtx
4808 expand_builtin_profile_func (bool exitp)
4810 rtx this, which;
4812 this = DECL_RTL (current_function_decl);
4813 gcc_assert (MEM_P (this));
4814 this = XEXP (this, 0);
4816 if (exitp)
4817 which = profile_function_exit_libfunc;
4818 else
4819 which = profile_function_entry_libfunc;
4821 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
4822 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
4823 0, hard_frame_pointer_rtx),
4824 Pmode);
4826 return const0_rtx;
4829 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
4831 static rtx
4832 round_trampoline_addr (rtx tramp)
4834 rtx temp, addend, mask;
4836 /* If we don't need too much alignment, we'll have been guaranteed
4837 proper alignment by get_trampoline_type. */
4838 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4839 return tramp;
4841 /* Round address up to desired boundary. */
4842 temp = gen_reg_rtx (Pmode);
4843 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4844 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4846 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
4847 temp, 0, OPTAB_LIB_WIDEN);
4848 tramp = expand_simple_binop (Pmode, AND, temp, mask,
4849 temp, 0, OPTAB_LIB_WIDEN);
4851 return tramp;
4854 static rtx
4855 expand_builtin_init_trampoline (tree arglist)
4857 tree t_tramp, t_func, t_chain;
4858 rtx r_tramp, r_func, r_chain;
4859 #ifdef TRAMPOLINE_TEMPLATE
4860 rtx blktramp;
4861 #endif
4863 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
4864 POINTER_TYPE, VOID_TYPE))
4865 return NULL_RTX;
4867 t_tramp = TREE_VALUE (arglist);
4868 arglist = TREE_CHAIN (arglist);
4869 t_func = TREE_VALUE (arglist);
4870 arglist = TREE_CHAIN (arglist);
4871 t_chain = TREE_VALUE (arglist);
4873 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
4874 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
4875 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
4877 /* Generate insns to initialize the trampoline. */
4878 r_tramp = round_trampoline_addr (r_tramp);
4879 #ifdef TRAMPOLINE_TEMPLATE
4880 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
4881 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
4882 emit_block_move (blktramp, assemble_trampoline_template (),
4883 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4884 #endif
4885 trampolines_created = 1;
4886 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
4888 return const0_rtx;
4891 static rtx
4892 expand_builtin_adjust_trampoline (tree arglist)
4894 rtx tramp;
4896 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4897 return NULL_RTX;
4899 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4900 tramp = round_trampoline_addr (tramp);
4901 #ifdef TRAMPOLINE_ADJUST_ADDRESS
4902 TRAMPOLINE_ADJUST_ADDRESS (tramp);
4903 #endif
4905 return tramp;
4908 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4909 Return NULL_RTX if a normal call should be emitted rather than expanding
4910 the function in-line. EXP is the expression that is a call to the builtin
4911 function; if convenient, the result should be placed in TARGET. */
4913 static rtx
4914 expand_builtin_signbit (tree exp, rtx target)
4916 const struct real_format *fmt;
4917 enum machine_mode fmode, imode, rmode;
4918 HOST_WIDE_INT hi, lo;
4919 tree arg, arglist;
4920 int bitpos;
4921 rtx temp;
4923 arglist = TREE_OPERAND (exp, 1);
4924 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4925 return 0;
4927 arg = TREE_VALUE (arglist);
4928 fmode = TYPE_MODE (TREE_TYPE (arg));
4929 rmode = TYPE_MODE (TREE_TYPE (exp));
4930 fmt = REAL_MODE_FORMAT (fmode);
4932 /* For floating point formats without a sign bit, implement signbit
4933 as "ARG < 0.0". */
4934 if (fmt->signbit < 0)
4936 /* But we can't do this if the format supports signed zero. */
4937 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4938 return 0;
4940 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
4941 build_real (TREE_TYPE (arg), dconst0)));
4942 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4945 imode = int_mode_for_mode (fmode);
4946 if (imode == BLKmode)
4947 return 0;
4949 bitpos = fmt->signbit;
4950 /* Handle targets with different FP word orders. */
4951 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4953 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4954 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4955 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4958 /* If the sign bit is not in the lowpart and the floating point format
4959 is wider than an integer, check that is twice the size of an integer
4960 so that we can use gen_highpart below. */
4961 if (bitpos >= GET_MODE_BITSIZE (rmode)
4962 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4963 return 0;
4965 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4966 temp = gen_lowpart (imode, temp);
4968 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4970 if (BYTES_BIG_ENDIAN)
4971 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
4972 temp = copy_to_mode_reg (imode, temp);
4973 temp = extract_bit_field (temp, 1, bitpos, 1,
4974 NULL_RTX, rmode, rmode);
4976 else
4978 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
4979 temp = gen_lowpart (rmode, temp);
4980 if (bitpos < HOST_BITS_PER_WIDE_INT)
4982 hi = 0;
4983 lo = (HOST_WIDE_INT) 1 << bitpos;
4985 else
4987 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
4988 lo = 0;
4991 temp = force_reg (rmode, temp);
4992 temp = expand_binop (rmode, and_optab, temp,
4993 immed_double_const (lo, hi, rmode),
4994 target, 1, OPTAB_LIB_WIDEN);
4996 return temp;
4999 /* Expand fork or exec calls. TARGET is the desired target of the
5000 call. ARGLIST is the list of arguments of the call. FN is the
5001 identificator of the actual function. IGNORE is nonzero if the
5002 value is to be ignored. */
5004 static rtx
5005 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5007 tree id, decl;
5008 tree call;
5010 /* If we are not profiling, just call the function. */
5011 if (!profile_arc_flag)
5012 return NULL_RTX;
5014 /* Otherwise call the wrapper. This should be equivalent for the rest of
5015 compiler, so the code does not diverge, and the wrapper may run the
5016 code necessary for keeping the profiling sane. */
5018 switch (DECL_FUNCTION_CODE (fn))
5020 case BUILT_IN_FORK:
5021 id = get_identifier ("__gcov_fork");
5022 break;
5024 case BUILT_IN_EXECL:
5025 id = get_identifier ("__gcov_execl");
5026 break;
5028 case BUILT_IN_EXECV:
5029 id = get_identifier ("__gcov_execv");
5030 break;
5032 case BUILT_IN_EXECLP:
5033 id = get_identifier ("__gcov_execlp");
5034 break;
5036 case BUILT_IN_EXECLE:
5037 id = get_identifier ("__gcov_execle");
5038 break;
5040 case BUILT_IN_EXECVP:
5041 id = get_identifier ("__gcov_execvp");
5042 break;
5044 case BUILT_IN_EXECVE:
5045 id = get_identifier ("__gcov_execve");
5046 break;
5048 default:
5049 gcc_unreachable ();
5052 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5053 DECL_EXTERNAL (decl) = 1;
5054 TREE_PUBLIC (decl) = 1;
5055 DECL_ARTIFICIAL (decl) = 1;
5056 TREE_NOTHROW (decl) = 1;
5057 call = build_function_call_expr (decl, arglist);
5059 return expand_call (call, target, ignore);
5062 /* Expand an expression EXP that calls a built-in function,
5063 with result going to TARGET if that's convenient
5064 (and in mode MODE if that's convenient).
5065 SUBTARGET may be used as the target for computing one of EXP's operands.
5066 IGNORE is nonzero if the value is to be ignored. */
5069 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5070 int ignore)
5072 tree fndecl = get_callee_fndecl (exp);
5073 tree arglist = TREE_OPERAND (exp, 1);
5074 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5075 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5077 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5078 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5080 /* When not optimizing, generate calls to library functions for a certain
5081 set of builtins. */
5082 if (!optimize
5083 && !CALLED_AS_BUILT_IN (fndecl)
5084 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5085 && fcode != BUILT_IN_ALLOCA)
5086 return expand_call (exp, target, ignore);
5088 /* The built-in function expanders test for target == const0_rtx
5089 to determine whether the function's result will be ignored. */
5090 if (ignore)
5091 target = const0_rtx;
5093 /* If the result of a pure or const built-in function is ignored, and
5094 none of its arguments are volatile, we can avoid expanding the
5095 built-in call and just evaluate the arguments for side-effects. */
5096 if (target == const0_rtx
5097 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5099 bool volatilep = false;
5100 tree arg;
5102 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5103 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5105 volatilep = true;
5106 break;
5109 if (! volatilep)
5111 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5112 expand_expr (TREE_VALUE (arg), const0_rtx,
5113 VOIDmode, EXPAND_NORMAL);
5114 return const0_rtx;
5118 switch (fcode)
5120 case BUILT_IN_FABS:
5121 case BUILT_IN_FABSF:
5122 case BUILT_IN_FABSL:
5123 target = expand_builtin_fabs (arglist, target, subtarget);
5124 if (target)
5125 return target;
5126 break;
5128 /* Just do a normal library call if we were unable to fold
5129 the values. */
5130 case BUILT_IN_CABS:
5131 case BUILT_IN_CABSF:
5132 case BUILT_IN_CABSL:
5133 break;
5135 case BUILT_IN_EXP:
5136 case BUILT_IN_EXPF:
5137 case BUILT_IN_EXPL:
5138 case BUILT_IN_EXP10:
5139 case BUILT_IN_EXP10F:
5140 case BUILT_IN_EXP10L:
5141 case BUILT_IN_POW10:
5142 case BUILT_IN_POW10F:
5143 case BUILT_IN_POW10L:
5144 case BUILT_IN_EXP2:
5145 case BUILT_IN_EXP2F:
5146 case BUILT_IN_EXP2L:
5147 case BUILT_IN_EXPM1:
5148 case BUILT_IN_EXPM1F:
5149 case BUILT_IN_EXPM1L:
5150 case BUILT_IN_LOGB:
5151 case BUILT_IN_LOGBF:
5152 case BUILT_IN_LOGBL:
5153 case BUILT_IN_ILOGB:
5154 case BUILT_IN_ILOGBF:
5155 case BUILT_IN_ILOGBL:
5156 case BUILT_IN_LOG:
5157 case BUILT_IN_LOGF:
5158 case BUILT_IN_LOGL:
5159 case BUILT_IN_LOG10:
5160 case BUILT_IN_LOG10F:
5161 case BUILT_IN_LOG10L:
5162 case BUILT_IN_LOG2:
5163 case BUILT_IN_LOG2F:
5164 case BUILT_IN_LOG2L:
5165 case BUILT_IN_LOG1P:
5166 case BUILT_IN_LOG1PF:
5167 case BUILT_IN_LOG1PL:
5168 case BUILT_IN_TAN:
5169 case BUILT_IN_TANF:
5170 case BUILT_IN_TANL:
5171 case BUILT_IN_ASIN:
5172 case BUILT_IN_ASINF:
5173 case BUILT_IN_ASINL:
5174 case BUILT_IN_ACOS:
5175 case BUILT_IN_ACOSF:
5176 case BUILT_IN_ACOSL:
5177 case BUILT_IN_ATAN:
5178 case BUILT_IN_ATANF:
5179 case BUILT_IN_ATANL:
5180 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5181 because of possible accuracy problems. */
5182 if (! flag_unsafe_math_optimizations)
5183 break;
5184 case BUILT_IN_SQRT:
5185 case BUILT_IN_SQRTF:
5186 case BUILT_IN_SQRTL:
5187 case BUILT_IN_FLOOR:
5188 case BUILT_IN_FLOORF:
5189 case BUILT_IN_FLOORL:
5190 case BUILT_IN_CEIL:
5191 case BUILT_IN_CEILF:
5192 case BUILT_IN_CEILL:
5193 case BUILT_IN_TRUNC:
5194 case BUILT_IN_TRUNCF:
5195 case BUILT_IN_TRUNCL:
5196 case BUILT_IN_ROUND:
5197 case BUILT_IN_ROUNDF:
5198 case BUILT_IN_ROUNDL:
5199 case BUILT_IN_NEARBYINT:
5200 case BUILT_IN_NEARBYINTF:
5201 case BUILT_IN_NEARBYINTL:
5202 case BUILT_IN_RINT:
5203 case BUILT_IN_RINTF:
5204 case BUILT_IN_RINTL:
5205 target = expand_builtin_mathfn (exp, target, subtarget);
5206 if (target)
5207 return target;
5208 break;
5210 case BUILT_IN_POW:
5211 case BUILT_IN_POWF:
5212 case BUILT_IN_POWL:
5213 target = expand_builtin_pow (exp, target, subtarget);
5214 if (target)
5215 return target;
5216 break;
5218 case BUILT_IN_ATAN2:
5219 case BUILT_IN_ATAN2F:
5220 case BUILT_IN_ATAN2L:
5221 case BUILT_IN_FMOD:
5222 case BUILT_IN_FMODF:
5223 case BUILT_IN_FMODL:
5224 case BUILT_IN_DREM:
5225 case BUILT_IN_DREMF:
5226 case BUILT_IN_DREML:
5227 if (! flag_unsafe_math_optimizations)
5228 break;
5229 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5230 if (target)
5231 return target;
5232 break;
5234 case BUILT_IN_SIN:
5235 case BUILT_IN_SINF:
5236 case BUILT_IN_SINL:
5237 case BUILT_IN_COS:
5238 case BUILT_IN_COSF:
5239 case BUILT_IN_COSL:
5240 if (! flag_unsafe_math_optimizations)
5241 break;
5242 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5243 if (target)
5244 return target;
5245 break;
5247 case BUILT_IN_APPLY_ARGS:
5248 return expand_builtin_apply_args ();
5250 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5251 FUNCTION with a copy of the parameters described by
5252 ARGUMENTS, and ARGSIZE. It returns a block of memory
5253 allocated on the stack into which is stored all the registers
5254 that might possibly be used for returning the result of a
5255 function. ARGUMENTS is the value returned by
5256 __builtin_apply_args. ARGSIZE is the number of bytes of
5257 arguments that must be copied. ??? How should this value be
5258 computed? We'll also need a safe worst case value for varargs
5259 functions. */
5260 case BUILT_IN_APPLY:
5261 if (!validate_arglist (arglist, POINTER_TYPE,
5262 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5263 && !validate_arglist (arglist, REFERENCE_TYPE,
5264 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5265 return const0_rtx;
5266 else
5268 int i;
5269 tree t;
5270 rtx ops[3];
5272 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5273 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5275 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5278 /* __builtin_return (RESULT) causes the function to return the
5279 value described by RESULT. RESULT is address of the block of
5280 memory returned by __builtin_apply. */
5281 case BUILT_IN_RETURN:
5282 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5283 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5284 NULL_RTX, VOIDmode, 0));
5285 return const0_rtx;
5287 case BUILT_IN_SAVEREGS:
5288 return expand_builtin_saveregs ();
5290 case BUILT_IN_ARGS_INFO:
5291 return expand_builtin_args_info (arglist);
5293 /* Return the address of the first anonymous stack arg. */
5294 case BUILT_IN_NEXT_ARG:
5295 fold_builtin_next_arg (arglist);
5296 return expand_builtin_next_arg (arglist);
5298 case BUILT_IN_CLASSIFY_TYPE:
5299 return expand_builtin_classify_type (arglist);
5301 case BUILT_IN_CONSTANT_P:
5302 return const0_rtx;
5304 case BUILT_IN_FRAME_ADDRESS:
5305 case BUILT_IN_RETURN_ADDRESS:
5306 return expand_builtin_frame_address (fndecl, arglist);
5308 /* Returns the address of the area where the structure is returned.
5309 0 otherwise. */
5310 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5311 if (arglist != 0
5312 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5313 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5314 return const0_rtx;
5315 else
5316 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5318 case BUILT_IN_ALLOCA:
5319 target = expand_builtin_alloca (arglist, target);
5320 if (target)
5321 return target;
5322 break;
5324 case BUILT_IN_STACK_SAVE:
5325 return expand_stack_save ();
5327 case BUILT_IN_STACK_RESTORE:
5328 expand_stack_restore (TREE_VALUE (arglist));
5329 return const0_rtx;
5331 case BUILT_IN_FFS:
5332 case BUILT_IN_FFSL:
5333 case BUILT_IN_FFSLL:
5334 case BUILT_IN_FFSIMAX:
5335 target = expand_builtin_unop (target_mode, arglist, target,
5336 subtarget, ffs_optab);
5337 if (target)
5338 return target;
5339 break;
5341 case BUILT_IN_CLZ:
5342 case BUILT_IN_CLZL:
5343 case BUILT_IN_CLZLL:
5344 case BUILT_IN_CLZIMAX:
5345 target = expand_builtin_unop (target_mode, arglist, target,
5346 subtarget, clz_optab);
5347 if (target)
5348 return target;
5349 break;
5351 case BUILT_IN_CTZ:
5352 case BUILT_IN_CTZL:
5353 case BUILT_IN_CTZLL:
5354 case BUILT_IN_CTZIMAX:
5355 target = expand_builtin_unop (target_mode, arglist, target,
5356 subtarget, ctz_optab);
5357 if (target)
5358 return target;
5359 break;
5361 case BUILT_IN_POPCOUNT:
5362 case BUILT_IN_POPCOUNTL:
5363 case BUILT_IN_POPCOUNTLL:
5364 case BUILT_IN_POPCOUNTIMAX:
5365 target = expand_builtin_unop (target_mode, arglist, target,
5366 subtarget, popcount_optab);
5367 if (target)
5368 return target;
5369 break;
5371 case BUILT_IN_PARITY:
5372 case BUILT_IN_PARITYL:
5373 case BUILT_IN_PARITYLL:
5374 case BUILT_IN_PARITYIMAX:
5375 target = expand_builtin_unop (target_mode, arglist, target,
5376 subtarget, parity_optab);
5377 if (target)
5378 return target;
5379 break;
5381 case BUILT_IN_STRLEN:
5382 target = expand_builtin_strlen (arglist, target, target_mode);
5383 if (target)
5384 return target;
5385 break;
5387 case BUILT_IN_STRCPY:
5388 target = expand_builtin_strcpy (exp, target, mode);
5389 if (target)
5390 return target;
5391 break;
5393 case BUILT_IN_STRNCPY:
5394 target = expand_builtin_strncpy (arglist, target, mode);
5395 if (target)
5396 return target;
5397 break;
5399 case BUILT_IN_STPCPY:
5400 target = expand_builtin_stpcpy (exp, target, mode);
5401 if (target)
5402 return target;
5403 break;
5405 case BUILT_IN_STRCAT:
5406 target = expand_builtin_strcat (arglist, target, mode);
5407 if (target)
5408 return target;
5409 break;
5411 case BUILT_IN_STRNCAT:
5412 target = expand_builtin_strncat (arglist, target, mode);
5413 if (target)
5414 return target;
5415 break;
5417 case BUILT_IN_STRSPN:
5418 target = expand_builtin_strspn (arglist, target, mode);
5419 if (target)
5420 return target;
5421 break;
5423 case BUILT_IN_STRCSPN:
5424 target = expand_builtin_strcspn (arglist, target, mode);
5425 if (target)
5426 return target;
5427 break;
5429 case BUILT_IN_STRSTR:
5430 target = expand_builtin_strstr (arglist, target, mode);
5431 if (target)
5432 return target;
5433 break;
5435 case BUILT_IN_STRPBRK:
5436 target = expand_builtin_strpbrk (arglist, target, mode);
5437 if (target)
5438 return target;
5439 break;
5441 case BUILT_IN_INDEX:
5442 case BUILT_IN_STRCHR:
5443 target = expand_builtin_strchr (arglist, target, mode);
5444 if (target)
5445 return target;
5446 break;
5448 case BUILT_IN_RINDEX:
5449 case BUILT_IN_STRRCHR:
5450 target = expand_builtin_strrchr (arglist, target, mode);
5451 if (target)
5452 return target;
5453 break;
5455 case BUILT_IN_MEMCPY:
5456 target = expand_builtin_memcpy (exp, target, mode);
5457 if (target)
5458 return target;
5459 break;
5461 case BUILT_IN_MEMPCPY:
5462 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5463 if (target)
5464 return target;
5465 break;
5467 case BUILT_IN_MEMMOVE:
5468 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5469 if (target)
5470 return target;
5471 break;
5473 case BUILT_IN_BCOPY:
5474 target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5475 if (target)
5476 return target;
5477 break;
5479 case BUILT_IN_MEMSET:
5480 target = expand_builtin_memset (arglist, target, mode);
5481 if (target)
5482 return target;
5483 break;
5485 case BUILT_IN_BZERO:
5486 target = expand_builtin_bzero (arglist);
5487 if (target)
5488 return target;
5489 break;
5491 case BUILT_IN_STRCMP:
5492 target = expand_builtin_strcmp (exp, target, mode);
5493 if (target)
5494 return target;
5495 break;
5497 case BUILT_IN_STRNCMP:
5498 target = expand_builtin_strncmp (exp, target, mode);
5499 if (target)
5500 return target;
5501 break;
5503 case BUILT_IN_BCMP:
5504 case BUILT_IN_MEMCMP:
5505 target = expand_builtin_memcmp (exp, arglist, target, mode);
5506 if (target)
5507 return target;
5508 break;
5510 case BUILT_IN_SETJMP:
5511 target = expand_builtin_setjmp (arglist, target);
5512 if (target)
5513 return target;
5514 break;
5516 /* __builtin_longjmp is passed a pointer to an array of five words.
5517 It's similar to the C library longjmp function but works with
5518 __builtin_setjmp above. */
5519 case BUILT_IN_LONGJMP:
5520 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5521 break;
5522 else
5524 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5525 VOIDmode, 0);
5526 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5527 NULL_RTX, VOIDmode, 0);
5529 if (value != const1_rtx)
5531 error ("__builtin_longjmp second argument must be 1");
5532 return const0_rtx;
5535 expand_builtin_longjmp (buf_addr, value);
5536 return const0_rtx;
5539 case BUILT_IN_NONLOCAL_GOTO:
5540 target = expand_builtin_nonlocal_goto (arglist);
5541 if (target)
5542 return target;
5543 break;
5545 /* This updates the setjmp buffer that is its argument with the value
5546 of the current stack pointer. */
5547 case BUILT_IN_UPDATE_SETJMP_BUF:
5548 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5550 rtx buf_addr
5551 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5553 expand_builtin_update_setjmp_buf (buf_addr);
5554 return const0_rtx;
5556 break;
5558 case BUILT_IN_TRAP:
5559 expand_builtin_trap ();
5560 return const0_rtx;
5562 case BUILT_IN_PRINTF:
5563 target = expand_builtin_printf (arglist, target, mode, false);
5564 if (target)
5565 return target;
5566 break;
5568 case BUILT_IN_PRINTF_UNLOCKED:
5569 target = expand_builtin_printf (arglist, target, mode, true);
5570 if (target)
5571 return target;
5572 break;
5574 case BUILT_IN_FPUTS:
5575 target = expand_builtin_fputs (arglist, target, false);
5576 if (target)
5577 return target;
5578 break;
5579 case BUILT_IN_FPUTS_UNLOCKED:
5580 target = expand_builtin_fputs (arglist, target, true);
5581 if (target)
5582 return target;
5583 break;
5585 case BUILT_IN_FPRINTF:
5586 target = expand_builtin_fprintf (arglist, target, mode, false);
5587 if (target)
5588 return target;
5589 break;
5591 case BUILT_IN_FPRINTF_UNLOCKED:
5592 target = expand_builtin_fprintf (arglist, target, mode, true);
5593 if (target)
5594 return target;
5595 break;
5597 case BUILT_IN_SPRINTF:
5598 target = expand_builtin_sprintf (arglist, target, mode);
5599 if (target)
5600 return target;
5601 break;
5603 case BUILT_IN_SIGNBIT:
5604 case BUILT_IN_SIGNBITF:
5605 case BUILT_IN_SIGNBITL:
5606 target = expand_builtin_signbit (exp, target);
5607 if (target)
5608 return target;
5609 break;
5611 /* Various hooks for the DWARF 2 __throw routine. */
5612 case BUILT_IN_UNWIND_INIT:
5613 expand_builtin_unwind_init ();
5614 return const0_rtx;
5615 case BUILT_IN_DWARF_CFA:
5616 return virtual_cfa_rtx;
5617 #ifdef DWARF2_UNWIND_INFO
5618 case BUILT_IN_DWARF_SP_COLUMN:
5619 return expand_builtin_dwarf_sp_column ();
5620 case BUILT_IN_INIT_DWARF_REG_SIZES:
5621 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5622 return const0_rtx;
5623 #endif
5624 case BUILT_IN_FROB_RETURN_ADDR:
5625 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5626 case BUILT_IN_EXTRACT_RETURN_ADDR:
5627 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5628 case BUILT_IN_EH_RETURN:
5629 expand_builtin_eh_return (TREE_VALUE (arglist),
5630 TREE_VALUE (TREE_CHAIN (arglist)));
5631 return const0_rtx;
5632 #ifdef EH_RETURN_DATA_REGNO
5633 case BUILT_IN_EH_RETURN_DATA_REGNO:
5634 return expand_builtin_eh_return_data_regno (arglist);
5635 #endif
5636 case BUILT_IN_EXTEND_POINTER:
5637 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5639 case BUILT_IN_VA_START:
5640 case BUILT_IN_STDARG_START:
5641 return expand_builtin_va_start (arglist);
5642 case BUILT_IN_VA_END:
5643 return expand_builtin_va_end (arglist);
5644 case BUILT_IN_VA_COPY:
5645 return expand_builtin_va_copy (arglist);
5646 case BUILT_IN_EXPECT:
5647 return expand_builtin_expect (arglist, target);
5648 case BUILT_IN_PREFETCH:
5649 expand_builtin_prefetch (arglist);
5650 return const0_rtx;
5652 case BUILT_IN_PROFILE_FUNC_ENTER:
5653 return expand_builtin_profile_func (false);
5654 case BUILT_IN_PROFILE_FUNC_EXIT:
5655 return expand_builtin_profile_func (true);
5657 case BUILT_IN_INIT_TRAMPOLINE:
5658 return expand_builtin_init_trampoline (arglist);
5659 case BUILT_IN_ADJUST_TRAMPOLINE:
5660 return expand_builtin_adjust_trampoline (arglist);
5662 case BUILT_IN_FORK:
5663 case BUILT_IN_EXECL:
5664 case BUILT_IN_EXECV:
5665 case BUILT_IN_EXECLP:
5666 case BUILT_IN_EXECLE:
5667 case BUILT_IN_EXECVP:
5668 case BUILT_IN_EXECVE:
5669 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5670 if (target)
5671 return target;
5672 break;
5674 default: /* just do library call, if unknown builtin */
5675 break;
5678 /* The switch statement above can drop through to cause the function
5679 to be called normally. */
5680 return expand_call (exp, target, ignore);
5683 /* Determine whether a tree node represents a call to a built-in
5684 function. If the tree T is a call to a built-in function with
5685 the right number of arguments of the appropriate types, return
5686 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5687 Otherwise the return value is END_BUILTINS. */
5689 enum built_in_function
5690 builtin_mathfn_code (tree t)
5692 tree fndecl, arglist, parmlist;
5693 tree argtype, parmtype;
5695 if (TREE_CODE (t) != CALL_EXPR
5696 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5697 return END_BUILTINS;
5699 fndecl = get_callee_fndecl (t);
5700 if (fndecl == NULL_TREE
5701 || TREE_CODE (fndecl) != FUNCTION_DECL
5702 || ! DECL_BUILT_IN (fndecl)
5703 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5704 return END_BUILTINS;
5706 arglist = TREE_OPERAND (t, 1);
5707 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5708 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5710 /* If a function doesn't take a variable number of arguments,
5711 the last element in the list will have type `void'. */
5712 parmtype = TREE_VALUE (parmlist);
5713 if (VOID_TYPE_P (parmtype))
5715 if (arglist)
5716 return END_BUILTINS;
5717 return DECL_FUNCTION_CODE (fndecl);
5720 if (! arglist)
5721 return END_BUILTINS;
5723 argtype = TREE_TYPE (TREE_VALUE (arglist));
5725 if (SCALAR_FLOAT_TYPE_P (parmtype))
5727 if (! SCALAR_FLOAT_TYPE_P (argtype))
5728 return END_BUILTINS;
5730 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5732 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5733 return END_BUILTINS;
5735 else if (POINTER_TYPE_P (parmtype))
5737 if (! POINTER_TYPE_P (argtype))
5738 return END_BUILTINS;
5740 else if (INTEGRAL_TYPE_P (parmtype))
5742 if (! INTEGRAL_TYPE_P (argtype))
5743 return END_BUILTINS;
5745 else
5746 return END_BUILTINS;
5748 arglist = TREE_CHAIN (arglist);
5751 /* Variable-length argument list. */
5752 return DECL_FUNCTION_CODE (fndecl);
5755 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5756 constant. ARGLIST is the argument list of the call. */
5758 static tree
5759 fold_builtin_constant_p (tree arglist)
5761 if (arglist == 0)
5762 return 0;
5764 arglist = TREE_VALUE (arglist);
5766 /* We return 1 for a numeric type that's known to be a constant
5767 value at compile-time or for an aggregate type that's a
5768 literal constant. */
5769 STRIP_NOPS (arglist);
5771 /* If we know this is a constant, emit the constant of one. */
5772 if (CONSTANT_CLASS_P (arglist)
5773 || (TREE_CODE (arglist) == CONSTRUCTOR
5774 && TREE_CONSTANT (arglist))
5775 || (TREE_CODE (arglist) == ADDR_EXPR
5776 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5777 return integer_one_node;
5779 /* If this expression has side effects, show we don't know it to be a
5780 constant. Likewise if it's a pointer or aggregate type since in
5781 those case we only want literals, since those are only optimized
5782 when generating RTL, not later.
5783 And finally, if we are compiling an initializer, not code, we
5784 need to return a definite result now; there's not going to be any
5785 more optimization done. */
5786 if (TREE_SIDE_EFFECTS (arglist)
5787 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5788 || POINTER_TYPE_P (TREE_TYPE (arglist))
5789 || cfun == 0)
5790 return integer_zero_node;
5792 return 0;
5795 /* Fold a call to __builtin_expect, if we expect that a comparison against
5796 the argument will fold to a constant. In practice, this means a true
5797 constant or the address of a non-weak symbol. ARGLIST is the argument
5798 list of the call. */
5800 static tree
5801 fold_builtin_expect (tree arglist)
5803 tree arg, inner;
5805 if (arglist == 0)
5806 return 0;
5808 arg = TREE_VALUE (arglist);
5810 /* If the argument isn't invariant, then there's nothing we can do. */
5811 if (!TREE_INVARIANT (arg))
5812 return 0;
5814 /* If we're looking at an address of a weak decl, then do not fold. */
5815 inner = arg;
5816 STRIP_NOPS (inner);
5817 if (TREE_CODE (inner) == ADDR_EXPR)
5821 inner = TREE_OPERAND (inner, 0);
5823 while (TREE_CODE (inner) == COMPONENT_REF
5824 || TREE_CODE (inner) == ARRAY_REF);
5825 if (DECL_P (inner) && DECL_WEAK (inner))
5826 return 0;
5829 /* Otherwise, ARG already has the proper type for the return value. */
5830 return arg;
5833 /* Fold a call to __builtin_classify_type. */
5835 static tree
5836 fold_builtin_classify_type (tree arglist)
5838 if (arglist == 0)
5839 return build_int_cst (NULL_TREE, no_type_class);
5841 return build_int_cst (NULL_TREE,
5842 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
5845 /* Fold a call to __builtin_strlen. */
5847 static tree
5848 fold_builtin_strlen (tree arglist)
5850 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5851 return NULL_TREE;
5852 else
5854 tree len = c_strlen (TREE_VALUE (arglist), 0);
5856 if (len)
5858 /* Convert from the internal "sizetype" type to "size_t". */
5859 if (size_type_node)
5860 len = fold_convert (size_type_node, len);
5861 return len;
5864 return NULL_TREE;
5868 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5870 static tree
5871 fold_builtin_inf (tree type, int warn)
5873 REAL_VALUE_TYPE real;
5875 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5876 warning ("target format does not support infinity");
5878 real_inf (&real);
5879 return build_real (type, real);
5882 /* Fold a call to __builtin_nan or __builtin_nans. */
5884 static tree
5885 fold_builtin_nan (tree arglist, tree type, int quiet)
5887 REAL_VALUE_TYPE real;
5888 const char *str;
5890 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5891 return 0;
5892 str = c_getstr (TREE_VALUE (arglist));
5893 if (!str)
5894 return 0;
5896 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5897 return 0;
5899 return build_real (type, real);
5902 /* Return true if the floating point expression T has an integer value.
5903 We also allow +Inf, -Inf and NaN to be considered integer values. */
5905 static bool
5906 integer_valued_real_p (tree t)
5908 switch (TREE_CODE (t))
5910 case FLOAT_EXPR:
5911 return true;
5913 case ABS_EXPR:
5914 case SAVE_EXPR:
5915 case NON_LVALUE_EXPR:
5916 return integer_valued_real_p (TREE_OPERAND (t, 0));
5918 case COMPOUND_EXPR:
5919 case MODIFY_EXPR:
5920 case BIND_EXPR:
5921 return integer_valued_real_p (TREE_OPERAND (t, 1));
5923 case PLUS_EXPR:
5924 case MINUS_EXPR:
5925 case MULT_EXPR:
5926 case MIN_EXPR:
5927 case MAX_EXPR:
5928 return integer_valued_real_p (TREE_OPERAND (t, 0))
5929 && integer_valued_real_p (TREE_OPERAND (t, 1));
5931 case COND_EXPR:
5932 return integer_valued_real_p (TREE_OPERAND (t, 1))
5933 && integer_valued_real_p (TREE_OPERAND (t, 2));
5935 case REAL_CST:
5936 if (! TREE_CONSTANT_OVERFLOW (t))
5938 REAL_VALUE_TYPE c, cint;
5940 c = TREE_REAL_CST (t);
5941 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5942 return real_identical (&c, &cint);
5945 case NOP_EXPR:
5947 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5948 if (TREE_CODE (type) == INTEGER_TYPE)
5949 return true;
5950 if (TREE_CODE (type) == REAL_TYPE)
5951 return integer_valued_real_p (TREE_OPERAND (t, 0));
5952 break;
5955 case CALL_EXPR:
5956 switch (builtin_mathfn_code (t))
5958 case BUILT_IN_CEIL:
5959 case BUILT_IN_CEILF:
5960 case BUILT_IN_CEILL:
5961 case BUILT_IN_FLOOR:
5962 case BUILT_IN_FLOORF:
5963 case BUILT_IN_FLOORL:
5964 case BUILT_IN_NEARBYINT:
5965 case BUILT_IN_NEARBYINTF:
5966 case BUILT_IN_NEARBYINTL:
5967 case BUILT_IN_RINT:
5968 case BUILT_IN_RINTF:
5969 case BUILT_IN_RINTL:
5970 case BUILT_IN_ROUND:
5971 case BUILT_IN_ROUNDF:
5972 case BUILT_IN_ROUNDL:
5973 case BUILT_IN_TRUNC:
5974 case BUILT_IN_TRUNCF:
5975 case BUILT_IN_TRUNCL:
5976 return true;
5978 default:
5979 break;
5981 break;
5983 default:
5984 break;
5986 return false;
5989 /* EXP is assumed to be builtin call where truncation can be propagated
5990 across (for instance floor((double)f) == (double)floorf (f).
5991 Do the transformation. */
5993 static tree
5994 fold_trunc_transparent_mathfn (tree exp)
5996 tree fndecl = get_callee_fndecl (exp);
5997 tree arglist = TREE_OPERAND (exp, 1);
5998 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5999 tree arg;
6001 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6002 return 0;
6004 arg = TREE_VALUE (arglist);
6005 /* Integer rounding functions are idempotent. */
6006 if (fcode == builtin_mathfn_code (arg))
6007 return arg;
6009 /* If argument is already integer valued, and we don't need to worry
6010 about setting errno, there's no need to perform rounding. */
6011 if (! flag_errno_math && integer_valued_real_p (arg))
6012 return arg;
6014 if (optimize)
6016 tree arg0 = strip_float_extensions (arg);
6017 tree ftype = TREE_TYPE (exp);
6018 tree newtype = TREE_TYPE (arg0);
6019 tree decl;
6021 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6022 && (decl = mathfn_built_in (newtype, fcode)))
6024 arglist =
6025 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6026 return fold_convert (ftype,
6027 build_function_call_expr (decl, arglist));
6030 return 0;
6033 /* EXP is assumed to be builtin call which can narrow the FP type of
6034 the argument, for instance lround((double)f) -> lroundf (f). */
6036 static tree
6037 fold_fixed_mathfn (tree exp)
6039 tree fndecl = get_callee_fndecl (exp);
6040 tree arglist = TREE_OPERAND (exp, 1);
6041 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6042 tree arg;
6044 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6045 return 0;
6047 arg = TREE_VALUE (arglist);
6049 /* If argument is already integer valued, and we don't need to worry
6050 about setting errno, there's no need to perform rounding. */
6051 if (! flag_errno_math && integer_valued_real_p (arg))
6052 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6054 if (optimize)
6056 tree ftype = TREE_TYPE (arg);
6057 tree arg0 = strip_float_extensions (arg);
6058 tree newtype = TREE_TYPE (arg0);
6059 tree decl;
6061 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6062 && (decl = mathfn_built_in (newtype, fcode)))
6064 arglist =
6065 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6066 return build_function_call_expr (decl, arglist);
6069 return 0;
6072 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6073 is the argument list and TYPE is the return type. Return
6074 NULL_TREE if no if no simplification can be made. */
6076 static tree
6077 fold_builtin_cabs (tree arglist, tree type)
6079 tree arg;
6081 if (!arglist || TREE_CHAIN (arglist))
6082 return NULL_TREE;
6084 arg = TREE_VALUE (arglist);
6085 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6086 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6087 return NULL_TREE;
6089 /* Evaluate cabs of a constant at compile-time. */
6090 if (flag_unsafe_math_optimizations
6091 && TREE_CODE (arg) == COMPLEX_CST
6092 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6093 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6094 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6095 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6097 REAL_VALUE_TYPE r, i;
6099 r = TREE_REAL_CST (TREE_REALPART (arg));
6100 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6102 real_arithmetic (&r, MULT_EXPR, &r, &r);
6103 real_arithmetic (&i, MULT_EXPR, &i, &i);
6104 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6105 if (real_sqrt (&r, TYPE_MODE (type), &r)
6106 || ! flag_trapping_math)
6107 return build_real (type, r);
6110 /* If either part is zero, cabs is fabs of the other. */
6111 if (TREE_CODE (arg) == COMPLEX_EXPR
6112 && real_zerop (TREE_OPERAND (arg, 0)))
6113 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6114 if (TREE_CODE (arg) == COMPLEX_EXPR
6115 && real_zerop (TREE_OPERAND (arg, 1)))
6116 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6118 /* Don't do this when optimizing for size. */
6119 if (flag_unsafe_math_optimizations
6120 && optimize && !optimize_size)
6122 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6124 if (sqrtfn != NULL_TREE)
6126 tree rpart, ipart, result, arglist;
6128 arg = builtin_save_expr (arg);
6130 rpart = fold (build1 (REALPART_EXPR, type, arg));
6131 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6133 rpart = builtin_save_expr (rpart);
6134 ipart = builtin_save_expr (ipart);
6136 result = fold (build2 (PLUS_EXPR, type,
6137 fold (build2 (MULT_EXPR, type,
6138 rpart, rpart)),
6139 fold (build2 (MULT_EXPR, type,
6140 ipart, ipart))));
6142 arglist = build_tree_list (NULL_TREE, result);
6143 return build_function_call_expr (sqrtfn, arglist);
6147 return NULL_TREE;
6150 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6151 NULL_TREE if no simplification can be made. */
6153 static tree
6154 fold_builtin_sqrt (tree arglist, tree type)
6157 enum built_in_function fcode;
6158 tree arg = TREE_VALUE (arglist);
6160 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6161 return NULL_TREE;
6163 /* Optimize sqrt of constant value. */
6164 if (TREE_CODE (arg) == REAL_CST
6165 && ! TREE_CONSTANT_OVERFLOW (arg))
6167 REAL_VALUE_TYPE r, x;
6169 x = TREE_REAL_CST (arg);
6170 if (real_sqrt (&r, TYPE_MODE (type), &x)
6171 || (!flag_trapping_math && !flag_errno_math))
6172 return build_real (type, r);
6175 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6176 fcode = builtin_mathfn_code (arg);
6177 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6179 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6180 arg = fold (build2 (MULT_EXPR, type,
6181 TREE_VALUE (TREE_OPERAND (arg, 1)),
6182 build_real (type, dconsthalf)));
6183 arglist = build_tree_list (NULL_TREE, arg);
6184 return build_function_call_expr (expfn, arglist);
6187 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6188 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6190 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6192 if (powfn)
6194 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6195 tree tree_root;
6196 /* The inner root was either sqrt or cbrt. */
6197 REAL_VALUE_TYPE dconstroot =
6198 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6200 /* Adjust for the outer root. */
6201 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6202 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6203 tree_root = build_real (type, dconstroot);
6204 arglist = tree_cons (NULL_TREE, arg0,
6205 build_tree_list (NULL_TREE, tree_root));
6206 return build_function_call_expr (powfn, arglist);
6210 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6211 if (flag_unsafe_math_optimizations
6212 && (fcode == BUILT_IN_POW
6213 || fcode == BUILT_IN_POWF
6214 || fcode == BUILT_IN_POWL))
6216 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6217 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6218 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6219 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6220 build_real (type, dconsthalf)));
6221 arglist = tree_cons (NULL_TREE, arg0,
6222 build_tree_list (NULL_TREE, narg1));
6223 return build_function_call_expr (powfn, arglist);
6226 return NULL_TREE;
6229 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6230 NULL_TREE if no simplification can be made. */
6231 static tree
6232 fold_builtin_cbrt (tree arglist, tree type)
6234 tree arg = TREE_VALUE (arglist);
6235 const enum built_in_function fcode = builtin_mathfn_code (arg);
6237 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6238 return NULL_TREE;
6240 /* Optimize cbrt of constant value. */
6241 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6242 return arg;
6244 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6245 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6247 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6248 const REAL_VALUE_TYPE third_trunc =
6249 real_value_truncate (TYPE_MODE (type), dconstthird);
6250 arg = fold (build2 (MULT_EXPR, type,
6251 TREE_VALUE (TREE_OPERAND (arg, 1)),
6252 build_real (type, third_trunc)));
6253 arglist = build_tree_list (NULL_TREE, arg);
6254 return build_function_call_expr (expfn, arglist);
6257 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6258 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6259 x is negative pow will error but cbrt won't. */
6260 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6262 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6264 if (powfn)
6266 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6267 tree tree_root;
6268 REAL_VALUE_TYPE dconstroot = dconstthird;
6270 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6271 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6272 tree_root = build_real (type, dconstroot);
6273 arglist = tree_cons (NULL_TREE, arg0,
6274 build_tree_list (NULL_TREE, tree_root));
6275 return build_function_call_expr (powfn, arglist);
6279 return NULL_TREE;
6282 /* Fold function call to builtin sin, sinf, or sinl. Return
6283 NULL_TREE if no simplification can be made. */
6284 static tree
6285 fold_builtin_sin (tree arglist)
6287 tree arg = TREE_VALUE (arglist);
6289 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6290 return NULL_TREE;
6292 /* Optimize sin (0.0) = 0.0. */
6293 if (real_zerop (arg))
6294 return arg;
6296 return NULL_TREE;
6299 /* Fold function call to builtin cos, cosf, or cosl. Return
6300 NULL_TREE if no simplification can be made. */
6301 static tree
6302 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6304 tree arg = TREE_VALUE (arglist);
6306 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6307 return NULL_TREE;
6309 /* Optimize cos (0.0) = 1.0. */
6310 if (real_zerop (arg))
6311 return build_real (type, dconst1);
6313 /* Optimize cos(-x) into cos (x). */
6314 if (TREE_CODE (arg) == NEGATE_EXPR)
6316 tree args = build_tree_list (NULL_TREE,
6317 TREE_OPERAND (arg, 0));
6318 return build_function_call_expr (fndecl, args);
6321 return NULL_TREE;
6324 /* Fold function call to builtin tan, tanf, or tanl. Return
6325 NULL_TREE if no simplification can be made. */
6326 static tree
6327 fold_builtin_tan (tree arglist)
6329 enum built_in_function fcode;
6330 tree arg = TREE_VALUE (arglist);
6332 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6333 return NULL_TREE;
6335 /* Optimize tan(0.0) = 0.0. */
6336 if (real_zerop (arg))
6337 return arg;
6339 /* Optimize tan(atan(x)) = x. */
6340 fcode = builtin_mathfn_code (arg);
6341 if (flag_unsafe_math_optimizations
6342 && (fcode == BUILT_IN_ATAN
6343 || fcode == BUILT_IN_ATANF
6344 || fcode == BUILT_IN_ATANL))
6345 return TREE_VALUE (TREE_OPERAND (arg, 1));
6347 return NULL_TREE;
6350 /* Fold function call to builtin atan, atanf, or atanl. Return
6351 NULL_TREE if no simplification can be made. */
6353 static tree
6354 fold_builtin_atan (tree arglist, tree type)
6357 tree arg = TREE_VALUE (arglist);
6359 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6360 return NULL_TREE;
6362 /* Optimize atan(0.0) = 0.0. */
6363 if (real_zerop (arg))
6364 return arg;
6366 /* Optimize atan(1.0) = pi/4. */
6367 if (real_onep (arg))
6369 REAL_VALUE_TYPE cst;
6371 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6372 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6373 return build_real (type, cst);
6376 return NULL_TREE;
6379 /* Fold function call to builtin trunc, truncf or truncl. Return
6380 NULL_TREE if no simplification can be made. */
6382 static tree
6383 fold_builtin_trunc (tree exp)
6385 tree arglist = TREE_OPERAND (exp, 1);
6386 tree arg;
6388 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6389 return 0;
6391 /* Optimize trunc of constant value. */
6392 arg = TREE_VALUE (arglist);
6393 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6395 REAL_VALUE_TYPE r, x;
6396 tree type = TREE_TYPE (exp);
6398 x = TREE_REAL_CST (arg);
6399 real_trunc (&r, TYPE_MODE (type), &x);
6400 return build_real (type, r);
6403 return fold_trunc_transparent_mathfn (exp);
6406 /* Fold function call to builtin floor, floorf or floorl. Return
6407 NULL_TREE if no simplification can be made. */
6409 static tree
6410 fold_builtin_floor (tree exp)
6412 tree arglist = TREE_OPERAND (exp, 1);
6413 tree arg;
6415 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6416 return 0;
6418 /* Optimize floor of constant value. */
6419 arg = TREE_VALUE (arglist);
6420 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6422 REAL_VALUE_TYPE x;
6424 x = TREE_REAL_CST (arg);
6425 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6427 tree type = TREE_TYPE (exp);
6428 REAL_VALUE_TYPE r;
6430 real_floor (&r, TYPE_MODE (type), &x);
6431 return build_real (type, r);
6435 return fold_trunc_transparent_mathfn (exp);
6438 /* Fold function call to builtin ceil, ceilf or ceill. Return
6439 NULL_TREE if no simplification can be made. */
6441 static tree
6442 fold_builtin_ceil (tree exp)
6444 tree arglist = TREE_OPERAND (exp, 1);
6445 tree arg;
6447 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6448 return 0;
6450 /* Optimize ceil of constant value. */
6451 arg = TREE_VALUE (arglist);
6452 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6454 REAL_VALUE_TYPE x;
6456 x = TREE_REAL_CST (arg);
6457 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6459 tree type = TREE_TYPE (exp);
6460 REAL_VALUE_TYPE r;
6462 real_ceil (&r, TYPE_MODE (type), &x);
6463 return build_real (type, r);
6467 return fold_trunc_transparent_mathfn (exp);
6470 /* Fold function call to builtin round, roundf or roundl. Return
6471 NULL_TREE if no simplification can be made. */
6473 static tree
6474 fold_builtin_round (tree exp)
6476 tree arglist = TREE_OPERAND (exp, 1);
6477 tree arg;
6479 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6480 return 0;
6482 /* Optimize round of constant value. */
6483 arg = TREE_VALUE (arglist);
6484 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6486 REAL_VALUE_TYPE x;
6488 x = TREE_REAL_CST (arg);
6489 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6491 tree type = TREE_TYPE (exp);
6492 REAL_VALUE_TYPE r;
6494 real_round (&r, TYPE_MODE (type), &x);
6495 return build_real (type, r);
6499 return fold_trunc_transparent_mathfn (exp);
6502 /* Fold function call to builtin lround, lroundf or lroundl (or the
6503 corresponding long long versions). Return NULL_TREE if no
6504 simplification can be made. */
6506 static tree
6507 fold_builtin_lround (tree exp)
6509 tree arglist = TREE_OPERAND (exp, 1);
6510 tree arg;
6512 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6513 return 0;
6515 /* Optimize lround of constant value. */
6516 arg = TREE_VALUE (arglist);
6517 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6519 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6521 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6523 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6524 HOST_WIDE_INT hi, lo;
6525 REAL_VALUE_TYPE r;
6527 real_round (&r, TYPE_MODE (ftype), &x);
6528 REAL_VALUE_TO_INT (&lo, &hi, r);
6529 result = build_int_cst_wide (NULL_TREE, lo, hi);
6530 if (int_fits_type_p (result, itype))
6531 return fold_convert (itype, result);
6535 return fold_fixed_mathfn (exp);
6538 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6539 and their long and long long variants (i.e. ffsl and ffsll).
6540 Return NULL_TREE if no simplification can be made. */
6542 static tree
6543 fold_builtin_bitop (tree exp)
6545 tree fndecl = get_callee_fndecl (exp);
6546 tree arglist = TREE_OPERAND (exp, 1);
6547 tree arg;
6549 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6550 return NULL_TREE;
6552 /* Optimize for constant argument. */
6553 arg = TREE_VALUE (arglist);
6554 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6556 HOST_WIDE_INT hi, width, result;
6557 unsigned HOST_WIDE_INT lo;
6558 tree type;
6560 type = TREE_TYPE (arg);
6561 width = TYPE_PRECISION (type);
6562 lo = TREE_INT_CST_LOW (arg);
6564 /* Clear all the bits that are beyond the type's precision. */
6565 if (width > HOST_BITS_PER_WIDE_INT)
6567 hi = TREE_INT_CST_HIGH (arg);
6568 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6569 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6571 else
6573 hi = 0;
6574 if (width < HOST_BITS_PER_WIDE_INT)
6575 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6578 switch (DECL_FUNCTION_CODE (fndecl))
6580 case BUILT_IN_FFS:
6581 case BUILT_IN_FFSL:
6582 case BUILT_IN_FFSLL:
6583 if (lo != 0)
6584 result = exact_log2 (lo & -lo) + 1;
6585 else if (hi != 0)
6586 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6587 else
6588 result = 0;
6589 break;
6591 case BUILT_IN_CLZ:
6592 case BUILT_IN_CLZL:
6593 case BUILT_IN_CLZLL:
6594 if (hi != 0)
6595 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6596 else if (lo != 0)
6597 result = width - floor_log2 (lo) - 1;
6598 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6599 result = width;
6600 break;
6602 case BUILT_IN_CTZ:
6603 case BUILT_IN_CTZL:
6604 case BUILT_IN_CTZLL:
6605 if (lo != 0)
6606 result = exact_log2 (lo & -lo);
6607 else if (hi != 0)
6608 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6609 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6610 result = width;
6611 break;
6613 case BUILT_IN_POPCOUNT:
6614 case BUILT_IN_POPCOUNTL:
6615 case BUILT_IN_POPCOUNTLL:
6616 result = 0;
6617 while (lo)
6618 result++, lo &= lo - 1;
6619 while (hi)
6620 result++, hi &= hi - 1;
6621 break;
6623 case BUILT_IN_PARITY:
6624 case BUILT_IN_PARITYL:
6625 case BUILT_IN_PARITYLL:
6626 result = 0;
6627 while (lo)
6628 result++, lo &= lo - 1;
6629 while (hi)
6630 result++, hi &= hi - 1;
6631 result &= 1;
6632 break;
6634 default:
6635 gcc_unreachable ();
6638 return build_int_cst (TREE_TYPE (exp), result);
6641 return NULL_TREE;
6644 /* Return true if EXPR is the real constant contained in VALUE. */
6646 static bool
6647 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6649 STRIP_NOPS (expr);
6651 return ((TREE_CODE (expr) == REAL_CST
6652 && ! TREE_CONSTANT_OVERFLOW (expr)
6653 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6654 || (TREE_CODE (expr) == COMPLEX_CST
6655 && real_dconstp (TREE_REALPART (expr), value)
6656 && real_zerop (TREE_IMAGPART (expr))));
6659 /* A subroutine of fold_builtin to fold the various logarithmic
6660 functions. EXP is the CALL_EXPR of a call to a builtin logN
6661 function. VALUE is the base of the logN function. */
6663 static tree
6664 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6666 tree arglist = TREE_OPERAND (exp, 1);
6668 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6670 tree fndecl = get_callee_fndecl (exp);
6671 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6672 tree arg = TREE_VALUE (arglist);
6673 const enum built_in_function fcode = builtin_mathfn_code (arg);
6675 /* Optimize logN(1.0) = 0.0. */
6676 if (real_onep (arg))
6677 return build_real (type, dconst0);
6679 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6680 exactly, then only do this if flag_unsafe_math_optimizations. */
6681 if (exact_real_truncate (TYPE_MODE (type), value)
6682 || flag_unsafe_math_optimizations)
6684 const REAL_VALUE_TYPE value_truncate =
6685 real_value_truncate (TYPE_MODE (type), *value);
6686 if (real_dconstp (arg, &value_truncate))
6687 return build_real (type, dconst1);
6690 /* Special case, optimize logN(expN(x)) = x. */
6691 if (flag_unsafe_math_optimizations
6692 && ((value == &dconste
6693 && (fcode == BUILT_IN_EXP
6694 || fcode == BUILT_IN_EXPF
6695 || fcode == BUILT_IN_EXPL))
6696 || (value == &dconst2
6697 && (fcode == BUILT_IN_EXP2
6698 || fcode == BUILT_IN_EXP2F
6699 || fcode == BUILT_IN_EXP2L))
6700 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6701 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6703 /* Optimize logN(func()) for various exponential functions. We
6704 want to determine the value "x" and the power "exponent" in
6705 order to transform logN(x**exponent) into exponent*logN(x). */
6706 if (flag_unsafe_math_optimizations)
6708 tree exponent = 0, x = 0;
6710 switch (fcode)
6712 case BUILT_IN_EXP:
6713 case BUILT_IN_EXPF:
6714 case BUILT_IN_EXPL:
6715 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6716 x = build_real (type,
6717 real_value_truncate (TYPE_MODE (type), dconste));
6718 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6719 break;
6720 case BUILT_IN_EXP2:
6721 case BUILT_IN_EXP2F:
6722 case BUILT_IN_EXP2L:
6723 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6724 x = build_real (type, dconst2);
6725 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6726 break;
6727 case BUILT_IN_EXP10:
6728 case BUILT_IN_EXP10F:
6729 case BUILT_IN_EXP10L:
6730 case BUILT_IN_POW10:
6731 case BUILT_IN_POW10F:
6732 case BUILT_IN_POW10L:
6733 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6734 x = build_real (type, dconst10);
6735 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6736 break;
6737 case BUILT_IN_SQRT:
6738 case BUILT_IN_SQRTF:
6739 case BUILT_IN_SQRTL:
6740 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6741 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6742 exponent = build_real (type, dconsthalf);
6743 break;
6744 case BUILT_IN_CBRT:
6745 case BUILT_IN_CBRTF:
6746 case BUILT_IN_CBRTL:
6747 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6748 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6749 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6750 dconstthird));
6751 break;
6752 case BUILT_IN_POW:
6753 case BUILT_IN_POWF:
6754 case BUILT_IN_POWL:
6755 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6756 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6757 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6758 break;
6759 default:
6760 break;
6763 /* Now perform the optimization. */
6764 if (x && exponent)
6766 tree logfn;
6767 arglist = build_tree_list (NULL_TREE, x);
6768 logfn = build_function_call_expr (fndecl, arglist);
6769 return fold (build2 (MULT_EXPR, type, exponent, logfn));
6774 return 0;
6777 /* Fold a builtin function call to pow, powf, or powl. Return
6778 NULL_TREE if no simplification can be made. */
6779 static tree
6780 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6782 enum built_in_function fcode;
6783 tree arg0 = TREE_VALUE (arglist);
6784 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6786 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6787 return NULL_TREE;
6789 /* Optimize pow(1.0,y) = 1.0. */
6790 if (real_onep (arg0))
6791 return omit_one_operand (type, build_real (type, dconst1), arg1);
6793 if (TREE_CODE (arg1) == REAL_CST
6794 && ! TREE_CONSTANT_OVERFLOW (arg1))
6796 REAL_VALUE_TYPE c;
6797 c = TREE_REAL_CST (arg1);
6799 /* Optimize pow(x,0.0) = 1.0. */
6800 if (REAL_VALUES_EQUAL (c, dconst0))
6801 return omit_one_operand (type, build_real (type, dconst1),
6802 arg0);
6804 /* Optimize pow(x,1.0) = x. */
6805 if (REAL_VALUES_EQUAL (c, dconst1))
6806 return arg0;
6808 /* Optimize pow(x,-1.0) = 1.0/x. */
6809 if (REAL_VALUES_EQUAL (c, dconstm1))
6810 return fold (build2 (RDIV_EXPR, type,
6811 build_real (type, dconst1), arg0));
6813 /* Optimize pow(x,0.5) = sqrt(x). */
6814 if (flag_unsafe_math_optimizations
6815 && REAL_VALUES_EQUAL (c, dconsthalf))
6817 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6819 if (sqrtfn != NULL_TREE)
6821 tree arglist = build_tree_list (NULL_TREE, arg0);
6822 return build_function_call_expr (sqrtfn, arglist);
6826 /* Attempt to evaluate pow at compile-time. */
6827 if (TREE_CODE (arg0) == REAL_CST
6828 && ! TREE_CONSTANT_OVERFLOW (arg0))
6830 REAL_VALUE_TYPE cint;
6831 HOST_WIDE_INT n;
6833 n = real_to_integer (&c);
6834 real_from_integer (&cint, VOIDmode, n,
6835 n < 0 ? -1 : 0, 0);
6836 if (real_identical (&c, &cint))
6838 REAL_VALUE_TYPE x;
6839 bool inexact;
6841 x = TREE_REAL_CST (arg0);
6842 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6843 if (flag_unsafe_math_optimizations || !inexact)
6844 return build_real (type, x);
6849 /* Optimize pow(expN(x),y) = expN(x*y). */
6850 fcode = builtin_mathfn_code (arg0);
6851 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6853 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6854 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6855 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6856 arglist = build_tree_list (NULL_TREE, arg);
6857 return build_function_call_expr (expfn, arglist);
6860 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6861 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6863 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6864 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6865 build_real (type, dconsthalf)));
6867 arglist = tree_cons (NULL_TREE, narg0,
6868 build_tree_list (NULL_TREE, narg1));
6869 return build_function_call_expr (fndecl, arglist);
6872 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
6873 if (flag_unsafe_math_optimizations
6874 && (fcode == BUILT_IN_POW
6875 || fcode == BUILT_IN_POWF
6876 || fcode == BUILT_IN_POWL))
6878 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6879 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6880 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
6881 arglist = tree_cons (NULL_TREE, arg00,
6882 build_tree_list (NULL_TREE, narg1));
6883 return build_function_call_expr (fndecl, arglist);
6885 return NULL_TREE;
6888 /* A subroutine of fold_builtin to fold the various exponent
6889 functions. EXP is the CALL_EXPR of a call to a builtin function.
6890 VALUE is the value which will be raised to a power. */
6892 static tree
6893 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6895 tree arglist = TREE_OPERAND (exp, 1);
6897 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6899 tree fndecl = get_callee_fndecl (exp);
6900 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6901 tree arg = TREE_VALUE (arglist);
6903 /* Optimize exp*(0.0) = 1.0. */
6904 if (real_zerop (arg))
6905 return build_real (type, dconst1);
6907 /* Optimize expN(1.0) = N. */
6908 if (real_onep (arg))
6910 REAL_VALUE_TYPE cst;
6912 real_convert (&cst, TYPE_MODE (type), value);
6913 return build_real (type, cst);
6916 /* Attempt to evaluate expN(integer) at compile-time. */
6917 if (flag_unsafe_math_optimizations
6918 && TREE_CODE (arg) == REAL_CST
6919 && ! TREE_CONSTANT_OVERFLOW (arg))
6921 REAL_VALUE_TYPE cint;
6922 REAL_VALUE_TYPE c;
6923 HOST_WIDE_INT n;
6925 c = TREE_REAL_CST (arg);
6926 n = real_to_integer (&c);
6927 real_from_integer (&cint, VOIDmode, n,
6928 n < 0 ? -1 : 0, 0);
6929 if (real_identical (&c, &cint))
6931 REAL_VALUE_TYPE x;
6933 real_powi (&x, TYPE_MODE (type), value, n);
6934 return build_real (type, x);
6938 /* Optimize expN(logN(x)) = x. */
6939 if (flag_unsafe_math_optimizations)
6941 const enum built_in_function fcode = builtin_mathfn_code (arg);
6943 if ((value == &dconste
6944 && (fcode == BUILT_IN_LOG
6945 || fcode == BUILT_IN_LOGF
6946 || fcode == BUILT_IN_LOGL))
6947 || (value == &dconst2
6948 && (fcode == BUILT_IN_LOG2
6949 || fcode == BUILT_IN_LOG2F
6950 || fcode == BUILT_IN_LOG2L))
6951 || (value == &dconst10
6952 && (fcode == BUILT_IN_LOG10
6953 || fcode == BUILT_IN_LOG10F
6954 || fcode == BUILT_IN_LOG10L)))
6955 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6959 return 0;
6962 /* Fold function call to builtin memcpy. Return
6963 NULL_TREE if no simplification can be made. */
6965 static tree
6966 fold_builtin_memcpy (tree exp)
6968 tree arglist = TREE_OPERAND (exp, 1);
6969 tree dest, src, len;
6971 if (!validate_arglist (arglist,
6972 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6973 return 0;
6975 dest = TREE_VALUE (arglist);
6976 src = TREE_VALUE (TREE_CHAIN (arglist));
6977 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6979 /* If the LEN parameter is zero, return DEST. */
6980 if (integer_zerop (len))
6981 return omit_one_operand (TREE_TYPE (exp), dest, src);
6983 /* If SRC and DEST are the same (and not volatile), return DEST. */
6984 if (operand_equal_p (src, dest, 0))
6985 return omit_one_operand (TREE_TYPE (exp), dest, len);
6987 return 0;
6990 /* Fold function call to builtin mempcpy. Return
6991 NULL_TREE if no simplification can be made. */
6993 static tree
6994 fold_builtin_mempcpy (tree exp)
6996 tree arglist = TREE_OPERAND (exp, 1);
6997 tree dest, src, len;
6999 if (!validate_arglist (arglist,
7000 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7001 return 0;
7003 dest = TREE_VALUE (arglist);
7004 src = TREE_VALUE (TREE_CHAIN (arglist));
7005 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7007 /* If the LEN parameter is zero, return DEST. */
7008 if (integer_zerop (len))
7009 return omit_one_operand (TREE_TYPE (exp), dest, src);
7011 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7012 if (operand_equal_p (src, dest, 0))
7014 tree temp = fold_convert (TREE_TYPE (dest), len);
7015 temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7016 return fold_convert (TREE_TYPE (exp), temp);
7019 return 0;
7022 /* Fold function call to builtin memmove. Return
7023 NULL_TREE if no simplification can be made. */
7025 static tree
7026 fold_builtin_memmove (tree arglist, tree type)
7028 tree dest, src, len;
7030 if (!validate_arglist (arglist,
7031 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7032 return 0;
7034 dest = TREE_VALUE (arglist);
7035 src = TREE_VALUE (TREE_CHAIN (arglist));
7036 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7038 /* If the LEN parameter is zero, return DEST. */
7039 if (integer_zerop (len))
7040 return omit_one_operand (type, dest, src);
7042 /* If SRC and DEST are the same (and not volatile), return DEST. */
7043 if (operand_equal_p (src, dest, 0))
7044 return omit_one_operand (type, dest, len);
7046 return 0;
7049 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7050 the length of the string to be copied. Return NULL_TREE if no
7051 simplification can be made. */
7053 tree
7054 fold_builtin_strcpy (tree exp, tree len)
7056 tree arglist = TREE_OPERAND (exp, 1);
7057 tree dest, src, fn;
7059 if (!validate_arglist (arglist,
7060 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7061 return 0;
7063 dest = TREE_VALUE (arglist);
7064 src = TREE_VALUE (TREE_CHAIN (arglist));
7066 /* If SRC and DEST are the same (and not volatile), return DEST. */
7067 if (operand_equal_p (src, dest, 0))
7068 return fold_convert (TREE_TYPE (exp), dest);
7070 if (optimize_size)
7071 return 0;
7073 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7074 if (!fn)
7075 return 0;
7077 if (!len)
7079 len = c_strlen (src, 1);
7080 if (! len || TREE_SIDE_EFFECTS (len))
7081 return 0;
7084 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7085 arglist = build_tree_list (NULL_TREE, len);
7086 arglist = tree_cons (NULL_TREE, src, arglist);
7087 arglist = tree_cons (NULL_TREE, dest, arglist);
7088 return fold_convert (TREE_TYPE (exp),
7089 build_function_call_expr (fn, arglist));
7092 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7093 the length of the source string. Return NULL_TREE if no simplification
7094 can be made. */
7096 tree
7097 fold_builtin_strncpy (tree exp, tree slen)
7099 tree arglist = TREE_OPERAND (exp, 1);
7100 tree dest, src, len, fn;
7102 if (!validate_arglist (arglist,
7103 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7104 return 0;
7106 dest = TREE_VALUE (arglist);
7107 src = TREE_VALUE (TREE_CHAIN (arglist));
7108 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7110 /* If the LEN parameter is zero, return DEST. */
7111 if (integer_zerop (len))
7112 return omit_one_operand (TREE_TYPE (exp), dest, src);
7114 /* We can't compare slen with len as constants below if len is not a
7115 constant. */
7116 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7117 return 0;
7119 if (!slen)
7120 slen = c_strlen (src, 1);
7122 /* Now, we must be passed a constant src ptr parameter. */
7123 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7124 return 0;
7126 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7128 /* We do not support simplification of this case, though we do
7129 support it when expanding trees into RTL. */
7130 /* FIXME: generate a call to __builtin_memset. */
7131 if (tree_int_cst_lt (slen, len))
7132 return 0;
7134 /* OK transform into builtin memcpy. */
7135 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7136 if (!fn)
7137 return 0;
7138 return fold_convert (TREE_TYPE (exp),
7139 build_function_call_expr (fn, arglist));
7142 /* Fold function call to builtin memcmp. Return
7143 NULL_TREE if no simplification can be made. */
7145 static tree
7146 fold_builtin_memcmp (tree arglist)
7148 tree arg1, arg2, len;
7149 const char *p1, *p2;
7151 if (!validate_arglist (arglist,
7152 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7153 return 0;
7155 arg1 = TREE_VALUE (arglist);
7156 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7157 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7159 /* If the LEN parameter is zero, return zero. */
7160 if (integer_zerop (len))
7161 return omit_two_operands (integer_type_node, integer_zero_node,
7162 arg1, arg2);
7164 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7165 if (operand_equal_p (arg1, arg2, 0))
7166 return omit_one_operand (integer_type_node, integer_zero_node, len);
7168 p1 = c_getstr (arg1);
7169 p2 = c_getstr (arg2);
7171 /* If all arguments are constant, and the value of len is not greater
7172 than the lengths of arg1 and arg2, evaluate at compile-time. */
7173 if (host_integerp (len, 1) && p1 && p2
7174 && compare_tree_int (len, strlen (p1) + 1) <= 0
7175 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7177 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7179 if (r > 0)
7180 return integer_one_node;
7181 else if (r < 0)
7182 return integer_minus_one_node;
7183 else
7184 return integer_zero_node;
7187 /* If len parameter is one, return an expression corresponding to
7188 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7189 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7191 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7192 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7193 tree ind1 = fold_convert (integer_type_node,
7194 build1 (INDIRECT_REF, cst_uchar_node,
7195 fold_convert (cst_uchar_ptr_node,
7196 arg1)));
7197 tree ind2 = fold_convert (integer_type_node,
7198 build1 (INDIRECT_REF, cst_uchar_node,
7199 fold_convert (cst_uchar_ptr_node,
7200 arg2)));
7201 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7204 return 0;
7207 /* Fold function call to builtin strcmp. Return
7208 NULL_TREE if no simplification can be made. */
7210 static tree
7211 fold_builtin_strcmp (tree arglist)
7213 tree arg1, arg2;
7214 const char *p1, *p2;
7216 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7217 return 0;
7219 arg1 = TREE_VALUE (arglist);
7220 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7222 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7223 if (operand_equal_p (arg1, arg2, 0))
7224 return integer_zero_node;
7226 p1 = c_getstr (arg1);
7227 p2 = c_getstr (arg2);
7229 if (p1 && p2)
7231 const int i = strcmp (p1, p2);
7232 if (i < 0)
7233 return integer_minus_one_node;
7234 else if (i > 0)
7235 return integer_one_node;
7236 else
7237 return integer_zero_node;
7240 /* If the second arg is "", return *(const unsigned char*)arg1. */
7241 if (p2 && *p2 == '\0')
7243 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7244 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7245 return fold_convert (integer_type_node,
7246 build1 (INDIRECT_REF, cst_uchar_node,
7247 fold_convert (cst_uchar_ptr_node,
7248 arg1)));
7251 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7252 if (p1 && *p1 == '\0')
7254 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7255 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7256 tree temp = fold_convert (integer_type_node,
7257 build1 (INDIRECT_REF, cst_uchar_node,
7258 fold_convert (cst_uchar_ptr_node,
7259 arg2)));
7260 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7263 return 0;
7266 /* Fold function call to builtin strncmp. Return
7267 NULL_TREE if no simplification can be made. */
7269 static tree
7270 fold_builtin_strncmp (tree arglist)
7272 tree arg1, arg2, len;
7273 const char *p1, *p2;
7275 if (!validate_arglist (arglist,
7276 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7277 return 0;
7279 arg1 = TREE_VALUE (arglist);
7280 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7281 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7283 /* If the LEN parameter is zero, return zero. */
7284 if (integer_zerop (len))
7285 return omit_two_operands (integer_type_node, integer_zero_node,
7286 arg1, arg2);
7288 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7289 if (operand_equal_p (arg1, arg2, 0))
7290 return omit_one_operand (integer_type_node, integer_zero_node, len);
7292 p1 = c_getstr (arg1);
7293 p2 = c_getstr (arg2);
7295 if (host_integerp (len, 1) && p1 && p2)
7297 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7298 if (i > 0)
7299 return integer_one_node;
7300 else if (i < 0)
7301 return integer_minus_one_node;
7302 else
7303 return integer_zero_node;
7306 /* If the second arg is "", and the length is greater than zero,
7307 return *(const unsigned char*)arg1. */
7308 if (p2 && *p2 == '\0'
7309 && TREE_CODE (len) == INTEGER_CST
7310 && tree_int_cst_sgn (len) == 1)
7312 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7313 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7314 return fold_convert (integer_type_node,
7315 build1 (INDIRECT_REF, cst_uchar_node,
7316 fold_convert (cst_uchar_ptr_node,
7317 arg1)));
7320 /* If the first arg is "", and the length is greater than zero,
7321 return -*(const unsigned char*)arg2. */
7322 if (p1 && *p1 == '\0'
7323 && TREE_CODE (len) == INTEGER_CST
7324 && tree_int_cst_sgn (len) == 1)
7326 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7327 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7328 tree temp = fold_convert (integer_type_node,
7329 build1 (INDIRECT_REF, cst_uchar_node,
7330 fold_convert (cst_uchar_ptr_node,
7331 arg2)));
7332 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7335 /* If len parameter is one, return an expression corresponding to
7336 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7337 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7339 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7340 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7341 tree ind1 = fold_convert (integer_type_node,
7342 build1 (INDIRECT_REF, cst_uchar_node,
7343 fold_convert (cst_uchar_ptr_node,
7344 arg1)));
7345 tree ind2 = fold_convert (integer_type_node,
7346 build1 (INDIRECT_REF, cst_uchar_node,
7347 fold_convert (cst_uchar_ptr_node,
7348 arg2)));
7349 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7352 return 0;
7355 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7356 NULL_TREE if no simplification can be made. */
7358 static tree
7359 fold_builtin_signbit (tree exp)
7361 tree arglist = TREE_OPERAND (exp, 1);
7362 tree arg, temp;
7364 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7365 return NULL_TREE;
7367 arg = TREE_VALUE (arglist);
7369 /* If ARG is a compile-time constant, determine the result. */
7370 if (TREE_CODE (arg) == REAL_CST
7371 && !TREE_CONSTANT_OVERFLOW (arg))
7373 REAL_VALUE_TYPE c;
7375 c = TREE_REAL_CST (arg);
7376 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7377 return fold_convert (TREE_TYPE (exp), temp);
7380 /* If ARG is non-negative, the result is always zero. */
7381 if (tree_expr_nonnegative_p (arg))
7382 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7384 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7385 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7386 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7387 build_real (TREE_TYPE (arg), dconst0)));
7389 return NULL_TREE;
7392 /* Fold function call to builtin copysign, copysignf or copysignl.
7393 Return NULL_TREE if no simplification can be made. */
7395 static tree
7396 fold_builtin_copysign (tree arglist, tree type)
7398 tree arg1, arg2;
7400 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7401 return NULL_TREE;
7403 arg1 = TREE_VALUE (arglist);
7404 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7406 /* copysign(X,X) is X. */
7407 if (operand_equal_p (arg1, arg2, 0))
7408 return fold_convert (type, arg1);
7410 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7411 if (TREE_CODE (arg1) == REAL_CST
7412 && TREE_CODE (arg2) == REAL_CST
7413 && !TREE_CONSTANT_OVERFLOW (arg1)
7414 && !TREE_CONSTANT_OVERFLOW (arg2))
7416 REAL_VALUE_TYPE c1, c2;
7418 c1 = TREE_REAL_CST (arg1);
7419 c2 = TREE_REAL_CST (arg2);
7420 real_copysign (&c1, &c2);
7421 return build_real (type, c1);
7422 c1.sign = c2.sign;
7425 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7426 Remember to evaluate Y for side-effects. */
7427 if (tree_expr_nonnegative_p (arg2))
7428 return omit_one_operand (type,
7429 fold (build1 (ABS_EXPR, type, arg1)),
7430 arg2);
7432 return NULL_TREE;
7435 /* Fold a call to builtin isascii. */
7437 static tree
7438 fold_builtin_isascii (tree arglist)
7440 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7441 return 0;
7442 else
7444 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7445 tree arg = TREE_VALUE (arglist);
7447 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7448 build_int_cst (NULL_TREE,
7449 ~ (unsigned HOST_WIDE_INT) 0x7f));
7450 arg = fold (build2 (EQ_EXPR, integer_type_node,
7451 arg, integer_zero_node));
7453 if (in_gimple_form && !TREE_CONSTANT (arg))
7454 return NULL_TREE;
7455 else
7456 return arg;
7460 /* Fold a call to builtin toascii. */
7462 static tree
7463 fold_builtin_toascii (tree arglist)
7465 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7466 return 0;
7467 else
7469 /* Transform toascii(c) -> (c & 0x7f). */
7470 tree arg = TREE_VALUE (arglist);
7472 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7473 build_int_cst (NULL_TREE, 0x7f)));
7477 /* Fold a call to builtin isdigit. */
7479 static tree
7480 fold_builtin_isdigit (tree arglist)
7482 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7483 return 0;
7484 else
7486 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7487 /* According to the C standard, isdigit is unaffected by locale. */
7488 tree arg = TREE_VALUE (arglist);
7489 arg = fold_convert (unsigned_type_node, arg);
7490 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7491 build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7492 arg = build2 (LE_EXPR, integer_type_node, arg,
7493 build_int_cst (unsigned_type_node, 9));
7494 arg = fold (arg);
7495 if (in_gimple_form && !TREE_CONSTANT (arg))
7496 return NULL_TREE;
7497 else
7498 return arg;
7502 /* Fold a call to fabs, fabsf or fabsl. */
7504 static tree
7505 fold_builtin_fabs (tree arglist, tree type)
7507 tree arg;
7509 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7510 return 0;
7512 arg = TREE_VALUE (arglist);
7513 if (TREE_CODE (arg) == REAL_CST)
7514 return fold_abs_const (arg, type);
7515 return fold (build1 (ABS_EXPR, type, arg));
7518 /* Fold a call to abs, labs, llabs or imaxabs. */
7520 static tree
7521 fold_builtin_abs (tree arglist, tree type)
7523 tree arg;
7525 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7526 return 0;
7528 arg = TREE_VALUE (arglist);
7529 if (TREE_CODE (arg) == INTEGER_CST)
7530 return fold_abs_const (arg, type);
7531 return fold (build1 (ABS_EXPR, type, arg));
7534 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7535 EXP is the CALL_EXPR for the call. */
7537 static tree
7538 fold_builtin_classify (tree exp, int builtin_index)
7540 tree fndecl = get_callee_fndecl (exp);
7541 tree arglist = TREE_OPERAND (exp, 1);
7542 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7543 tree arg;
7544 REAL_VALUE_TYPE r;
7546 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7548 /* Check that we have exactly one argument. */
7549 if (arglist == 0)
7551 error ("too few arguments to function %qs",
7552 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7553 return error_mark_node;
7555 else if (TREE_CHAIN (arglist) != 0)
7557 error ("too many arguments to function %qs",
7558 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7559 return error_mark_node;
7561 else
7563 error ("non-floating-point argument to function %qs",
7564 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7565 return error_mark_node;
7569 arg = TREE_VALUE (arglist);
7570 switch (builtin_index)
7572 case BUILT_IN_ISINF:
7573 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7574 return omit_one_operand (type, integer_zero_node, arg);
7576 if (TREE_CODE (arg) == REAL_CST)
7578 r = TREE_REAL_CST (arg);
7579 if (real_isinf (&r))
7580 return real_compare (GT_EXPR, &r, &dconst0)
7581 ? integer_one_node : integer_minus_one_node;
7582 else
7583 return integer_zero_node;
7586 return NULL_TREE;
7588 case BUILT_IN_FINITE:
7589 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7590 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7591 return omit_one_operand (type, integer_zero_node, arg);
7593 if (TREE_CODE (arg) == REAL_CST)
7595 r = TREE_REAL_CST (arg);
7596 return real_isinf (&r) || real_isnan (&r)
7597 ? integer_zero_node : integer_one_node;
7600 return NULL_TREE;
7602 case BUILT_IN_ISNAN:
7603 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7604 return omit_one_operand (type, integer_zero_node, arg);
7606 if (TREE_CODE (arg) == REAL_CST)
7608 r = TREE_REAL_CST (arg);
7609 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7612 arg = builtin_save_expr (arg);
7613 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7615 default:
7616 gcc_unreachable ();
7620 /* Fold a call to an unordered comparison function such as
7621 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7622 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7623 the opposite of the desired result. UNORDERED_CODE is used
7624 for modes that can hold NaNs and ORDERED_CODE is used for
7625 the rest. */
7627 static tree
7628 fold_builtin_unordered_cmp (tree exp,
7629 enum tree_code unordered_code,
7630 enum tree_code ordered_code)
7632 tree fndecl = get_callee_fndecl (exp);
7633 tree arglist = TREE_OPERAND (exp, 1);
7634 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7635 enum tree_code code;
7636 tree arg0, arg1;
7638 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7640 enum tree_code code0, code1;
7641 tree type0, type1;
7642 tree cmp_type = 0;
7644 /* Check that we have exactly two arguments. */
7645 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7647 error ("too few arguments to function %qs",
7648 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7649 return error_mark_node;
7651 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7653 error ("too many arguments to function %qs",
7654 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7655 return error_mark_node;
7658 arg0 = TREE_VALUE (arglist);
7659 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7661 type0 = TREE_TYPE (arg0);
7662 type1 = TREE_TYPE (arg1);
7664 code0 = TREE_CODE (type0);
7665 code1 = TREE_CODE (type1);
7667 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7668 /* Choose the wider of two real types. */
7669 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7670 ? type0 : type1;
7671 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7672 cmp_type = type0;
7673 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7674 cmp_type = type1;
7675 else
7677 error ("non-floating-point argument to function %qs",
7678 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7679 return error_mark_node;
7682 arg0 = fold_convert (cmp_type, arg0);
7683 arg1 = fold_convert (cmp_type, arg1);
7685 else
7687 arg0 = TREE_VALUE (arglist);
7688 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7691 if (unordered_code == UNORDERED_EXPR)
7693 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7694 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7695 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7698 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7699 : ordered_code;
7700 return fold (build1 (TRUTH_NOT_EXPR, type,
7701 fold (build2 (code, type, arg0, arg1))));
7704 /* Used by constant folding to simplify calls to builtin functions. EXP is
7705 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7706 result of the function call is ignored. This function returns NULL_TREE
7707 if no simplification was possible. */
7709 static tree
7710 fold_builtin_1 (tree exp, bool ignore)
7712 tree fndecl = get_callee_fndecl (exp);
7713 tree arglist = TREE_OPERAND (exp, 1);
7714 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7716 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7717 return targetm.fold_builtin (exp, ignore);
7719 switch (DECL_FUNCTION_CODE (fndecl))
7721 case BUILT_IN_FPUTS:
7722 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7724 case BUILT_IN_FPUTS_UNLOCKED:
7725 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7727 case BUILT_IN_STRSTR:
7728 return fold_builtin_strstr (arglist);
7730 case BUILT_IN_STRCAT:
7731 return fold_builtin_strcat (arglist);
7733 case BUILT_IN_STRNCAT:
7734 return fold_builtin_strncat (arglist);
7736 case BUILT_IN_STRSPN:
7737 return fold_builtin_strspn (arglist);
7739 case BUILT_IN_STRCSPN:
7740 return fold_builtin_strcspn (arglist);
7742 case BUILT_IN_STRCHR:
7743 case BUILT_IN_INDEX:
7744 return fold_builtin_strchr (arglist);
7746 case BUILT_IN_STRRCHR:
7747 case BUILT_IN_RINDEX:
7748 return fold_builtin_strrchr (arglist);
7750 case BUILT_IN_STRCPY:
7751 return fold_builtin_strcpy (exp, NULL_TREE);
7753 case BUILT_IN_STRNCPY:
7754 return fold_builtin_strncpy (exp, NULL_TREE);
7756 case BUILT_IN_STRCMP:
7757 return fold_builtin_strcmp (arglist);
7759 case BUILT_IN_STRNCMP:
7760 return fold_builtin_strncmp (arglist);
7762 case BUILT_IN_STRPBRK:
7763 return fold_builtin_strpbrk (arglist);
7765 case BUILT_IN_BCMP:
7766 case BUILT_IN_MEMCMP:
7767 return fold_builtin_memcmp (arglist);
7769 case BUILT_IN_SPRINTF:
7770 return fold_builtin_sprintf (arglist, ignore);
7772 case BUILT_IN_CONSTANT_P:
7774 tree val;
7776 val = fold_builtin_constant_p (arglist);
7777 /* Gimplification will pull the CALL_EXPR for the builtin out of
7778 an if condition. When not optimizing, we'll not CSE it back.
7779 To avoid link error types of regressions, return false now. */
7780 if (!val && !optimize)
7781 val = integer_zero_node;
7783 return val;
7786 case BUILT_IN_EXPECT:
7787 return fold_builtin_expect (arglist);
7789 case BUILT_IN_CLASSIFY_TYPE:
7790 return fold_builtin_classify_type (arglist);
7792 case BUILT_IN_STRLEN:
7793 return fold_builtin_strlen (arglist);
7795 case BUILT_IN_FABS:
7796 case BUILT_IN_FABSF:
7797 case BUILT_IN_FABSL:
7798 return fold_builtin_fabs (arglist, type);
7800 case BUILT_IN_ABS:
7801 case BUILT_IN_LABS:
7802 case BUILT_IN_LLABS:
7803 case BUILT_IN_IMAXABS:
7804 return fold_builtin_abs (arglist, type);
7806 case BUILT_IN_CONJ:
7807 case BUILT_IN_CONJF:
7808 case BUILT_IN_CONJL:
7809 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7810 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7811 break;
7813 case BUILT_IN_CREAL:
7814 case BUILT_IN_CREALF:
7815 case BUILT_IN_CREALL:
7816 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7817 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7818 TREE_VALUE (arglist))));
7819 break;
7821 case BUILT_IN_CIMAG:
7822 case BUILT_IN_CIMAGF:
7823 case BUILT_IN_CIMAGL:
7824 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7825 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7826 TREE_VALUE (arglist))));
7827 break;
7829 case BUILT_IN_CABS:
7830 case BUILT_IN_CABSF:
7831 case BUILT_IN_CABSL:
7832 return fold_builtin_cabs (arglist, type);
7834 case BUILT_IN_SQRT:
7835 case BUILT_IN_SQRTF:
7836 case BUILT_IN_SQRTL:
7837 return fold_builtin_sqrt (arglist, type);
7839 case BUILT_IN_CBRT:
7840 case BUILT_IN_CBRTF:
7841 case BUILT_IN_CBRTL:
7842 return fold_builtin_cbrt (arglist, type);
7844 case BUILT_IN_SIN:
7845 case BUILT_IN_SINF:
7846 case BUILT_IN_SINL:
7847 return fold_builtin_sin (arglist);
7849 case BUILT_IN_COS:
7850 case BUILT_IN_COSF:
7851 case BUILT_IN_COSL:
7852 return fold_builtin_cos (arglist, type, fndecl);
7854 case BUILT_IN_EXP:
7855 case BUILT_IN_EXPF:
7856 case BUILT_IN_EXPL:
7857 return fold_builtin_exponent (exp, &dconste);
7859 case BUILT_IN_EXP2:
7860 case BUILT_IN_EXP2F:
7861 case BUILT_IN_EXP2L:
7862 return fold_builtin_exponent (exp, &dconst2);
7864 case BUILT_IN_EXP10:
7865 case BUILT_IN_EXP10F:
7866 case BUILT_IN_EXP10L:
7867 case BUILT_IN_POW10:
7868 case BUILT_IN_POW10F:
7869 case BUILT_IN_POW10L:
7870 return fold_builtin_exponent (exp, &dconst10);
7872 case BUILT_IN_LOG:
7873 case BUILT_IN_LOGF:
7874 case BUILT_IN_LOGL:
7875 return fold_builtin_logarithm (exp, &dconste);
7877 case BUILT_IN_LOG2:
7878 case BUILT_IN_LOG2F:
7879 case BUILT_IN_LOG2L:
7880 return fold_builtin_logarithm (exp, &dconst2);
7882 case BUILT_IN_LOG10:
7883 case BUILT_IN_LOG10F:
7884 case BUILT_IN_LOG10L:
7885 return fold_builtin_logarithm (exp, &dconst10);
7887 case BUILT_IN_TAN:
7888 case BUILT_IN_TANF:
7889 case BUILT_IN_TANL:
7890 return fold_builtin_tan (arglist);
7892 case BUILT_IN_ATAN:
7893 case BUILT_IN_ATANF:
7894 case BUILT_IN_ATANL:
7895 return fold_builtin_atan (arglist, type);
7897 case BUILT_IN_POW:
7898 case BUILT_IN_POWF:
7899 case BUILT_IN_POWL:
7900 return fold_builtin_pow (fndecl, arglist, type);
7902 case BUILT_IN_INF:
7903 case BUILT_IN_INFF:
7904 case BUILT_IN_INFL:
7905 return fold_builtin_inf (type, true);
7907 case BUILT_IN_HUGE_VAL:
7908 case BUILT_IN_HUGE_VALF:
7909 case BUILT_IN_HUGE_VALL:
7910 return fold_builtin_inf (type, false);
7912 case BUILT_IN_NAN:
7913 case BUILT_IN_NANF:
7914 case BUILT_IN_NANL:
7915 return fold_builtin_nan (arglist, type, true);
7917 case BUILT_IN_NANS:
7918 case BUILT_IN_NANSF:
7919 case BUILT_IN_NANSL:
7920 return fold_builtin_nan (arglist, type, false);
7922 case BUILT_IN_FLOOR:
7923 case BUILT_IN_FLOORF:
7924 case BUILT_IN_FLOORL:
7925 return fold_builtin_floor (exp);
7927 case BUILT_IN_CEIL:
7928 case BUILT_IN_CEILF:
7929 case BUILT_IN_CEILL:
7930 return fold_builtin_ceil (exp);
7932 case BUILT_IN_TRUNC:
7933 case BUILT_IN_TRUNCF:
7934 case BUILT_IN_TRUNCL:
7935 return fold_builtin_trunc (exp);
7937 case BUILT_IN_ROUND:
7938 case BUILT_IN_ROUNDF:
7939 case BUILT_IN_ROUNDL:
7940 return fold_builtin_round (exp);
7942 case BUILT_IN_NEARBYINT:
7943 case BUILT_IN_NEARBYINTF:
7944 case BUILT_IN_NEARBYINTL:
7945 case BUILT_IN_RINT:
7946 case BUILT_IN_RINTF:
7947 case BUILT_IN_RINTL:
7948 return fold_trunc_transparent_mathfn (exp);
7950 case BUILT_IN_LROUND:
7951 case BUILT_IN_LROUNDF:
7952 case BUILT_IN_LROUNDL:
7953 case BUILT_IN_LLROUND:
7954 case BUILT_IN_LLROUNDF:
7955 case BUILT_IN_LLROUNDL:
7956 return fold_builtin_lround (exp);
7958 case BUILT_IN_LRINT:
7959 case BUILT_IN_LRINTF:
7960 case BUILT_IN_LRINTL:
7961 case BUILT_IN_LLRINT:
7962 case BUILT_IN_LLRINTF:
7963 case BUILT_IN_LLRINTL:
7964 return fold_fixed_mathfn (exp);
7966 case BUILT_IN_FFS:
7967 case BUILT_IN_FFSL:
7968 case BUILT_IN_FFSLL:
7969 case BUILT_IN_CLZ:
7970 case BUILT_IN_CLZL:
7971 case BUILT_IN_CLZLL:
7972 case BUILT_IN_CTZ:
7973 case BUILT_IN_CTZL:
7974 case BUILT_IN_CTZLL:
7975 case BUILT_IN_POPCOUNT:
7976 case BUILT_IN_POPCOUNTL:
7977 case BUILT_IN_POPCOUNTLL:
7978 case BUILT_IN_PARITY:
7979 case BUILT_IN_PARITYL:
7980 case BUILT_IN_PARITYLL:
7981 return fold_builtin_bitop (exp);
7983 case BUILT_IN_MEMCPY:
7984 return fold_builtin_memcpy (exp);
7986 case BUILT_IN_MEMPCPY:
7987 return fold_builtin_mempcpy (exp);
7989 case BUILT_IN_MEMMOVE:
7990 return fold_builtin_memmove (arglist, type);
7992 case BUILT_IN_SIGNBIT:
7993 case BUILT_IN_SIGNBITF:
7994 case BUILT_IN_SIGNBITL:
7995 return fold_builtin_signbit (exp);
7997 case BUILT_IN_ISASCII:
7998 return fold_builtin_isascii (arglist);
8000 case BUILT_IN_TOASCII:
8001 return fold_builtin_toascii (arglist);
8003 case BUILT_IN_ISDIGIT:
8004 return fold_builtin_isdigit (arglist);
8006 case BUILT_IN_COPYSIGN:
8007 case BUILT_IN_COPYSIGNF:
8008 case BUILT_IN_COPYSIGNL:
8009 return fold_builtin_copysign (arglist, type);
8011 case BUILT_IN_FINITE:
8012 case BUILT_IN_FINITEF:
8013 case BUILT_IN_FINITEL:
8014 return fold_builtin_classify (exp, BUILT_IN_FINITE);
8016 case BUILT_IN_ISINF:
8017 case BUILT_IN_ISINFF:
8018 case BUILT_IN_ISINFL:
8019 return fold_builtin_classify (exp, BUILT_IN_ISINF);
8021 case BUILT_IN_ISNAN:
8022 case BUILT_IN_ISNANF:
8023 case BUILT_IN_ISNANL:
8024 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8026 case BUILT_IN_ISGREATER:
8027 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8028 case BUILT_IN_ISGREATEREQUAL:
8029 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8030 case BUILT_IN_ISLESS:
8031 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8032 case BUILT_IN_ISLESSEQUAL:
8033 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8034 case BUILT_IN_ISLESSGREATER:
8035 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8036 case BUILT_IN_ISUNORDERED:
8037 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8039 /* We do the folding for va_start in the expander. */
8040 case BUILT_IN_VA_START:
8041 break;
8043 default:
8044 break;
8047 return 0;
8050 /* A wrapper function for builtin folding that prevents warnings for
8051 "statement without effect" and the like, caused by removing the
8052 call node earlier than the warning is generated. */
8054 tree
8055 fold_builtin (tree exp, bool ignore)
8057 exp = fold_builtin_1 (exp, ignore);
8058 if (exp)
8060 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8061 if (CONSTANT_CLASS_P (exp))
8062 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8063 TREE_NO_WARNING (exp) = 1;
8066 return exp;
8069 /* Conveniently construct a function call expression. */
8071 tree
8072 build_function_call_expr (tree fn, tree arglist)
8074 tree call_expr;
8076 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8077 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8078 call_expr, arglist, NULL_TREE);
8079 return fold (call_expr);
8082 /* This function validates the types of a function call argument list
8083 represented as a tree chain of parameters against a specified list
8084 of tree_codes. If the last specifier is a 0, that represents an
8085 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8087 static int
8088 validate_arglist (tree arglist, ...)
8090 enum tree_code code;
8091 int res = 0;
8092 va_list ap;
8094 va_start (ap, arglist);
8098 code = va_arg (ap, enum tree_code);
8099 switch (code)
8101 case 0:
8102 /* This signifies an ellipses, any further arguments are all ok. */
8103 res = 1;
8104 goto end;
8105 case VOID_TYPE:
8106 /* This signifies an endlink, if no arguments remain, return
8107 true, otherwise return false. */
8108 res = arglist == 0;
8109 goto end;
8110 default:
8111 /* If no parameters remain or the parameter's code does not
8112 match the specified code, return false. Otherwise continue
8113 checking any remaining arguments. */
8114 if (arglist == 0
8115 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8116 goto end;
8117 break;
8119 arglist = TREE_CHAIN (arglist);
8121 while (1);
8123 /* We need gotos here since we can only have one VA_CLOSE in a
8124 function. */
8125 end: ;
8126 va_end (ap);
8128 return res;
8131 /* Default target-specific builtin expander that does nothing. */
8134 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8135 rtx target ATTRIBUTE_UNUSED,
8136 rtx subtarget ATTRIBUTE_UNUSED,
8137 enum machine_mode mode ATTRIBUTE_UNUSED,
8138 int ignore ATTRIBUTE_UNUSED)
8140 return NULL_RTX;
8143 /* Returns true is EXP represents data that would potentially reside
8144 in a readonly section. */
8146 static bool
8147 readonly_data_expr (tree exp)
8149 STRIP_NOPS (exp);
8151 if (TREE_CODE (exp) != ADDR_EXPR)
8152 return false;
8154 exp = get_base_address (TREE_OPERAND (exp, 0));
8155 if (!exp)
8156 return false;
8158 /* Make sure we call decl_readonly_section only for trees it
8159 can handle (since it returns true for everything it doesn't
8160 understand). */
8161 if (TREE_CODE (exp) == STRING_CST
8162 || TREE_CODE (exp) == CONSTRUCTOR
8163 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8164 return decl_readonly_section (exp, 0);
8165 else
8166 return false;
8169 /* Simplify a call to the strstr builtin.
8171 Return 0 if no simplification was possible, otherwise return the
8172 simplified form of the call as a tree.
8174 The simplified form may be a constant or other expression which
8175 computes the same value, but in a more efficient manner (including
8176 calls to other builtin functions).
8178 The call may contain arguments which need to be evaluated, but
8179 which are not useful to determine the result of the call. In
8180 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8181 COMPOUND_EXPR will be an argument which must be evaluated.
8182 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8183 COMPOUND_EXPR in the chain will contain the tree for the simplified
8184 form of the builtin function call. */
8186 static tree
8187 fold_builtin_strstr (tree arglist)
8189 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8190 return 0;
8191 else
8193 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8194 tree fn;
8195 const char *p1, *p2;
8197 p2 = c_getstr (s2);
8198 if (p2 == NULL)
8199 return 0;
8201 p1 = c_getstr (s1);
8202 if (p1 != NULL)
8204 const char *r = strstr (p1, p2);
8206 if (r == NULL)
8207 return build_int_cst (TREE_TYPE (s1), 0);
8209 /* Return an offset into the constant string argument. */
8210 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8211 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8214 if (p2[0] == '\0')
8215 return s1;
8217 if (p2[1] != '\0')
8218 return 0;
8220 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8221 if (!fn)
8222 return 0;
8224 /* New argument list transforming strstr(s1, s2) to
8225 strchr(s1, s2[0]). */
8226 arglist = build_tree_list (NULL_TREE,
8227 build_int_cst (NULL_TREE, p2[0]));
8228 arglist = tree_cons (NULL_TREE, s1, arglist);
8229 return build_function_call_expr (fn, arglist);
8233 /* Simplify a call to the strchr builtin.
8235 Return 0 if no simplification was possible, otherwise return the
8236 simplified form of the call as a tree.
8238 The simplified form may be a constant or other expression which
8239 computes the same value, but in a more efficient manner (including
8240 calls to other builtin functions).
8242 The call may contain arguments which need to be evaluated, but
8243 which are not useful to determine the result of the call. In
8244 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8245 COMPOUND_EXPR will be an argument which must be evaluated.
8246 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8247 COMPOUND_EXPR in the chain will contain the tree for the simplified
8248 form of the builtin function call. */
8250 static tree
8251 fold_builtin_strchr (tree arglist)
8253 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8254 return 0;
8255 else
8257 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8258 const char *p1;
8260 if (TREE_CODE (s2) != INTEGER_CST)
8261 return 0;
8263 p1 = c_getstr (s1);
8264 if (p1 != NULL)
8266 char c;
8267 const char *r;
8269 if (target_char_cast (s2, &c))
8270 return 0;
8272 r = strchr (p1, c);
8274 if (r == NULL)
8275 return build_int_cst (TREE_TYPE (s1), 0);
8277 /* Return an offset into the constant string argument. */
8278 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8279 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8281 return 0;
8285 /* Simplify a call to the strrchr builtin.
8287 Return 0 if no simplification was possible, otherwise return the
8288 simplified form of the call as a tree.
8290 The simplified form may be a constant or other expression which
8291 computes the same value, but in a more efficient manner (including
8292 calls to other builtin functions).
8294 The call may contain arguments which need to be evaluated, but
8295 which are not useful to determine the result of the call. In
8296 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8297 COMPOUND_EXPR will be an argument which must be evaluated.
8298 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8299 COMPOUND_EXPR in the chain will contain the tree for the simplified
8300 form of the builtin function call. */
8302 static tree
8303 fold_builtin_strrchr (tree arglist)
8305 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8306 return 0;
8307 else
8309 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8310 tree fn;
8311 const char *p1;
8313 if (TREE_CODE (s2) != INTEGER_CST)
8314 return 0;
8316 p1 = c_getstr (s1);
8317 if (p1 != NULL)
8319 char c;
8320 const char *r;
8322 if (target_char_cast (s2, &c))
8323 return 0;
8325 r = strrchr (p1, c);
8327 if (r == NULL)
8328 return build_int_cst (TREE_TYPE (s1), 0);
8330 /* Return an offset into the constant string argument. */
8331 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8332 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8335 if (! integer_zerop (s2))
8336 return 0;
8338 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8339 if (!fn)
8340 return 0;
8342 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8343 return build_function_call_expr (fn, arglist);
8347 /* Simplify a call to the strpbrk builtin.
8349 Return 0 if no simplification was possible, otherwise return the
8350 simplified form of the call as a tree.
8352 The simplified form may be a constant or other expression which
8353 computes the same value, but in a more efficient manner (including
8354 calls to other builtin functions).
8356 The call may contain arguments which need to be evaluated, but
8357 which are not useful to determine the result of the call. In
8358 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8359 COMPOUND_EXPR will be an argument which must be evaluated.
8360 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8361 COMPOUND_EXPR in the chain will contain the tree for the simplified
8362 form of the builtin function call. */
8364 static tree
8365 fold_builtin_strpbrk (tree arglist)
8367 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8368 return 0;
8369 else
8371 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8372 tree fn;
8373 const char *p1, *p2;
8375 p2 = c_getstr (s2);
8376 if (p2 == NULL)
8377 return 0;
8379 p1 = c_getstr (s1);
8380 if (p1 != NULL)
8382 const char *r = strpbrk (p1, p2);
8384 if (r == NULL)
8385 return build_int_cst (TREE_TYPE (s1), 0);
8387 /* Return an offset into the constant string argument. */
8388 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8389 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8392 if (p2[0] == '\0')
8393 /* strpbrk(x, "") == NULL.
8394 Evaluate and ignore s1 in case it had side-effects. */
8395 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8397 if (p2[1] != '\0')
8398 return 0; /* Really call strpbrk. */
8400 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8401 if (!fn)
8402 return 0;
8404 /* New argument list transforming strpbrk(s1, s2) to
8405 strchr(s1, s2[0]). */
8406 arglist = build_tree_list (NULL_TREE,
8407 build_int_cst (NULL_TREE, p2[0]));
8408 arglist = tree_cons (NULL_TREE, s1, arglist);
8409 return build_function_call_expr (fn, arglist);
8413 /* Simplify a call to the strcat builtin.
8415 Return 0 if no simplification was possible, otherwise return the
8416 simplified form of the call as a tree.
8418 The simplified form may be a constant or other expression which
8419 computes the same value, but in a more efficient manner (including
8420 calls to other builtin functions).
8422 The call may contain arguments which need to be evaluated, but
8423 which are not useful to determine the result of the call. In
8424 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8425 COMPOUND_EXPR will be an argument which must be evaluated.
8426 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8427 COMPOUND_EXPR in the chain will contain the tree for the simplified
8428 form of the builtin function call. */
8430 static tree
8431 fold_builtin_strcat (tree arglist)
8433 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8434 return 0;
8435 else
8437 tree dst = TREE_VALUE (arglist),
8438 src = TREE_VALUE (TREE_CHAIN (arglist));
8439 const char *p = c_getstr (src);
8441 /* If the string length is zero, return the dst parameter. */
8442 if (p && *p == '\0')
8443 return dst;
8445 return 0;
8449 /* Simplify a call to the strncat builtin.
8451 Return 0 if no simplification was possible, otherwise return the
8452 simplified form of the call as a tree.
8454 The simplified form may be a constant or other expression which
8455 computes the same value, but in a more efficient manner (including
8456 calls to other builtin functions).
8458 The call may contain arguments which need to be evaluated, but
8459 which are not useful to determine the result of the call. In
8460 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8461 COMPOUND_EXPR will be an argument which must be evaluated.
8462 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8463 COMPOUND_EXPR in the chain will contain the tree for the simplified
8464 form of the builtin function call. */
8466 static tree
8467 fold_builtin_strncat (tree arglist)
8469 if (!validate_arglist (arglist,
8470 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8471 return 0;
8472 else
8474 tree dst = TREE_VALUE (arglist);
8475 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8476 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8477 const char *p = c_getstr (src);
8479 /* If the requested length is zero, or the src parameter string
8480 length is zero, return the dst parameter. */
8481 if (integer_zerop (len) || (p && *p == '\0'))
8482 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8484 /* If the requested len is greater than or equal to the string
8485 length, call strcat. */
8486 if (TREE_CODE (len) == INTEGER_CST && p
8487 && compare_tree_int (len, strlen (p)) >= 0)
8489 tree newarglist
8490 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8491 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8493 /* If the replacement _DECL isn't initialized, don't do the
8494 transformation. */
8495 if (!fn)
8496 return 0;
8498 return build_function_call_expr (fn, newarglist);
8500 return 0;
8504 /* Simplify a call to the strspn builtin.
8506 Return 0 if no simplification was possible, otherwise return the
8507 simplified form of the call as a tree.
8509 The simplified form may be a constant or other expression which
8510 computes the same value, but in a more efficient manner (including
8511 calls to other builtin functions).
8513 The call may contain arguments which need to be evaluated, but
8514 which are not useful to determine the result of the call. In
8515 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8516 COMPOUND_EXPR will be an argument which must be evaluated.
8517 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8518 COMPOUND_EXPR in the chain will contain the tree for the simplified
8519 form of the builtin function call. */
8521 static tree
8522 fold_builtin_strspn (tree arglist)
8524 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8525 return 0;
8526 else
8528 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8529 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8531 /* If both arguments are constants, evaluate at compile-time. */
8532 if (p1 && p2)
8534 const size_t r = strspn (p1, p2);
8535 return size_int (r);
8538 /* If either argument is "", return 0. */
8539 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8540 /* Evaluate and ignore both arguments in case either one has
8541 side-effects. */
8542 return omit_two_operands (integer_type_node, integer_zero_node,
8543 s1, s2);
8544 return 0;
8548 /* Simplify a call to the strcspn builtin.
8550 Return 0 if no simplification was possible, otherwise return the
8551 simplified form of the call as a tree.
8553 The simplified form may be a constant or other expression which
8554 computes the same value, but in a more efficient manner (including
8555 calls to other builtin functions).
8557 The call may contain arguments which need to be evaluated, but
8558 which are not useful to determine the result of the call. In
8559 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8560 COMPOUND_EXPR will be an argument which must be evaluated.
8561 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8562 COMPOUND_EXPR in the chain will contain the tree for the simplified
8563 form of the builtin function call. */
8565 static tree
8566 fold_builtin_strcspn (tree arglist)
8568 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8569 return 0;
8570 else
8572 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8573 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8575 /* If both arguments are constants, evaluate at compile-time. */
8576 if (p1 && p2)
8578 const size_t r = strcspn (p1, p2);
8579 return size_int (r);
8582 /* If the first argument is "", return 0. */
8583 if (p1 && *p1 == '\0')
8585 /* Evaluate and ignore argument s2 in case it has
8586 side-effects. */
8587 return omit_one_operand (integer_type_node,
8588 integer_zero_node, s2);
8591 /* If the second argument is "", return __builtin_strlen(s1). */
8592 if (p2 && *p2 == '\0')
8594 tree newarglist = build_tree_list (NULL_TREE, s1),
8595 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8597 /* If the replacement _DECL isn't initialized, don't do the
8598 transformation. */
8599 if (!fn)
8600 return 0;
8602 return build_function_call_expr (fn, newarglist);
8604 return 0;
8608 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
8609 by the builtin will be ignored. UNLOCKED is true is true if this
8610 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
8611 the known length of the string. Return NULL_TREE if no simplification
8612 was possible. */
8614 tree
8615 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8617 tree fn;
8618 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8619 : implicit_built_in_decls[BUILT_IN_FPUTC];
8620 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8621 : implicit_built_in_decls[BUILT_IN_FWRITE];
8623 /* If the return value is used, or the replacement _DECL isn't
8624 initialized, don't do the transformation. */
8625 if (!ignore || !fn_fputc || !fn_fwrite)
8626 return 0;
8628 /* Verify the arguments in the original call. */
8629 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8630 return 0;
8632 if (! len)
8633 len = c_strlen (TREE_VALUE (arglist), 0);
8635 /* Get the length of the string passed to fputs. If the length
8636 can't be determined, punt. */
8637 if (!len
8638 || TREE_CODE (len) != INTEGER_CST)
8639 return 0;
8641 switch (compare_tree_int (len, 1))
8643 case -1: /* length is 0, delete the call entirely . */
8644 return omit_one_operand (integer_type_node, integer_zero_node,
8645 TREE_VALUE (TREE_CHAIN (arglist)));
8647 case 0: /* length is 1, call fputc. */
8649 const char *p = c_getstr (TREE_VALUE (arglist));
8651 if (p != NULL)
8653 /* New argument list transforming fputs(string, stream) to
8654 fputc(string[0], stream). */
8655 arglist = build_tree_list (NULL_TREE,
8656 TREE_VALUE (TREE_CHAIN (arglist)));
8657 arglist = tree_cons (NULL_TREE,
8658 build_int_cst (NULL_TREE, p[0]),
8659 arglist);
8660 fn = fn_fputc;
8661 break;
8664 /* FALLTHROUGH */
8665 case 1: /* length is greater than 1, call fwrite. */
8667 tree string_arg;
8669 /* If optimizing for size keep fputs. */
8670 if (optimize_size)
8671 return 0;
8672 string_arg = TREE_VALUE (arglist);
8673 /* New argument list transforming fputs(string, stream) to
8674 fwrite(string, 1, len, stream). */
8675 arglist = build_tree_list (NULL_TREE,
8676 TREE_VALUE (TREE_CHAIN (arglist)));
8677 arglist = tree_cons (NULL_TREE, len, arglist);
8678 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8679 arglist = tree_cons (NULL_TREE, string_arg, arglist);
8680 fn = fn_fwrite;
8681 break;
8683 default:
8684 gcc_unreachable ();
8687 /* These optimizations are only performed when the result is ignored,
8688 hence there's no need to cast the result to integer_type_node. */
8689 return build_function_call_expr (fn, arglist);
8692 static void
8693 fold_builtin_next_arg (tree arglist)
8695 tree fntype = TREE_TYPE (current_function_decl);
8697 if (TYPE_ARG_TYPES (fntype) == 0
8698 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8699 == void_type_node))
8700 error ("%<va_start%> used in function with fixed args");
8701 else if (arglist)
8703 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8704 tree arg = TREE_VALUE (arglist);
8706 /* Strip off all nops for the sake of the comparison. This
8707 is not quite the same as STRIP_NOPS. It does more.
8708 We must also strip off INDIRECT_EXPR for C++ reference
8709 parameters. */
8710 while (TREE_CODE (arg) == NOP_EXPR
8711 || TREE_CODE (arg) == CONVERT_EXPR
8712 || TREE_CODE (arg) == NON_LVALUE_EXPR
8713 || TREE_CODE (arg) == INDIRECT_REF)
8714 arg = TREE_OPERAND (arg, 0);
8715 if (arg != last_parm)
8716 warning ("second parameter of %<va_start%> not last named argument");
8717 TREE_VALUE (arglist) = arg;
8719 else
8720 /* Evidently an out of date version of <stdarg.h>; can't validate
8721 va_start's second argument, but can still work as intended. */
8722 warning ("%<__builtin_next_arg%> called without an argument");
8726 /* Simplify a call to the sprintf builtin.
8728 Return 0 if no simplification was possible, otherwise return the
8729 simplified form of the call as a tree. If IGNORED is true, it means that
8730 the caller does not use the returned value of the function. */
8732 static tree
8733 fold_builtin_sprintf (tree arglist, int ignored)
8735 tree call, retval, dest, fmt;
8736 const char *fmt_str = NULL;
8738 /* Verify the required arguments in the original call. We deal with two
8739 types of sprintf() calls: 'sprintf (str, fmt)' and
8740 'sprintf (dest, "%s", orig)'. */
8741 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8742 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8743 VOID_TYPE))
8744 return NULL_TREE;
8746 /* Get the destination string and the format specifier. */
8747 dest = TREE_VALUE (arglist);
8748 fmt = TREE_VALUE (TREE_CHAIN (arglist));
8750 /* Check whether the format is a literal string constant. */
8751 fmt_str = c_getstr (fmt);
8752 if (fmt_str == NULL)
8753 return NULL_TREE;
8755 call = NULL_TREE;
8756 retval = NULL_TREE;
8758 /* If the format doesn't contain % args or %%, use strcpy. */
8759 if (strchr (fmt_str, '%') == NULL)
8761 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8763 if (!fn)
8764 return NULL_TREE;
8766 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8767 'format' is known to contain no % formats. */
8768 arglist = build_tree_list (NULL_TREE, fmt);
8769 arglist = tree_cons (NULL_TREE, dest, arglist);
8770 call = build_function_call_expr (fn, arglist);
8771 if (!ignored)
8772 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
8775 /* If the format is "%s", use strcpy if the result isn't used. */
8776 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
8778 tree fn, orig;
8779 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8781 if (!fn)
8782 return NULL_TREE;
8784 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
8785 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8786 arglist = build_tree_list (NULL_TREE, orig);
8787 arglist = tree_cons (NULL_TREE, dest, arglist);
8788 if (!ignored)
8790 retval = c_strlen (orig, 1);
8791 if (!retval || TREE_CODE (retval) != INTEGER_CST)
8792 return NULL_TREE;
8794 call = build_function_call_expr (fn, arglist);
8797 if (call && retval)
8799 retval = convert
8800 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
8801 retval);
8802 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
8804 else
8805 return call;