* tree-ssa-pre.c (grand_bitmap_obstack): New.
[official-gcc.git] / gcc / builtins.c
blob50965228f91c8e7b6e0ec34fd73b629f5ea12123
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"
50 #define CALLED_AS_BUILT_IN(NODE) \
51 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
53 #ifndef PAD_VARARGS_DOWN
54 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 #endif
57 /* Define the names of the builtin function types and codes. */
58 const char *const built_in_class_names[4]
59 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
61 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
62 const char *const built_in_names[(int) END_BUILTINS] =
64 #include "builtins.def"
66 #undef DEF_BUILTIN
68 /* Setup an array of _DECL trees, make sure each element is
69 initialized to NULL_TREE. */
70 tree built_in_decls[(int) END_BUILTINS];
71 /* Declarations used when constructing the builtin implicitly in the compiler.
72 It may be NULL_TREE when this is invalid (for instance runtime is not
73 required to implement the function call in all cases). */
74 tree implicit_built_in_decls[(int) END_BUILTINS];
76 static int get_pointer_alignment (tree, unsigned int);
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree);
81 static tree build_string_literal (int, const char *);
82 static int apply_args_size (void);
83 static int apply_result_size (void);
84 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
85 static rtx result_vector (int, rtx);
86 #endif
87 static rtx expand_builtin_setjmp (tree, rtx);
88 static void expand_builtin_update_setjmp_buf (rtx);
89 static void expand_builtin_prefetch (tree);
90 static rtx expand_builtin_apply_args (void);
91 static rtx expand_builtin_apply_args_1 (void);
92 static rtx expand_builtin_apply (rtx, rtx, rtx);
93 static void expand_builtin_return (rtx);
94 static enum type_class type_to_class (tree);
95 static rtx expand_builtin_classify_type (tree);
96 static void expand_errno_check (tree, rtx);
97 static rtx expand_builtin_mathfn (tree, rtx, rtx);
98 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (tree);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_bzero (tree);
125 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_alloca (tree, rtx);
131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
132 static rtx expand_builtin_frame_address (tree, tree);
133 static rtx expand_builtin_fputs (tree, rtx, bool);
134 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
137 static tree stabilize_va_list (tree, int);
138 static rtx expand_builtin_expect (tree, rtx);
139 static tree fold_builtin_constant_p (tree);
140 static tree fold_builtin_classify_type (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_trunc (tree);
151 static tree fold_builtin_floor (tree);
152 static tree fold_builtin_ceil (tree);
153 static tree fold_builtin_round (tree);
154 static tree fold_builtin_bitop (tree);
155 static tree fold_builtin_memcpy (tree);
156 static tree fold_builtin_mempcpy (tree);
157 static tree fold_builtin_memmove (tree);
158 static tree fold_builtin_strchr (tree, bool);
159 static tree fold_builtin_memcmp (tree);
160 static tree fold_builtin_strcmp (tree);
161 static tree fold_builtin_strncmp (tree);
162 static tree fold_builtin_signbit (tree);
163 static tree fold_builtin_copysign (tree, tree);
164 static tree fold_builtin_isascii (tree);
165 static tree fold_builtin_toascii (tree);
166 static tree fold_builtin_isdigit (tree);
167 static tree fold_builtin_fabs (tree, tree);
168 static tree fold_builtin_abs (tree, tree);
169 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
170 static tree fold_builtin_1 (tree, bool);
172 static tree simplify_builtin_strpbrk (tree);
173 static tree simplify_builtin_strstr (tree);
174 static tree simplify_builtin_strchr (tree);
175 static tree simplify_builtin_strrchr (tree);
176 static tree simplify_builtin_strcat (tree);
177 static tree simplify_builtin_strncat (tree);
178 static tree simplify_builtin_strspn (tree);
179 static tree simplify_builtin_strcspn (tree);
180 static void simplify_builtin_next_arg (tree);
181 static void simplify_builtin_va_start (tree);
182 static tree simplify_builtin_sprintf (tree, int);
185 /* Return the alignment in bits of EXP, a pointer valued expression.
186 But don't return more than MAX_ALIGN no matter what.
187 The alignment returned is, by default, the alignment of the thing that
188 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
190 Otherwise, look at the expression to see if we can do better, i.e., if the
191 expression is actually pointing at an object whose alignment is tighter. */
193 static int
194 get_pointer_alignment (tree exp, unsigned int max_align)
196 unsigned int align, inner;
198 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
199 return 0;
201 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
202 align = MIN (align, max_align);
204 while (1)
206 switch (TREE_CODE (exp))
208 case NOP_EXPR:
209 case CONVERT_EXPR:
210 case NON_LVALUE_EXPR:
211 exp = TREE_OPERAND (exp, 0);
212 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
213 return align;
215 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
216 align = MIN (inner, max_align);
217 break;
219 case PLUS_EXPR:
220 /* If sum of pointer + int, restrict our maximum alignment to that
221 imposed by the integer. If not, we can't do any better than
222 ALIGN. */
223 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
224 return align;
226 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
227 & (max_align / BITS_PER_UNIT - 1))
228 != 0)
229 max_align >>= 1;
231 exp = TREE_OPERAND (exp, 0);
232 break;
234 case ADDR_EXPR:
235 /* See what we are pointing at and look at its alignment. */
236 exp = TREE_OPERAND (exp, 0);
237 if (TREE_CODE (exp) == FUNCTION_DECL)
238 align = FUNCTION_BOUNDARY;
239 else if (DECL_P (exp))
240 align = DECL_ALIGN (exp);
241 #ifdef CONSTANT_ALIGNMENT
242 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
243 align = CONSTANT_ALIGNMENT (exp, align);
244 #endif
245 return MIN (align, max_align);
247 default:
248 return align;
253 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
254 way, because it could contain a zero byte in the middle.
255 TREE_STRING_LENGTH is the size of the character array, not the string.
257 ONLY_VALUE should be nonzero if the result is not going to be emitted
258 into the instruction stream and zero if it is going to be expanded.
259 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
260 is returned, otherwise NULL, since
261 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
262 evaluate the side-effects.
264 The value returned is of type `ssizetype'.
266 Unfortunately, string_constant can't access the values of const char
267 arrays with initializers, so neither can we do so here. */
269 tree
270 c_strlen (tree src, int only_value)
272 tree offset_node;
273 HOST_WIDE_INT offset;
274 int max;
275 const char *ptr;
277 STRIP_NOPS (src);
278 if (TREE_CODE (src) == COND_EXPR
279 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
281 tree len1, len2;
283 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
284 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
285 if (tree_int_cst_equal (len1, len2))
286 return len1;
289 if (TREE_CODE (src) == COMPOUND_EXPR
290 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
291 return c_strlen (TREE_OPERAND (src, 1), only_value);
293 src = string_constant (src, &offset_node);
294 if (src == 0)
295 return 0;
297 max = TREE_STRING_LENGTH (src) - 1;
298 ptr = TREE_STRING_POINTER (src);
300 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
302 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
303 compute the offset to the following null if we don't know where to
304 start searching for it. */
305 int i;
307 for (i = 0; i < max; i++)
308 if (ptr[i] == 0)
309 return 0;
311 /* We don't know the starting offset, but we do know that the string
312 has no internal zero bytes. We can assume that the offset falls
313 within the bounds of the string; otherwise, the programmer deserves
314 what he gets. Subtract the offset from the length of the string,
315 and return that. This would perhaps not be valid if we were dealing
316 with named arrays in addition to literal string constants. */
318 return size_diffop (size_int (max), offset_node);
321 /* We have a known offset into the string. Start searching there for
322 a null character if we can represent it as a single HOST_WIDE_INT. */
323 if (offset_node == 0)
324 offset = 0;
325 else if (! host_integerp (offset_node, 0))
326 offset = -1;
327 else
328 offset = tree_low_cst (offset_node, 0);
330 /* If the offset is known to be out of bounds, warn, and call strlen at
331 runtime. */
332 if (offset < 0 || offset > max)
334 warning ("offset outside bounds of constant string");
335 return 0;
338 /* Use strlen to search for the first zero byte. Since any strings
339 constructed with build_string will have nulls appended, we win even
340 if we get handed something like (char[4])"abcd".
342 Since OFFSET is our starting index into the string, no further
343 calculation is needed. */
344 return ssize_int (strlen (ptr + offset));
347 /* Return a char pointer for a C string if it is a string constant
348 or sum of string constant and integer constant. */
350 static const char *
351 c_getstr (tree src)
353 tree offset_node;
355 src = string_constant (src, &offset_node);
356 if (src == 0)
357 return 0;
359 if (offset_node == 0)
360 return TREE_STRING_POINTER (src);
361 else if (!host_integerp (offset_node, 1)
362 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
363 return 0;
365 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
368 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
369 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
371 static rtx
372 c_readstr (const char *str, enum machine_mode mode)
374 HOST_WIDE_INT c[2];
375 HOST_WIDE_INT ch;
376 unsigned int i, j;
378 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
380 c[0] = 0;
381 c[1] = 0;
382 ch = 1;
383 for (i = 0; i < GET_MODE_SIZE (mode); i++)
385 j = i;
386 if (WORDS_BIG_ENDIAN)
387 j = GET_MODE_SIZE (mode) - i - 1;
388 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
389 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
390 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
391 j *= BITS_PER_UNIT;
392 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
394 if (ch)
395 ch = (unsigned char) str[i];
396 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
398 return immed_double_const (c[0], c[1], mode);
401 /* Cast a target constant CST to target CHAR and if that value fits into
402 host char type, return zero and put that value into variable pointed by
403 P. */
405 static int
406 target_char_cast (tree cst, char *p)
408 unsigned HOST_WIDE_INT val, hostval;
410 if (!host_integerp (cst, 1)
411 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
412 return 1;
414 val = tree_low_cst (cst, 1);
415 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
416 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
418 hostval = val;
419 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
420 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
422 if (val != hostval)
423 return 1;
425 *p = hostval;
426 return 0;
429 /* Similar to save_expr, but assumes that arbitrary code is not executed
430 in between the multiple evaluations. In particular, we assume that a
431 non-addressable local variable will not be modified. */
433 static tree
434 builtin_save_expr (tree exp)
436 if (TREE_ADDRESSABLE (exp) == 0
437 && (TREE_CODE (exp) == PARM_DECL
438 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
439 return exp;
441 return save_expr (exp);
444 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
445 times to get the address of either a higher stack frame, or a return
446 address located within it (depending on FNDECL_CODE). */
449 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
450 rtx tem)
452 int i;
454 /* Some machines need special handling before we can access
455 arbitrary frames. For example, on the sparc, we must first flush
456 all register windows to the stack. */
457 #ifdef SETUP_FRAME_ADDRESSES
458 if (count > 0)
459 SETUP_FRAME_ADDRESSES ();
460 #endif
462 /* On the sparc, the return address is not in the frame, it is in a
463 register. There is no way to access it off of the current frame
464 pointer, but it can be accessed off the previous frame pointer by
465 reading the value from the register window save area. */
466 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
467 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
468 count--;
469 #endif
471 /* Scan back COUNT frames to the specified frame. */
472 for (i = 0; i < count; i++)
474 /* Assume the dynamic chain pointer is in the word that the
475 frame address points to, unless otherwise specified. */
476 #ifdef DYNAMIC_CHAIN_ADDRESS
477 tem = DYNAMIC_CHAIN_ADDRESS (tem);
478 #endif
479 tem = memory_address (Pmode, tem);
480 tem = gen_rtx_MEM (Pmode, tem);
481 set_mem_alias_set (tem, get_frame_alias_set ());
482 tem = copy_to_reg (tem);
485 /* For __builtin_frame_address, return what we've got. */
486 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
487 return tem;
489 /* For __builtin_return_address, Get the return address from that
490 frame. */
491 #ifdef RETURN_ADDR_RTX
492 tem = RETURN_ADDR_RTX (count, tem);
493 #else
494 tem = memory_address (Pmode,
495 plus_constant (tem, GET_MODE_SIZE (Pmode)));
496 tem = gen_rtx_MEM (Pmode, tem);
497 set_mem_alias_set (tem, get_frame_alias_set ());
498 #endif
499 return tem;
502 /* Alias set used for setjmp buffer. */
503 static HOST_WIDE_INT setjmp_alias_set = -1;
505 /* Construct the leading half of a __builtin_setjmp call. Control will
506 return to RECEIVER_LABEL. This is used directly by sjlj exception
507 handling code. */
509 void
510 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
512 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
513 rtx stack_save;
514 rtx mem;
516 if (setjmp_alias_set == -1)
517 setjmp_alias_set = new_alias_set ();
519 buf_addr = convert_memory_address (Pmode, buf_addr);
521 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
523 /* We store the frame pointer and the address of receiver_label in
524 the buffer and use the rest of it for the stack save area, which
525 is machine-dependent. */
527 mem = gen_rtx_MEM (Pmode, buf_addr);
528 set_mem_alias_set (mem, setjmp_alias_set);
529 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
531 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
532 set_mem_alias_set (mem, setjmp_alias_set);
534 emit_move_insn (validize_mem (mem),
535 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
537 stack_save = gen_rtx_MEM (sa_mode,
538 plus_constant (buf_addr,
539 2 * GET_MODE_SIZE (Pmode)));
540 set_mem_alias_set (stack_save, setjmp_alias_set);
541 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
543 /* If there is further processing to do, do it. */
544 #ifdef HAVE_builtin_setjmp_setup
545 if (HAVE_builtin_setjmp_setup)
546 emit_insn (gen_builtin_setjmp_setup (buf_addr));
547 #endif
549 /* Tell optimize_save_area_alloca that extra work is going to
550 need to go on during alloca. */
551 current_function_calls_setjmp = 1;
553 /* Set this so all the registers get saved in our frame; we need to be
554 able to copy the saved values for any registers from frames we unwind. */
555 current_function_has_nonlocal_label = 1;
558 /* Construct the trailing part of a __builtin_setjmp call.
559 This is used directly by sjlj exception handling code. */
561 void
562 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
564 /* Clobber the FP when we get here, so we have to make sure it's
565 marked as used by this function. */
566 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
568 /* Mark the static chain as clobbered here so life information
569 doesn't get messed up for it. */
570 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
572 /* Now put in the code to restore the frame pointer, and argument
573 pointer, if needed. */
574 #ifdef HAVE_nonlocal_goto
575 if (! HAVE_nonlocal_goto)
576 #endif
577 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
579 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
580 if (fixed_regs[ARG_POINTER_REGNUM])
582 #ifdef ELIMINABLE_REGS
583 size_t i;
584 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
586 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
587 if (elim_regs[i].from == ARG_POINTER_REGNUM
588 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
589 break;
591 if (i == ARRAY_SIZE (elim_regs))
592 #endif
594 /* Now restore our arg pointer from the address at which it
595 was saved in our stack frame. */
596 emit_move_insn (virtual_incoming_args_rtx,
597 copy_to_reg (get_arg_pointer_save_area (cfun)));
600 #endif
602 #ifdef HAVE_builtin_setjmp_receiver
603 if (HAVE_builtin_setjmp_receiver)
604 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
605 else
606 #endif
607 #ifdef HAVE_nonlocal_goto_receiver
608 if (HAVE_nonlocal_goto_receiver)
609 emit_insn (gen_nonlocal_goto_receiver ());
610 else
611 #endif
612 { /* Nothing */ }
614 /* @@@ This is a kludge. Not all machine descriptions define a blockage
615 insn, but we must not allow the code we just generated to be reordered
616 by scheduling. Specifically, the update of the frame pointer must
617 happen immediately, not later. So emit an ASM_INPUT to act as blockage
618 insn. */
619 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
622 /* __builtin_setjmp is passed a pointer to an array of five words (not
623 all will be used on all machines). It operates similarly to the C
624 library function of the same name, but is more efficient. Much of
625 the code below (and for longjmp) is copied from the handling of
626 non-local gotos.
628 NOTE: This is intended for use by GNAT and the exception handling
629 scheme in the compiler and will only work in the method used by
630 them. */
632 static rtx
633 expand_builtin_setjmp (tree arglist, rtx target)
635 rtx buf_addr, next_lab, cont_lab;
637 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
638 return NULL_RTX;
640 if (target == 0 || !REG_P (target)
641 || REGNO (target) < FIRST_PSEUDO_REGISTER)
642 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
644 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
646 next_lab = gen_label_rtx ();
647 cont_lab = gen_label_rtx ();
649 expand_builtin_setjmp_setup (buf_addr, next_lab);
651 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
652 ensure that pending stack adjustments are flushed. */
653 emit_move_insn (target, const0_rtx);
654 emit_jump (cont_lab);
656 emit_label (next_lab);
658 expand_builtin_setjmp_receiver (next_lab);
660 /* Set TARGET to one. */
661 emit_move_insn (target, const1_rtx);
662 emit_label (cont_lab);
664 /* Tell flow about the strange goings on. Putting `next_lab' on
665 `nonlocal_goto_handler_labels' to indicates that function
666 calls may traverse the arc back to this label. */
668 current_function_has_nonlocal_label = 1;
669 nonlocal_goto_handler_labels
670 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
672 return target;
675 /* __builtin_longjmp is passed a pointer to an array of five words (not
676 all will be used on all machines). It operates similarly to the C
677 library function of the same name, but is more efficient. Much of
678 the code below is copied from the handling of non-local gotos.
680 NOTE: This is intended for use by GNAT and the exception handling
681 scheme in the compiler and will only work in the method used by
682 them. */
684 void
685 expand_builtin_longjmp (rtx buf_addr, rtx value)
687 rtx fp, lab, stack, insn, last;
688 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
690 if (setjmp_alias_set == -1)
691 setjmp_alias_set = new_alias_set ();
693 buf_addr = convert_memory_address (Pmode, buf_addr);
695 buf_addr = force_reg (Pmode, buf_addr);
697 /* We used to store value in static_chain_rtx, but that fails if pointers
698 are smaller than integers. We instead require that the user must pass
699 a second argument of 1, because that is what builtin_setjmp will
700 return. This also makes EH slightly more efficient, since we are no
701 longer copying around a value that we don't care about. */
702 gcc_assert (value == const1_rtx);
704 current_function_calls_longjmp = 1;
706 last = get_last_insn ();
707 #ifdef HAVE_builtin_longjmp
708 if (HAVE_builtin_longjmp)
709 emit_insn (gen_builtin_longjmp (buf_addr));
710 else
711 #endif
713 fp = gen_rtx_MEM (Pmode, buf_addr);
714 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
715 GET_MODE_SIZE (Pmode)));
717 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
718 2 * GET_MODE_SIZE (Pmode)));
719 set_mem_alias_set (fp, setjmp_alias_set);
720 set_mem_alias_set (lab, setjmp_alias_set);
721 set_mem_alias_set (stack, setjmp_alias_set);
723 /* Pick up FP, label, and SP from the block and jump. This code is
724 from expand_goto in stmt.c; see there for detailed comments. */
725 #if HAVE_nonlocal_goto
726 if (HAVE_nonlocal_goto)
727 /* We have to pass a value to the nonlocal_goto pattern that will
728 get copied into the static_chain pointer, but it does not matter
729 what that value is, because builtin_setjmp does not use it. */
730 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
731 else
732 #endif
734 lab = copy_to_reg (lab);
736 emit_insn (gen_rtx_CLOBBER (VOIDmode,
737 gen_rtx_MEM (BLKmode,
738 gen_rtx_SCRATCH (VOIDmode))));
739 emit_insn (gen_rtx_CLOBBER (VOIDmode,
740 gen_rtx_MEM (BLKmode,
741 hard_frame_pointer_rtx)));
743 emit_move_insn (hard_frame_pointer_rtx, fp);
744 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
746 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
747 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
748 emit_indirect_jump (lab);
752 /* Search backwards and mark the jump insn as a non-local goto.
753 Note that this precludes the use of __builtin_longjmp to a
754 __builtin_setjmp target in the same function. However, we've
755 already cautioned the user that these functions are for
756 internal exception handling use only. */
757 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
759 gcc_assert (insn != last);
761 if (JUMP_P (insn))
763 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
764 REG_NOTES (insn));
765 break;
767 else if (CALL_P (insn))
768 break;
772 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
773 and the address of the save area. */
775 static rtx
776 expand_builtin_nonlocal_goto (tree arglist)
778 tree t_label, t_save_area;
779 rtx r_label, r_save_area, r_fp, r_sp, insn;
781 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
782 return NULL_RTX;
784 t_label = TREE_VALUE (arglist);
785 arglist = TREE_CHAIN (arglist);
786 t_save_area = TREE_VALUE (arglist);
788 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
789 r_label = convert_memory_address (Pmode, r_label);
790 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
791 r_save_area = convert_memory_address (Pmode, r_save_area);
792 r_fp = gen_rtx_MEM (Pmode, r_save_area);
793 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
794 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
796 current_function_has_nonlocal_goto = 1;
798 #if HAVE_nonlocal_goto
799 /* ??? We no longer need to pass the static chain value, afaik. */
800 if (HAVE_nonlocal_goto)
801 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
802 else
803 #endif
805 r_label = copy_to_reg (r_label);
807 emit_insn (gen_rtx_CLOBBER (VOIDmode,
808 gen_rtx_MEM (BLKmode,
809 gen_rtx_SCRATCH (VOIDmode))));
811 emit_insn (gen_rtx_CLOBBER (VOIDmode,
812 gen_rtx_MEM (BLKmode,
813 hard_frame_pointer_rtx)));
815 /* Restore frame pointer for containing function.
816 This sets the actual hard register used for the frame pointer
817 to the location of the function's incoming static chain info.
818 The non-local goto handler will then adjust it to contain the
819 proper value and reload the argument pointer, if needed. */
820 emit_move_insn (hard_frame_pointer_rtx, r_fp);
821 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
823 /* USE of hard_frame_pointer_rtx added for consistency;
824 not clear if really needed. */
825 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
826 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
827 emit_indirect_jump (r_label);
830 /* Search backwards to the jump insn and mark it as a
831 non-local goto. */
832 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
834 if (JUMP_P (insn))
836 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
837 const0_rtx, REG_NOTES (insn));
838 break;
840 else if (CALL_P (insn))
841 break;
844 return const0_rtx;
847 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
848 (not all will be used on all machines) that was passed to __builtin_setjmp.
849 It updates the stack pointer in that block to correspond to the current
850 stack pointer. */
852 static void
853 expand_builtin_update_setjmp_buf (rtx buf_addr)
855 enum machine_mode sa_mode = Pmode;
856 rtx stack_save;
859 #ifdef HAVE_save_stack_nonlocal
860 if (HAVE_save_stack_nonlocal)
861 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
862 #endif
863 #ifdef STACK_SAVEAREA_MODE
864 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
865 #endif
867 stack_save
868 = gen_rtx_MEM (sa_mode,
869 memory_address
870 (sa_mode,
871 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
873 #ifdef HAVE_setjmp
874 if (HAVE_setjmp)
875 emit_insn (gen_setjmp ());
876 #endif
878 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
881 /* Expand a call to __builtin_prefetch. For a target that does not support
882 data prefetch, evaluate the memory address argument in case it has side
883 effects. */
885 static void
886 expand_builtin_prefetch (tree arglist)
888 tree arg0, arg1, arg2;
889 rtx op0, op1, op2;
891 if (!validate_arglist (arglist, POINTER_TYPE, 0))
892 return;
894 arg0 = TREE_VALUE (arglist);
895 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
896 zero (read) and argument 2 (locality) defaults to 3 (high degree of
897 locality). */
898 if (TREE_CHAIN (arglist))
900 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
901 if (TREE_CHAIN (TREE_CHAIN (arglist)))
902 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
903 else
904 arg2 = build_int_cst (NULL_TREE, 3);
906 else
908 arg1 = integer_zero_node;
909 arg2 = build_int_cst (NULL_TREE, 3);
912 /* Argument 0 is an address. */
913 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
915 /* Argument 1 (read/write flag) must be a compile-time constant int. */
916 if (TREE_CODE (arg1) != INTEGER_CST)
918 error ("second arg to `__builtin_prefetch' must be a constant");
919 arg1 = integer_zero_node;
921 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
922 /* Argument 1 must be either zero or one. */
923 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
925 warning ("invalid second arg to __builtin_prefetch; using zero");
926 op1 = const0_rtx;
929 /* Argument 2 (locality) must be a compile-time constant int. */
930 if (TREE_CODE (arg2) != INTEGER_CST)
932 error ("third arg to `__builtin_prefetch' must be a constant");
933 arg2 = integer_zero_node;
935 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
936 /* Argument 2 must be 0, 1, 2, or 3. */
937 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
939 warning ("invalid third arg to __builtin_prefetch; using zero");
940 op2 = const0_rtx;
943 #ifdef HAVE_prefetch
944 if (HAVE_prefetch)
946 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
947 (op0,
948 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
949 || (GET_MODE (op0) != Pmode))
951 op0 = convert_memory_address (Pmode, op0);
952 op0 = force_reg (Pmode, op0);
954 emit_insn (gen_prefetch (op0, op1, op2));
956 #endif
958 /* Don't do anything with direct references to volatile memory, but
959 generate code to handle other side effects. */
960 if (!MEM_P (op0) && side_effects_p (op0))
961 emit_insn (op0);
964 /* Get a MEM rtx for expression EXP which is the address of an operand
965 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
967 static rtx
968 get_memory_rtx (tree exp)
970 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
971 rtx mem;
973 addr = convert_memory_address (Pmode, addr);
975 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
977 /* Get an expression we can use to find the attributes to assign to MEM.
978 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
979 we can. First remove any nops. */
980 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
981 || TREE_CODE (exp) == NON_LVALUE_EXPR)
982 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
983 exp = TREE_OPERAND (exp, 0);
985 if (TREE_CODE (exp) == ADDR_EXPR)
987 exp = TREE_OPERAND (exp, 0);
988 set_mem_attributes (mem, exp, 0);
990 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
992 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
993 /* memcpy, memset and other builtin stringops can alias with anything. */
994 set_mem_alias_set (mem, 0);
997 return mem;
1000 /* Built-in functions to perform an untyped call and return. */
1002 /* For each register that may be used for calling a function, this
1003 gives a mode used to copy the register's value. VOIDmode indicates
1004 the register is not used for calling a function. If the machine
1005 has register windows, this gives only the outbound registers.
1006 INCOMING_REGNO gives the corresponding inbound register. */
1007 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1009 /* For each register that may be used for returning values, this gives
1010 a mode used to copy the register's value. VOIDmode indicates the
1011 register is not used for returning values. If the machine has
1012 register windows, this gives only the outbound registers.
1013 INCOMING_REGNO gives the corresponding inbound register. */
1014 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1016 /* For each register that may be used for calling a function, this
1017 gives the offset of that register into the block returned by
1018 __builtin_apply_args. 0 indicates that the register is not
1019 used for calling a function. */
1020 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1022 /* Return the size required for the block returned by __builtin_apply_args,
1023 and initialize apply_args_mode. */
1025 static int
1026 apply_args_size (void)
1028 static int size = -1;
1029 int align;
1030 unsigned int regno;
1031 enum machine_mode mode;
1033 /* The values computed by this function never change. */
1034 if (size < 0)
1036 /* The first value is the incoming arg-pointer. */
1037 size = GET_MODE_SIZE (Pmode);
1039 /* The second value is the structure value address unless this is
1040 passed as an "invisible" first argument. */
1041 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1042 size += GET_MODE_SIZE (Pmode);
1044 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1045 if (FUNCTION_ARG_REGNO_P (regno))
1047 mode = reg_raw_mode[regno];
1049 gcc_assert (mode != VOIDmode);
1051 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1052 if (size % align != 0)
1053 size = CEIL (size, align) * align;
1054 apply_args_reg_offset[regno] = size;
1055 size += GET_MODE_SIZE (mode);
1056 apply_args_mode[regno] = mode;
1058 else
1060 apply_args_mode[regno] = VOIDmode;
1061 apply_args_reg_offset[regno] = 0;
1064 return size;
1067 /* Return the size required for the block returned by __builtin_apply,
1068 and initialize apply_result_mode. */
1070 static int
1071 apply_result_size (void)
1073 static int size = -1;
1074 int align, regno;
1075 enum machine_mode mode;
1077 /* The values computed by this function never change. */
1078 if (size < 0)
1080 size = 0;
1082 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1083 if (FUNCTION_VALUE_REGNO_P (regno))
1085 mode = reg_raw_mode[regno];
1087 gcc_assert (mode != VOIDmode);
1089 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1090 if (size % align != 0)
1091 size = CEIL (size, align) * align;
1092 size += GET_MODE_SIZE (mode);
1093 apply_result_mode[regno] = mode;
1095 else
1096 apply_result_mode[regno] = VOIDmode;
1098 /* Allow targets that use untyped_call and untyped_return to override
1099 the size so that machine-specific information can be stored here. */
1100 #ifdef APPLY_RESULT_SIZE
1101 size = APPLY_RESULT_SIZE;
1102 #endif
1104 return size;
1107 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1108 /* Create a vector describing the result block RESULT. If SAVEP is true,
1109 the result block is used to save the values; otherwise it is used to
1110 restore the values. */
1112 static rtx
1113 result_vector (int savep, rtx result)
1115 int regno, size, align, nelts;
1116 enum machine_mode mode;
1117 rtx reg, mem;
1118 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1120 size = nelts = 0;
1121 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1122 if ((mode = apply_result_mode[regno]) != VOIDmode)
1124 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1125 if (size % align != 0)
1126 size = CEIL (size, align) * align;
1127 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1128 mem = adjust_address (result, mode, size);
1129 savevec[nelts++] = (savep
1130 ? gen_rtx_SET (VOIDmode, mem, reg)
1131 : gen_rtx_SET (VOIDmode, reg, mem));
1132 size += GET_MODE_SIZE (mode);
1134 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1136 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1138 /* Save the state required to perform an untyped call with the same
1139 arguments as were passed to the current function. */
1141 static rtx
1142 expand_builtin_apply_args_1 (void)
1144 rtx registers, tem;
1145 int size, align, regno;
1146 enum machine_mode mode;
1147 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1149 /* Create a block where the arg-pointer, structure value address,
1150 and argument registers can be saved. */
1151 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1153 /* Walk past the arg-pointer and structure value address. */
1154 size = GET_MODE_SIZE (Pmode);
1155 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1156 size += GET_MODE_SIZE (Pmode);
1158 /* Save each register used in calling a function to the block. */
1159 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1160 if ((mode = apply_args_mode[regno]) != VOIDmode)
1162 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1163 if (size % align != 0)
1164 size = CEIL (size, align) * align;
1166 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1168 emit_move_insn (adjust_address (registers, mode, size), tem);
1169 size += GET_MODE_SIZE (mode);
1172 /* Save the arg pointer to the block. */
1173 tem = copy_to_reg (virtual_incoming_args_rtx);
1174 #ifdef STACK_GROWS_DOWNWARD
1175 /* We need the pointer as the caller actually passed them to us, not
1176 as we might have pretended they were passed. Make sure it's a valid
1177 operand, as emit_move_insn isn't expected to handle a PLUS. */
1179 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1180 NULL_RTX);
1181 #endif
1182 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1184 size = GET_MODE_SIZE (Pmode);
1186 /* Save the structure value address unless this is passed as an
1187 "invisible" first argument. */
1188 if (struct_incoming_value)
1190 emit_move_insn (adjust_address (registers, Pmode, size),
1191 copy_to_reg (struct_incoming_value));
1192 size += GET_MODE_SIZE (Pmode);
1195 /* Return the address of the block. */
1196 return copy_addr_to_reg (XEXP (registers, 0));
1199 /* __builtin_apply_args returns block of memory allocated on
1200 the stack into which is stored the arg pointer, structure
1201 value address, static chain, and all the registers that might
1202 possibly be used in performing a function call. The code is
1203 moved to the start of the function so the incoming values are
1204 saved. */
1206 static rtx
1207 expand_builtin_apply_args (void)
1209 /* Don't do __builtin_apply_args more than once in a function.
1210 Save the result of the first call and reuse it. */
1211 if (apply_args_value != 0)
1212 return apply_args_value;
1214 /* When this function is called, it means that registers must be
1215 saved on entry to this function. So we migrate the
1216 call to the first insn of this function. */
1217 rtx temp;
1218 rtx seq;
1220 start_sequence ();
1221 temp = expand_builtin_apply_args_1 ();
1222 seq = get_insns ();
1223 end_sequence ();
1225 apply_args_value = temp;
1227 /* Put the insns after the NOTE that starts the function.
1228 If this is inside a start_sequence, make the outer-level insn
1229 chain current, so the code is placed at the start of the
1230 function. */
1231 push_topmost_sequence ();
1232 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1233 pop_topmost_sequence ();
1234 return temp;
1238 /* Perform an untyped call and save the state required to perform an
1239 untyped return of whatever value was returned by the given function. */
1241 static rtx
1242 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1244 int size, align, regno;
1245 enum machine_mode mode;
1246 rtx incoming_args, result, reg, dest, src, call_insn;
1247 rtx old_stack_level = 0;
1248 rtx call_fusage = 0;
1249 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1251 arguments = convert_memory_address (Pmode, arguments);
1253 /* Create a block where the return registers can be saved. */
1254 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1256 /* Fetch the arg pointer from the ARGUMENTS block. */
1257 incoming_args = gen_reg_rtx (Pmode);
1258 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1259 #ifndef STACK_GROWS_DOWNWARD
1260 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1261 incoming_args, 0, OPTAB_LIB_WIDEN);
1262 #endif
1264 /* Push a new argument block and copy the arguments. Do not allow
1265 the (potential) memcpy call below to interfere with our stack
1266 manipulations. */
1267 do_pending_stack_adjust ();
1268 NO_DEFER_POP;
1270 /* Save the stack with nonlocal if available. */
1271 #ifdef HAVE_save_stack_nonlocal
1272 if (HAVE_save_stack_nonlocal)
1273 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1274 else
1275 #endif
1276 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1278 /* Allocate a block of memory onto the stack and copy the memory
1279 arguments to the outgoing arguments address. */
1280 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1281 dest = virtual_outgoing_args_rtx;
1282 #ifndef STACK_GROWS_DOWNWARD
1283 if (GET_CODE (argsize) == CONST_INT)
1284 dest = plus_constant (dest, -INTVAL (argsize));
1285 else
1286 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1287 #endif
1288 dest = gen_rtx_MEM (BLKmode, dest);
1289 set_mem_align (dest, PARM_BOUNDARY);
1290 src = gen_rtx_MEM (BLKmode, incoming_args);
1291 set_mem_align (src, PARM_BOUNDARY);
1292 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1294 /* Refer to the argument block. */
1295 apply_args_size ();
1296 arguments = gen_rtx_MEM (BLKmode, arguments);
1297 set_mem_align (arguments, PARM_BOUNDARY);
1299 /* Walk past the arg-pointer and structure value address. */
1300 size = GET_MODE_SIZE (Pmode);
1301 if (struct_value)
1302 size += GET_MODE_SIZE (Pmode);
1304 /* Restore each of the registers previously saved. Make USE insns
1305 for each of these registers for use in making the call. */
1306 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1307 if ((mode = apply_args_mode[regno]) != VOIDmode)
1309 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1310 if (size % align != 0)
1311 size = CEIL (size, align) * align;
1312 reg = gen_rtx_REG (mode, regno);
1313 emit_move_insn (reg, adjust_address (arguments, mode, size));
1314 use_reg (&call_fusage, reg);
1315 size += GET_MODE_SIZE (mode);
1318 /* Restore the structure value address unless this is passed as an
1319 "invisible" first argument. */
1320 size = GET_MODE_SIZE (Pmode);
1321 if (struct_value)
1323 rtx value = gen_reg_rtx (Pmode);
1324 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1325 emit_move_insn (struct_value, value);
1326 if (REG_P (struct_value))
1327 use_reg (&call_fusage, struct_value);
1328 size += GET_MODE_SIZE (Pmode);
1331 /* All arguments and registers used for the call are set up by now! */
1332 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1334 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1335 and we don't want to load it into a register as an optimization,
1336 because prepare_call_address already did it if it should be done. */
1337 if (GET_CODE (function) != SYMBOL_REF)
1338 function = memory_address (FUNCTION_MODE, function);
1340 /* Generate the actual call instruction and save the return value. */
1341 #ifdef HAVE_untyped_call
1342 if (HAVE_untyped_call)
1343 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1344 result, result_vector (1, result)));
1345 else
1346 #endif
1347 #ifdef HAVE_call_value
1348 if (HAVE_call_value)
1350 rtx valreg = 0;
1352 /* Locate the unique return register. It is not possible to
1353 express a call that sets more than one return register using
1354 call_value; use untyped_call for that. In fact, untyped_call
1355 only needs to save the return registers in the given block. */
1356 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1357 if ((mode = apply_result_mode[regno]) != VOIDmode)
1359 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1361 valreg = gen_rtx_REG (mode, regno);
1364 emit_call_insn (GEN_CALL_VALUE (valreg,
1365 gen_rtx_MEM (FUNCTION_MODE, function),
1366 const0_rtx, NULL_RTX, const0_rtx));
1368 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1370 else
1371 #endif
1372 gcc_unreachable ();
1374 /* Find the CALL insn we just emitted, and attach the register usage
1375 information. */
1376 call_insn = last_call_insn ();
1377 add_function_usage_to (call_insn, call_fusage);
1379 /* Restore the stack. */
1380 #ifdef HAVE_save_stack_nonlocal
1381 if (HAVE_save_stack_nonlocal)
1382 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1383 else
1384 #endif
1385 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1387 OK_DEFER_POP;
1389 /* Return the address of the result block. */
1390 result = copy_addr_to_reg (XEXP (result, 0));
1391 return convert_memory_address (ptr_mode, result);
1394 /* Perform an untyped return. */
1396 static void
1397 expand_builtin_return (rtx result)
1399 int size, align, regno;
1400 enum machine_mode mode;
1401 rtx reg;
1402 rtx call_fusage = 0;
1404 result = convert_memory_address (Pmode, result);
1406 apply_result_size ();
1407 result = gen_rtx_MEM (BLKmode, result);
1409 #ifdef HAVE_untyped_return
1410 if (HAVE_untyped_return)
1412 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1413 emit_barrier ();
1414 return;
1416 #endif
1418 /* Restore the return value and note that each value is used. */
1419 size = 0;
1420 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1421 if ((mode = apply_result_mode[regno]) != VOIDmode)
1423 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1424 if (size % align != 0)
1425 size = CEIL (size, align) * align;
1426 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1427 emit_move_insn (reg, adjust_address (result, mode, size));
1429 push_to_sequence (call_fusage);
1430 emit_insn (gen_rtx_USE (VOIDmode, reg));
1431 call_fusage = get_insns ();
1432 end_sequence ();
1433 size += GET_MODE_SIZE (mode);
1436 /* Put the USE insns before the return. */
1437 emit_insn (call_fusage);
1439 /* Return whatever values was restored by jumping directly to the end
1440 of the function. */
1441 expand_naked_return ();
1444 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1446 static enum type_class
1447 type_to_class (tree type)
1449 switch (TREE_CODE (type))
1451 case VOID_TYPE: return void_type_class;
1452 case INTEGER_TYPE: return integer_type_class;
1453 case CHAR_TYPE: return char_type_class;
1454 case ENUMERAL_TYPE: return enumeral_type_class;
1455 case BOOLEAN_TYPE: return boolean_type_class;
1456 case POINTER_TYPE: return pointer_type_class;
1457 case REFERENCE_TYPE: return reference_type_class;
1458 case OFFSET_TYPE: return offset_type_class;
1459 case REAL_TYPE: return real_type_class;
1460 case COMPLEX_TYPE: return complex_type_class;
1461 case FUNCTION_TYPE: return function_type_class;
1462 case METHOD_TYPE: return method_type_class;
1463 case RECORD_TYPE: return record_type_class;
1464 case UNION_TYPE:
1465 case QUAL_UNION_TYPE: return union_type_class;
1466 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1467 ? string_type_class : array_type_class);
1468 case SET_TYPE: return set_type_class;
1469 case FILE_TYPE: return file_type_class;
1470 case LANG_TYPE: return lang_type_class;
1471 default: return no_type_class;
1475 /* Expand a call to __builtin_classify_type with arguments found in
1476 ARGLIST. */
1478 static rtx
1479 expand_builtin_classify_type (tree arglist)
1481 if (arglist != 0)
1482 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1483 return GEN_INT (no_type_class);
1486 /* This helper macro, meant to be used in mathfn_built_in below,
1487 determines which among a set of three builtin math functions is
1488 appropriate for a given type mode. The `F' and `L' cases are
1489 automatically generated from the `double' case. */
1490 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1491 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1492 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1493 fcodel = BUILT_IN_MATHFN##L ; break;
1495 /* Return mathematic function equivalent to FN but operating directly
1496 on TYPE, if available. If we can't do the conversion, return zero. */
1497 tree
1498 mathfn_built_in (tree type, enum built_in_function fn)
1500 enum built_in_function fcode, fcodef, fcodel;
1502 switch (fn)
1504 CASE_MATHFN (BUILT_IN_ACOS)
1505 CASE_MATHFN (BUILT_IN_ACOSH)
1506 CASE_MATHFN (BUILT_IN_ASIN)
1507 CASE_MATHFN (BUILT_IN_ASINH)
1508 CASE_MATHFN (BUILT_IN_ATAN)
1509 CASE_MATHFN (BUILT_IN_ATAN2)
1510 CASE_MATHFN (BUILT_IN_ATANH)
1511 CASE_MATHFN (BUILT_IN_CBRT)
1512 CASE_MATHFN (BUILT_IN_CEIL)
1513 CASE_MATHFN (BUILT_IN_COPYSIGN)
1514 CASE_MATHFN (BUILT_IN_COS)
1515 CASE_MATHFN (BUILT_IN_COSH)
1516 CASE_MATHFN (BUILT_IN_DREM)
1517 CASE_MATHFN (BUILT_IN_ERF)
1518 CASE_MATHFN (BUILT_IN_ERFC)
1519 CASE_MATHFN (BUILT_IN_EXP)
1520 CASE_MATHFN (BUILT_IN_EXP10)
1521 CASE_MATHFN (BUILT_IN_EXP2)
1522 CASE_MATHFN (BUILT_IN_EXPM1)
1523 CASE_MATHFN (BUILT_IN_FABS)
1524 CASE_MATHFN (BUILT_IN_FDIM)
1525 CASE_MATHFN (BUILT_IN_FLOOR)
1526 CASE_MATHFN (BUILT_IN_FMA)
1527 CASE_MATHFN (BUILT_IN_FMAX)
1528 CASE_MATHFN (BUILT_IN_FMIN)
1529 CASE_MATHFN (BUILT_IN_FMOD)
1530 CASE_MATHFN (BUILT_IN_FREXP)
1531 CASE_MATHFN (BUILT_IN_GAMMA)
1532 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1533 CASE_MATHFN (BUILT_IN_HYPOT)
1534 CASE_MATHFN (BUILT_IN_ILOGB)
1535 CASE_MATHFN (BUILT_IN_INF)
1536 CASE_MATHFN (BUILT_IN_J0)
1537 CASE_MATHFN (BUILT_IN_J1)
1538 CASE_MATHFN (BUILT_IN_JN)
1539 CASE_MATHFN (BUILT_IN_LDEXP)
1540 CASE_MATHFN (BUILT_IN_LGAMMA)
1541 CASE_MATHFN (BUILT_IN_LLRINT)
1542 CASE_MATHFN (BUILT_IN_LLROUND)
1543 CASE_MATHFN (BUILT_IN_LOG)
1544 CASE_MATHFN (BUILT_IN_LOG10)
1545 CASE_MATHFN (BUILT_IN_LOG1P)
1546 CASE_MATHFN (BUILT_IN_LOG2)
1547 CASE_MATHFN (BUILT_IN_LOGB)
1548 CASE_MATHFN (BUILT_IN_LRINT)
1549 CASE_MATHFN (BUILT_IN_LROUND)
1550 CASE_MATHFN (BUILT_IN_MODF)
1551 CASE_MATHFN (BUILT_IN_NAN)
1552 CASE_MATHFN (BUILT_IN_NANS)
1553 CASE_MATHFN (BUILT_IN_NEARBYINT)
1554 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1555 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1556 CASE_MATHFN (BUILT_IN_POW)
1557 CASE_MATHFN (BUILT_IN_POW10)
1558 CASE_MATHFN (BUILT_IN_REMAINDER)
1559 CASE_MATHFN (BUILT_IN_REMQUO)
1560 CASE_MATHFN (BUILT_IN_RINT)
1561 CASE_MATHFN (BUILT_IN_ROUND)
1562 CASE_MATHFN (BUILT_IN_SCALB)
1563 CASE_MATHFN (BUILT_IN_SCALBLN)
1564 CASE_MATHFN (BUILT_IN_SCALBN)
1565 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1566 CASE_MATHFN (BUILT_IN_SIN)
1567 CASE_MATHFN (BUILT_IN_SINCOS)
1568 CASE_MATHFN (BUILT_IN_SINH)
1569 CASE_MATHFN (BUILT_IN_SQRT)
1570 CASE_MATHFN (BUILT_IN_TAN)
1571 CASE_MATHFN (BUILT_IN_TANH)
1572 CASE_MATHFN (BUILT_IN_TGAMMA)
1573 CASE_MATHFN (BUILT_IN_TRUNC)
1574 CASE_MATHFN (BUILT_IN_Y0)
1575 CASE_MATHFN (BUILT_IN_Y1)
1576 CASE_MATHFN (BUILT_IN_YN)
1578 default:
1579 return 0;
1582 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1583 return implicit_built_in_decls[fcode];
1584 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1585 return implicit_built_in_decls[fcodef];
1586 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1587 return implicit_built_in_decls[fcodel];
1588 else
1589 return 0;
1592 /* If errno must be maintained, expand the RTL to check if the result,
1593 TARGET, of a built-in function call, EXP, is NaN, and if so set
1594 errno to EDOM. */
1596 static void
1597 expand_errno_check (tree exp, rtx target)
1599 rtx lab = gen_label_rtx ();
1601 /* Test the result; if it is NaN, set errno=EDOM because
1602 the argument was not in the domain. */
1603 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1604 0, lab);
1606 #ifdef TARGET_EDOM
1607 /* If this built-in doesn't throw an exception, set errno directly. */
1608 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1610 #ifdef GEN_ERRNO_RTX
1611 rtx errno_rtx = GEN_ERRNO_RTX;
1612 #else
1613 rtx errno_rtx
1614 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1615 #endif
1616 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1617 emit_label (lab);
1618 return;
1620 #endif
1622 /* We can't set errno=EDOM directly; let the library call do it.
1623 Pop the arguments right away in case the call gets deleted. */
1624 NO_DEFER_POP;
1625 expand_call (exp, target, 0);
1626 OK_DEFER_POP;
1627 emit_label (lab);
1631 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1632 Return 0 if a normal call should be emitted rather than expanding the
1633 function in-line. EXP is the expression that is a call to the builtin
1634 function; if convenient, the result should be placed in TARGET.
1635 SUBTARGET may be used as the target for computing one of EXP's operands. */
1637 static rtx
1638 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1640 optab builtin_optab;
1641 rtx op0, insns, before_call;
1642 tree fndecl = get_callee_fndecl (exp);
1643 tree arglist = TREE_OPERAND (exp, 1);
1644 enum machine_mode mode;
1645 bool errno_set = false;
1646 tree arg, narg;
1648 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1649 return 0;
1651 arg = TREE_VALUE (arglist);
1653 switch (DECL_FUNCTION_CODE (fndecl))
1655 case BUILT_IN_SQRT:
1656 case BUILT_IN_SQRTF:
1657 case BUILT_IN_SQRTL:
1658 errno_set = ! tree_expr_nonnegative_p (arg);
1659 builtin_optab = sqrt_optab;
1660 break;
1661 case BUILT_IN_EXP:
1662 case BUILT_IN_EXPF:
1663 case BUILT_IN_EXPL:
1664 errno_set = true; builtin_optab = exp_optab; break;
1665 case BUILT_IN_EXP10:
1666 case BUILT_IN_EXP10F:
1667 case BUILT_IN_EXP10L:
1668 case BUILT_IN_POW10:
1669 case BUILT_IN_POW10F:
1670 case BUILT_IN_POW10L:
1671 errno_set = true; builtin_optab = exp10_optab; break;
1672 case BUILT_IN_EXP2:
1673 case BUILT_IN_EXP2F:
1674 case BUILT_IN_EXP2L:
1675 errno_set = true; builtin_optab = exp2_optab; break;
1676 case BUILT_IN_EXPM1:
1677 case BUILT_IN_EXPM1F:
1678 case BUILT_IN_EXPM1L:
1679 errno_set = true; builtin_optab = expm1_optab; break;
1680 case BUILT_IN_LOGB:
1681 case BUILT_IN_LOGBF:
1682 case BUILT_IN_LOGBL:
1683 errno_set = true; builtin_optab = logb_optab; break;
1684 case BUILT_IN_ILOGB:
1685 case BUILT_IN_ILOGBF:
1686 case BUILT_IN_ILOGBL:
1687 errno_set = true; builtin_optab = ilogb_optab; break;
1688 case BUILT_IN_LOG:
1689 case BUILT_IN_LOGF:
1690 case BUILT_IN_LOGL:
1691 errno_set = true; builtin_optab = log_optab; break;
1692 case BUILT_IN_LOG10:
1693 case BUILT_IN_LOG10F:
1694 case BUILT_IN_LOG10L:
1695 errno_set = true; builtin_optab = log10_optab; break;
1696 case BUILT_IN_LOG2:
1697 case BUILT_IN_LOG2F:
1698 case BUILT_IN_LOG2L:
1699 errno_set = true; builtin_optab = log2_optab; break;
1700 case BUILT_IN_LOG1P:
1701 case BUILT_IN_LOG1PF:
1702 case BUILT_IN_LOG1PL:
1703 errno_set = true; builtin_optab = log1p_optab; break;
1704 case BUILT_IN_ASIN:
1705 case BUILT_IN_ASINF:
1706 case BUILT_IN_ASINL:
1707 builtin_optab = asin_optab; break;
1708 case BUILT_IN_ACOS:
1709 case BUILT_IN_ACOSF:
1710 case BUILT_IN_ACOSL:
1711 builtin_optab = acos_optab; break;
1712 case BUILT_IN_TAN:
1713 case BUILT_IN_TANF:
1714 case BUILT_IN_TANL:
1715 builtin_optab = tan_optab; break;
1716 case BUILT_IN_ATAN:
1717 case BUILT_IN_ATANF:
1718 case BUILT_IN_ATANL:
1719 builtin_optab = atan_optab; break;
1720 case BUILT_IN_FLOOR:
1721 case BUILT_IN_FLOORF:
1722 case BUILT_IN_FLOORL:
1723 builtin_optab = floor_optab; break;
1724 case BUILT_IN_CEIL:
1725 case BUILT_IN_CEILF:
1726 case BUILT_IN_CEILL:
1727 builtin_optab = ceil_optab; break;
1728 case BUILT_IN_TRUNC:
1729 case BUILT_IN_TRUNCF:
1730 case BUILT_IN_TRUNCL:
1731 builtin_optab = btrunc_optab; break;
1732 case BUILT_IN_ROUND:
1733 case BUILT_IN_ROUNDF:
1734 case BUILT_IN_ROUNDL:
1735 builtin_optab = round_optab; break;
1736 case BUILT_IN_NEARBYINT:
1737 case BUILT_IN_NEARBYINTF:
1738 case BUILT_IN_NEARBYINTL:
1739 builtin_optab = nearbyint_optab; break;
1740 case BUILT_IN_RINT:
1741 case BUILT_IN_RINTF:
1742 case BUILT_IN_RINTL:
1743 builtin_optab = rint_optab; break;
1744 default:
1745 gcc_unreachable ();
1748 /* Make a suitable register to place result in. */
1749 mode = TYPE_MODE (TREE_TYPE (exp));
1751 if (! flag_errno_math || ! HONOR_NANS (mode))
1752 errno_set = false;
1754 /* Before working hard, check whether the instruction is available. */
1755 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1757 target = gen_reg_rtx (mode);
1759 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1760 need to expand the argument again. This way, we will not perform
1761 side-effects more the once. */
1762 narg = builtin_save_expr (arg);
1763 if (narg != arg)
1765 arglist = build_tree_list (NULL_TREE, arg);
1766 exp = build_function_call_expr (fndecl, arglist);
1769 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1771 start_sequence ();
1773 /* Compute into TARGET.
1774 Set TARGET to wherever the result comes back. */
1775 target = expand_unop (mode, builtin_optab, op0, target, 0);
1777 if (target != 0)
1779 if (errno_set)
1780 expand_errno_check (exp, target);
1782 /* Output the entire sequence. */
1783 insns = get_insns ();
1784 end_sequence ();
1785 emit_insn (insns);
1786 return target;
1789 /* If we were unable to expand via the builtin, stop the sequence
1790 (without outputting the insns) and call to the library function
1791 with the stabilized argument list. */
1792 end_sequence ();
1795 before_call = get_last_insn ();
1797 target = expand_call (exp, target, target == const0_rtx);
1799 /* If this is a sqrt operation and we don't care about errno, try to
1800 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1801 This allows the semantics of the libcall to be visible to the RTL
1802 optimizers. */
1803 if (builtin_optab == sqrt_optab && !errno_set)
1805 /* Search backwards through the insns emitted by expand_call looking
1806 for the instruction with the REG_RETVAL note. */
1807 rtx last = get_last_insn ();
1808 while (last != before_call)
1810 if (find_reg_note (last, REG_RETVAL, NULL))
1812 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1813 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1814 two elements, i.e. symbol_ref(sqrt) and the operand. */
1815 if (note
1816 && GET_CODE (note) == EXPR_LIST
1817 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1818 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1819 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1821 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1822 /* Check operand is a register with expected mode. */
1823 if (operand
1824 && REG_P (operand)
1825 && GET_MODE (operand) == mode)
1827 /* Replace the REG_EQUAL note with a SQRT rtx. */
1828 rtx equiv = gen_rtx_SQRT (mode, operand);
1829 set_unique_reg_note (last, REG_EQUAL, equiv);
1832 break;
1834 last = PREV_INSN (last);
1838 return target;
1841 /* Expand a call to the builtin binary math functions (pow and atan2).
1842 Return 0 if a normal call should be emitted rather than expanding the
1843 function in-line. EXP is the expression that is a call to the builtin
1844 function; if convenient, the result should be placed in TARGET.
1845 SUBTARGET may be used as the target for computing one of EXP's
1846 operands. */
1848 static rtx
1849 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1851 optab builtin_optab;
1852 rtx op0, op1, insns;
1853 tree fndecl = get_callee_fndecl (exp);
1854 tree arglist = TREE_OPERAND (exp, 1);
1855 tree arg0, arg1, temp, narg;
1856 enum machine_mode mode;
1857 bool errno_set = true;
1858 bool stable = true;
1860 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1861 return 0;
1863 arg0 = TREE_VALUE (arglist);
1864 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1866 switch (DECL_FUNCTION_CODE (fndecl))
1868 case BUILT_IN_POW:
1869 case BUILT_IN_POWF:
1870 case BUILT_IN_POWL:
1871 builtin_optab = pow_optab; break;
1872 case BUILT_IN_ATAN2:
1873 case BUILT_IN_ATAN2F:
1874 case BUILT_IN_ATAN2L:
1875 builtin_optab = atan2_optab; break;
1876 case BUILT_IN_FMOD:
1877 case BUILT_IN_FMODF:
1878 case BUILT_IN_FMODL:
1879 builtin_optab = fmod_optab; break;
1880 case BUILT_IN_DREM:
1881 case BUILT_IN_DREMF:
1882 case BUILT_IN_DREML:
1883 builtin_optab = drem_optab; break;
1884 default:
1885 gcc_unreachable ();
1888 /* Make a suitable register to place result in. */
1889 mode = TYPE_MODE (TREE_TYPE (exp));
1891 /* Before working hard, check whether the instruction is available. */
1892 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1893 return 0;
1895 target = gen_reg_rtx (mode);
1897 if (! flag_errno_math || ! HONOR_NANS (mode))
1898 errno_set = false;
1900 /* Always stabilize the argument list. */
1901 narg = builtin_save_expr (arg1);
1902 if (narg != arg1)
1904 temp = build_tree_list (NULL_TREE, narg);
1905 stable = false;
1907 else
1908 temp = TREE_CHAIN (arglist);
1910 narg = builtin_save_expr (arg0);
1911 if (narg != arg0)
1913 arglist = tree_cons (NULL_TREE, narg, temp);
1914 stable = false;
1916 else if (! stable)
1917 arglist = tree_cons (NULL_TREE, arg0, temp);
1919 if (! stable)
1920 exp = build_function_call_expr (fndecl, arglist);
1922 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1923 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1925 start_sequence ();
1927 /* Compute into TARGET.
1928 Set TARGET to wherever the result comes back. */
1929 target = expand_binop (mode, builtin_optab, op0, op1,
1930 target, 0, OPTAB_DIRECT);
1932 /* If we were unable to expand via the builtin, stop the sequence
1933 (without outputting the insns) and call to the library function
1934 with the stabilized argument list. */
1935 if (target == 0)
1937 end_sequence ();
1938 return expand_call (exp, target, target == const0_rtx);
1941 if (errno_set)
1942 expand_errno_check (exp, target);
1944 /* Output the entire sequence. */
1945 insns = get_insns ();
1946 end_sequence ();
1947 emit_insn (insns);
1949 return target;
1952 /* Expand a call to the builtin sin and cos math functions.
1953 Return 0 if a normal call should be emitted rather than expanding the
1954 function in-line. EXP is the expression that is a call to the builtin
1955 function; if convenient, the result should be placed in TARGET.
1956 SUBTARGET may be used as the target for computing one of EXP's
1957 operands. */
1959 static rtx
1960 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1962 optab builtin_optab;
1963 rtx op0, insns, before_call;
1964 tree fndecl = get_callee_fndecl (exp);
1965 tree arglist = TREE_OPERAND (exp, 1);
1966 enum machine_mode mode;
1967 bool errno_set = false;
1968 tree arg, narg;
1970 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1971 return 0;
1973 arg = TREE_VALUE (arglist);
1975 switch (DECL_FUNCTION_CODE (fndecl))
1977 case BUILT_IN_SIN:
1978 case BUILT_IN_SINF:
1979 case BUILT_IN_SINL:
1980 case BUILT_IN_COS:
1981 case BUILT_IN_COSF:
1982 case BUILT_IN_COSL:
1983 builtin_optab = sincos_optab; break;
1984 default:
1985 gcc_unreachable ();
1988 /* Make a suitable register to place result in. */
1989 mode = TYPE_MODE (TREE_TYPE (exp));
1991 if (! flag_errno_math || ! HONOR_NANS (mode))
1992 errno_set = false;
1994 /* Check if sincos insn is available, otherwise fallback
1995 to sin or cos insn. */
1996 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1997 switch (DECL_FUNCTION_CODE (fndecl))
1999 case BUILT_IN_SIN:
2000 case BUILT_IN_SINF:
2001 case BUILT_IN_SINL:
2002 builtin_optab = sin_optab; break;
2003 case BUILT_IN_COS:
2004 case BUILT_IN_COSF:
2005 case BUILT_IN_COSL:
2006 builtin_optab = cos_optab; break;
2007 default:
2008 gcc_unreachable ();
2012 /* Before working hard, check whether the instruction is available. */
2013 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2015 target = gen_reg_rtx (mode);
2017 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2018 need to expand the argument again. This way, we will not perform
2019 side-effects more the once. */
2020 narg = save_expr (arg);
2021 if (narg != arg)
2023 arglist = build_tree_list (NULL_TREE, arg);
2024 exp = build_function_call_expr (fndecl, arglist);
2027 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2029 start_sequence ();
2031 /* Compute into TARGET.
2032 Set TARGET to wherever the result comes back. */
2033 if (builtin_optab == sincos_optab)
2035 int result;
2037 switch (DECL_FUNCTION_CODE (fndecl))
2039 case BUILT_IN_SIN:
2040 case BUILT_IN_SINF:
2041 case BUILT_IN_SINL:
2042 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2043 break;
2044 case BUILT_IN_COS:
2045 case BUILT_IN_COSF:
2046 case BUILT_IN_COSL:
2047 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2048 break;
2049 default:
2050 gcc_unreachable ();
2052 gcc_assert (result);
2054 else
2056 target = expand_unop (mode, builtin_optab, op0, target, 0);
2059 if (target != 0)
2061 if (errno_set)
2062 expand_errno_check (exp, target);
2064 /* Output the entire sequence. */
2065 insns = get_insns ();
2066 end_sequence ();
2067 emit_insn (insns);
2068 return target;
2071 /* If we were unable to expand via the builtin, stop the sequence
2072 (without outputting the insns) and call to the library function
2073 with the stabilized argument list. */
2074 end_sequence ();
2077 before_call = get_last_insn ();
2079 target = expand_call (exp, target, target == const0_rtx);
2081 return target;
2084 /* To evaluate powi(x,n), the floating point value x raised to the
2085 constant integer exponent n, we use a hybrid algorithm that
2086 combines the "window method" with look-up tables. For an
2087 introduction to exponentiation algorithms and "addition chains",
2088 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2089 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2090 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2091 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2093 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2094 multiplications to inline before calling the system library's pow
2095 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2096 so this default never requires calling pow, powf or powl. */
2098 #ifndef POWI_MAX_MULTS
2099 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2100 #endif
2102 /* The size of the "optimal power tree" lookup table. All
2103 exponents less than this value are simply looked up in the
2104 powi_table below. This threshold is also used to size the
2105 cache of pseudo registers that hold intermediate results. */
2106 #define POWI_TABLE_SIZE 256
2108 /* The size, in bits of the window, used in the "window method"
2109 exponentiation algorithm. This is equivalent to a radix of
2110 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2111 #define POWI_WINDOW_SIZE 3
2113 /* The following table is an efficient representation of an
2114 "optimal power tree". For each value, i, the corresponding
2115 value, j, in the table states than an optimal evaluation
2116 sequence for calculating pow(x,i) can be found by evaluating
2117 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2118 100 integers is given in Knuth's "Seminumerical algorithms". */
2120 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2122 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2123 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2124 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2125 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2126 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2127 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2128 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2129 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2130 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2131 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2132 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2133 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2134 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2135 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2136 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2137 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2138 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2139 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2140 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2141 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2142 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2143 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2144 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2145 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2146 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2147 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2148 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2149 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2150 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2151 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2152 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2153 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2157 /* Return the number of multiplications required to calculate
2158 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2159 subroutine of powi_cost. CACHE is an array indicating
2160 which exponents have already been calculated. */
2162 static int
2163 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2165 /* If we've already calculated this exponent, then this evaluation
2166 doesn't require any additional multiplications. */
2167 if (cache[n])
2168 return 0;
2170 cache[n] = true;
2171 return powi_lookup_cost (n - powi_table[n], cache)
2172 + powi_lookup_cost (powi_table[n], cache) + 1;
2175 /* Return the number of multiplications required to calculate
2176 powi(x,n) for an arbitrary x, given the exponent N. This
2177 function needs to be kept in sync with expand_powi below. */
2179 static int
2180 powi_cost (HOST_WIDE_INT n)
2182 bool cache[POWI_TABLE_SIZE];
2183 unsigned HOST_WIDE_INT digit;
2184 unsigned HOST_WIDE_INT val;
2185 int result;
2187 if (n == 0)
2188 return 0;
2190 /* Ignore the reciprocal when calculating the cost. */
2191 val = (n < 0) ? -n : n;
2193 /* Initialize the exponent cache. */
2194 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2195 cache[1] = true;
2197 result = 0;
2199 while (val >= POWI_TABLE_SIZE)
2201 if (val & 1)
2203 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2204 result += powi_lookup_cost (digit, cache)
2205 + POWI_WINDOW_SIZE + 1;
2206 val >>= POWI_WINDOW_SIZE;
2208 else
2210 val >>= 1;
2211 result++;
2215 return result + powi_lookup_cost (val, cache);
2218 /* Recursive subroutine of expand_powi. This function takes the array,
2219 CACHE, of already calculated exponents and an exponent N and returns
2220 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2222 static rtx
2223 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2225 unsigned HOST_WIDE_INT digit;
2226 rtx target, result;
2227 rtx op0, op1;
2229 if (n < POWI_TABLE_SIZE)
2231 if (cache[n])
2232 return cache[n];
2234 target = gen_reg_rtx (mode);
2235 cache[n] = target;
2237 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2238 op1 = expand_powi_1 (mode, powi_table[n], cache);
2240 else if (n & 1)
2242 target = gen_reg_rtx (mode);
2243 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2244 op0 = expand_powi_1 (mode, n - digit, cache);
2245 op1 = expand_powi_1 (mode, digit, cache);
2247 else
2249 target = gen_reg_rtx (mode);
2250 op0 = expand_powi_1 (mode, n >> 1, cache);
2251 op1 = op0;
2254 result = expand_mult (mode, op0, op1, target, 0);
2255 if (result != target)
2256 emit_move_insn (target, result);
2257 return target;
2260 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2261 floating point operand in mode MODE, and N is the exponent. This
2262 function needs to be kept in sync with powi_cost above. */
2264 static rtx
2265 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2267 unsigned HOST_WIDE_INT val;
2268 rtx cache[POWI_TABLE_SIZE];
2269 rtx result;
2271 if (n == 0)
2272 return CONST1_RTX (mode);
2274 val = (n < 0) ? -n : n;
2276 memset (cache, 0, sizeof (cache));
2277 cache[1] = x;
2279 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2281 /* If the original exponent was negative, reciprocate the result. */
2282 if (n < 0)
2283 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2284 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2286 return result;
2289 /* Expand a call to the pow built-in mathematical function. Return 0 if
2290 a normal call should be emitted rather than expanding the function
2291 in-line. EXP is the expression that is a call to the builtin
2292 function; if convenient, the result should be placed in TARGET. */
2294 static rtx
2295 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2297 tree arglist = TREE_OPERAND (exp, 1);
2298 tree arg0, arg1;
2300 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2301 return 0;
2303 arg0 = TREE_VALUE (arglist);
2304 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2306 if (TREE_CODE (arg1) == REAL_CST
2307 && ! TREE_CONSTANT_OVERFLOW (arg1))
2309 REAL_VALUE_TYPE cint;
2310 REAL_VALUE_TYPE c;
2311 HOST_WIDE_INT n;
2313 c = TREE_REAL_CST (arg1);
2314 n = real_to_integer (&c);
2315 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2316 if (real_identical (&c, &cint))
2318 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2319 Otherwise, check the number of multiplications required.
2320 Note that pow never sets errno for an integer exponent. */
2321 if ((n >= -1 && n <= 2)
2322 || (flag_unsafe_math_optimizations
2323 && ! optimize_size
2324 && powi_cost (n) <= POWI_MAX_MULTS))
2326 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2327 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2328 op = force_reg (mode, op);
2329 return expand_powi (op, mode, n);
2334 if (! flag_unsafe_math_optimizations)
2335 return NULL_RTX;
2336 return expand_builtin_mathfn_2 (exp, target, subtarget);
2339 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2340 if we failed the caller should emit a normal call, otherwise
2341 try to get the result in TARGET, if convenient. */
2343 static rtx
2344 expand_builtin_strlen (tree arglist, rtx target,
2345 enum machine_mode target_mode)
2347 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2348 return 0;
2349 else
2351 rtx pat;
2352 tree len, src = TREE_VALUE (arglist);
2353 rtx result, src_reg, char_rtx, before_strlen;
2354 enum machine_mode insn_mode = target_mode, char_mode;
2355 enum insn_code icode = CODE_FOR_nothing;
2356 int align;
2358 /* If the length can be computed at compile-time, return it. */
2359 len = c_strlen (src, 0);
2360 if (len)
2361 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2363 /* If the length can be computed at compile-time and is constant
2364 integer, but there are side-effects in src, evaluate
2365 src for side-effects, then return len.
2366 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2367 can be optimized into: i++; x = 3; */
2368 len = c_strlen (src, 1);
2369 if (len && TREE_CODE (len) == INTEGER_CST)
2371 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2372 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2375 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2377 /* If SRC is not a pointer type, don't do this operation inline. */
2378 if (align == 0)
2379 return 0;
2381 /* Bail out if we can't compute strlen in the right mode. */
2382 while (insn_mode != VOIDmode)
2384 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2385 if (icode != CODE_FOR_nothing)
2386 break;
2388 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2390 if (insn_mode == VOIDmode)
2391 return 0;
2393 /* Make a place to write the result of the instruction. */
2394 result = target;
2395 if (! (result != 0
2396 && REG_P (result)
2397 && GET_MODE (result) == insn_mode
2398 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2399 result = gen_reg_rtx (insn_mode);
2401 /* Make a place to hold the source address. We will not expand
2402 the actual source until we are sure that the expansion will
2403 not fail -- there are trees that cannot be expanded twice. */
2404 src_reg = gen_reg_rtx (Pmode);
2406 /* Mark the beginning of the strlen sequence so we can emit the
2407 source operand later. */
2408 before_strlen = get_last_insn ();
2410 char_rtx = const0_rtx;
2411 char_mode = insn_data[(int) icode].operand[2].mode;
2412 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2413 char_mode))
2414 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2416 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2417 char_rtx, GEN_INT (align));
2418 if (! pat)
2419 return 0;
2420 emit_insn (pat);
2422 /* Now that we are assured of success, expand the source. */
2423 start_sequence ();
2424 pat = memory_address (BLKmode,
2425 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2426 if (pat != src_reg)
2427 emit_move_insn (src_reg, pat);
2428 pat = get_insns ();
2429 end_sequence ();
2431 if (before_strlen)
2432 emit_insn_after (pat, before_strlen);
2433 else
2434 emit_insn_before (pat, get_insns ());
2436 /* Return the value in the proper mode for this function. */
2437 if (GET_MODE (result) == target_mode)
2438 target = result;
2439 else if (target != 0)
2440 convert_move (target, result, 0);
2441 else
2442 target = convert_to_mode (target_mode, result, 0);
2444 return target;
2448 /* Expand a call to the strstr builtin. Return 0 if we failed the
2449 caller should emit a normal call, otherwise try to get the result
2450 in TARGET, if convenient (and in mode MODE if that's convenient). */
2452 static rtx
2453 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2455 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2456 return 0;
2457 else
2459 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2460 tree fn, tmp;
2461 const char *p1, *p2;
2463 p2 = c_getstr (s2);
2464 if (p2 == NULL)
2465 return 0;
2467 p1 = c_getstr (s1);
2468 if (p1 != NULL)
2470 const char *r = strstr (p1, p2);
2472 if (r == NULL)
2473 return const0_rtx;
2475 /* Return an offset into the constant string argument. */
2476 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2477 fold_convert (TREE_TYPE (s1),
2478 ssize_int (r - p1))));
2479 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2482 if (p2[0] == '\0')
2483 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2485 if (p2[1] != '\0')
2486 return 0;
2488 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2489 if (!fn)
2490 return 0;
2492 /* New argument list transforming strstr(s1, s2) to
2493 strchr(s1, s2[0]). */
2494 arglist = build_tree_list (NULL_TREE,
2495 build_int_cst (NULL_TREE, p2[0]));
2496 arglist = tree_cons (NULL_TREE, s1, arglist);
2497 return expand_expr (build_function_call_expr (fn, arglist),
2498 target, mode, EXPAND_NORMAL);
2502 /* Expand a call to the strchr builtin. Return 0 if we failed the
2503 caller should emit a normal call, otherwise try to get the result
2504 in TARGET, if convenient (and in mode MODE if that's convenient). */
2506 static rtx
2507 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2509 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2510 return 0;
2511 else
2513 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2514 const char *p1;
2516 if (TREE_CODE (s2) != INTEGER_CST)
2517 return 0;
2519 p1 = c_getstr (s1);
2520 if (p1 != NULL)
2522 char c;
2523 const char *r;
2524 tree tmp;
2526 if (target_char_cast (s2, &c))
2527 return 0;
2529 r = strchr (p1, c);
2531 if (r == NULL)
2532 return const0_rtx;
2534 /* Return an offset into the constant string argument. */
2535 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2536 fold_convert (TREE_TYPE (s1),
2537 ssize_int (r - p1))));
2538 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2541 /* FIXME: Should use here strchrM optab so that ports can optimize
2542 this. */
2543 return 0;
2547 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2548 caller should emit a normal call, otherwise try to get the result
2549 in TARGET, if convenient (and in mode MODE if that's convenient). */
2551 static rtx
2552 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2554 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2555 return 0;
2556 else
2558 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2559 tree fn, tmp;
2560 const char *p1;
2562 if (TREE_CODE (s2) != INTEGER_CST)
2563 return 0;
2565 p1 = c_getstr (s1);
2566 if (p1 != NULL)
2568 char c;
2569 const char *r;
2571 if (target_char_cast (s2, &c))
2572 return 0;
2574 r = strrchr (p1, c);
2576 if (r == NULL)
2577 return const0_rtx;
2579 /* Return an offset into the constant string argument. */
2580 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2581 fold_convert (TREE_TYPE (s1),
2582 ssize_int (r - p1))));
2583 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2586 if (! integer_zerop (s2))
2587 return 0;
2589 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2590 if (!fn)
2591 return 0;
2593 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2594 return expand_expr (build_function_call_expr (fn, arglist),
2595 target, mode, EXPAND_NORMAL);
2599 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2600 caller should emit a normal call, otherwise try to get the result
2601 in TARGET, if convenient (and in mode MODE if that's convenient). */
2603 static rtx
2604 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2606 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2607 return 0;
2608 else
2610 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2611 tree fn, tmp;
2612 const char *p1, *p2;
2614 p2 = c_getstr (s2);
2615 if (p2 == NULL)
2616 return 0;
2618 p1 = c_getstr (s1);
2619 if (p1 != NULL)
2621 const char *r = strpbrk (p1, p2);
2623 if (r == NULL)
2624 return const0_rtx;
2626 /* Return an offset into the constant string argument. */
2627 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2628 fold_convert (TREE_TYPE (s1),
2629 ssize_int (r - p1))));
2630 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2633 if (p2[0] == '\0')
2635 /* strpbrk(x, "") == NULL.
2636 Evaluate and ignore the arguments in case they had
2637 side-effects. */
2638 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2639 return const0_rtx;
2642 if (p2[1] != '\0')
2643 return 0; /* Really call strpbrk. */
2645 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2646 if (!fn)
2647 return 0;
2649 /* New argument list transforming strpbrk(s1, s2) to
2650 strchr(s1, s2[0]). */
2651 arglist = build_tree_list (NULL_TREE,
2652 build_int_cst (NULL_TREE, p2[0]));
2653 arglist = tree_cons (NULL_TREE, s1, arglist);
2654 return expand_expr (build_function_call_expr (fn, arglist),
2655 target, mode, EXPAND_NORMAL);
2659 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2660 bytes from constant string DATA + OFFSET and return it as target
2661 constant. */
2663 static rtx
2664 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2665 enum machine_mode mode)
2667 const char *str = (const char *) data;
2669 gcc_assert (offset >= 0
2670 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2671 <= strlen (str) + 1));
2673 return c_readstr (str + offset, mode);
2676 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2677 Return 0 if we failed, the caller should emit a normal call,
2678 otherwise try to get the result in TARGET, if convenient (and in
2679 mode MODE if that's convenient). */
2680 static rtx
2681 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2683 if (!validate_arglist (arglist,
2684 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2685 return 0;
2686 else
2688 tree dest = TREE_VALUE (arglist);
2689 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2690 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2691 const char *src_str;
2692 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2693 unsigned int dest_align
2694 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2695 rtx dest_mem, src_mem, dest_addr, len_rtx;
2697 /* If DEST is not a pointer type, call the normal function. */
2698 if (dest_align == 0)
2699 return 0;
2701 /* If the LEN parameter is zero, return DEST. */
2702 if (integer_zerop (len))
2704 /* Evaluate and ignore SRC in case it has side-effects. */
2705 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2706 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2709 /* If SRC and DEST are the same (and not volatile), return DEST. */
2710 if (operand_equal_p (src, dest, 0))
2712 /* Evaluate and ignore LEN in case it has side-effects. */
2713 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2714 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2717 /* If either SRC is not a pointer type, don't do this
2718 operation in-line. */
2719 if (src_align == 0)
2720 return 0;
2722 dest_mem = get_memory_rtx (dest);
2723 set_mem_align (dest_mem, dest_align);
2724 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2725 src_str = c_getstr (src);
2727 /* If SRC is a string constant and block move would be done
2728 by pieces, we can avoid loading the string from memory
2729 and only stored the computed constants. */
2730 if (src_str
2731 && GET_CODE (len_rtx) == CONST_INT
2732 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2733 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2734 (void *) src_str, dest_align))
2736 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2737 builtin_memcpy_read_str,
2738 (void *) src_str, dest_align, 0);
2739 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2740 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2741 return dest_mem;
2744 src_mem = get_memory_rtx (src);
2745 set_mem_align (src_mem, src_align);
2747 /* Copy word part most expediently. */
2748 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2749 BLOCK_OP_NORMAL);
2751 if (dest_addr == 0)
2753 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2754 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2756 return dest_addr;
2760 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2761 Return 0 if we failed the caller should emit a normal call,
2762 otherwise try to get the result in TARGET, if convenient (and in
2763 mode MODE if that's convenient). If ENDP is 0 return the
2764 destination pointer, if ENDP is 1 return the end pointer ala
2765 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2766 stpcpy. */
2768 static rtx
2769 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2770 int endp)
2772 if (!validate_arglist (arglist,
2773 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2774 return 0;
2775 /* If return value is ignored, transform mempcpy into memcpy. */
2776 else if (target == const0_rtx)
2778 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2780 if (!fn)
2781 return 0;
2783 return expand_expr (build_function_call_expr (fn, arglist),
2784 target, mode, EXPAND_NORMAL);
2786 else
2788 tree dest = TREE_VALUE (arglist);
2789 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2790 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2791 const char *src_str;
2792 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2793 unsigned int dest_align
2794 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2795 rtx dest_mem, src_mem, len_rtx;
2797 /* If DEST is not a pointer type, call the normal function. */
2798 if (dest_align == 0)
2799 return 0;
2801 /* If SRC and DEST are the same (and not volatile), do nothing. */
2802 if (operand_equal_p (src, dest, 0))
2804 tree expr;
2806 if (endp == 0)
2808 /* Evaluate and ignore LEN in case it has side-effects. */
2809 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2810 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2813 if (endp == 2)
2814 len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2815 integer_one_node));
2816 len = fold_convert (TREE_TYPE (dest), len);
2817 expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2818 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2821 /* If LEN is not constant, call the normal function. */
2822 if (! host_integerp (len, 1))
2823 return 0;
2825 /* If the LEN parameter is zero, return DEST. */
2826 if (tree_low_cst (len, 1) == 0)
2828 /* Evaluate and ignore SRC in case it has side-effects. */
2829 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2830 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2833 /* If either SRC is not a pointer type, don't do this
2834 operation in-line. */
2835 if (src_align == 0)
2836 return 0;
2838 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2839 src_str = c_getstr (src);
2841 /* If SRC is a string constant and block move would be done
2842 by pieces, we can avoid loading the string from memory
2843 and only stored the computed constants. */
2844 if (src_str
2845 && GET_CODE (len_rtx) == CONST_INT
2846 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2847 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2848 (void *) src_str, dest_align))
2850 dest_mem = get_memory_rtx (dest);
2851 set_mem_align (dest_mem, dest_align);
2852 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2853 builtin_memcpy_read_str,
2854 (void *) src_str, dest_align, endp);
2855 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2856 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2857 return dest_mem;
2860 if (GET_CODE (len_rtx) == CONST_INT
2861 && can_move_by_pieces (INTVAL (len_rtx),
2862 MIN (dest_align, src_align)))
2864 dest_mem = get_memory_rtx (dest);
2865 set_mem_align (dest_mem, dest_align);
2866 src_mem = get_memory_rtx (src);
2867 set_mem_align (src_mem, src_align);
2868 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2869 MIN (dest_align, src_align), endp);
2870 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2871 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2872 return dest_mem;
2875 return 0;
2879 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2880 if we failed the caller should emit a normal call. */
2882 static rtx
2883 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2885 if (!validate_arglist (arglist,
2886 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2887 return 0;
2888 else
2890 tree dest = TREE_VALUE (arglist);
2891 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2892 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2894 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2895 unsigned int dest_align
2896 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2898 /* If DEST is not a pointer type, call the normal function. */
2899 if (dest_align == 0)
2900 return 0;
2902 /* If the LEN parameter is zero, return DEST. */
2903 if (integer_zerop (len))
2905 /* Evaluate and ignore SRC in case it has side-effects. */
2906 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2907 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2910 /* If SRC and DEST are the same (and not volatile), return DEST. */
2911 if (operand_equal_p (src, dest, 0))
2913 /* Evaluate and ignore LEN in case it has side-effects. */
2914 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2915 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2918 /* If either SRC is not a pointer type, don't do this
2919 operation in-line. */
2920 if (src_align == 0)
2921 return 0;
2923 /* If src is categorized for a readonly section we can use
2924 normal memcpy. */
2925 if (readonly_data_expr (src))
2927 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2928 if (!fn)
2929 return 0;
2930 return expand_expr (build_function_call_expr (fn, arglist),
2931 target, mode, EXPAND_NORMAL);
2934 /* Otherwise, call the normal function. */
2935 return 0;
2939 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2940 if we failed the caller should emit a normal call. */
2942 static rtx
2943 expand_builtin_bcopy (tree arglist)
2945 tree src, dest, size, newarglist;
2947 if (!validate_arglist (arglist,
2948 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2949 return NULL_RTX;
2951 src = TREE_VALUE (arglist);
2952 dest = TREE_VALUE (TREE_CHAIN (arglist));
2953 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2955 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2956 memmove(ptr y, ptr x, size_t z). This is done this way
2957 so that if it isn't expanded inline, we fallback to
2958 calling bcopy instead of memmove. */
2960 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2961 newarglist = tree_cons (NULL_TREE, src, newarglist);
2962 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2964 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2967 #ifndef HAVE_movstr
2968 # define HAVE_movstr 0
2969 # define CODE_FOR_movstr CODE_FOR_nothing
2970 #endif
2972 /* Expand into a movstr instruction, if one is available. Return 0 if
2973 we failed, the caller should emit a normal call, otherwise try to
2974 get the result in TARGET, if convenient. If ENDP is 0 return the
2975 destination pointer, if ENDP is 1 return the end pointer ala
2976 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2977 stpcpy. */
2979 static rtx
2980 expand_movstr (tree dest, tree src, rtx target, int endp)
2982 rtx end;
2983 rtx dest_mem;
2984 rtx src_mem;
2985 rtx insn;
2986 const struct insn_data * data;
2988 if (!HAVE_movstr)
2989 return 0;
2991 dest_mem = get_memory_rtx (dest);
2992 src_mem = get_memory_rtx (src);
2993 if (!endp)
2995 target = force_reg (Pmode, XEXP (dest_mem, 0));
2996 dest_mem = replace_equiv_address (dest_mem, target);
2997 end = gen_reg_rtx (Pmode);
2999 else
3001 if (target == 0 || target == const0_rtx)
3003 end = gen_reg_rtx (Pmode);
3004 if (target == 0)
3005 target = end;
3007 else
3008 end = target;
3011 data = insn_data + CODE_FOR_movstr;
3013 if (data->operand[0].mode != VOIDmode)
3014 end = gen_lowpart (data->operand[0].mode, end);
3016 insn = data->genfun (end, dest_mem, src_mem);
3018 gcc_assert (insn);
3020 emit_insn (insn);
3022 /* movstr is supposed to set end to the address of the NUL
3023 terminator. If the caller requested a mempcpy-like return value,
3024 adjust it. */
3025 if (endp == 1 && target != const0_rtx)
3026 emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3027 end), 1));
3029 return target;
3032 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3033 if we failed the caller should emit a normal call, otherwise try to get
3034 the result in TARGET, if convenient (and in mode MODE if that's
3035 convenient). */
3037 static rtx
3038 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3040 tree fn, len, src, dst;
3042 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3043 return 0;
3045 src = TREE_VALUE (TREE_CHAIN (arglist));
3046 dst = TREE_VALUE (arglist);
3048 /* If SRC and DST are equal (and not volatile), return DST. */
3049 if (operand_equal_p (src, dst, 0))
3050 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3052 len = c_strlen (src, 1);
3053 if (len == 0 || TREE_SIDE_EFFECTS (len))
3054 return expand_movstr (TREE_VALUE (arglist),
3055 TREE_VALUE (TREE_CHAIN (arglist)),
3056 target, /*endp=*/0);
3058 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3059 if (!fn)
3060 return 0;
3062 len = size_binop (PLUS_EXPR, len, ssize_int (1));
3063 arglist = build_tree_list (NULL_TREE, len);
3064 arglist = tree_cons (NULL_TREE, src, arglist);
3065 arglist = tree_cons (NULL_TREE, dst, arglist);
3066 return expand_expr (build_function_call_expr (fn, arglist),
3067 target, mode, EXPAND_NORMAL);
3070 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3071 Return 0 if we failed the caller should emit a normal call,
3072 otherwise try to get the result in TARGET, if convenient (and in
3073 mode MODE if that's convenient). */
3075 static rtx
3076 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3078 /* If return value is ignored, transform stpcpy into strcpy. */
3079 if (target == const0_rtx)
3081 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3082 if (!fn)
3083 return 0;
3085 return expand_expr (build_function_call_expr (fn, arglist),
3086 target, mode, EXPAND_NORMAL);
3089 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3090 return 0;
3091 else
3093 tree dst, src, len, lenp1;
3094 tree narglist;
3095 rtx ret;
3097 /* Ensure we get an actual string whose length can be evaluated at
3098 compile-time, not an expression containing a string. This is
3099 because the latter will potentially produce pessimized code
3100 when used to produce the return value. */
3101 src = TREE_VALUE (TREE_CHAIN (arglist));
3102 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3103 return expand_movstr (TREE_VALUE (arglist),
3104 TREE_VALUE (TREE_CHAIN (arglist)),
3105 target, /*endp=*/2);
3107 dst = TREE_VALUE (arglist);
3108 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3109 narglist = build_tree_list (NULL_TREE, lenp1);
3110 narglist = tree_cons (NULL_TREE, src, narglist);
3111 narglist = tree_cons (NULL_TREE, dst, narglist);
3112 ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3114 if (ret)
3115 return ret;
3117 if (TREE_CODE (len) == INTEGER_CST)
3119 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3121 if (GET_CODE (len_rtx) == CONST_INT)
3123 ret = expand_builtin_strcpy (arglist, target, mode);
3125 if (ret)
3127 if (! target)
3129 if (mode != VOIDmode)
3130 target = gen_reg_rtx (mode);
3131 else
3132 target = gen_reg_rtx (GET_MODE (ret));
3134 if (GET_MODE (target) != GET_MODE (ret))
3135 ret = gen_lowpart (GET_MODE (target), ret);
3137 ret = emit_move_insn (target,
3138 plus_constant (ret,
3139 INTVAL (len_rtx)));
3140 gcc_assert (ret);
3142 return target;
3147 return expand_movstr (TREE_VALUE (arglist),
3148 TREE_VALUE (TREE_CHAIN (arglist)),
3149 target, /*endp=*/2);
3153 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3154 bytes from constant string DATA + OFFSET and return it as target
3155 constant. */
3157 static rtx
3158 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3159 enum machine_mode mode)
3161 const char *str = (const char *) data;
3163 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3164 return const0_rtx;
3166 return c_readstr (str + offset, mode);
3169 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3170 if we failed the caller should emit a normal call. */
3172 static rtx
3173 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3175 if (!validate_arglist (arglist,
3176 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3177 return 0;
3178 else
3180 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3181 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3182 tree fn;
3184 /* We must be passed a constant len parameter. */
3185 if (TREE_CODE (len) != INTEGER_CST)
3186 return 0;
3188 /* If the len parameter is zero, return the dst parameter. */
3189 if (integer_zerop (len))
3191 /* Evaluate and ignore the src argument in case it has
3192 side-effects. */
3193 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3194 VOIDmode, EXPAND_NORMAL);
3195 /* Return the dst parameter. */
3196 return expand_expr (TREE_VALUE (arglist), target, mode,
3197 EXPAND_NORMAL);
3200 /* Now, we must be passed a constant src ptr parameter. */
3201 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3202 return 0;
3204 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3206 /* We're required to pad with trailing zeros if the requested
3207 len is greater than strlen(s2)+1. In that case try to
3208 use store_by_pieces, if it fails, punt. */
3209 if (tree_int_cst_lt (slen, len))
3211 tree dest = TREE_VALUE (arglist);
3212 unsigned int dest_align
3213 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3214 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3215 rtx dest_mem;
3217 if (!p || dest_align == 0 || !host_integerp (len, 1)
3218 || !can_store_by_pieces (tree_low_cst (len, 1),
3219 builtin_strncpy_read_str,
3220 (void *) p, dest_align))
3221 return 0;
3223 dest_mem = get_memory_rtx (dest);
3224 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3225 builtin_strncpy_read_str,
3226 (void *) p, dest_align, 0);
3227 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3228 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3229 return dest_mem;
3232 /* OK transform into builtin memcpy. */
3233 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3234 if (!fn)
3235 return 0;
3236 return expand_expr (build_function_call_expr (fn, arglist),
3237 target, mode, EXPAND_NORMAL);
3241 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3242 bytes from constant string DATA + OFFSET and return it as target
3243 constant. */
3245 static rtx
3246 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3247 enum machine_mode mode)
3249 const char *c = (const char *) data;
3250 char *p = alloca (GET_MODE_SIZE (mode));
3252 memset (p, *c, GET_MODE_SIZE (mode));
3254 return c_readstr (p, mode);
3257 /* Callback routine for store_by_pieces. Return the RTL of a register
3258 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3259 char value given in the RTL register data. For example, if mode is
3260 4 bytes wide, return the RTL for 0x01010101*data. */
3262 static rtx
3263 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3264 enum machine_mode mode)
3266 rtx target, coeff;
3267 size_t size;
3268 char *p;
3270 size = GET_MODE_SIZE (mode);
3271 if (size == 1)
3272 return (rtx) data;
3274 p = alloca (size);
3275 memset (p, 1, size);
3276 coeff = c_readstr (p, mode);
3278 target = convert_to_mode (mode, (rtx) data, 1);
3279 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3280 return force_reg (mode, target);
3283 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3284 if we failed the caller should emit a normal call, otherwise try to get
3285 the result in TARGET, if convenient (and in mode MODE if that's
3286 convenient). */
3288 static rtx
3289 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3291 if (!validate_arglist (arglist,
3292 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3293 return 0;
3294 else
3296 tree dest = TREE_VALUE (arglist);
3297 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3298 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3299 char c;
3301 unsigned int dest_align
3302 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3303 rtx dest_mem, dest_addr, len_rtx;
3305 /* If DEST is not a pointer type, don't do this
3306 operation in-line. */
3307 if (dest_align == 0)
3308 return 0;
3310 /* If the LEN parameter is zero, return DEST. */
3311 if (integer_zerop (len))
3313 /* Evaluate and ignore VAL in case it has side-effects. */
3314 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3315 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3318 if (TREE_CODE (val) != INTEGER_CST)
3320 rtx val_rtx;
3322 if (!host_integerp (len, 1))
3323 return 0;
3325 if (optimize_size && tree_low_cst (len, 1) > 1)
3326 return 0;
3328 /* Assume that we can memset by pieces if we can store the
3329 * the coefficients by pieces (in the required modes).
3330 * We can't pass builtin_memset_gen_str as that emits RTL. */
3331 c = 1;
3332 if (!can_store_by_pieces (tree_low_cst (len, 1),
3333 builtin_memset_read_str,
3334 &c, dest_align))
3335 return 0;
3337 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3338 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3339 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3340 val_rtx);
3341 dest_mem = get_memory_rtx (dest);
3342 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3343 builtin_memset_gen_str,
3344 val_rtx, dest_align, 0);
3345 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3346 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3347 return dest_mem;
3350 if (target_char_cast (val, &c))
3351 return 0;
3353 if (c)
3355 if (!host_integerp (len, 1))
3356 return 0;
3357 if (!can_store_by_pieces (tree_low_cst (len, 1),
3358 builtin_memset_read_str, &c,
3359 dest_align))
3360 return 0;
3362 dest_mem = get_memory_rtx (dest);
3363 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3364 builtin_memset_read_str,
3365 &c, dest_align, 0);
3366 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3367 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3368 return dest_mem;
3371 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3373 dest_mem = get_memory_rtx (dest);
3374 set_mem_align (dest_mem, dest_align);
3375 dest_addr = clear_storage (dest_mem, len_rtx);
3377 if (dest_addr == 0)
3379 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3380 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3383 return dest_addr;
3387 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3388 if we failed the caller should emit a normal call. */
3390 static rtx
3391 expand_builtin_bzero (tree arglist)
3393 tree dest, size, newarglist;
3395 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3396 return NULL_RTX;
3398 dest = TREE_VALUE (arglist);
3399 size = TREE_VALUE (TREE_CHAIN (arglist));
3401 /* New argument list transforming bzero(ptr x, int y) to
3402 memset(ptr x, int 0, size_t y). This is done this way
3403 so that if it isn't expanded inline, we fallback to
3404 calling bzero instead of memset. */
3406 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3407 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3408 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3410 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3413 /* Expand expression EXP, which is a call to the memcmp built-in function.
3414 ARGLIST is the argument list for this call. Return 0 if we failed and the
3415 caller should emit a normal call, otherwise try to get the result in
3416 TARGET, if convenient (and in mode MODE, if that's convenient). */
3418 static rtx
3419 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3420 enum machine_mode mode)
3422 tree arg1, arg2, len;
3423 const char *p1, *p2;
3425 if (!validate_arglist (arglist,
3426 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3427 return 0;
3429 arg1 = TREE_VALUE (arglist);
3430 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3431 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3433 /* If the len parameter is zero, return zero. */
3434 if (integer_zerop (len))
3436 /* Evaluate and ignore arg1 and arg2 in case they have
3437 side-effects. */
3438 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3439 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3440 return const0_rtx;
3443 /* If both arguments are equal (and not volatile), return zero. */
3444 if (operand_equal_p (arg1, arg2, 0))
3446 /* Evaluate and ignore len in case it has side-effects. */
3447 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3448 return const0_rtx;
3451 p1 = c_getstr (arg1);
3452 p2 = c_getstr (arg2);
3454 /* If all arguments are constant, and the value of len is not greater
3455 than the lengths of arg1 and arg2, evaluate at compile-time. */
3456 if (host_integerp (len, 1) && p1 && p2
3457 && compare_tree_int (len, strlen (p1) + 1) <= 0
3458 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3460 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3462 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3465 /* If len parameter is one, return an expression corresponding to
3466 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3467 if (integer_onep (len))
3469 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3470 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3471 tree ind1 =
3472 fold (build1 (CONVERT_EXPR, integer_type_node,
3473 build1 (INDIRECT_REF, cst_uchar_node,
3474 fold_convert (cst_uchar_ptr_node, arg1))));
3475 tree ind2 =
3476 fold (build1 (CONVERT_EXPR, integer_type_node,
3477 build1 (INDIRECT_REF, cst_uchar_node,
3478 fold_convert (cst_uchar_ptr_node, arg2))));
3479 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3480 return expand_expr (result, target, mode, EXPAND_NORMAL);
3483 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3485 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3486 rtx result;
3487 rtx insn;
3489 int arg1_align
3490 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3491 int arg2_align
3492 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3493 enum machine_mode insn_mode;
3495 #ifdef HAVE_cmpmemsi
3496 if (HAVE_cmpmemsi)
3497 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3498 else
3499 #endif
3500 #ifdef HAVE_cmpstrsi
3501 if (HAVE_cmpstrsi)
3502 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3503 else
3504 #endif
3505 return 0;
3507 /* If we don't have POINTER_TYPE, call the function. */
3508 if (arg1_align == 0 || arg2_align == 0)
3509 return 0;
3511 /* Make a place to write the result of the instruction. */
3512 result = target;
3513 if (! (result != 0
3514 && REG_P (result) && GET_MODE (result) == insn_mode
3515 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3516 result = gen_reg_rtx (insn_mode);
3518 arg1_rtx = get_memory_rtx (arg1);
3519 arg2_rtx = get_memory_rtx (arg2);
3520 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3521 #ifdef HAVE_cmpmemsi
3522 if (HAVE_cmpmemsi)
3523 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3524 GEN_INT (MIN (arg1_align, arg2_align)));
3525 else
3526 #endif
3527 #ifdef HAVE_cmpstrsi
3528 if (HAVE_cmpstrsi)
3529 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3530 GEN_INT (MIN (arg1_align, arg2_align)));
3531 else
3532 #endif
3533 gcc_unreachable ();
3535 if (insn)
3536 emit_insn (insn);
3537 else
3538 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3539 TYPE_MODE (integer_type_node), 3,
3540 XEXP (arg1_rtx, 0), Pmode,
3541 XEXP (arg2_rtx, 0), Pmode,
3542 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3543 TYPE_UNSIGNED (sizetype)),
3544 TYPE_MODE (sizetype));
3546 /* Return the value in the proper mode for this function. */
3547 mode = TYPE_MODE (TREE_TYPE (exp));
3548 if (GET_MODE (result) == mode)
3549 return result;
3550 else if (target != 0)
3552 convert_move (target, result, 0);
3553 return target;
3555 else
3556 return convert_to_mode (mode, result, 0);
3558 #endif
3560 return 0;
3563 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3564 if we failed the caller should emit a normal call, otherwise try to get
3565 the result in TARGET, if convenient. */
3567 static rtx
3568 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3570 tree arglist = TREE_OPERAND (exp, 1);
3571 tree arg1, arg2;
3572 const char *p1, *p2;
3574 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3575 return 0;
3577 arg1 = TREE_VALUE (arglist);
3578 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3580 /* If both arguments are equal (and not volatile), return zero. */
3581 if (operand_equal_p (arg1, arg2, 0))
3582 return const0_rtx;
3584 p1 = c_getstr (arg1);
3585 p2 = c_getstr (arg2);
3587 if (p1 && p2)
3589 const int i = strcmp (p1, p2);
3590 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3593 /* If either arg is "", return an expression corresponding to
3594 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3595 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3597 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3598 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3599 tree ind1 =
3600 fold (build1 (CONVERT_EXPR, integer_type_node,
3601 build1 (INDIRECT_REF, cst_uchar_node,
3602 fold_convert (cst_uchar_ptr_node, arg1))));
3603 tree ind2 =
3604 fold (build1 (CONVERT_EXPR, integer_type_node,
3605 build1 (INDIRECT_REF, cst_uchar_node,
3606 fold_convert (cst_uchar_ptr_node, arg2))));
3607 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3608 return expand_expr (result, target, mode, EXPAND_NORMAL);
3611 #ifdef HAVE_cmpstrsi
3612 if (HAVE_cmpstrsi)
3614 tree len, len1, len2;
3615 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3616 rtx result, insn;
3617 tree fndecl;
3619 int arg1_align
3620 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3621 int arg2_align
3622 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3623 enum machine_mode insn_mode
3624 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3626 len1 = c_strlen (arg1, 1);
3627 len2 = c_strlen (arg2, 1);
3629 if (len1)
3630 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3631 if (len2)
3632 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3634 /* If we don't have a constant length for the first, use the length
3635 of the second, if we know it. We don't require a constant for
3636 this case; some cost analysis could be done if both are available
3637 but neither is constant. For now, assume they're equally cheap,
3638 unless one has side effects. If both strings have constant lengths,
3639 use the smaller. */
3641 if (!len1)
3642 len = len2;
3643 else if (!len2)
3644 len = len1;
3645 else if (TREE_SIDE_EFFECTS (len1))
3646 len = len2;
3647 else if (TREE_SIDE_EFFECTS (len2))
3648 len = len1;
3649 else if (TREE_CODE (len1) != INTEGER_CST)
3650 len = len2;
3651 else if (TREE_CODE (len2) != INTEGER_CST)
3652 len = len1;
3653 else if (tree_int_cst_lt (len1, len2))
3654 len = len1;
3655 else
3656 len = len2;
3658 /* If both arguments have side effects, we cannot optimize. */
3659 if (!len || TREE_SIDE_EFFECTS (len))
3660 return 0;
3662 /* If we don't have POINTER_TYPE, call the function. */
3663 if (arg1_align == 0 || arg2_align == 0)
3664 return 0;
3666 /* Make a place to write the result of the instruction. */
3667 result = target;
3668 if (! (result != 0
3669 && REG_P (result) && GET_MODE (result) == insn_mode
3670 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3671 result = gen_reg_rtx (insn_mode);
3673 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3674 arg1 = builtin_save_expr (arg1);
3675 arg2 = builtin_save_expr (arg2);
3677 arg1_rtx = get_memory_rtx (arg1);
3678 arg2_rtx = get_memory_rtx (arg2);
3679 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3680 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3681 GEN_INT (MIN (arg1_align, arg2_align)));
3682 if (insn)
3684 emit_insn (insn);
3686 /* Return the value in the proper mode for this function. */
3687 mode = TYPE_MODE (TREE_TYPE (exp));
3688 if (GET_MODE (result) == mode)
3689 return result;
3690 if (target == 0)
3691 return convert_to_mode (mode, result, 0);
3692 convert_move (target, result, 0);
3693 return target;
3696 /* Expand the library call ourselves using a stabilized argument
3697 list to avoid re-evaluating the function's arguments twice. */
3698 arglist = build_tree_list (NULL_TREE, arg2);
3699 arglist = tree_cons (NULL_TREE, arg1, arglist);
3700 fndecl = get_callee_fndecl (exp);
3701 exp = build_function_call_expr (fndecl, arglist);
3702 return expand_call (exp, target, target == const0_rtx);
3704 #endif
3705 return 0;
3708 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3709 if we failed the caller should emit a normal call, otherwise try to get
3710 the result in TARGET, if convenient. */
3712 static rtx
3713 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3715 tree arglist = TREE_OPERAND (exp, 1);
3716 tree arg1, arg2, arg3;
3717 const char *p1, *p2;
3719 if (!validate_arglist (arglist,
3720 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3721 return 0;
3723 arg1 = TREE_VALUE (arglist);
3724 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3725 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3727 /* If the len parameter is zero, return zero. */
3728 if (integer_zerop (arg3))
3730 /* Evaluate and ignore arg1 and arg2 in case they have
3731 side-effects. */
3732 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3733 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3734 return const0_rtx;
3737 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3738 if (operand_equal_p (arg1, arg2, 0))
3740 /* Evaluate and ignore arg3 in case it has side-effects. */
3741 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3742 return const0_rtx;
3745 p1 = c_getstr (arg1);
3746 p2 = c_getstr (arg2);
3748 /* If all arguments are constant, evaluate at compile-time. */
3749 if (host_integerp (arg3, 1) && p1 && p2)
3751 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3752 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3755 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3756 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3757 if (host_integerp (arg3, 1)
3758 && (tree_low_cst (arg3, 1) == 1
3759 || (tree_low_cst (arg3, 1) > 1
3760 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3762 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3763 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3764 tree ind1 =
3765 fold (build1 (CONVERT_EXPR, integer_type_node,
3766 build1 (INDIRECT_REF, cst_uchar_node,
3767 fold_convert (cst_uchar_ptr_node, arg1))));
3768 tree ind2 =
3769 fold (build1 (CONVERT_EXPR, integer_type_node,
3770 build1 (INDIRECT_REF, cst_uchar_node,
3771 fold_convert (cst_uchar_ptr_node, arg2))));
3772 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3773 return expand_expr (result, target, mode, EXPAND_NORMAL);
3776 /* If c_strlen can determine an expression for one of the string
3777 lengths, and it doesn't have side effects, then emit cmpstrsi
3778 using length MIN(strlen(string)+1, arg3). */
3779 #ifdef HAVE_cmpstrsi
3780 if (HAVE_cmpstrsi)
3782 tree len, len1, len2;
3783 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3784 rtx result, insn;
3785 tree fndecl;
3787 int arg1_align
3788 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3789 int arg2_align
3790 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3791 enum machine_mode insn_mode
3792 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3794 len1 = c_strlen (arg1, 1);
3795 len2 = c_strlen (arg2, 1);
3797 if (len1)
3798 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3799 if (len2)
3800 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3802 /* If we don't have a constant length for the first, use the length
3803 of the second, if we know it. We don't require a constant for
3804 this case; some cost analysis could be done if both are available
3805 but neither is constant. For now, assume they're equally cheap,
3806 unless one has side effects. If both strings have constant lengths,
3807 use the smaller. */
3809 if (!len1)
3810 len = len2;
3811 else if (!len2)
3812 len = len1;
3813 else if (TREE_SIDE_EFFECTS (len1))
3814 len = len2;
3815 else if (TREE_SIDE_EFFECTS (len2))
3816 len = len1;
3817 else if (TREE_CODE (len1) != INTEGER_CST)
3818 len = len2;
3819 else if (TREE_CODE (len2) != INTEGER_CST)
3820 len = len1;
3821 else if (tree_int_cst_lt (len1, len2))
3822 len = len1;
3823 else
3824 len = len2;
3826 /* If both arguments have side effects, we cannot optimize. */
3827 if (!len || TREE_SIDE_EFFECTS (len))
3828 return 0;
3830 /* The actual new length parameter is MIN(len,arg3). */
3831 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len,
3832 fold_convert (TREE_TYPE (len), arg3)));
3834 /* If we don't have POINTER_TYPE, call the function. */
3835 if (arg1_align == 0 || arg2_align == 0)
3836 return 0;
3838 /* Make a place to write the result of the instruction. */
3839 result = target;
3840 if (! (result != 0
3841 && REG_P (result) && GET_MODE (result) == insn_mode
3842 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3843 result = gen_reg_rtx (insn_mode);
3845 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3846 arg1 = builtin_save_expr (arg1);
3847 arg2 = builtin_save_expr (arg2);
3848 len = builtin_save_expr (len);
3850 arg1_rtx = get_memory_rtx (arg1);
3851 arg2_rtx = get_memory_rtx (arg2);
3852 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3853 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3854 GEN_INT (MIN (arg1_align, arg2_align)));
3855 if (insn)
3857 emit_insn (insn);
3859 /* Return the value in the proper mode for this function. */
3860 mode = TYPE_MODE (TREE_TYPE (exp));
3861 if (GET_MODE (result) == mode)
3862 return result;
3863 if (target == 0)
3864 return convert_to_mode (mode, result, 0);
3865 convert_move (target, result, 0);
3866 return target;
3869 /* Expand the library call ourselves using a stabilized argument
3870 list to avoid re-evaluating the function's arguments twice. */
3871 arglist = build_tree_list (NULL_TREE, len);
3872 arglist = tree_cons (NULL_TREE, arg2, arglist);
3873 arglist = tree_cons (NULL_TREE, arg1, arglist);
3874 fndecl = get_callee_fndecl (exp);
3875 exp = build_function_call_expr (fndecl, arglist);
3876 return expand_call (exp, target, target == const0_rtx);
3878 #endif
3879 return 0;
3882 /* Expand expression EXP, which is a call to the strcat builtin.
3883 Return 0 if we failed the caller should emit a normal call,
3884 otherwise try to get the result in TARGET, if convenient. */
3886 static rtx
3887 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3889 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3890 return 0;
3891 else
3893 tree dst = TREE_VALUE (arglist),
3894 src = TREE_VALUE (TREE_CHAIN (arglist));
3895 const char *p = c_getstr (src);
3897 if (p)
3899 /* If the string length is zero, return the dst parameter. */
3900 if (*p == '\0')
3901 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3902 else if (!optimize_size)
3904 /* Otherwise if !optimize_size, see if we can store by
3905 pieces into (dst + strlen(dst)). */
3906 tree newdst, arglist,
3907 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3909 /* This is the length argument. */
3910 arglist = build_tree_list (NULL_TREE,
3911 fold (size_binop (PLUS_EXPR,
3912 c_strlen (src, 0),
3913 ssize_int (1))));
3914 /* Prepend src argument. */
3915 arglist = tree_cons (NULL_TREE, src, arglist);
3917 /* We're going to use dst more than once. */
3918 dst = builtin_save_expr (dst);
3920 /* Create strlen (dst). */
3921 newdst =
3922 fold (build_function_call_expr (strlen_fn,
3923 build_tree_list (NULL_TREE,
3924 dst)));
3925 /* Create (dst + strlen (dst)). */
3926 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3928 /* Prepend the new dst argument. */
3929 arglist = tree_cons (NULL_TREE, newdst, arglist);
3931 /* We don't want to get turned into a memcpy if the
3932 target is const0_rtx, i.e. when the return value
3933 isn't used. That would produce pessimized code so
3934 pass in a target of zero, it should never actually be
3935 used. If this was successful return the original
3936 dst, not the result of mempcpy. */
3937 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3938 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3939 else
3940 return 0;
3944 return 0;
3948 /* Expand expression EXP, which is a call to the strncat builtin.
3949 Return 0 if we failed the caller should emit a normal call,
3950 otherwise try to get the result in TARGET, if convenient. */
3952 static rtx
3953 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3955 if (!validate_arglist (arglist,
3956 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3957 return 0;
3958 else
3960 tree dst = TREE_VALUE (arglist),
3961 src = TREE_VALUE (TREE_CHAIN (arglist)),
3962 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3963 const char *p = c_getstr (src);
3965 /* If the requested length is zero, or the src parameter string
3966 length is zero, return the dst parameter. */
3967 if (integer_zerop (len) || (p && *p == '\0'))
3969 /* Evaluate and ignore the src and len parameters in case
3970 they have side-effects. */
3971 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3972 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3973 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3976 /* If the requested len is greater than or equal to the string
3977 length, call strcat. */
3978 if (TREE_CODE (len) == INTEGER_CST && p
3979 && compare_tree_int (len, strlen (p)) >= 0)
3981 tree newarglist
3982 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3983 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3985 /* If the replacement _DECL isn't initialized, don't do the
3986 transformation. */
3987 if (!fn)
3988 return 0;
3990 return expand_expr (build_function_call_expr (fn, newarglist),
3991 target, mode, EXPAND_NORMAL);
3993 return 0;
3997 /* Expand expression EXP, which is a call to the strspn builtin.
3998 Return 0 if we failed the caller should emit a normal call,
3999 otherwise try to get the result in TARGET, if convenient. */
4001 static rtx
4002 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4004 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4005 return 0;
4006 else
4008 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4009 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4011 /* If both arguments are constants, evaluate at compile-time. */
4012 if (p1 && p2)
4014 const size_t r = strspn (p1, p2);
4015 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4018 /* If either argument is "", return 0. */
4019 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4021 /* Evaluate and ignore both arguments in case either one has
4022 side-effects. */
4023 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4024 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4025 return const0_rtx;
4027 return 0;
4031 /* Expand expression EXP, which is a call to the strcspn builtin.
4032 Return 0 if we failed the caller should emit a normal call,
4033 otherwise try to get the result in TARGET, if convenient. */
4035 static rtx
4036 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4038 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4039 return 0;
4040 else
4042 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4043 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4045 /* If both arguments are constants, evaluate at compile-time. */
4046 if (p1 && p2)
4048 const size_t r = strcspn (p1, p2);
4049 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4052 /* If the first argument is "", return 0. */
4053 if (p1 && *p1 == '\0')
4055 /* Evaluate and ignore argument s2 in case it has
4056 side-effects. */
4057 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4058 return const0_rtx;
4061 /* If the second argument is "", return __builtin_strlen(s1). */
4062 if (p2 && *p2 == '\0')
4064 tree newarglist = build_tree_list (NULL_TREE, s1),
4065 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4067 /* If the replacement _DECL isn't initialized, don't do the
4068 transformation. */
4069 if (!fn)
4070 return 0;
4072 return expand_expr (build_function_call_expr (fn, newarglist),
4073 target, mode, EXPAND_NORMAL);
4075 return 0;
4079 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4080 if that's convenient. */
4083 expand_builtin_saveregs (void)
4085 rtx val, seq;
4087 /* Don't do __builtin_saveregs more than once in a function.
4088 Save the result of the first call and reuse it. */
4089 if (saveregs_value != 0)
4090 return saveregs_value;
4092 /* When this function is called, it means that registers must be
4093 saved on entry to this function. So we migrate the call to the
4094 first insn of this function. */
4096 start_sequence ();
4098 /* Do whatever the machine needs done in this case. */
4099 val = targetm.calls.expand_builtin_saveregs ();
4101 seq = get_insns ();
4102 end_sequence ();
4104 saveregs_value = val;
4106 /* Put the insns after the NOTE that starts the function. If this
4107 is inside a start_sequence, make the outer-level insn chain current, so
4108 the code is placed at the start of the function. */
4109 push_topmost_sequence ();
4110 emit_insn_after (seq, entry_of_function ());
4111 pop_topmost_sequence ();
4113 return val;
4116 /* __builtin_args_info (N) returns word N of the arg space info
4117 for the current function. The number and meanings of words
4118 is controlled by the definition of CUMULATIVE_ARGS. */
4120 static rtx
4121 expand_builtin_args_info (tree arglist)
4123 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4124 int *word_ptr = (int *) &current_function_args_info;
4126 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4128 if (arglist != 0)
4130 if (!host_integerp (TREE_VALUE (arglist), 0))
4131 error ("argument of `__builtin_args_info' must be constant");
4132 else
4134 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4136 if (wordnum < 0 || wordnum >= nwords)
4137 error ("argument of `__builtin_args_info' out of range");
4138 else
4139 return GEN_INT (word_ptr[wordnum]);
4142 else
4143 error ("missing argument in `__builtin_args_info'");
4145 return const0_rtx;
4148 /* Expand ARGLIST, from a call to __builtin_next_arg. */
4150 static rtx
4151 expand_builtin_next_arg (tree arglist)
4153 tree fntype = TREE_TYPE (current_function_decl);
4155 if (TYPE_ARG_TYPES (fntype) == 0
4156 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4157 == void_type_node))
4159 error ("`va_start' used in function with fixed args");
4160 return const0_rtx;
4163 if (arglist)
4165 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4166 tree arg = TREE_VALUE (arglist);
4168 /* Strip off all nops for the sake of the comparison. This
4169 is not quite the same as STRIP_NOPS. It does more.
4170 We must also strip off INDIRECT_EXPR for C++ reference
4171 parameters. */
4172 while (TREE_CODE (arg) == NOP_EXPR
4173 || TREE_CODE (arg) == CONVERT_EXPR
4174 || TREE_CODE (arg) == NON_LVALUE_EXPR
4175 || TREE_CODE (arg) == INDIRECT_REF)
4176 arg = TREE_OPERAND (arg, 0);
4177 if (arg != last_parm)
4178 warning ("second parameter of `va_start' not last named argument");
4180 else
4181 /* Evidently an out of date version of <stdarg.h>; can't validate
4182 va_start's second argument, but can still work as intended. */
4183 warning ("`__builtin_next_arg' called without an argument");
4185 return expand_binop (Pmode, add_optab,
4186 current_function_internal_arg_pointer,
4187 current_function_arg_offset_rtx,
4188 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4191 /* Make it easier for the backends by protecting the valist argument
4192 from multiple evaluations. */
4194 static tree
4195 stabilize_va_list (tree valist, int needs_lvalue)
4197 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4199 if (TREE_SIDE_EFFECTS (valist))
4200 valist = save_expr (valist);
4202 /* For this case, the backends will be expecting a pointer to
4203 TREE_TYPE (va_list_type_node), but it's possible we've
4204 actually been given an array (an actual va_list_type_node).
4205 So fix it. */
4206 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4208 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4209 valist = build_fold_addr_expr_with_type (valist, p1);
4212 else
4214 tree pt;
4216 if (! needs_lvalue)
4218 if (! TREE_SIDE_EFFECTS (valist))
4219 return valist;
4221 pt = build_pointer_type (va_list_type_node);
4222 valist = fold (build1 (ADDR_EXPR, pt, valist));
4223 TREE_SIDE_EFFECTS (valist) = 1;
4226 if (TREE_SIDE_EFFECTS (valist))
4227 valist = save_expr (valist);
4228 valist = build_fold_indirect_ref (valist);
4231 return valist;
4234 /* The "standard" definition of va_list is void*. */
4236 tree
4237 std_build_builtin_va_list (void)
4239 return ptr_type_node;
4242 /* The "standard" implementation of va_start: just assign `nextarg' to
4243 the variable. */
4245 void
4246 std_expand_builtin_va_start (tree valist, rtx nextarg)
4248 tree t;
4250 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4251 make_tree (ptr_type_node, nextarg));
4252 TREE_SIDE_EFFECTS (t) = 1;
4254 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4257 /* Expand ARGLIST, from a call to __builtin_va_start. */
4259 static rtx
4260 expand_builtin_va_start (tree arglist)
4262 rtx nextarg;
4263 tree chain, valist;
4265 chain = TREE_CHAIN (arglist);
4267 if (TREE_CHAIN (chain))
4268 error ("too many arguments to function `va_start'");
4270 nextarg = expand_builtin_next_arg (chain);
4271 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4273 #ifdef EXPAND_BUILTIN_VA_START
4274 EXPAND_BUILTIN_VA_START (valist, nextarg);
4275 #else
4276 std_expand_builtin_va_start (valist, nextarg);
4277 #endif
4279 return const0_rtx;
4282 /* The "standard" implementation of va_arg: read the value from the
4283 current (padded) address and increment by the (padded) size. */
4285 tree
4286 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4288 tree addr, t, type_size, rounded_size, valist_tmp;
4289 unsigned HOST_WIDE_INT align, boundary;
4290 bool indirect;
4292 #ifdef ARGS_GROW_DOWNWARD
4293 /* All of the alignment and movement below is for args-grow-up machines.
4294 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4295 implement their own specialized gimplify_va_arg_expr routines. */
4296 gcc_unreachable ();
4297 #endif
4299 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4300 if (indirect)
4301 type = build_pointer_type (type);
4303 align = PARM_BOUNDARY / BITS_PER_UNIT;
4304 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4306 /* Hoist the valist value into a temporary for the moment. */
4307 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4309 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4310 requires greater alignment, we must perform dynamic alignment. */
4311 if (boundary > align)
4313 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4314 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4315 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4316 gimplify_and_add (t, pre_p);
4318 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4319 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4320 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4321 gimplify_and_add (t, pre_p);
4324 /* Compute the rounded size of the type. */
4325 type_size = size_in_bytes (type);
4326 rounded_size = round_up (type_size, align);
4328 /* Reduce rounded_size so it's sharable with the postqueue. */
4329 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4331 /* Get AP. */
4332 addr = valist_tmp;
4333 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4335 /* Small args are padded downward. */
4336 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4337 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4338 size_binop (MINUS_EXPR, rounded_size, type_size)));
4339 t = fold_convert (TREE_TYPE (addr), t);
4340 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4343 /* Compute new value for AP. */
4344 t = fold_convert (TREE_TYPE (valist), rounded_size);
4345 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4346 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4347 gimplify_and_add (t, pre_p);
4349 addr = fold_convert (build_pointer_type (type), addr);
4351 if (indirect)
4352 addr = build_fold_indirect_ref (addr);
4354 return build_fold_indirect_ref (addr);
4357 /* Return a dummy expression of type TYPE in order to keep going after an
4358 error. */
4360 static tree
4361 dummy_object (tree type)
4363 tree t = convert (build_pointer_type (type), null_pointer_node);
4364 return build1 (INDIRECT_REF, type, t);
4367 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4368 builtin function, but a very special sort of operator. */
4370 enum gimplify_status
4371 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4373 tree promoted_type, want_va_type, have_va_type;
4374 tree valist = TREE_OPERAND (*expr_p, 0);
4375 tree type = TREE_TYPE (*expr_p);
4376 tree t;
4378 /* Verify that valist is of the proper type. */
4379 want_va_type = va_list_type_node;
4380 have_va_type = TREE_TYPE (valist);
4382 if (have_va_type == error_mark_node)
4383 return GS_ERROR;
4385 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4387 /* If va_list is an array type, the argument may have decayed
4388 to a pointer type, e.g. by being passed to another function.
4389 In that case, unwrap both types so that we can compare the
4390 underlying records. */
4391 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4392 || TREE_CODE (have_va_type) == POINTER_TYPE)
4394 want_va_type = TREE_TYPE (want_va_type);
4395 have_va_type = TREE_TYPE (have_va_type);
4399 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4401 error ("first argument to `va_arg' not of type `va_list'");
4402 return GS_ERROR;
4405 /* Generate a diagnostic for requesting data of a type that cannot
4406 be passed through `...' due to type promotion at the call site. */
4407 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4408 != type)
4410 static bool gave_help;
4412 /* Unfortunately, this is merely undefined, rather than a constraint
4413 violation, so we cannot make this an error. If this call is never
4414 executed, the program is still strictly conforming. */
4415 warning ("`%T' is promoted to `%T' when passed through `...'",
4416 type, promoted_type);
4417 if (! gave_help)
4419 gave_help = true;
4420 warning ("(so you should pass `%T' not `%T' to `va_arg')",
4421 promoted_type, type);
4424 /* We can, however, treat "undefined" any way we please.
4425 Call abort to encourage the user to fix the program. */
4426 inform ("if this code is reached, the program will abort");
4427 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4428 NULL);
4429 append_to_statement_list (t, pre_p);
4431 /* This is dead code, but go ahead and finish so that the
4432 mode of the result comes out right. */
4433 *expr_p = dummy_object (type);
4434 return GS_ALL_DONE;
4436 else
4438 /* Make it easier for the backends by protecting the valist argument
4439 from multiple evaluations. */
4440 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4442 /* For this case, the backends will be expecting a pointer to
4443 TREE_TYPE (va_list_type_node), but it's possible we've
4444 actually been given an array (an actual va_list_type_node).
4445 So fix it. */
4446 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4448 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4449 valist = build_fold_addr_expr_with_type (valist, p1);
4451 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4453 else
4454 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4456 if (!targetm.gimplify_va_arg_expr)
4457 /* Once most targets are converted this should abort. */
4458 return GS_ALL_DONE;
4460 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4461 return GS_OK;
4465 /* Expand ARGLIST, from a call to __builtin_va_end. */
4467 static rtx
4468 expand_builtin_va_end (tree arglist)
4470 tree valist = TREE_VALUE (arglist);
4472 /* Evaluate for side effects, if needed. I hate macros that don't
4473 do that. */
4474 if (TREE_SIDE_EFFECTS (valist))
4475 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4477 return const0_rtx;
4480 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4481 builtin rather than just as an assignment in stdarg.h because of the
4482 nastiness of array-type va_list types. */
4484 static rtx
4485 expand_builtin_va_copy (tree arglist)
4487 tree dst, src, t;
4489 dst = TREE_VALUE (arglist);
4490 src = TREE_VALUE (TREE_CHAIN (arglist));
4492 dst = stabilize_va_list (dst, 1);
4493 src = stabilize_va_list (src, 0);
4495 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4497 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4498 TREE_SIDE_EFFECTS (t) = 1;
4499 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4501 else
4503 rtx dstb, srcb, size;
4505 /* Evaluate to pointers. */
4506 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4507 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4508 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4509 VOIDmode, EXPAND_NORMAL);
4511 dstb = convert_memory_address (Pmode, dstb);
4512 srcb = convert_memory_address (Pmode, srcb);
4514 /* "Dereference" to BLKmode memories. */
4515 dstb = gen_rtx_MEM (BLKmode, dstb);
4516 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4517 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4518 srcb = gen_rtx_MEM (BLKmode, srcb);
4519 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4520 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4522 /* Copy. */
4523 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4526 return const0_rtx;
4529 /* Expand a call to one of the builtin functions __builtin_frame_address or
4530 __builtin_return_address. */
4532 static rtx
4533 expand_builtin_frame_address (tree fndecl, tree arglist)
4535 /* The argument must be a nonnegative integer constant.
4536 It counts the number of frames to scan up the stack.
4537 The value is the return address saved in that frame. */
4538 if (arglist == 0)
4539 /* Warning about missing arg was already issued. */
4540 return const0_rtx;
4541 else if (! host_integerp (TREE_VALUE (arglist), 1))
4543 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4544 error ("invalid arg to `__builtin_frame_address'");
4545 else
4546 error ("invalid arg to `__builtin_return_address'");
4547 return const0_rtx;
4549 else
4551 rtx tem
4552 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4553 tree_low_cst (TREE_VALUE (arglist), 1),
4554 hard_frame_pointer_rtx);
4556 /* Some ports cannot access arbitrary stack frames. */
4557 if (tem == NULL)
4559 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4560 warning ("unsupported arg to `__builtin_frame_address'");
4561 else
4562 warning ("unsupported arg to `__builtin_return_address'");
4563 return const0_rtx;
4566 /* For __builtin_frame_address, return what we've got. */
4567 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4568 return tem;
4570 if (!REG_P (tem)
4571 && ! CONSTANT_P (tem))
4572 tem = copy_to_mode_reg (Pmode, tem);
4573 return tem;
4577 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4578 we failed and the caller should emit a normal call, otherwise try to get
4579 the result in TARGET, if convenient. */
4581 static rtx
4582 expand_builtin_alloca (tree arglist, rtx target)
4584 rtx op0;
4585 rtx result;
4587 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4588 should always expand to function calls. These can be intercepted
4589 in libmudflap. */
4590 if (flag_mudflap)
4591 return 0;
4593 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4594 return 0;
4596 /* Compute the argument. */
4597 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4599 /* Allocate the desired space. */
4600 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4601 result = convert_memory_address (ptr_mode, result);
4603 return result;
4606 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4607 Return 0 if a normal call should be emitted rather than expanding the
4608 function in-line. If convenient, the result should be placed in TARGET.
4609 SUBTARGET may be used as the target for computing one of EXP's operands. */
4611 static rtx
4612 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4613 rtx subtarget, optab op_optab)
4615 rtx op0;
4616 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4617 return 0;
4619 /* Compute the argument. */
4620 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4621 /* Compute op, into TARGET if possible.
4622 Set TARGET to wherever the result comes back. */
4623 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4624 op_optab, op0, target, 1);
4625 gcc_assert (target);
4627 return convert_to_mode (target_mode, target, 0);
4630 /* If the string passed to fputs is a constant and is one character
4631 long, we attempt to transform this call into __builtin_fputc(). */
4633 static rtx
4634 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4636 tree len, fn;
4637 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4638 : implicit_built_in_decls[BUILT_IN_FPUTC];
4639 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4640 : implicit_built_in_decls[BUILT_IN_FWRITE];
4642 /* If the return value is used, or the replacement _DECL isn't
4643 initialized, don't do the transformation. */
4644 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4645 return 0;
4647 /* Verify the arguments in the original call. */
4648 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4649 return 0;
4651 /* Get the length of the string passed to fputs. If the length
4652 can't be determined, punt. */
4653 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4654 || TREE_CODE (len) != INTEGER_CST)
4655 return 0;
4657 switch (compare_tree_int (len, 1))
4659 case -1: /* length is 0, delete the call entirely . */
4661 /* Evaluate and ignore the argument in case it has
4662 side-effects. */
4663 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4664 VOIDmode, EXPAND_NORMAL);
4665 return const0_rtx;
4667 case 0: /* length is 1, call fputc. */
4669 const char *p = c_getstr (TREE_VALUE (arglist));
4671 if (p != NULL)
4673 /* New argument list transforming fputs(string, stream) to
4674 fputc(string[0], stream). */
4675 arglist = build_tree_list (NULL_TREE,
4676 TREE_VALUE (TREE_CHAIN (arglist)));
4677 arglist = tree_cons (NULL_TREE,
4678 build_int_cst (NULL_TREE, p[0]),
4679 arglist);
4680 fn = fn_fputc;
4681 break;
4684 /* Fall through. */
4685 case 1: /* length is greater than 1, call fwrite. */
4687 tree string_arg;
4689 /* If optimizing for size keep fputs. */
4690 if (optimize_size)
4691 return 0;
4692 string_arg = TREE_VALUE (arglist);
4693 /* New argument list transforming fputs(string, stream) to
4694 fwrite(string, 1, len, stream). */
4695 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4696 arglist = tree_cons (NULL_TREE, len, arglist);
4697 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4698 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4699 fn = fn_fwrite;
4700 break;
4702 default:
4703 gcc_unreachable ();
4706 return expand_expr (build_function_call_expr (fn, arglist),
4707 const0_rtx, VOIDmode, EXPAND_NORMAL);
4710 /* Expand a call to __builtin_expect. We return our argument and emit a
4711 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4712 a non-jump context. */
4714 static rtx
4715 expand_builtin_expect (tree arglist, rtx target)
4717 tree exp, c;
4718 rtx note, rtx_c;
4720 if (arglist == NULL_TREE
4721 || TREE_CHAIN (arglist) == NULL_TREE)
4722 return const0_rtx;
4723 exp = TREE_VALUE (arglist);
4724 c = TREE_VALUE (TREE_CHAIN (arglist));
4726 if (TREE_CODE (c) != INTEGER_CST)
4728 error ("second arg to `__builtin_expect' must be a constant");
4729 c = integer_zero_node;
4732 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4734 /* Don't bother with expected value notes for integral constants. */
4735 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4737 /* We do need to force this into a register so that we can be
4738 moderately sure to be able to correctly interpret the branch
4739 condition later. */
4740 target = force_reg (GET_MODE (target), target);
4742 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4744 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4745 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4748 return target;
4751 /* Like expand_builtin_expect, except do this in a jump context. This is
4752 called from do_jump if the conditional is a __builtin_expect. Return either
4753 a list of insns to emit the jump or NULL if we cannot optimize
4754 __builtin_expect. We need to optimize this at jump time so that machines
4755 like the PowerPC don't turn the test into a SCC operation, and then jump
4756 based on the test being 0/1. */
4759 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4761 tree arglist = TREE_OPERAND (exp, 1);
4762 tree arg0 = TREE_VALUE (arglist);
4763 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4764 rtx ret = NULL_RTX;
4766 /* Only handle __builtin_expect (test, 0) and
4767 __builtin_expect (test, 1). */
4768 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4769 && (integer_zerop (arg1) || integer_onep (arg1)))
4771 rtx insn, drop_through_label, temp;
4773 /* Expand the jump insns. */
4774 start_sequence ();
4775 do_jump (arg0, if_false_label, if_true_label);
4776 ret = get_insns ();
4778 drop_through_label = get_last_insn ();
4779 if (drop_through_label && NOTE_P (drop_through_label))
4780 drop_through_label = prev_nonnote_insn (drop_through_label);
4781 if (drop_through_label && !LABEL_P (drop_through_label))
4782 drop_through_label = NULL_RTX;
4783 end_sequence ();
4785 if (! if_true_label)
4786 if_true_label = drop_through_label;
4787 if (! if_false_label)
4788 if_false_label = drop_through_label;
4790 /* Go through and add the expect's to each of the conditional jumps. */
4791 insn = ret;
4792 while (insn != NULL_RTX)
4794 rtx next = NEXT_INSN (insn);
4796 if (JUMP_P (insn) && any_condjump_p (insn))
4798 rtx ifelse = SET_SRC (pc_set (insn));
4799 rtx then_dest = XEXP (ifelse, 1);
4800 rtx else_dest = XEXP (ifelse, 2);
4801 int taken = -1;
4803 /* First check if we recognize any of the labels. */
4804 if (GET_CODE (then_dest) == LABEL_REF
4805 && XEXP (then_dest, 0) == if_true_label)
4806 taken = 1;
4807 else if (GET_CODE (then_dest) == LABEL_REF
4808 && XEXP (then_dest, 0) == if_false_label)
4809 taken = 0;
4810 else if (GET_CODE (else_dest) == LABEL_REF
4811 && XEXP (else_dest, 0) == if_false_label)
4812 taken = 1;
4813 else if (GET_CODE (else_dest) == LABEL_REF
4814 && XEXP (else_dest, 0) == if_true_label)
4815 taken = 0;
4816 /* Otherwise check where we drop through. */
4817 else if (else_dest == pc_rtx)
4819 if (next && NOTE_P (next))
4820 next = next_nonnote_insn (next);
4822 if (next && JUMP_P (next)
4823 && any_uncondjump_p (next))
4824 temp = XEXP (SET_SRC (pc_set (next)), 0);
4825 else
4826 temp = next;
4828 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4829 else that can't possibly match either target label. */
4830 if (temp == if_false_label)
4831 taken = 1;
4832 else if (temp == if_true_label)
4833 taken = 0;
4835 else if (then_dest == pc_rtx)
4837 if (next && NOTE_P (next))
4838 next = next_nonnote_insn (next);
4840 if (next && JUMP_P (next)
4841 && any_uncondjump_p (next))
4842 temp = XEXP (SET_SRC (pc_set (next)), 0);
4843 else
4844 temp = next;
4846 if (temp == if_false_label)
4847 taken = 0;
4848 else if (temp == if_true_label)
4849 taken = 1;
4852 if (taken != -1)
4854 /* If the test is expected to fail, reverse the
4855 probabilities. */
4856 if (integer_zerop (arg1))
4857 taken = 1 - taken;
4858 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4862 insn = next;
4866 return ret;
4869 void
4870 expand_builtin_trap (void)
4872 #ifdef HAVE_trap
4873 if (HAVE_trap)
4874 emit_insn (gen_trap ());
4875 else
4876 #endif
4877 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4878 emit_barrier ();
4881 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4882 Return 0 if a normal call should be emitted rather than expanding
4883 the function inline. If convenient, the result should be placed
4884 in TARGET. SUBTARGET may be used as the target for computing
4885 the operand. */
4887 static rtx
4888 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4890 enum machine_mode mode;
4891 tree arg;
4892 rtx op0;
4894 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4895 return 0;
4897 arg = TREE_VALUE (arglist);
4898 mode = TYPE_MODE (TREE_TYPE (arg));
4899 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4900 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4903 /* Create a new constant string literal and return a char* pointer to it.
4904 The STRING_CST value is the LEN characters at STR. */
4905 static tree
4906 build_string_literal (int len, const char *str)
4908 tree t, elem, index, type;
4910 t = build_string (len, str);
4911 elem = build_type_variant (char_type_node, 1, 0);
4912 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4913 type = build_array_type (elem, index);
4914 TREE_TYPE (t) = type;
4915 TREE_CONSTANT (t) = 1;
4916 TREE_INVARIANT (t) = 1;
4917 TREE_READONLY (t) = 1;
4918 TREE_STATIC (t) = 1;
4920 type = build_pointer_type (type);
4921 t = build1 (ADDR_EXPR, type, t);
4923 type = build_pointer_type (elem);
4924 t = build1 (NOP_EXPR, type, t);
4925 return t;
4928 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4929 Return 0 if a normal call should be emitted rather than transforming
4930 the function inline. If convenient, the result should be placed in
4931 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4932 call. */
4933 static rtx
4934 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4935 bool unlocked)
4937 tree fn_putchar = unlocked
4938 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4939 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4940 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4941 : implicit_built_in_decls[BUILT_IN_PUTS];
4942 const char *fmt_str;
4943 tree fn, fmt, arg;
4945 /* If the return value is used, don't do the transformation. */
4946 if (target != const0_rtx)
4947 return 0;
4949 /* Verify the required arguments in the original call. */
4950 if (! arglist)
4951 return 0;
4952 fmt = TREE_VALUE (arglist);
4953 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4954 return 0;
4955 arglist = TREE_CHAIN (arglist);
4957 /* Check whether the format is a literal string constant. */
4958 fmt_str = c_getstr (fmt);
4959 if (fmt_str == NULL)
4960 return 0;
4962 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4963 if (strcmp (fmt_str, "%s\n") == 0)
4965 if (! arglist
4966 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4967 || TREE_CHAIN (arglist))
4968 return 0;
4969 fn = fn_puts;
4971 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4972 else if (strcmp (fmt_str, "%c") == 0)
4974 if (! arglist
4975 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4976 || TREE_CHAIN (arglist))
4977 return 0;
4978 fn = fn_putchar;
4980 else
4982 /* We can't handle anything else with % args or %% ... yet. */
4983 if (strchr (fmt_str, '%'))
4984 return 0;
4986 if (arglist)
4987 return 0;
4989 /* If the format specifier was "", printf does nothing. */
4990 if (fmt_str[0] == '\0')
4991 return const0_rtx;
4992 /* If the format specifier has length of 1, call putchar. */
4993 if (fmt_str[1] == '\0')
4995 /* Given printf("c"), (where c is any one character,)
4996 convert "c"[0] to an int and pass that to the replacement
4997 function. */
4998 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4999 arglist = build_tree_list (NULL_TREE, arg);
5000 fn = fn_putchar;
5002 else
5004 /* If the format specifier was "string\n", call puts("string"). */
5005 size_t len = strlen (fmt_str);
5006 if (fmt_str[len - 1] == '\n')
5008 /* Create a NUL-terminated string that's one char shorter
5009 than the original, stripping off the trailing '\n'. */
5010 char *newstr = alloca (len);
5011 memcpy (newstr, fmt_str, len - 1);
5012 newstr[len - 1] = 0;
5014 arg = build_string_literal (len, newstr);
5015 arglist = build_tree_list (NULL_TREE, arg);
5016 fn = fn_puts;
5018 else
5019 /* We'd like to arrange to call fputs(string,stdout) here,
5020 but we need stdout and don't have a way to get it yet. */
5021 return 0;
5025 if (!fn)
5026 return 0;
5027 return expand_expr (build_function_call_expr (fn, arglist),
5028 target, mode, EXPAND_NORMAL);
5031 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5032 Return 0 if a normal call should be emitted rather than transforming
5033 the function inline. If convenient, the result should be placed in
5034 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5035 call. */
5036 static rtx
5037 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5038 bool unlocked)
5040 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5041 : implicit_built_in_decls[BUILT_IN_FPUTC];
5042 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5043 : implicit_built_in_decls[BUILT_IN_FPUTS];
5044 const char *fmt_str;
5045 tree fn, fmt, fp, arg;
5047 /* If the return value is used, don't do the transformation. */
5048 if (target != const0_rtx)
5049 return 0;
5051 /* Verify the required arguments in the original call. */
5052 if (! arglist)
5053 return 0;
5054 fp = TREE_VALUE (arglist);
5055 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5056 return 0;
5057 arglist = TREE_CHAIN (arglist);
5058 if (! arglist)
5059 return 0;
5060 fmt = TREE_VALUE (arglist);
5061 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5062 return 0;
5063 arglist = TREE_CHAIN (arglist);
5065 /* Check whether the format is a literal string constant. */
5066 fmt_str = c_getstr (fmt);
5067 if (fmt_str == NULL)
5068 return 0;
5070 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5071 if (strcmp (fmt_str, "%s") == 0)
5073 if (! arglist
5074 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5075 || TREE_CHAIN (arglist))
5076 return 0;
5077 arg = TREE_VALUE (arglist);
5078 arglist = build_tree_list (NULL_TREE, fp);
5079 arglist = tree_cons (NULL_TREE, arg, arglist);
5080 fn = fn_fputs;
5082 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5083 else if (strcmp (fmt_str, "%c") == 0)
5085 if (! arglist
5086 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5087 || TREE_CHAIN (arglist))
5088 return 0;
5089 arg = TREE_VALUE (arglist);
5090 arglist = build_tree_list (NULL_TREE, fp);
5091 arglist = tree_cons (NULL_TREE, arg, arglist);
5092 fn = fn_fputc;
5094 else
5096 /* We can't handle anything else with % args or %% ... yet. */
5097 if (strchr (fmt_str, '%'))
5098 return 0;
5100 if (arglist)
5101 return 0;
5103 /* If the format specifier was "", fprintf does nothing. */
5104 if (fmt_str[0] == '\0')
5106 /* Evaluate and ignore FILE* argument for side-effects. */
5107 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5108 return const0_rtx;
5111 /* When "string" doesn't contain %, replace all cases of
5112 fprintf(stream,string) with fputs(string,stream). The fputs
5113 builtin will take care of special cases like length == 1. */
5114 arglist = build_tree_list (NULL_TREE, fp);
5115 arglist = tree_cons (NULL_TREE, fmt, arglist);
5116 fn = fn_fputs;
5119 if (!fn)
5120 return 0;
5121 return expand_expr (build_function_call_expr (fn, arglist),
5122 target, mode, EXPAND_NORMAL);
5125 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5126 a normal call should be emitted rather than expanding the function
5127 inline. If convenient, the result should be placed in TARGET with
5128 mode MODE. */
5130 static rtx
5131 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5133 tree orig_arglist, dest, fmt;
5134 const char *fmt_str;
5136 orig_arglist = arglist;
5138 /* Verify the required arguments in the original call. */
5139 if (! arglist)
5140 return 0;
5141 dest = TREE_VALUE (arglist);
5142 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5143 return 0;
5144 arglist = TREE_CHAIN (arglist);
5145 if (! arglist)
5146 return 0;
5147 fmt = TREE_VALUE (arglist);
5148 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5149 return 0;
5150 arglist = TREE_CHAIN (arglist);
5152 /* Check whether the format is a literal string constant. */
5153 fmt_str = c_getstr (fmt);
5154 if (fmt_str == NULL)
5155 return 0;
5157 /* If the format doesn't contain % args or %%, use strcpy. */
5158 if (strchr (fmt_str, '%') == 0)
5160 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5161 tree exp;
5163 if (arglist || ! fn)
5164 return 0;
5165 expand_expr (build_function_call_expr (fn, orig_arglist),
5166 const0_rtx, VOIDmode, EXPAND_NORMAL);
5167 if (target == const0_rtx)
5168 return const0_rtx;
5169 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5170 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5172 /* If the format is "%s", use strcpy if the result isn't used. */
5173 else if (strcmp (fmt_str, "%s") == 0)
5175 tree fn, arg, len;
5176 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5178 if (! fn)
5179 return 0;
5181 if (! arglist || TREE_CHAIN (arglist))
5182 return 0;
5183 arg = TREE_VALUE (arglist);
5184 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5185 return 0;
5187 if (target != const0_rtx)
5189 len = c_strlen (arg, 1);
5190 if (! len || TREE_CODE (len) != INTEGER_CST)
5191 return 0;
5193 else
5194 len = NULL_TREE;
5196 arglist = build_tree_list (NULL_TREE, arg);
5197 arglist = tree_cons (NULL_TREE, dest, arglist);
5198 expand_expr (build_function_call_expr (fn, arglist),
5199 const0_rtx, VOIDmode, EXPAND_NORMAL);
5201 if (target == const0_rtx)
5202 return const0_rtx;
5203 return expand_expr (len, target, mode, EXPAND_NORMAL);
5206 return 0;
5209 /* Expand a call to either the entry or exit function profiler. */
5211 static rtx
5212 expand_builtin_profile_func (bool exitp)
5214 rtx this, which;
5216 this = DECL_RTL (current_function_decl);
5217 gcc_assert (MEM_P (this));
5218 this = XEXP (this, 0);
5220 if (exitp)
5221 which = profile_function_exit_libfunc;
5222 else
5223 which = profile_function_entry_libfunc;
5225 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5226 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5227 0, hard_frame_pointer_rtx),
5228 Pmode);
5230 return const0_rtx;
5233 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5235 static rtx
5236 round_trampoline_addr (rtx tramp)
5238 rtx temp, addend, mask;
5240 /* If we don't need too much alignment, we'll have been guaranteed
5241 proper alignment by get_trampoline_type. */
5242 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5243 return tramp;
5245 /* Round address up to desired boundary. */
5246 temp = gen_reg_rtx (Pmode);
5247 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5248 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5250 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5251 temp, 0, OPTAB_LIB_WIDEN);
5252 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5253 temp, 0, OPTAB_LIB_WIDEN);
5255 return tramp;
5258 static rtx
5259 expand_builtin_init_trampoline (tree arglist)
5261 tree t_tramp, t_func, t_chain;
5262 rtx r_tramp, r_func, r_chain;
5263 #ifdef TRAMPOLINE_TEMPLATE
5264 rtx blktramp;
5265 #endif
5267 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5268 POINTER_TYPE, VOID_TYPE))
5269 return NULL_RTX;
5271 t_tramp = TREE_VALUE (arglist);
5272 arglist = TREE_CHAIN (arglist);
5273 t_func = TREE_VALUE (arglist);
5274 arglist = TREE_CHAIN (arglist);
5275 t_chain = TREE_VALUE (arglist);
5277 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5278 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5279 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5281 /* Generate insns to initialize the trampoline. */
5282 r_tramp = round_trampoline_addr (r_tramp);
5283 #ifdef TRAMPOLINE_TEMPLATE
5284 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5285 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5286 emit_block_move (blktramp, assemble_trampoline_template (),
5287 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5288 #endif
5289 trampolines_created = 1;
5290 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5292 return const0_rtx;
5295 static rtx
5296 expand_builtin_adjust_trampoline (tree arglist)
5298 rtx tramp;
5300 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5301 return NULL_RTX;
5303 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5304 tramp = round_trampoline_addr (tramp);
5305 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5306 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5307 #endif
5309 return tramp;
5312 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5313 Return NULL_RTX if a normal call should be emitted rather than expanding
5314 the function in-line. EXP is the expression that is a call to the builtin
5315 function; if convenient, the result should be placed in TARGET. */
5317 static rtx
5318 expand_builtin_signbit (tree exp, rtx target)
5320 const struct real_format *fmt;
5321 enum machine_mode fmode, imode, rmode;
5322 HOST_WIDE_INT hi, lo;
5323 tree arg, arglist;
5324 int bitpos;
5325 rtx temp;
5327 arglist = TREE_OPERAND (exp, 1);
5328 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5329 return 0;
5331 arg = TREE_VALUE (arglist);
5332 fmode = TYPE_MODE (TREE_TYPE (arg));
5333 rmode = TYPE_MODE (TREE_TYPE (exp));
5334 fmt = REAL_MODE_FORMAT (fmode);
5336 /* For floating point formats without a sign bit, implement signbit
5337 as "ARG < 0.0". */
5338 if (fmt->signbit < 0)
5340 /* But we can't do this if the format supports signed zero. */
5341 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5342 return 0;
5344 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5345 build_real (TREE_TYPE (arg), dconst0)));
5346 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5349 imode = int_mode_for_mode (fmode);
5350 if (imode == BLKmode)
5351 return 0;
5353 bitpos = fmt->signbit;
5354 /* Handle targets with different FP word orders. */
5355 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5357 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5358 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5359 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5362 /* If the sign bit is not in the lowpart and the floating point format
5363 is wider than an integer, check that is twice the size of an integer
5364 so that we can use gen_highpart below. */
5365 if (bitpos >= GET_MODE_BITSIZE (rmode)
5366 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5367 return 0;
5369 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5370 temp = gen_lowpart (imode, temp);
5372 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5374 if (BYTES_BIG_ENDIAN)
5375 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5376 temp = copy_to_mode_reg (imode, temp);
5377 temp = extract_bit_field (temp, 1, bitpos, 1,
5378 NULL_RTX, rmode, rmode);
5380 else
5382 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5383 temp = gen_lowpart (rmode, temp);
5384 if (bitpos < HOST_BITS_PER_WIDE_INT)
5386 hi = 0;
5387 lo = (HOST_WIDE_INT) 1 << bitpos;
5389 else
5391 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5392 lo = 0;
5395 temp = force_reg (rmode, temp);
5396 temp = expand_binop (rmode, and_optab, temp,
5397 immed_double_const (lo, hi, rmode),
5398 target, 1, OPTAB_LIB_WIDEN);
5400 return temp;
5403 /* Expand fork or exec calls. TARGET is the desired target of the
5404 call. ARGLIST is the list of arguments of the call. FN is the
5405 identificator of the actual function. IGNORE is nonzero if the
5406 value is to be ignored. */
5408 static rtx
5409 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5411 tree id, decl;
5412 tree call;
5414 /* If we are not profiling, just call the function. */
5415 if (!profile_arc_flag)
5416 return NULL_RTX;
5418 /* Otherwise call the wrapper. This should be equivalent for the rest of
5419 compiler, so the code does not diverge, and the wrapper may run the
5420 code necessary for keeping the profiling sane. */
5422 switch (DECL_FUNCTION_CODE (fn))
5424 case BUILT_IN_FORK:
5425 id = get_identifier ("__gcov_fork");
5426 break;
5428 case BUILT_IN_EXECL:
5429 id = get_identifier ("__gcov_execl");
5430 break;
5432 case BUILT_IN_EXECV:
5433 id = get_identifier ("__gcov_execv");
5434 break;
5436 case BUILT_IN_EXECLP:
5437 id = get_identifier ("__gcov_execlp");
5438 break;
5440 case BUILT_IN_EXECLE:
5441 id = get_identifier ("__gcov_execle");
5442 break;
5444 case BUILT_IN_EXECVP:
5445 id = get_identifier ("__gcov_execvp");
5446 break;
5448 case BUILT_IN_EXECVE:
5449 id = get_identifier ("__gcov_execve");
5450 break;
5452 default:
5453 gcc_unreachable ();
5456 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5457 DECL_EXTERNAL (decl) = 1;
5458 TREE_PUBLIC (decl) = 1;
5459 DECL_ARTIFICIAL (decl) = 1;
5460 TREE_NOTHROW (decl) = 1;
5461 call = build_function_call_expr (decl, arglist);
5463 return expand_call (call, target, ignore);
5466 /* Expand an expression EXP that calls a built-in function,
5467 with result going to TARGET if that's convenient
5468 (and in mode MODE if that's convenient).
5469 SUBTARGET may be used as the target for computing one of EXP's operands.
5470 IGNORE is nonzero if the value is to be ignored. */
5473 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5474 int ignore)
5476 tree fndecl = get_callee_fndecl (exp);
5477 tree arglist = TREE_OPERAND (exp, 1);
5478 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5479 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5481 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5482 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5484 /* When not optimizing, generate calls to library functions for a certain
5485 set of builtins. */
5486 if (!optimize
5487 && !CALLED_AS_BUILT_IN (fndecl)
5488 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5489 && fcode != BUILT_IN_ALLOCA)
5490 return expand_call (exp, target, ignore);
5492 /* The built-in function expanders test for target == const0_rtx
5493 to determine whether the function's result will be ignored. */
5494 if (ignore)
5495 target = const0_rtx;
5497 /* If the result of a pure or const built-in function is ignored, and
5498 none of its arguments are volatile, we can avoid expanding the
5499 built-in call and just evaluate the arguments for side-effects. */
5500 if (target == const0_rtx
5501 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5503 bool volatilep = false;
5504 tree arg;
5506 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5507 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5509 volatilep = true;
5510 break;
5513 if (! volatilep)
5515 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5516 expand_expr (TREE_VALUE (arg), const0_rtx,
5517 VOIDmode, EXPAND_NORMAL);
5518 return const0_rtx;
5522 switch (fcode)
5524 case BUILT_IN_FABS:
5525 case BUILT_IN_FABSF:
5526 case BUILT_IN_FABSL:
5527 target = expand_builtin_fabs (arglist, target, subtarget);
5528 if (target)
5529 return target;
5530 break;
5532 /* Just do a normal library call if we were unable to fold
5533 the values. */
5534 case BUILT_IN_CABS:
5535 case BUILT_IN_CABSF:
5536 case BUILT_IN_CABSL:
5537 break;
5539 case BUILT_IN_EXP:
5540 case BUILT_IN_EXPF:
5541 case BUILT_IN_EXPL:
5542 case BUILT_IN_EXP10:
5543 case BUILT_IN_EXP10F:
5544 case BUILT_IN_EXP10L:
5545 case BUILT_IN_POW10:
5546 case BUILT_IN_POW10F:
5547 case BUILT_IN_POW10L:
5548 case BUILT_IN_EXP2:
5549 case BUILT_IN_EXP2F:
5550 case BUILT_IN_EXP2L:
5551 case BUILT_IN_EXPM1:
5552 case BUILT_IN_EXPM1F:
5553 case BUILT_IN_EXPM1L:
5554 case BUILT_IN_LOGB:
5555 case BUILT_IN_LOGBF:
5556 case BUILT_IN_LOGBL:
5557 case BUILT_IN_ILOGB:
5558 case BUILT_IN_ILOGBF:
5559 case BUILT_IN_ILOGBL:
5560 case BUILT_IN_LOG:
5561 case BUILT_IN_LOGF:
5562 case BUILT_IN_LOGL:
5563 case BUILT_IN_LOG10:
5564 case BUILT_IN_LOG10F:
5565 case BUILT_IN_LOG10L:
5566 case BUILT_IN_LOG2:
5567 case BUILT_IN_LOG2F:
5568 case BUILT_IN_LOG2L:
5569 case BUILT_IN_LOG1P:
5570 case BUILT_IN_LOG1PF:
5571 case BUILT_IN_LOG1PL:
5572 case BUILT_IN_TAN:
5573 case BUILT_IN_TANF:
5574 case BUILT_IN_TANL:
5575 case BUILT_IN_ASIN:
5576 case BUILT_IN_ASINF:
5577 case BUILT_IN_ASINL:
5578 case BUILT_IN_ACOS:
5579 case BUILT_IN_ACOSF:
5580 case BUILT_IN_ACOSL:
5581 case BUILT_IN_ATAN:
5582 case BUILT_IN_ATANF:
5583 case BUILT_IN_ATANL:
5584 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5585 because of possible accuracy problems. */
5586 if (! flag_unsafe_math_optimizations)
5587 break;
5588 case BUILT_IN_SQRT:
5589 case BUILT_IN_SQRTF:
5590 case BUILT_IN_SQRTL:
5591 case BUILT_IN_FLOOR:
5592 case BUILT_IN_FLOORF:
5593 case BUILT_IN_FLOORL:
5594 case BUILT_IN_CEIL:
5595 case BUILT_IN_CEILF:
5596 case BUILT_IN_CEILL:
5597 case BUILT_IN_TRUNC:
5598 case BUILT_IN_TRUNCF:
5599 case BUILT_IN_TRUNCL:
5600 case BUILT_IN_ROUND:
5601 case BUILT_IN_ROUNDF:
5602 case BUILT_IN_ROUNDL:
5603 case BUILT_IN_NEARBYINT:
5604 case BUILT_IN_NEARBYINTF:
5605 case BUILT_IN_NEARBYINTL:
5606 case BUILT_IN_RINT:
5607 case BUILT_IN_RINTF:
5608 case BUILT_IN_RINTL:
5609 target = expand_builtin_mathfn (exp, target, subtarget);
5610 if (target)
5611 return target;
5612 break;
5614 case BUILT_IN_POW:
5615 case BUILT_IN_POWF:
5616 case BUILT_IN_POWL:
5617 target = expand_builtin_pow (exp, target, subtarget);
5618 if (target)
5619 return target;
5620 break;
5622 case BUILT_IN_ATAN2:
5623 case BUILT_IN_ATAN2F:
5624 case BUILT_IN_ATAN2L:
5625 case BUILT_IN_FMOD:
5626 case BUILT_IN_FMODF:
5627 case BUILT_IN_FMODL:
5628 case BUILT_IN_DREM:
5629 case BUILT_IN_DREMF:
5630 case BUILT_IN_DREML:
5631 if (! flag_unsafe_math_optimizations)
5632 break;
5633 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5634 if (target)
5635 return target;
5636 break;
5638 case BUILT_IN_SIN:
5639 case BUILT_IN_SINF:
5640 case BUILT_IN_SINL:
5641 case BUILT_IN_COS:
5642 case BUILT_IN_COSF:
5643 case BUILT_IN_COSL:
5644 if (! flag_unsafe_math_optimizations)
5645 break;
5646 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5647 if (target)
5648 return target;
5649 break;
5651 case BUILT_IN_APPLY_ARGS:
5652 return expand_builtin_apply_args ();
5654 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5655 FUNCTION with a copy of the parameters described by
5656 ARGUMENTS, and ARGSIZE. It returns a block of memory
5657 allocated on the stack into which is stored all the registers
5658 that might possibly be used for returning the result of a
5659 function. ARGUMENTS is the value returned by
5660 __builtin_apply_args. ARGSIZE is the number of bytes of
5661 arguments that must be copied. ??? How should this value be
5662 computed? We'll also need a safe worst case value for varargs
5663 functions. */
5664 case BUILT_IN_APPLY:
5665 if (!validate_arglist (arglist, POINTER_TYPE,
5666 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5667 && !validate_arglist (arglist, REFERENCE_TYPE,
5668 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5669 return const0_rtx;
5670 else
5672 int i;
5673 tree t;
5674 rtx ops[3];
5676 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5677 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5679 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5682 /* __builtin_return (RESULT) causes the function to return the
5683 value described by RESULT. RESULT is address of the block of
5684 memory returned by __builtin_apply. */
5685 case BUILT_IN_RETURN:
5686 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5687 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5688 NULL_RTX, VOIDmode, 0));
5689 return const0_rtx;
5691 case BUILT_IN_SAVEREGS:
5692 return expand_builtin_saveregs ();
5694 case BUILT_IN_ARGS_INFO:
5695 return expand_builtin_args_info (arglist);
5697 /* Return the address of the first anonymous stack arg. */
5698 case BUILT_IN_NEXT_ARG:
5699 simplify_builtin_next_arg (arglist);
5700 return expand_builtin_next_arg (arglist);
5702 case BUILT_IN_CLASSIFY_TYPE:
5703 return expand_builtin_classify_type (arglist);
5705 case BUILT_IN_CONSTANT_P:
5706 return const0_rtx;
5708 case BUILT_IN_FRAME_ADDRESS:
5709 case BUILT_IN_RETURN_ADDRESS:
5710 return expand_builtin_frame_address (fndecl, arglist);
5712 /* Returns the address of the area where the structure is returned.
5713 0 otherwise. */
5714 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5715 if (arglist != 0
5716 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5717 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5718 return const0_rtx;
5719 else
5720 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5722 case BUILT_IN_ALLOCA:
5723 target = expand_builtin_alloca (arglist, target);
5724 if (target)
5725 return target;
5726 break;
5728 case BUILT_IN_STACK_SAVE:
5729 return expand_stack_save ();
5731 case BUILT_IN_STACK_RESTORE:
5732 expand_stack_restore (TREE_VALUE (arglist));
5733 return const0_rtx;
5735 case BUILT_IN_FFS:
5736 case BUILT_IN_FFSL:
5737 case BUILT_IN_FFSLL:
5738 case BUILT_IN_FFSIMAX:
5739 target = expand_builtin_unop (target_mode, arglist, target,
5740 subtarget, ffs_optab);
5741 if (target)
5742 return target;
5743 break;
5745 case BUILT_IN_CLZ:
5746 case BUILT_IN_CLZL:
5747 case BUILT_IN_CLZLL:
5748 case BUILT_IN_CLZIMAX:
5749 target = expand_builtin_unop (target_mode, arglist, target,
5750 subtarget, clz_optab);
5751 if (target)
5752 return target;
5753 break;
5755 case BUILT_IN_CTZ:
5756 case BUILT_IN_CTZL:
5757 case BUILT_IN_CTZLL:
5758 case BUILT_IN_CTZIMAX:
5759 target = expand_builtin_unop (target_mode, arglist, target,
5760 subtarget, ctz_optab);
5761 if (target)
5762 return target;
5763 break;
5765 case BUILT_IN_POPCOUNT:
5766 case BUILT_IN_POPCOUNTL:
5767 case BUILT_IN_POPCOUNTLL:
5768 case BUILT_IN_POPCOUNTIMAX:
5769 target = expand_builtin_unop (target_mode, arglist, target,
5770 subtarget, popcount_optab);
5771 if (target)
5772 return target;
5773 break;
5775 case BUILT_IN_PARITY:
5776 case BUILT_IN_PARITYL:
5777 case BUILT_IN_PARITYLL:
5778 case BUILT_IN_PARITYIMAX:
5779 target = expand_builtin_unop (target_mode, arglist, target,
5780 subtarget, parity_optab);
5781 if (target)
5782 return target;
5783 break;
5785 case BUILT_IN_STRLEN:
5786 target = expand_builtin_strlen (arglist, target, target_mode);
5787 if (target)
5788 return target;
5789 break;
5791 case BUILT_IN_STRCPY:
5792 target = expand_builtin_strcpy (arglist, target, mode);
5793 if (target)
5794 return target;
5795 break;
5797 case BUILT_IN_STRNCPY:
5798 target = expand_builtin_strncpy (arglist, target, mode);
5799 if (target)
5800 return target;
5801 break;
5803 case BUILT_IN_STPCPY:
5804 target = expand_builtin_stpcpy (arglist, target, mode);
5805 if (target)
5806 return target;
5807 break;
5809 case BUILT_IN_STRCAT:
5810 target = expand_builtin_strcat (arglist, target, mode);
5811 if (target)
5812 return target;
5813 break;
5815 case BUILT_IN_STRNCAT:
5816 target = expand_builtin_strncat (arglist, target, mode);
5817 if (target)
5818 return target;
5819 break;
5821 case BUILT_IN_STRSPN:
5822 target = expand_builtin_strspn (arglist, target, mode);
5823 if (target)
5824 return target;
5825 break;
5827 case BUILT_IN_STRCSPN:
5828 target = expand_builtin_strcspn (arglist, target, mode);
5829 if (target)
5830 return target;
5831 break;
5833 case BUILT_IN_STRSTR:
5834 target = expand_builtin_strstr (arglist, target, mode);
5835 if (target)
5836 return target;
5837 break;
5839 case BUILT_IN_STRPBRK:
5840 target = expand_builtin_strpbrk (arglist, target, mode);
5841 if (target)
5842 return target;
5843 break;
5845 case BUILT_IN_INDEX:
5846 case BUILT_IN_STRCHR:
5847 target = expand_builtin_strchr (arglist, target, mode);
5848 if (target)
5849 return target;
5850 break;
5852 case BUILT_IN_RINDEX:
5853 case BUILT_IN_STRRCHR:
5854 target = expand_builtin_strrchr (arglist, target, mode);
5855 if (target)
5856 return target;
5857 break;
5859 case BUILT_IN_MEMCPY:
5860 target = expand_builtin_memcpy (arglist, target, mode);
5861 if (target)
5862 return target;
5863 break;
5865 case BUILT_IN_MEMPCPY:
5866 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5867 if (target)
5868 return target;
5869 break;
5871 case BUILT_IN_MEMMOVE:
5872 target = expand_builtin_memmove (arglist, target, mode);
5873 if (target)
5874 return target;
5875 break;
5877 case BUILT_IN_BCOPY:
5878 target = expand_builtin_bcopy (arglist);
5879 if (target)
5880 return target;
5881 break;
5883 case BUILT_IN_MEMSET:
5884 target = expand_builtin_memset (arglist, target, mode);
5885 if (target)
5886 return target;
5887 break;
5889 case BUILT_IN_BZERO:
5890 target = expand_builtin_bzero (arglist);
5891 if (target)
5892 return target;
5893 break;
5895 case BUILT_IN_STRCMP:
5896 target = expand_builtin_strcmp (exp, target, mode);
5897 if (target)
5898 return target;
5899 break;
5901 case BUILT_IN_STRNCMP:
5902 target = expand_builtin_strncmp (exp, target, mode);
5903 if (target)
5904 return target;
5905 break;
5907 case BUILT_IN_BCMP:
5908 case BUILT_IN_MEMCMP:
5909 target = expand_builtin_memcmp (exp, arglist, target, mode);
5910 if (target)
5911 return target;
5912 break;
5914 case BUILT_IN_SETJMP:
5915 target = expand_builtin_setjmp (arglist, target);
5916 if (target)
5917 return target;
5918 break;
5920 /* __builtin_longjmp is passed a pointer to an array of five words.
5921 It's similar to the C library longjmp function but works with
5922 __builtin_setjmp above. */
5923 case BUILT_IN_LONGJMP:
5924 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5925 break;
5926 else
5928 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5929 VOIDmode, 0);
5930 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5931 NULL_RTX, VOIDmode, 0);
5933 if (value != const1_rtx)
5935 error ("__builtin_longjmp second argument must be 1");
5936 return const0_rtx;
5939 expand_builtin_longjmp (buf_addr, value);
5940 return const0_rtx;
5943 case BUILT_IN_NONLOCAL_GOTO:
5944 target = expand_builtin_nonlocal_goto (arglist);
5945 if (target)
5946 return target;
5947 break;
5949 /* This updates the setjmp buffer that is its argument with the value
5950 of the current stack pointer. */
5951 case BUILT_IN_UPDATE_SETJMP_BUF:
5952 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5954 rtx buf_addr
5955 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5957 expand_builtin_update_setjmp_buf (buf_addr);
5958 return const0_rtx;
5960 break;
5962 case BUILT_IN_TRAP:
5963 expand_builtin_trap ();
5964 return const0_rtx;
5966 case BUILT_IN_PRINTF:
5967 target = expand_builtin_printf (arglist, target, mode, false);
5968 if (target)
5969 return target;
5970 break;
5972 case BUILT_IN_PRINTF_UNLOCKED:
5973 target = expand_builtin_printf (arglist, target, mode, true);
5974 if (target)
5975 return target;
5976 break;
5978 case BUILT_IN_FPUTS:
5979 target = expand_builtin_fputs (arglist, target, false);
5980 if (target)
5981 return target;
5982 break;
5983 case BUILT_IN_FPUTS_UNLOCKED:
5984 target = expand_builtin_fputs (arglist, target, true);
5985 if (target)
5986 return target;
5987 break;
5989 case BUILT_IN_FPRINTF:
5990 target = expand_builtin_fprintf (arglist, target, mode, false);
5991 if (target)
5992 return target;
5993 break;
5995 case BUILT_IN_FPRINTF_UNLOCKED:
5996 target = expand_builtin_fprintf (arglist, target, mode, true);
5997 if (target)
5998 return target;
5999 break;
6001 case BUILT_IN_SPRINTF:
6002 target = expand_builtin_sprintf (arglist, target, mode);
6003 if (target)
6004 return target;
6005 break;
6007 case BUILT_IN_SIGNBIT:
6008 case BUILT_IN_SIGNBITF:
6009 case BUILT_IN_SIGNBITL:
6010 target = expand_builtin_signbit (exp, target);
6011 if (target)
6012 return target;
6013 break;
6015 /* Various hooks for the DWARF 2 __throw routine. */
6016 case BUILT_IN_UNWIND_INIT:
6017 expand_builtin_unwind_init ();
6018 return const0_rtx;
6019 case BUILT_IN_DWARF_CFA:
6020 return virtual_cfa_rtx;
6021 #ifdef DWARF2_UNWIND_INFO
6022 case BUILT_IN_DWARF_SP_COLUMN:
6023 return expand_builtin_dwarf_sp_column ();
6024 case BUILT_IN_INIT_DWARF_REG_SIZES:
6025 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6026 return const0_rtx;
6027 #endif
6028 case BUILT_IN_FROB_RETURN_ADDR:
6029 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6030 case BUILT_IN_EXTRACT_RETURN_ADDR:
6031 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6032 case BUILT_IN_EH_RETURN:
6033 expand_builtin_eh_return (TREE_VALUE (arglist),
6034 TREE_VALUE (TREE_CHAIN (arglist)));
6035 return const0_rtx;
6036 #ifdef EH_RETURN_DATA_REGNO
6037 case BUILT_IN_EH_RETURN_DATA_REGNO:
6038 return expand_builtin_eh_return_data_regno (arglist);
6039 #endif
6040 case BUILT_IN_EXTEND_POINTER:
6041 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6043 case BUILT_IN_VA_START:
6044 case BUILT_IN_STDARG_START:
6045 return expand_builtin_va_start (arglist);
6046 case BUILT_IN_VA_END:
6047 return expand_builtin_va_end (arglist);
6048 case BUILT_IN_VA_COPY:
6049 return expand_builtin_va_copy (arglist);
6050 case BUILT_IN_EXPECT:
6051 return expand_builtin_expect (arglist, target);
6052 case BUILT_IN_PREFETCH:
6053 expand_builtin_prefetch (arglist);
6054 return const0_rtx;
6056 case BUILT_IN_PROFILE_FUNC_ENTER:
6057 return expand_builtin_profile_func (false);
6058 case BUILT_IN_PROFILE_FUNC_EXIT:
6059 return expand_builtin_profile_func (true);
6061 case BUILT_IN_INIT_TRAMPOLINE:
6062 return expand_builtin_init_trampoline (arglist);
6063 case BUILT_IN_ADJUST_TRAMPOLINE:
6064 return expand_builtin_adjust_trampoline (arglist);
6066 case BUILT_IN_FORK:
6067 case BUILT_IN_EXECL:
6068 case BUILT_IN_EXECV:
6069 case BUILT_IN_EXECLP:
6070 case BUILT_IN_EXECLE:
6071 case BUILT_IN_EXECVP:
6072 case BUILT_IN_EXECVE:
6073 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6074 if (target)
6075 return target;
6076 break;
6078 default: /* just do library call, if unknown builtin */
6079 break;
6082 /* The switch statement above can drop through to cause the function
6083 to be called normally. */
6084 return expand_call (exp, target, ignore);
6087 /* Determine whether a tree node represents a call to a built-in
6088 function. If the tree T is a call to a built-in function with
6089 the right number of arguments of the appropriate types, return
6090 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6091 Otherwise the return value is END_BUILTINS. */
6093 enum built_in_function
6094 builtin_mathfn_code (tree t)
6096 tree fndecl, arglist, parmlist;
6097 tree argtype, parmtype;
6099 if (TREE_CODE (t) != CALL_EXPR
6100 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6101 return END_BUILTINS;
6103 fndecl = get_callee_fndecl (t);
6104 if (fndecl == NULL_TREE
6105 || TREE_CODE (fndecl) != FUNCTION_DECL
6106 || ! DECL_BUILT_IN (fndecl)
6107 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6108 return END_BUILTINS;
6110 arglist = TREE_OPERAND (t, 1);
6111 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6112 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6114 /* If a function doesn't take a variable number of arguments,
6115 the last element in the list will have type `void'. */
6116 parmtype = TREE_VALUE (parmlist);
6117 if (VOID_TYPE_P (parmtype))
6119 if (arglist)
6120 return END_BUILTINS;
6121 return DECL_FUNCTION_CODE (fndecl);
6124 if (! arglist)
6125 return END_BUILTINS;
6127 argtype = TREE_TYPE (TREE_VALUE (arglist));
6129 if (SCALAR_FLOAT_TYPE_P (parmtype))
6131 if (! SCALAR_FLOAT_TYPE_P (argtype))
6132 return END_BUILTINS;
6134 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6136 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6137 return END_BUILTINS;
6139 else if (POINTER_TYPE_P (parmtype))
6141 if (! POINTER_TYPE_P (argtype))
6142 return END_BUILTINS;
6144 else if (INTEGRAL_TYPE_P (parmtype))
6146 if (! INTEGRAL_TYPE_P (argtype))
6147 return END_BUILTINS;
6149 else
6150 return END_BUILTINS;
6152 arglist = TREE_CHAIN (arglist);
6155 /* Variable-length argument list. */
6156 return DECL_FUNCTION_CODE (fndecl);
6159 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6160 constant. ARGLIST is the argument list of the call. */
6162 static tree
6163 fold_builtin_constant_p (tree arglist)
6165 if (arglist == 0)
6166 return 0;
6168 arglist = TREE_VALUE (arglist);
6170 /* We return 1 for a numeric type that's known to be a constant
6171 value at compile-time or for an aggregate type that's a
6172 literal constant. */
6173 STRIP_NOPS (arglist);
6175 /* If we know this is a constant, emit the constant of one. */
6176 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6177 || (TREE_CODE (arglist) == CONSTRUCTOR
6178 && TREE_CONSTANT (arglist))
6179 || (TREE_CODE (arglist) == ADDR_EXPR
6180 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6181 return integer_one_node;
6183 /* If this expression has side effects, show we don't know it to be a
6184 constant. Likewise if it's a pointer or aggregate type since in
6185 those case we only want literals, since those are only optimized
6186 when generating RTL, not later.
6187 And finally, if we are compiling an initializer, not code, we
6188 need to return a definite result now; there's not going to be any
6189 more optimization done. */
6190 if (TREE_SIDE_EFFECTS (arglist)
6191 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6192 || POINTER_TYPE_P (TREE_TYPE (arglist))
6193 || cfun == 0)
6194 return integer_zero_node;
6196 return 0;
6199 /* Fold a call to __builtin_expect, if we expect that a comparison against
6200 the argument will fold to a constant. In practice, this means a true
6201 constant or the address of a non-weak symbol. ARGLIST is the argument
6202 list of the call. */
6204 static tree
6205 fold_builtin_expect (tree arglist)
6207 tree arg, inner;
6209 if (arglist == 0)
6210 return 0;
6212 arg = TREE_VALUE (arglist);
6214 /* If the argument isn't invariant, then there's nothing we can do. */
6215 if (!TREE_INVARIANT (arg))
6216 return 0;
6218 /* If we're looking at an address of a weak decl, then do not fold. */
6219 inner = arg;
6220 STRIP_NOPS (inner);
6221 if (TREE_CODE (inner) == ADDR_EXPR)
6225 inner = TREE_OPERAND (inner, 0);
6227 while (TREE_CODE (inner) == COMPONENT_REF
6228 || TREE_CODE (inner) == ARRAY_REF);
6229 if (DECL_P (inner) && DECL_WEAK (inner))
6230 return 0;
6233 /* Otherwise, ARG already has the proper type for the return value. */
6234 return arg;
6237 /* Fold a call to __builtin_classify_type. */
6239 static tree
6240 fold_builtin_classify_type (tree arglist)
6242 if (arglist == 0)
6243 return build_int_cst (NULL_TREE, no_type_class);
6245 return build_int_cst (NULL_TREE,
6246 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6249 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6251 static tree
6252 fold_builtin_inf (tree type, int warn)
6254 REAL_VALUE_TYPE real;
6256 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6257 warning ("target format does not support infinity");
6259 real_inf (&real);
6260 return build_real (type, real);
6263 /* Fold a call to __builtin_nan or __builtin_nans. */
6265 static tree
6266 fold_builtin_nan (tree arglist, tree type, int quiet)
6268 REAL_VALUE_TYPE real;
6269 const char *str;
6271 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6272 return 0;
6273 str = c_getstr (TREE_VALUE (arglist));
6274 if (!str)
6275 return 0;
6277 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6278 return 0;
6280 return build_real (type, real);
6283 /* Return true if the floating point expression T has an integer value.
6284 We also allow +Inf, -Inf and NaN to be considered integer values. */
6286 static bool
6287 integer_valued_real_p (tree t)
6289 switch (TREE_CODE (t))
6291 case FLOAT_EXPR:
6292 return true;
6294 case ABS_EXPR:
6295 case SAVE_EXPR:
6296 case NON_LVALUE_EXPR:
6297 return integer_valued_real_p (TREE_OPERAND (t, 0));
6299 case COMPOUND_EXPR:
6300 case MODIFY_EXPR:
6301 case BIND_EXPR:
6302 return integer_valued_real_p (TREE_OPERAND (t, 1));
6304 case PLUS_EXPR:
6305 case MINUS_EXPR:
6306 case MULT_EXPR:
6307 case MIN_EXPR:
6308 case MAX_EXPR:
6309 return integer_valued_real_p (TREE_OPERAND (t, 0))
6310 && integer_valued_real_p (TREE_OPERAND (t, 1));
6312 case COND_EXPR:
6313 return integer_valued_real_p (TREE_OPERAND (t, 1))
6314 && integer_valued_real_p (TREE_OPERAND (t, 2));
6316 case REAL_CST:
6317 if (! TREE_CONSTANT_OVERFLOW (t))
6319 REAL_VALUE_TYPE c, cint;
6321 c = TREE_REAL_CST (t);
6322 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6323 return real_identical (&c, &cint);
6326 case NOP_EXPR:
6328 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6329 if (TREE_CODE (type) == INTEGER_TYPE)
6330 return true;
6331 if (TREE_CODE (type) == REAL_TYPE)
6332 return integer_valued_real_p (TREE_OPERAND (t, 0));
6333 break;
6336 case CALL_EXPR:
6337 switch (builtin_mathfn_code (t))
6339 case BUILT_IN_CEIL:
6340 case BUILT_IN_CEILF:
6341 case BUILT_IN_CEILL:
6342 case BUILT_IN_FLOOR:
6343 case BUILT_IN_FLOORF:
6344 case BUILT_IN_FLOORL:
6345 case BUILT_IN_NEARBYINT:
6346 case BUILT_IN_NEARBYINTF:
6347 case BUILT_IN_NEARBYINTL:
6348 case BUILT_IN_RINT:
6349 case BUILT_IN_RINTF:
6350 case BUILT_IN_RINTL:
6351 case BUILT_IN_ROUND:
6352 case BUILT_IN_ROUNDF:
6353 case BUILT_IN_ROUNDL:
6354 case BUILT_IN_TRUNC:
6355 case BUILT_IN_TRUNCF:
6356 case BUILT_IN_TRUNCL:
6357 return true;
6359 default:
6360 break;
6362 break;
6364 default:
6365 break;
6367 return false;
6370 /* EXP is assumed to be builtin call where truncation can be propagated
6371 across (for instance floor((double)f) == (double)floorf (f).
6372 Do the transformation. */
6374 static tree
6375 fold_trunc_transparent_mathfn (tree exp)
6377 tree fndecl = get_callee_fndecl (exp);
6378 tree arglist = TREE_OPERAND (exp, 1);
6379 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6380 tree arg;
6382 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6383 return 0;
6385 arg = TREE_VALUE (arglist);
6386 /* Integer rounding functions are idempotent. */
6387 if (fcode == builtin_mathfn_code (arg))
6388 return arg;
6390 /* If argument is already integer valued, and we don't need to worry
6391 about setting errno, there's no need to perform rounding. */
6392 if (! flag_errno_math && integer_valued_real_p (arg))
6393 return arg;
6395 if (optimize)
6397 tree arg0 = strip_float_extensions (arg);
6398 tree ftype = TREE_TYPE (exp);
6399 tree newtype = TREE_TYPE (arg0);
6400 tree decl;
6402 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6403 && (decl = mathfn_built_in (newtype, fcode)))
6405 arglist =
6406 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6407 return fold_convert (ftype,
6408 build_function_call_expr (decl, arglist));
6411 return 0;
6414 /* EXP is assumed to be builtin call which can narrow the FP type of
6415 the argument, for instance lround((double)f) -> lroundf (f). */
6417 static tree
6418 fold_fixed_mathfn (tree exp)
6420 tree fndecl = get_callee_fndecl (exp);
6421 tree arglist = TREE_OPERAND (exp, 1);
6422 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6423 tree arg;
6425 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6426 return 0;
6428 arg = TREE_VALUE (arglist);
6430 /* If argument is already integer valued, and we don't need to worry
6431 about setting errno, there's no need to perform rounding. */
6432 if (! flag_errno_math && integer_valued_real_p (arg))
6433 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6435 if (optimize)
6437 tree ftype = TREE_TYPE (arg);
6438 tree arg0 = strip_float_extensions (arg);
6439 tree newtype = TREE_TYPE (arg0);
6440 tree decl;
6442 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6443 && (decl = mathfn_built_in (newtype, fcode)))
6445 arglist =
6446 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6447 return build_function_call_expr (decl, arglist);
6450 return 0;
6453 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6454 is the argument list and TYPE is the return type. Return
6455 NULL_TREE if no if no simplification can be made. */
6457 static tree
6458 fold_builtin_cabs (tree arglist, tree type)
6460 tree arg;
6462 if (!arglist || TREE_CHAIN (arglist))
6463 return NULL_TREE;
6465 arg = TREE_VALUE (arglist);
6466 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6467 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6468 return NULL_TREE;
6470 /* Evaluate cabs of a constant at compile-time. */
6471 if (flag_unsafe_math_optimizations
6472 && TREE_CODE (arg) == COMPLEX_CST
6473 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6474 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6475 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6476 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6478 REAL_VALUE_TYPE r, i;
6480 r = TREE_REAL_CST (TREE_REALPART (arg));
6481 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6483 real_arithmetic (&r, MULT_EXPR, &r, &r);
6484 real_arithmetic (&i, MULT_EXPR, &i, &i);
6485 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6486 if (real_sqrt (&r, TYPE_MODE (type), &r)
6487 || ! flag_trapping_math)
6488 return build_real (type, r);
6491 /* If either part is zero, cabs is fabs of the other. */
6492 if (TREE_CODE (arg) == COMPLEX_EXPR
6493 && real_zerop (TREE_OPERAND (arg, 0)))
6494 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6495 if (TREE_CODE (arg) == COMPLEX_EXPR
6496 && real_zerop (TREE_OPERAND (arg, 1)))
6497 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6499 /* Don't do this when optimizing for size. */
6500 if (flag_unsafe_math_optimizations
6501 && optimize && !optimize_size)
6503 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6505 if (sqrtfn != NULL_TREE)
6507 tree rpart, ipart, result, arglist;
6509 arg = builtin_save_expr (arg);
6511 rpart = fold (build1 (REALPART_EXPR, type, arg));
6512 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6514 rpart = builtin_save_expr (rpart);
6515 ipart = builtin_save_expr (ipart);
6517 result = fold (build2 (PLUS_EXPR, type,
6518 fold (build2 (MULT_EXPR, type,
6519 rpart, rpart)),
6520 fold (build2 (MULT_EXPR, type,
6521 ipart, ipart))));
6523 arglist = build_tree_list (NULL_TREE, result);
6524 return build_function_call_expr (sqrtfn, arglist);
6528 return NULL_TREE;
6531 /* Fold function call to builtin trunc, truncf or truncl. Return
6532 NULL_TREE if no simplification can be made. */
6534 static tree
6535 fold_builtin_trunc (tree exp)
6537 tree arglist = TREE_OPERAND (exp, 1);
6538 tree arg;
6540 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6541 return 0;
6543 /* Optimize trunc of constant value. */
6544 arg = TREE_VALUE (arglist);
6545 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6547 REAL_VALUE_TYPE r, x;
6548 tree type = TREE_TYPE (exp);
6550 x = TREE_REAL_CST (arg);
6551 real_trunc (&r, TYPE_MODE (type), &x);
6552 return build_real (type, r);
6555 return fold_trunc_transparent_mathfn (exp);
6558 /* Fold function call to builtin floor, floorf or floorl. Return
6559 NULL_TREE if no simplification can be made. */
6561 static tree
6562 fold_builtin_floor (tree exp)
6564 tree arglist = TREE_OPERAND (exp, 1);
6565 tree arg;
6567 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6568 return 0;
6570 /* Optimize floor of constant value. */
6571 arg = TREE_VALUE (arglist);
6572 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6574 REAL_VALUE_TYPE x;
6576 x = TREE_REAL_CST (arg);
6577 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6579 tree type = TREE_TYPE (exp);
6580 REAL_VALUE_TYPE r;
6582 real_floor (&r, TYPE_MODE (type), &x);
6583 return build_real (type, r);
6587 return fold_trunc_transparent_mathfn (exp);
6590 /* Fold function call to builtin ceil, ceilf or ceill. Return
6591 NULL_TREE if no simplification can be made. */
6593 static tree
6594 fold_builtin_ceil (tree exp)
6596 tree arglist = TREE_OPERAND (exp, 1);
6597 tree arg;
6599 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6600 return 0;
6602 /* Optimize ceil of constant value. */
6603 arg = TREE_VALUE (arglist);
6604 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6606 REAL_VALUE_TYPE x;
6608 x = TREE_REAL_CST (arg);
6609 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6611 tree type = TREE_TYPE (exp);
6612 REAL_VALUE_TYPE r;
6614 real_ceil (&r, TYPE_MODE (type), &x);
6615 return build_real (type, r);
6619 return fold_trunc_transparent_mathfn (exp);
6622 /* Fold function call to builtin round, roundf or roundl. Return
6623 NULL_TREE if no simplification can be made. */
6625 static tree
6626 fold_builtin_round (tree exp)
6628 tree arglist = TREE_OPERAND (exp, 1);
6629 tree arg;
6631 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6632 return 0;
6634 /* Optimize round of constant value. */
6635 arg = TREE_VALUE (arglist);
6636 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6638 REAL_VALUE_TYPE x;
6640 x = TREE_REAL_CST (arg);
6641 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6643 tree type = TREE_TYPE (exp);
6644 REAL_VALUE_TYPE r;
6646 real_round (&r, TYPE_MODE (type), &x);
6647 return build_real (type, r);
6651 return fold_trunc_transparent_mathfn (exp);
6654 /* Fold function call to builtin lround, lroundf or lroundl (or the
6655 corresponding long long versions). Return NULL_TREE if no
6656 simplification can be made. */
6658 static tree
6659 fold_builtin_lround (tree exp)
6661 tree arglist = TREE_OPERAND (exp, 1);
6662 tree arg;
6664 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6665 return 0;
6667 /* Optimize lround of constant value. */
6668 arg = TREE_VALUE (arglist);
6669 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6671 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6673 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6675 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6676 HOST_WIDE_INT hi, lo;
6677 REAL_VALUE_TYPE r;
6679 real_round (&r, TYPE_MODE (ftype), &x);
6680 REAL_VALUE_TO_INT (&lo, &hi, r);
6681 result = build_int_cst_wide (NULL_TREE, lo, hi);
6682 if (int_fits_type_p (result, itype))
6683 return fold_convert (itype, result);
6687 return fold_fixed_mathfn (exp);
6690 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6691 and their long and long long variants (i.e. ffsl and ffsll).
6692 Return NULL_TREE if no simplification can be made. */
6694 static tree
6695 fold_builtin_bitop (tree exp)
6697 tree fndecl = get_callee_fndecl (exp);
6698 tree arglist = TREE_OPERAND (exp, 1);
6699 tree arg;
6701 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6702 return NULL_TREE;
6704 /* Optimize for constant argument. */
6705 arg = TREE_VALUE (arglist);
6706 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6708 HOST_WIDE_INT hi, width, result;
6709 unsigned HOST_WIDE_INT lo;
6710 tree type;
6712 type = TREE_TYPE (arg);
6713 width = TYPE_PRECISION (type);
6714 lo = TREE_INT_CST_LOW (arg);
6716 /* Clear all the bits that are beyond the type's precision. */
6717 if (width > HOST_BITS_PER_WIDE_INT)
6719 hi = TREE_INT_CST_HIGH (arg);
6720 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6721 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6723 else
6725 hi = 0;
6726 if (width < HOST_BITS_PER_WIDE_INT)
6727 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6730 switch (DECL_FUNCTION_CODE (fndecl))
6732 case BUILT_IN_FFS:
6733 case BUILT_IN_FFSL:
6734 case BUILT_IN_FFSLL:
6735 if (lo != 0)
6736 result = exact_log2 (lo & -lo) + 1;
6737 else if (hi != 0)
6738 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6739 else
6740 result = 0;
6741 break;
6743 case BUILT_IN_CLZ:
6744 case BUILT_IN_CLZL:
6745 case BUILT_IN_CLZLL:
6746 if (hi != 0)
6747 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6748 else if (lo != 0)
6749 result = width - floor_log2 (lo) - 1;
6750 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6751 result = width;
6752 break;
6754 case BUILT_IN_CTZ:
6755 case BUILT_IN_CTZL:
6756 case BUILT_IN_CTZLL:
6757 if (lo != 0)
6758 result = exact_log2 (lo & -lo);
6759 else if (hi != 0)
6760 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6761 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6762 result = width;
6763 break;
6765 case BUILT_IN_POPCOUNT:
6766 case BUILT_IN_POPCOUNTL:
6767 case BUILT_IN_POPCOUNTLL:
6768 result = 0;
6769 while (lo)
6770 result++, lo &= lo - 1;
6771 while (hi)
6772 result++, hi &= hi - 1;
6773 break;
6775 case BUILT_IN_PARITY:
6776 case BUILT_IN_PARITYL:
6777 case BUILT_IN_PARITYLL:
6778 result = 0;
6779 while (lo)
6780 result++, lo &= lo - 1;
6781 while (hi)
6782 result++, hi &= hi - 1;
6783 result &= 1;
6784 break;
6786 default:
6787 gcc_unreachable ();
6790 return build_int_cst (TREE_TYPE (exp), result);
6793 return NULL_TREE;
6796 /* Return true if EXPR is the real constant contained in VALUE. */
6798 static bool
6799 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6801 STRIP_NOPS (expr);
6803 return ((TREE_CODE (expr) == REAL_CST
6804 && ! TREE_CONSTANT_OVERFLOW (expr)
6805 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6806 || (TREE_CODE (expr) == COMPLEX_CST
6807 && real_dconstp (TREE_REALPART (expr), value)
6808 && real_zerop (TREE_IMAGPART (expr))));
6811 /* A subroutine of fold_builtin to fold the various logarithmic
6812 functions. EXP is the CALL_EXPR of a call to a builtin logN
6813 function. VALUE is the base of the logN function. */
6815 static tree
6816 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6818 tree arglist = TREE_OPERAND (exp, 1);
6820 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6822 tree fndecl = get_callee_fndecl (exp);
6823 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6824 tree arg = TREE_VALUE (arglist);
6825 const enum built_in_function fcode = builtin_mathfn_code (arg);
6827 /* Optimize logN(1.0) = 0.0. */
6828 if (real_onep (arg))
6829 return build_real (type, dconst0);
6831 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6832 exactly, then only do this if flag_unsafe_math_optimizations. */
6833 if (exact_real_truncate (TYPE_MODE (type), value)
6834 || flag_unsafe_math_optimizations)
6836 const REAL_VALUE_TYPE value_truncate =
6837 real_value_truncate (TYPE_MODE (type), *value);
6838 if (real_dconstp (arg, &value_truncate))
6839 return build_real (type, dconst1);
6842 /* Special case, optimize logN(expN(x)) = x. */
6843 if (flag_unsafe_math_optimizations
6844 && ((value == &dconste
6845 && (fcode == BUILT_IN_EXP
6846 || fcode == BUILT_IN_EXPF
6847 || fcode == BUILT_IN_EXPL))
6848 || (value == &dconst2
6849 && (fcode == BUILT_IN_EXP2
6850 || fcode == BUILT_IN_EXP2F
6851 || fcode == BUILT_IN_EXP2L))
6852 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6853 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6855 /* Optimize logN(func()) for various exponential functions. We
6856 want to determine the value "x" and the power "exponent" in
6857 order to transform logN(x**exponent) into exponent*logN(x). */
6858 if (flag_unsafe_math_optimizations)
6860 tree exponent = 0, x = 0;
6862 switch (fcode)
6864 case BUILT_IN_EXP:
6865 case BUILT_IN_EXPF:
6866 case BUILT_IN_EXPL:
6867 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6868 x = build_real (type,
6869 real_value_truncate (TYPE_MODE (type), dconste));
6870 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6871 break;
6872 case BUILT_IN_EXP2:
6873 case BUILT_IN_EXP2F:
6874 case BUILT_IN_EXP2L:
6875 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6876 x = build_real (type, dconst2);
6877 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6878 break;
6879 case BUILT_IN_EXP10:
6880 case BUILT_IN_EXP10F:
6881 case BUILT_IN_EXP10L:
6882 case BUILT_IN_POW10:
6883 case BUILT_IN_POW10F:
6884 case BUILT_IN_POW10L:
6885 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6886 x = build_real (type, dconst10);
6887 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6888 break;
6889 case BUILT_IN_SQRT:
6890 case BUILT_IN_SQRTF:
6891 case BUILT_IN_SQRTL:
6892 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6893 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6894 exponent = build_real (type, dconsthalf);
6895 break;
6896 case BUILT_IN_CBRT:
6897 case BUILT_IN_CBRTF:
6898 case BUILT_IN_CBRTL:
6899 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6900 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6901 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6902 dconstthird));
6903 break;
6904 case BUILT_IN_POW:
6905 case BUILT_IN_POWF:
6906 case BUILT_IN_POWL:
6907 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6908 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6909 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6910 break;
6911 default:
6912 break;
6915 /* Now perform the optimization. */
6916 if (x && exponent)
6918 tree logfn;
6919 arglist = build_tree_list (NULL_TREE, x);
6920 logfn = build_function_call_expr (fndecl, arglist);
6921 return fold (build2 (MULT_EXPR, type, exponent, logfn));
6926 return 0;
6929 /* A subroutine of fold_builtin to fold the various exponent
6930 functions. EXP is the CALL_EXPR of a call to a builtin function.
6931 VALUE is the value which will be raised to a power. */
6933 static tree
6934 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6936 tree arglist = TREE_OPERAND (exp, 1);
6938 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6940 tree fndecl = get_callee_fndecl (exp);
6941 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6942 tree arg = TREE_VALUE (arglist);
6944 /* Optimize exp*(0.0) = 1.0. */
6945 if (real_zerop (arg))
6946 return build_real (type, dconst1);
6948 /* Optimize expN(1.0) = N. */
6949 if (real_onep (arg))
6951 REAL_VALUE_TYPE cst;
6953 real_convert (&cst, TYPE_MODE (type), value);
6954 return build_real (type, cst);
6957 /* Attempt to evaluate expN(integer) at compile-time. */
6958 if (flag_unsafe_math_optimizations
6959 && TREE_CODE (arg) == REAL_CST
6960 && ! TREE_CONSTANT_OVERFLOW (arg))
6962 REAL_VALUE_TYPE cint;
6963 REAL_VALUE_TYPE c;
6964 HOST_WIDE_INT n;
6966 c = TREE_REAL_CST (arg);
6967 n = real_to_integer (&c);
6968 real_from_integer (&cint, VOIDmode, n,
6969 n < 0 ? -1 : 0, 0);
6970 if (real_identical (&c, &cint))
6972 REAL_VALUE_TYPE x;
6974 real_powi (&x, TYPE_MODE (type), value, n);
6975 return build_real (type, x);
6979 /* Optimize expN(logN(x)) = x. */
6980 if (flag_unsafe_math_optimizations)
6982 const enum built_in_function fcode = builtin_mathfn_code (arg);
6984 if ((value == &dconste
6985 && (fcode == BUILT_IN_LOG
6986 || fcode == BUILT_IN_LOGF
6987 || fcode == BUILT_IN_LOGL))
6988 || (value == &dconst2
6989 && (fcode == BUILT_IN_LOG2
6990 || fcode == BUILT_IN_LOG2F
6991 || fcode == BUILT_IN_LOG2L))
6992 || (value == &dconst10
6993 && (fcode == BUILT_IN_LOG10
6994 || fcode == BUILT_IN_LOG10F
6995 || fcode == BUILT_IN_LOG10L)))
6996 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7000 return 0;
7003 /* Fold function call to builtin memcpy. Return
7004 NULL_TREE if no simplification can be made. */
7006 static tree
7007 fold_builtin_memcpy (tree exp)
7009 tree arglist = TREE_OPERAND (exp, 1);
7010 tree dest, src, len;
7012 if (!validate_arglist (arglist,
7013 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7014 return 0;
7016 dest = TREE_VALUE (arglist);
7017 src = TREE_VALUE (TREE_CHAIN (arglist));
7018 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7020 /* If the LEN parameter is zero, return DEST. */
7021 if (integer_zerop (len))
7022 return omit_one_operand (TREE_TYPE (exp), dest, src);
7024 /* If SRC and DEST are the same (and not volatile), return DEST. */
7025 if (operand_equal_p (src, dest, 0))
7026 return omit_one_operand (TREE_TYPE (exp), dest, len);
7028 return 0;
7031 /* Fold function call to builtin mempcpy. Return
7032 NULL_TREE if no simplification can be made. */
7034 static tree
7035 fold_builtin_mempcpy (tree exp)
7037 tree arglist = TREE_OPERAND (exp, 1);
7038 tree dest, src, len;
7040 if (!validate_arglist (arglist,
7041 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7042 return 0;
7044 dest = TREE_VALUE (arglist);
7045 src = TREE_VALUE (TREE_CHAIN (arglist));
7046 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7048 /* If the LEN parameter is zero, return DEST. */
7049 if (integer_zerop (len))
7050 return omit_one_operand (TREE_TYPE (exp), dest, src);
7052 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7053 if (operand_equal_p (src, dest, 0))
7055 tree temp = fold_convert (TREE_TYPE (dest), len);
7056 temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7057 return fold_convert (TREE_TYPE (exp), temp);
7060 return 0;
7063 /* Fold function call to builtin memmove. Return
7064 NULL_TREE if no simplification can be made. */
7066 static tree
7067 fold_builtin_memmove (tree exp)
7069 tree arglist = TREE_OPERAND (exp, 1);
7070 tree dest, src, len;
7072 if (!validate_arglist (arglist,
7073 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7074 return 0;
7076 dest = TREE_VALUE (arglist);
7077 src = TREE_VALUE (TREE_CHAIN (arglist));
7078 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7080 /* If the LEN parameter is zero, return DEST. */
7081 if (integer_zerop (len))
7082 return omit_one_operand (TREE_TYPE (exp), dest, src);
7084 /* If SRC and DEST are the same (and not volatile), return DEST. */
7085 if (operand_equal_p (src, dest, 0))
7086 return omit_one_operand (TREE_TYPE (exp), dest, len);
7088 return 0;
7091 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7092 the length of the string to be copied. Return NULL_TREE if no
7093 simplification can be made. */
7095 tree
7096 fold_builtin_strcpy (tree exp, tree len)
7098 tree arglist = TREE_OPERAND (exp, 1);
7099 tree dest, src, fn;
7101 if (!validate_arglist (arglist,
7102 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7103 return 0;
7105 dest = TREE_VALUE (arglist);
7106 src = TREE_VALUE (TREE_CHAIN (arglist));
7108 /* If SRC and DEST are the same (and not volatile), return DEST. */
7109 if (operand_equal_p (src, dest, 0))
7110 return fold_convert (TREE_TYPE (exp), dest);
7112 if (optimize_size)
7113 return 0;
7115 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7116 if (!fn)
7117 return 0;
7119 if (!len)
7121 len = c_strlen (src, 1);
7122 if (! len || TREE_SIDE_EFFECTS (len))
7123 return 0;
7126 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7127 arglist = build_tree_list (NULL_TREE, len);
7128 arglist = tree_cons (NULL_TREE, src, arglist);
7129 arglist = tree_cons (NULL_TREE, dest, arglist);
7130 return fold_convert (TREE_TYPE (exp),
7131 build_function_call_expr (fn, arglist));
7134 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7135 the length of the source string. Return NULL_TREE if no simplification
7136 can be made. */
7138 tree
7139 fold_builtin_strncpy (tree exp, tree slen)
7141 tree arglist = TREE_OPERAND (exp, 1);
7142 tree dest, src, len, fn;
7144 if (!validate_arglist (arglist,
7145 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7146 return 0;
7148 dest = TREE_VALUE (arglist);
7149 src = TREE_VALUE (TREE_CHAIN (arglist));
7150 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7152 /* If the LEN parameter is zero, return DEST. */
7153 if (integer_zerop (len))
7154 return omit_one_operand (TREE_TYPE (exp), dest, src);
7156 /* We can't compare slen with len as constants below if len is not a
7157 constant. */
7158 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7159 return 0;
7161 if (!slen)
7162 slen = c_strlen (src, 1);
7164 /* Now, we must be passed a constant src ptr parameter. */
7165 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7166 return 0;
7168 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7170 /* We do not support simplification of this case, though we do
7171 support it when expanding trees into RTL. */
7172 /* FIXME: generate a call to __builtin_memset. */
7173 if (tree_int_cst_lt (slen, len))
7174 return 0;
7176 /* OK transform into builtin memcpy. */
7177 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7178 if (!fn)
7179 return 0;
7180 return fold_convert (TREE_TYPE (exp),
7181 build_function_call_expr (fn, arglist));
7184 /* Fold function call to builtin strchr and strrchr.
7185 Return NULL_TREE if no simplification can be made. */
7187 static tree
7188 fold_builtin_strchr (tree exp, bool actually_strrchr)
7190 tree arglist = TREE_OPERAND (exp, 1);
7191 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7192 return 0;
7193 else
7195 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7196 const char *p1;
7198 if (TREE_CODE (s2) != INTEGER_CST)
7199 return 0;
7201 p1 = c_getstr (s1);
7202 if (p1 != NULL)
7204 char c;
7205 const char *r;
7207 if (target_char_cast (s2, &c))
7208 return 0;
7210 r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7212 if (r == NULL)
7213 return build_int_cst (TREE_TYPE (s1), 0);
7215 /* Return an offset into the constant string argument. */
7216 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7217 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
7220 if (actually_strrchr)
7222 tree fn;
7224 if (!integer_zerop (s2))
7225 return 0;
7227 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7228 if (!fn)
7229 return 0;
7231 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
7232 return build_function_call_expr (fn, arglist);
7235 return 0;
7239 /* Fold function call to builtin memcmp. Return
7240 NULL_TREE if no simplification can be made. */
7242 static tree
7243 fold_builtin_memcmp (tree arglist)
7245 tree arg1, arg2, len;
7246 const char *p1, *p2;
7248 if (!validate_arglist (arglist,
7249 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7250 return 0;
7252 arg1 = TREE_VALUE (arglist);
7253 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7254 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7256 /* If the LEN parameter is zero, return zero. */
7257 if (integer_zerop (len))
7258 return omit_two_operands (integer_type_node, integer_zero_node,
7259 arg1, arg2);
7261 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7262 if (operand_equal_p (arg1, arg2, 0))
7263 return omit_one_operand (integer_type_node, integer_zero_node, len);
7265 p1 = c_getstr (arg1);
7266 p2 = c_getstr (arg2);
7268 /* If all arguments are constant, and the value of len is not greater
7269 than the lengths of arg1 and arg2, evaluate at compile-time. */
7270 if (host_integerp (len, 1) && p1 && p2
7271 && compare_tree_int (len, strlen (p1) + 1) <= 0
7272 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7274 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7276 if (r > 0)
7277 return integer_one_node;
7278 else if (r < 0)
7279 return integer_minus_one_node;
7280 else
7281 return integer_zero_node;
7284 /* If len parameter is one, return an expression corresponding to
7285 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7286 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7288 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7289 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7290 tree ind1 = fold_convert (integer_type_node,
7291 build1 (INDIRECT_REF, cst_uchar_node,
7292 fold_convert (cst_uchar_ptr_node,
7293 arg1)));
7294 tree ind2 = fold_convert (integer_type_node,
7295 build1 (INDIRECT_REF, cst_uchar_node,
7296 fold_convert (cst_uchar_ptr_node,
7297 arg2)));
7298 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7301 return 0;
7304 /* Fold function call to builtin strcmp. Return
7305 NULL_TREE if no simplification can be made. */
7307 static tree
7308 fold_builtin_strcmp (tree arglist)
7310 tree arg1, arg2;
7311 const char *p1, *p2;
7313 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7314 return 0;
7316 arg1 = TREE_VALUE (arglist);
7317 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7319 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7320 if (operand_equal_p (arg1, arg2, 0))
7321 return integer_zero_node;
7323 p1 = c_getstr (arg1);
7324 p2 = c_getstr (arg2);
7326 if (p1 && p2)
7328 const int i = strcmp (p1, p2);
7329 if (i < 0)
7330 return integer_minus_one_node;
7331 else if (i > 0)
7332 return integer_one_node;
7333 else
7334 return integer_zero_node;
7337 /* If the second arg is "", return *(const unsigned char*)arg1. */
7338 if (p2 && *p2 == '\0')
7340 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7341 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7342 return fold_convert (integer_type_node,
7343 build1 (INDIRECT_REF, cst_uchar_node,
7344 fold_convert (cst_uchar_ptr_node,
7345 arg1)));
7348 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7349 if (p1 && *p1 == '\0')
7351 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7352 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7353 tree temp = fold_convert (integer_type_node,
7354 build1 (INDIRECT_REF, cst_uchar_node,
7355 fold_convert (cst_uchar_ptr_node,
7356 arg2)));
7357 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7360 return 0;
7363 /* Fold function call to builtin strncmp. Return
7364 NULL_TREE if no simplification can be made. */
7366 static tree
7367 fold_builtin_strncmp (tree arglist)
7369 tree arg1, arg2, len;
7370 const char *p1, *p2;
7372 if (!validate_arglist (arglist,
7373 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7374 return 0;
7376 arg1 = TREE_VALUE (arglist);
7377 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7378 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7380 /* If the LEN parameter is zero, return zero. */
7381 if (integer_zerop (len))
7382 return omit_two_operands (integer_type_node, integer_zero_node,
7383 arg1, arg2);
7385 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7386 if (operand_equal_p (arg1, arg2, 0))
7387 return omit_one_operand (integer_type_node, integer_zero_node, len);
7389 p1 = c_getstr (arg1);
7390 p2 = c_getstr (arg2);
7392 if (host_integerp (len, 1) && p1 && p2)
7394 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7395 if (i > 0)
7396 return integer_one_node;
7397 else if (i < 0)
7398 return integer_minus_one_node;
7399 else
7400 return integer_zero_node;
7403 /* If the second arg is "", and the length is greater than zero,
7404 return *(const unsigned char*)arg1. */
7405 if (p2 && *p2 == '\0'
7406 && TREE_CODE (len) == INTEGER_CST
7407 && tree_int_cst_sgn (len) == 1)
7409 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7410 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7411 return fold_convert (integer_type_node,
7412 build1 (INDIRECT_REF, cst_uchar_node,
7413 fold_convert (cst_uchar_ptr_node,
7414 arg1)));
7417 /* If the first arg is "", and the length is greater than zero,
7418 return -*(const unsigned char*)arg2. */
7419 if (p1 && *p1 == '\0'
7420 && TREE_CODE (len) == INTEGER_CST
7421 && tree_int_cst_sgn (len) == 1)
7423 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7424 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7425 tree temp = fold_convert (integer_type_node,
7426 build1 (INDIRECT_REF, cst_uchar_node,
7427 fold_convert (cst_uchar_ptr_node,
7428 arg2)));
7429 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7432 /* If len parameter is one, return an expression corresponding to
7433 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7434 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7436 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7437 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7438 tree ind1 = fold_convert (integer_type_node,
7439 build1 (INDIRECT_REF, cst_uchar_node,
7440 fold_convert (cst_uchar_ptr_node,
7441 arg1)));
7442 tree ind2 = fold_convert (integer_type_node,
7443 build1 (INDIRECT_REF, cst_uchar_node,
7444 fold_convert (cst_uchar_ptr_node,
7445 arg2)));
7446 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7449 return 0;
7452 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7453 NULL_TREE if no simplification can be made. */
7455 static tree
7456 fold_builtin_signbit (tree exp)
7458 tree arglist = TREE_OPERAND (exp, 1);
7459 tree arg, temp;
7461 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7462 return NULL_TREE;
7464 arg = TREE_VALUE (arglist);
7466 /* If ARG is a compile-time constant, determine the result. */
7467 if (TREE_CODE (arg) == REAL_CST
7468 && !TREE_CONSTANT_OVERFLOW (arg))
7470 REAL_VALUE_TYPE c;
7472 c = TREE_REAL_CST (arg);
7473 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7474 return fold_convert (TREE_TYPE (exp), temp);
7477 /* If ARG is non-negative, the result is always zero. */
7478 if (tree_expr_nonnegative_p (arg))
7479 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7481 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7482 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7483 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7484 build_real (TREE_TYPE (arg), dconst0)));
7486 return NULL_TREE;
7489 /* Fold function call to builtin copysign, copysignf or copysignl.
7490 Return NULL_TREE if no simplification can be made. */
7492 static tree
7493 fold_builtin_copysign (tree arglist, tree type)
7495 tree arg1, arg2;
7497 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7498 return NULL_TREE;
7500 arg1 = TREE_VALUE (arglist);
7501 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7503 /* copysign(X,X) is X. */
7504 if (operand_equal_p (arg1, arg2, 0))
7505 return fold_convert (type, arg1);
7507 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7508 if (TREE_CODE (arg1) == REAL_CST
7509 && TREE_CODE (arg2) == REAL_CST
7510 && !TREE_CONSTANT_OVERFLOW (arg1)
7511 && !TREE_CONSTANT_OVERFLOW (arg2))
7513 REAL_VALUE_TYPE c1, c2;
7515 c1 = TREE_REAL_CST (arg1);
7516 c2 = TREE_REAL_CST (arg2);
7517 real_copysign (&c1, &c2);
7518 return build_real (type, c1);
7519 c1.sign = c2.sign;
7522 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7523 Remember to evaluate Y for side-effects. */
7524 if (tree_expr_nonnegative_p (arg2))
7525 return omit_one_operand (type,
7526 fold (build1 (ABS_EXPR, type, arg1)),
7527 arg2);
7529 return NULL_TREE;
7532 /* Fold a call to builtin isascii. */
7534 static tree
7535 fold_builtin_isascii (tree arglist)
7537 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7538 return 0;
7539 else
7541 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7542 tree arg = TREE_VALUE (arglist);
7544 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7545 build_int_cst (NULL_TREE,
7546 ~ (unsigned HOST_WIDE_INT) 0x7f));
7547 arg = fold (build2 (EQ_EXPR, integer_type_node,
7548 arg, integer_zero_node));
7550 if (in_gimple_form && !TREE_CONSTANT (arg))
7551 return NULL_TREE;
7552 else
7553 return arg;
7557 /* Fold a call to builtin toascii. */
7559 static tree
7560 fold_builtin_toascii (tree arglist)
7562 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7563 return 0;
7564 else
7566 /* Transform toascii(c) -> (c & 0x7f). */
7567 tree arg = TREE_VALUE (arglist);
7569 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7570 build_int_cst (NULL_TREE, 0x7f)));
7574 /* Fold a call to builtin isdigit. */
7576 static tree
7577 fold_builtin_isdigit (tree arglist)
7579 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7580 return 0;
7581 else
7583 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7584 /* According to the C standard, isdigit is unaffected by locale. */
7585 tree arg = TREE_VALUE (arglist);
7586 arg = fold_convert (unsigned_type_node, arg);
7587 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7588 build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7589 arg = build2 (LE_EXPR, integer_type_node, arg,
7590 build_int_cst (unsigned_type_node, 9));
7591 arg = fold (arg);
7592 if (in_gimple_form && !TREE_CONSTANT (arg))
7593 return NULL_TREE;
7594 else
7595 return arg;
7599 /* Fold a call to fabs, fabsf or fabsl. */
7601 static tree
7602 fold_builtin_fabs (tree arglist, tree type)
7604 tree arg;
7606 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7607 return 0;
7609 arg = TREE_VALUE (arglist);
7610 if (TREE_CODE (arg) == REAL_CST)
7611 return fold_abs_const (arg, type);
7612 return fold (build1 (ABS_EXPR, type, arg));
7615 /* Fold a call to abs, labs, llabs or imaxabs. */
7617 static tree
7618 fold_builtin_abs (tree arglist, tree type)
7620 tree arg;
7622 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7623 return 0;
7625 arg = TREE_VALUE (arglist);
7626 if (TREE_CODE (arg) == INTEGER_CST)
7627 return fold_abs_const (arg, type);
7628 return fold (build1 (ABS_EXPR, type, arg));
7631 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7632 EXP is the CALL_EXPR for the call. */
7634 static tree
7635 fold_builtin_classify (tree exp, int builtin_index)
7637 tree fndecl = get_callee_fndecl (exp);
7638 tree arglist = TREE_OPERAND (exp, 1);
7639 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7640 tree arg;
7641 REAL_VALUE_TYPE r;
7643 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7645 /* Check that we have exactly one argument. */
7646 if (arglist == 0)
7648 error ("too few arguments to function `%s'",
7649 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7650 return error_mark_node;
7652 else if (TREE_CHAIN (arglist) != 0)
7654 error ("too many arguments to function `%s'",
7655 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7656 return error_mark_node;
7658 else
7660 error ("non-floating-point argument to function `%s'",
7661 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7662 return error_mark_node;
7666 arg = TREE_VALUE (arglist);
7667 switch (builtin_index)
7669 case BUILT_IN_ISINF:
7670 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7671 return omit_one_operand (type, integer_zero_node, arg);
7673 if (TREE_CODE (arg) == REAL_CST)
7675 r = TREE_REAL_CST (arg);
7676 if (real_isinf (&r))
7677 return real_compare (GT_EXPR, &r, &dconst0)
7678 ? integer_one_node : integer_minus_one_node;
7679 else
7680 return integer_zero_node;
7683 return NULL_TREE;
7685 case BUILT_IN_FINITE:
7686 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7687 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7688 return omit_one_operand (type, integer_zero_node, arg);
7690 if (TREE_CODE (arg) == REAL_CST)
7692 r = TREE_REAL_CST (arg);
7693 return real_isinf (&r) || real_isnan (&r)
7694 ? integer_zero_node : integer_one_node;
7697 return NULL_TREE;
7699 case BUILT_IN_ISNAN:
7700 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7701 return omit_one_operand (type, integer_zero_node, arg);
7703 if (TREE_CODE (arg) == REAL_CST)
7705 r = TREE_REAL_CST (arg);
7706 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7709 arg = builtin_save_expr (arg);
7710 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7712 default:
7713 gcc_unreachable ();
7717 /* Fold a call to an unordered comparison function such as
7718 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7719 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7720 the opposite of the desired result. UNORDERED_CODE is used
7721 for modes that can hold NaNs and ORDERED_CODE is used for
7722 the rest. */
7724 static tree
7725 fold_builtin_unordered_cmp (tree exp,
7726 enum tree_code unordered_code,
7727 enum tree_code ordered_code)
7729 tree fndecl = get_callee_fndecl (exp);
7730 tree arglist = TREE_OPERAND (exp, 1);
7731 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7732 enum tree_code code;
7733 tree arg0, arg1;
7735 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7737 enum tree_code code0, code1;
7738 tree type0, type1;
7739 tree cmp_type = 0;
7741 /* Check that we have exactly two arguments. */
7742 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7744 error ("too few arguments to function `%s'",
7745 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7746 return error_mark_node;
7748 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7750 error ("too many arguments to function `%s'",
7751 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7752 return error_mark_node;
7755 arg0 = TREE_VALUE (arglist);
7756 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7758 type0 = TREE_TYPE (arg0);
7759 type1 = TREE_TYPE (arg1);
7761 code0 = TREE_CODE (type0);
7762 code1 = TREE_CODE (type1);
7764 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7765 /* Choose the wider of two real types. */
7766 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7767 ? type0 : type1;
7768 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7769 cmp_type = type0;
7770 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7771 cmp_type = type1;
7772 else
7774 error ("non-floating-point argument to function `%s'",
7775 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7776 return error_mark_node;
7779 arg0 = fold_convert (cmp_type, arg0);
7780 arg1 = fold_convert (cmp_type, arg1);
7782 else
7784 arg0 = TREE_VALUE (arglist);
7785 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7788 if (unordered_code == UNORDERED_EXPR)
7790 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7791 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7792 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7795 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7796 : ordered_code;
7797 return fold (build1 (TRUTH_NOT_EXPR, type,
7798 fold (build2 (code, type, arg0, arg1))));
7801 /* Used by constant folding to simplify calls to builtin functions. EXP is
7802 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7803 result of the function call is ignored. This function returns NULL_TREE
7804 if no simplification was possible. */
7806 static tree
7807 fold_builtin_1 (tree exp, bool ignore)
7809 tree fndecl = get_callee_fndecl (exp);
7810 tree arglist = TREE_OPERAND (exp, 1);
7811 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7813 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7814 return 0;
7816 switch (DECL_FUNCTION_CODE (fndecl))
7818 case BUILT_IN_CONSTANT_P:
7819 return fold_builtin_constant_p (arglist);
7821 case BUILT_IN_EXPECT:
7822 return fold_builtin_expect (arglist);
7824 case BUILT_IN_CLASSIFY_TYPE:
7825 return fold_builtin_classify_type (arglist);
7827 case BUILT_IN_STRLEN:
7828 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7830 tree len = c_strlen (TREE_VALUE (arglist), 0);
7831 if (len)
7833 /* Convert from the internal "sizetype" type to "size_t". */
7834 if (size_type_node)
7835 len = fold_convert (size_type_node, len);
7836 return len;
7839 break;
7841 case BUILT_IN_FABS:
7842 case BUILT_IN_FABSF:
7843 case BUILT_IN_FABSL:
7844 return fold_builtin_fabs (arglist, type);
7846 case BUILT_IN_ABS:
7847 case BUILT_IN_LABS:
7848 case BUILT_IN_LLABS:
7849 case BUILT_IN_IMAXABS:
7850 return fold_builtin_abs (arglist, type);
7852 case BUILT_IN_CONJ:
7853 case BUILT_IN_CONJF:
7854 case BUILT_IN_CONJL:
7855 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7856 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7857 break;
7859 case BUILT_IN_CREAL:
7860 case BUILT_IN_CREALF:
7861 case BUILT_IN_CREALL:
7862 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7863 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7864 TREE_VALUE (arglist))));
7865 break;
7867 case BUILT_IN_CIMAG:
7868 case BUILT_IN_CIMAGF:
7869 case BUILT_IN_CIMAGL:
7870 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7871 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7872 TREE_VALUE (arglist))));
7873 break;
7875 case BUILT_IN_CABS:
7876 case BUILT_IN_CABSF:
7877 case BUILT_IN_CABSL:
7878 return fold_builtin_cabs (arglist, type);
7880 case BUILT_IN_SQRT:
7881 case BUILT_IN_SQRTF:
7882 case BUILT_IN_SQRTL:
7883 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7885 enum built_in_function fcode;
7886 tree arg = TREE_VALUE (arglist);
7888 /* Optimize sqrt of constant value. */
7889 if (TREE_CODE (arg) == REAL_CST
7890 && ! TREE_CONSTANT_OVERFLOW (arg))
7892 REAL_VALUE_TYPE r, x;
7894 x = TREE_REAL_CST (arg);
7895 if (real_sqrt (&r, TYPE_MODE (type), &x)
7896 || (!flag_trapping_math && !flag_errno_math))
7897 return build_real (type, r);
7900 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7901 fcode = builtin_mathfn_code (arg);
7902 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7904 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7905 arg = fold (build2 (MULT_EXPR, type,
7906 TREE_VALUE (TREE_OPERAND (arg, 1)),
7907 build_real (type, dconsthalf)));
7908 arglist = build_tree_list (NULL_TREE, arg);
7909 return build_function_call_expr (expfn, arglist);
7912 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7913 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7915 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7917 if (powfn)
7919 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7920 tree tree_root;
7921 /* The inner root was either sqrt or cbrt. */
7922 REAL_VALUE_TYPE dconstroot =
7923 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7925 /* Adjust for the outer root. */
7926 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7927 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7928 tree_root = build_real (type, dconstroot);
7929 arglist = tree_cons (NULL_TREE, arg0,
7930 build_tree_list (NULL_TREE, tree_root));
7931 return build_function_call_expr (powfn, arglist);
7935 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
7936 if (flag_unsafe_math_optimizations
7937 && (fcode == BUILT_IN_POW
7938 || fcode == BUILT_IN_POWF
7939 || fcode == BUILT_IN_POWL))
7941 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7942 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7943 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7944 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7945 build_real (type, dconsthalf)));
7946 arglist = tree_cons (NULL_TREE, arg0,
7947 build_tree_list (NULL_TREE, narg1));
7948 return build_function_call_expr (powfn, arglist);
7951 break;
7953 case BUILT_IN_CBRT:
7954 case BUILT_IN_CBRTF:
7955 case BUILT_IN_CBRTL:
7956 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7958 tree arg = TREE_VALUE (arglist);
7959 const enum built_in_function fcode = builtin_mathfn_code (arg);
7961 /* Optimize cbrt of constant value. */
7962 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7963 return arg;
7965 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7966 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7968 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7969 const REAL_VALUE_TYPE third_trunc =
7970 real_value_truncate (TYPE_MODE (type), dconstthird);
7971 arg = fold (build2 (MULT_EXPR, type,
7972 TREE_VALUE (TREE_OPERAND (arg, 1)),
7973 build_real (type, third_trunc)));
7974 arglist = build_tree_list (NULL_TREE, arg);
7975 return build_function_call_expr (expfn, arglist);
7978 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7979 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
7980 x is negative pow will error but cbrt won't. */
7981 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7983 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7985 if (powfn)
7987 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7988 tree tree_root;
7989 REAL_VALUE_TYPE dconstroot = dconstthird;
7991 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7992 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7993 tree_root = build_real (type, dconstroot);
7994 arglist = tree_cons (NULL_TREE, arg0,
7995 build_tree_list (NULL_TREE, tree_root));
7996 return build_function_call_expr (powfn, arglist);
8001 break;
8003 case BUILT_IN_SIN:
8004 case BUILT_IN_SINF:
8005 case BUILT_IN_SINL:
8006 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8008 tree arg = TREE_VALUE (arglist);
8010 /* Optimize sin(0.0) = 0.0. */
8011 if (real_zerop (arg))
8012 return arg;
8014 break;
8016 case BUILT_IN_COS:
8017 case BUILT_IN_COSF:
8018 case BUILT_IN_COSL:
8019 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8021 tree arg = TREE_VALUE (arglist);
8023 /* Optimize cos(0.0) = 1.0. */
8024 if (real_zerop (arg))
8025 return build_real (type, dconst1);
8027 /* Optimize cos(-x) into cos(x). */
8028 if (TREE_CODE (arg) == NEGATE_EXPR)
8030 tree arglist = build_tree_list (NULL_TREE,
8031 TREE_OPERAND (arg, 0));
8032 return build_function_call_expr (fndecl, arglist);
8035 break;
8037 case BUILT_IN_EXP:
8038 case BUILT_IN_EXPF:
8039 case BUILT_IN_EXPL:
8040 return fold_builtin_exponent (exp, &dconste);
8042 case BUILT_IN_EXP2:
8043 case BUILT_IN_EXP2F:
8044 case BUILT_IN_EXP2L:
8045 return fold_builtin_exponent (exp, &dconst2);
8047 case BUILT_IN_EXP10:
8048 case BUILT_IN_EXP10F:
8049 case BUILT_IN_EXP10L:
8050 case BUILT_IN_POW10:
8051 case BUILT_IN_POW10F:
8052 case BUILT_IN_POW10L:
8053 return fold_builtin_exponent (exp, &dconst10);
8055 case BUILT_IN_LOG:
8056 case BUILT_IN_LOGF:
8057 case BUILT_IN_LOGL:
8058 return fold_builtin_logarithm (exp, &dconste);
8060 case BUILT_IN_LOG2:
8061 case BUILT_IN_LOG2F:
8062 case BUILT_IN_LOG2L:
8063 return fold_builtin_logarithm (exp, &dconst2);
8065 case BUILT_IN_LOG10:
8066 case BUILT_IN_LOG10F:
8067 case BUILT_IN_LOG10L:
8068 return fold_builtin_logarithm (exp, &dconst10);
8070 case BUILT_IN_TAN:
8071 case BUILT_IN_TANF:
8072 case BUILT_IN_TANL:
8073 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8075 enum built_in_function fcode;
8076 tree arg = TREE_VALUE (arglist);
8078 /* Optimize tan(0.0) = 0.0. */
8079 if (real_zerop (arg))
8080 return arg;
8082 /* Optimize tan(atan(x)) = x. */
8083 fcode = builtin_mathfn_code (arg);
8084 if (flag_unsafe_math_optimizations
8085 && (fcode == BUILT_IN_ATAN
8086 || fcode == BUILT_IN_ATANF
8087 || fcode == BUILT_IN_ATANL))
8088 return TREE_VALUE (TREE_OPERAND (arg, 1));
8090 break;
8092 case BUILT_IN_ATAN:
8093 case BUILT_IN_ATANF:
8094 case BUILT_IN_ATANL:
8095 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8097 tree arg = TREE_VALUE (arglist);
8099 /* Optimize atan(0.0) = 0.0. */
8100 if (real_zerop (arg))
8101 return arg;
8103 /* Optimize atan(1.0) = pi/4. */
8104 if (real_onep (arg))
8106 REAL_VALUE_TYPE cst;
8108 real_convert (&cst, TYPE_MODE (type), &dconstpi);
8109 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8110 return build_real (type, cst);
8113 break;
8115 case BUILT_IN_POW:
8116 case BUILT_IN_POWF:
8117 case BUILT_IN_POWL:
8118 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8120 enum built_in_function fcode;
8121 tree arg0 = TREE_VALUE (arglist);
8122 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8124 /* Optimize pow(1.0,y) = 1.0. */
8125 if (real_onep (arg0))
8126 return omit_one_operand (type, build_real (type, dconst1), arg1);
8128 if (TREE_CODE (arg1) == REAL_CST
8129 && ! TREE_CONSTANT_OVERFLOW (arg1))
8131 REAL_VALUE_TYPE c;
8132 c = TREE_REAL_CST (arg1);
8134 /* Optimize pow(x,0.0) = 1.0. */
8135 if (REAL_VALUES_EQUAL (c, dconst0))
8136 return omit_one_operand (type, build_real (type, dconst1),
8137 arg0);
8139 /* Optimize pow(x,1.0) = x. */
8140 if (REAL_VALUES_EQUAL (c, dconst1))
8141 return arg0;
8143 /* Optimize pow(x,-1.0) = 1.0/x. */
8144 if (REAL_VALUES_EQUAL (c, dconstm1))
8145 return fold (build2 (RDIV_EXPR, type,
8146 build_real (type, dconst1), arg0));
8148 /* Optimize pow(x,0.5) = sqrt(x). */
8149 if (flag_unsafe_math_optimizations
8150 && REAL_VALUES_EQUAL (c, dconsthalf))
8152 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8154 if (sqrtfn != NULL_TREE)
8156 tree arglist = build_tree_list (NULL_TREE, arg0);
8157 return build_function_call_expr (sqrtfn, arglist);
8161 /* Attempt to evaluate pow at compile-time. */
8162 if (TREE_CODE (arg0) == REAL_CST
8163 && ! TREE_CONSTANT_OVERFLOW (arg0))
8165 REAL_VALUE_TYPE cint;
8166 HOST_WIDE_INT n;
8168 n = real_to_integer (&c);
8169 real_from_integer (&cint, VOIDmode, n,
8170 n < 0 ? -1 : 0, 0);
8171 if (real_identical (&c, &cint))
8173 REAL_VALUE_TYPE x;
8174 bool inexact;
8176 x = TREE_REAL_CST (arg0);
8177 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8178 if (flag_unsafe_math_optimizations || !inexact)
8179 return build_real (type, x);
8184 /* Optimize pow(expN(x),y) = expN(x*y). */
8185 fcode = builtin_mathfn_code (arg0);
8186 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8188 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8189 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8190 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8191 arglist = build_tree_list (NULL_TREE, arg);
8192 return build_function_call_expr (expfn, arglist);
8195 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8196 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8198 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8199 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8200 build_real (type, dconsthalf)));
8202 arglist = tree_cons (NULL_TREE, narg0,
8203 build_tree_list (NULL_TREE, narg1));
8204 return build_function_call_expr (fndecl, arglist);
8207 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8208 if (flag_unsafe_math_optimizations
8209 && (fcode == BUILT_IN_POW
8210 || fcode == BUILT_IN_POWF
8211 || fcode == BUILT_IN_POWL))
8213 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8214 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8215 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8216 arglist = tree_cons (NULL_TREE, arg00,
8217 build_tree_list (NULL_TREE, narg1));
8218 return build_function_call_expr (fndecl, arglist);
8221 break;
8223 case BUILT_IN_INF:
8224 case BUILT_IN_INFF:
8225 case BUILT_IN_INFL:
8226 return fold_builtin_inf (type, true);
8228 case BUILT_IN_HUGE_VAL:
8229 case BUILT_IN_HUGE_VALF:
8230 case BUILT_IN_HUGE_VALL:
8231 return fold_builtin_inf (type, false);
8233 case BUILT_IN_NAN:
8234 case BUILT_IN_NANF:
8235 case BUILT_IN_NANL:
8236 return fold_builtin_nan (arglist, type, true);
8238 case BUILT_IN_NANS:
8239 case BUILT_IN_NANSF:
8240 case BUILT_IN_NANSL:
8241 return fold_builtin_nan (arglist, type, false);
8243 case BUILT_IN_FLOOR:
8244 case BUILT_IN_FLOORF:
8245 case BUILT_IN_FLOORL:
8246 return fold_builtin_floor (exp);
8248 case BUILT_IN_CEIL:
8249 case BUILT_IN_CEILF:
8250 case BUILT_IN_CEILL:
8251 return fold_builtin_ceil (exp);
8253 case BUILT_IN_TRUNC:
8254 case BUILT_IN_TRUNCF:
8255 case BUILT_IN_TRUNCL:
8256 return fold_builtin_trunc (exp);
8258 case BUILT_IN_ROUND:
8259 case BUILT_IN_ROUNDF:
8260 case BUILT_IN_ROUNDL:
8261 return fold_builtin_round (exp);
8263 case BUILT_IN_NEARBYINT:
8264 case BUILT_IN_NEARBYINTF:
8265 case BUILT_IN_NEARBYINTL:
8266 case BUILT_IN_RINT:
8267 case BUILT_IN_RINTF:
8268 case BUILT_IN_RINTL:
8269 return fold_trunc_transparent_mathfn (exp);
8271 case BUILT_IN_LROUND:
8272 case BUILT_IN_LROUNDF:
8273 case BUILT_IN_LROUNDL:
8274 case BUILT_IN_LLROUND:
8275 case BUILT_IN_LLROUNDF:
8276 case BUILT_IN_LLROUNDL:
8277 return fold_builtin_lround (exp);
8279 case BUILT_IN_LRINT:
8280 case BUILT_IN_LRINTF:
8281 case BUILT_IN_LRINTL:
8282 case BUILT_IN_LLRINT:
8283 case BUILT_IN_LLRINTF:
8284 case BUILT_IN_LLRINTL:
8285 return fold_fixed_mathfn (exp);
8287 case BUILT_IN_FFS:
8288 case BUILT_IN_FFSL:
8289 case BUILT_IN_FFSLL:
8290 case BUILT_IN_CLZ:
8291 case BUILT_IN_CLZL:
8292 case BUILT_IN_CLZLL:
8293 case BUILT_IN_CTZ:
8294 case BUILT_IN_CTZL:
8295 case BUILT_IN_CTZLL:
8296 case BUILT_IN_POPCOUNT:
8297 case BUILT_IN_POPCOUNTL:
8298 case BUILT_IN_POPCOUNTLL:
8299 case BUILT_IN_PARITY:
8300 case BUILT_IN_PARITYL:
8301 case BUILT_IN_PARITYLL:
8302 return fold_builtin_bitop (exp);
8304 case BUILT_IN_MEMCPY:
8305 return fold_builtin_memcpy (exp);
8307 case BUILT_IN_MEMPCPY:
8308 return fold_builtin_mempcpy (exp);
8310 case BUILT_IN_MEMMOVE:
8311 return fold_builtin_memmove (exp);
8313 case BUILT_IN_STRCPY:
8314 return fold_builtin_strcpy (exp, NULL_TREE);
8316 case BUILT_IN_STRNCPY:
8317 return fold_builtin_strncpy (exp, NULL_TREE);
8319 case BUILT_IN_INDEX:
8320 case BUILT_IN_STRCHR:
8321 return fold_builtin_strchr (exp, false);
8323 case BUILT_IN_RINDEX:
8324 case BUILT_IN_STRRCHR:
8325 return fold_builtin_strchr (exp, true);
8327 case BUILT_IN_MEMCMP:
8328 return fold_builtin_memcmp (arglist);
8330 case BUILT_IN_STRCMP:
8331 return fold_builtin_strcmp (arglist);
8333 case BUILT_IN_STRNCMP:
8334 return fold_builtin_strncmp (arglist);
8336 case BUILT_IN_SIGNBIT:
8337 case BUILT_IN_SIGNBITF:
8338 case BUILT_IN_SIGNBITL:
8339 return fold_builtin_signbit (exp);
8341 case BUILT_IN_ISASCII:
8342 return fold_builtin_isascii (arglist);
8344 case BUILT_IN_TOASCII:
8345 return fold_builtin_toascii (arglist);
8347 case BUILT_IN_ISDIGIT:
8348 return fold_builtin_isdigit (arglist);
8350 case BUILT_IN_COPYSIGN:
8351 case BUILT_IN_COPYSIGNF:
8352 case BUILT_IN_COPYSIGNL:
8353 return fold_builtin_copysign (arglist, type);
8355 case BUILT_IN_FINITE:
8356 case BUILT_IN_FINITEF:
8357 case BUILT_IN_FINITEL:
8358 return fold_builtin_classify (exp, BUILT_IN_FINITE);
8360 case BUILT_IN_ISINF:
8361 case BUILT_IN_ISINFF:
8362 case BUILT_IN_ISINFL:
8363 return fold_builtin_classify (exp, BUILT_IN_ISINF);
8365 case BUILT_IN_ISNAN:
8366 case BUILT_IN_ISNANF:
8367 case BUILT_IN_ISNANL:
8368 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8370 case BUILT_IN_ISGREATER:
8371 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8372 case BUILT_IN_ISGREATEREQUAL:
8373 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8374 case BUILT_IN_ISLESS:
8375 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8376 case BUILT_IN_ISLESSEQUAL:
8377 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8378 case BUILT_IN_ISLESSGREATER:
8379 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8380 case BUILT_IN_ISUNORDERED:
8381 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8383 case BUILT_IN_FPUTS:
8384 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8386 case BUILT_IN_FPUTS_UNLOCKED:
8387 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8389 default:
8390 break;
8393 return 0;
8396 /* A wrapper function for builtin folding that prevents warnings for
8397 "statement without effect" and the like, caused by removing the
8398 call node earlier than the warning is generated. */
8400 tree
8401 fold_builtin (tree exp, bool ignore)
8403 exp = fold_builtin_1 (exp, ignore);
8404 if (exp)
8406 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8407 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8408 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8409 TREE_NO_WARNING (exp) = 1;
8411 return exp;
8414 /* Conveniently construct a function call expression. */
8416 tree
8417 build_function_call_expr (tree fn, tree arglist)
8419 tree call_expr;
8421 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8422 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8423 call_expr, arglist, NULL_TREE);
8424 return fold (call_expr);
8427 /* This function validates the types of a function call argument list
8428 represented as a tree chain of parameters against a specified list
8429 of tree_codes. If the last specifier is a 0, that represents an
8430 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8432 static int
8433 validate_arglist (tree arglist, ...)
8435 enum tree_code code;
8436 int res = 0;
8437 va_list ap;
8439 va_start (ap, arglist);
8443 code = va_arg (ap, enum tree_code);
8444 switch (code)
8446 case 0:
8447 /* This signifies an ellipses, any further arguments are all ok. */
8448 res = 1;
8449 goto end;
8450 case VOID_TYPE:
8451 /* This signifies an endlink, if no arguments remain, return
8452 true, otherwise return false. */
8453 res = arglist == 0;
8454 goto end;
8455 default:
8456 /* If no parameters remain or the parameter's code does not
8457 match the specified code, return false. Otherwise continue
8458 checking any remaining arguments. */
8459 if (arglist == 0
8460 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8461 goto end;
8462 break;
8464 arglist = TREE_CHAIN (arglist);
8466 while (1);
8468 /* We need gotos here since we can only have one VA_CLOSE in a
8469 function. */
8470 end: ;
8471 va_end (ap);
8473 return res;
8476 /* Default target-specific builtin expander that does nothing. */
8479 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8480 rtx target ATTRIBUTE_UNUSED,
8481 rtx subtarget ATTRIBUTE_UNUSED,
8482 enum machine_mode mode ATTRIBUTE_UNUSED,
8483 int ignore ATTRIBUTE_UNUSED)
8485 return NULL_RTX;
8488 /* Returns true is EXP represents data that would potentially reside
8489 in a readonly section. */
8491 static bool
8492 readonly_data_expr (tree exp)
8494 STRIP_NOPS (exp);
8496 if (TREE_CODE (exp) != ADDR_EXPR)
8497 return false;
8499 exp = get_base_address (TREE_OPERAND (exp, 0));
8500 if (!exp)
8501 return false;
8503 /* Make sure we call decl_readonly_section only for trees it
8504 can handle (since it returns true for everything it doesn't
8505 understand). */
8506 if (TREE_CODE (exp) == STRING_CST
8507 || TREE_CODE (exp) == CONSTRUCTOR
8508 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8509 return decl_readonly_section (exp, 0);
8510 else
8511 return false;
8514 /* Front-end to the simplify_builtin_XXX routines.
8516 EXP is a call to a builtin function. If possible try to simplify
8517 that into a constant, expression or call to a more efficient
8518 builtin function.
8520 If IGNORE is nonzero, then the result of this builtin function
8521 call is ignored.
8523 If simplification is possible, return the simplified tree, otherwise
8524 return NULL_TREE. */
8526 tree
8527 simplify_builtin (tree exp, int ignore)
8529 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8530 tree arglist = TREE_OPERAND (exp, 1);
8531 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8532 tree val;
8534 switch (fcode)
8536 case BUILT_IN_FPUTS:
8537 val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8538 break;
8539 case BUILT_IN_FPUTS_UNLOCKED:
8540 val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8541 break;
8542 case BUILT_IN_STRSTR:
8543 val = simplify_builtin_strstr (arglist);
8544 break;
8545 case BUILT_IN_STRCAT:
8546 val = simplify_builtin_strcat (arglist);
8547 break;
8548 case BUILT_IN_STRNCAT:
8549 val = simplify_builtin_strncat (arglist);
8550 break;
8551 case BUILT_IN_STRSPN:
8552 val = simplify_builtin_strspn (arglist);
8553 break;
8554 case BUILT_IN_STRCSPN:
8555 val = simplify_builtin_strcspn (arglist);
8556 break;
8557 case BUILT_IN_STRCHR:
8558 case BUILT_IN_INDEX:
8559 val = simplify_builtin_strchr (arglist);
8560 break;
8561 case BUILT_IN_STRRCHR:
8562 case BUILT_IN_RINDEX:
8563 val = simplify_builtin_strrchr (arglist);
8564 break;
8565 case BUILT_IN_STRCPY:
8566 val = fold_builtin_strcpy (exp, NULL_TREE);
8567 break;
8568 case BUILT_IN_STRNCPY:
8569 val = fold_builtin_strncpy (exp, NULL_TREE);
8570 break;
8571 case BUILT_IN_STRCMP:
8572 val = fold_builtin_strcmp (arglist);
8573 break;
8574 case BUILT_IN_STRNCMP:
8575 val = fold_builtin_strncmp (arglist);
8576 break;
8577 case BUILT_IN_STRPBRK:
8578 val = simplify_builtin_strpbrk (arglist);
8579 break;
8580 case BUILT_IN_BCMP:
8581 case BUILT_IN_MEMCMP:
8582 val = fold_builtin_memcmp (arglist);
8583 break;
8584 case BUILT_IN_VA_START:
8585 simplify_builtin_va_start (arglist);
8586 val = NULL_TREE;
8587 break;
8588 case BUILT_IN_SPRINTF:
8589 val = simplify_builtin_sprintf (arglist, ignore);
8590 break;
8591 case BUILT_IN_CONSTANT_P:
8592 val = fold_builtin_constant_p (arglist);
8593 /* Gimplification will pull the CALL_EXPR for the builtin out of
8594 an if condition. When not optimizing, we'll not CSE it back.
8595 To avoid link error types of regressions, return false now. */
8596 if (!val && !optimize)
8597 val = integer_zero_node;
8598 break;
8599 default:
8600 val = NULL_TREE;
8601 break;
8604 if (val)
8605 val = fold_convert (TREE_TYPE (exp), val);
8606 return val;
8609 /* Simplify a call to the strstr builtin.
8611 Return 0 if no simplification was possible, otherwise return the
8612 simplified form of the call as a tree.
8614 The simplified form may be a constant or other expression which
8615 computes the same value, but in a more efficient manner (including
8616 calls to other builtin functions).
8618 The call may contain arguments which need to be evaluated, but
8619 which are not useful to determine the result of the call. In
8620 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8621 COMPOUND_EXPR will be an argument which must be evaluated.
8622 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8623 COMPOUND_EXPR in the chain will contain the tree for the simplified
8624 form of the builtin function call. */
8626 static tree
8627 simplify_builtin_strstr (tree arglist)
8629 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8630 return 0;
8631 else
8633 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8634 tree fn;
8635 const char *p1, *p2;
8637 p2 = c_getstr (s2);
8638 if (p2 == NULL)
8639 return 0;
8641 p1 = c_getstr (s1);
8642 if (p1 != NULL)
8644 const char *r = strstr (p1, p2);
8646 if (r == NULL)
8647 return build_int_cst (TREE_TYPE (s1), 0);
8649 /* Return an offset into the constant string argument. */
8650 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8651 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8654 if (p2[0] == '\0')
8655 return s1;
8657 if (p2[1] != '\0')
8658 return 0;
8660 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8661 if (!fn)
8662 return 0;
8664 /* New argument list transforming strstr(s1, s2) to
8665 strchr(s1, s2[0]). */
8666 arglist = build_tree_list (NULL_TREE,
8667 build_int_cst (NULL_TREE, p2[0]));
8668 arglist = tree_cons (NULL_TREE, s1, arglist);
8669 return build_function_call_expr (fn, arglist);
8673 /* Simplify a call to the strstr builtin.
8675 Return 0 if no simplification was possible, otherwise return the
8676 simplified form of the call as a tree.
8678 The simplified form may be a constant or other expression which
8679 computes the same value, but in a more efficient manner (including
8680 calls to other builtin functions).
8682 The call may contain arguments which need to be evaluated, but
8683 which are not useful to determine the result of the call. In
8684 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8685 COMPOUND_EXPR will be an argument which must be evaluated.
8686 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8687 COMPOUND_EXPR in the chain will contain the tree for the simplified
8688 form of the builtin function call. */
8690 static tree
8691 simplify_builtin_strchr (tree arglist)
8693 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8694 return 0;
8695 else
8697 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8698 const char *p1;
8700 if (TREE_CODE (s2) != INTEGER_CST)
8701 return 0;
8703 p1 = c_getstr (s1);
8704 if (p1 != NULL)
8706 char c;
8707 const char *r;
8709 if (target_char_cast (s2, &c))
8710 return 0;
8712 r = strchr (p1, c);
8714 if (r == NULL)
8715 return build_int_cst (TREE_TYPE (s1), 0);
8717 /* Return an offset into the constant string argument. */
8718 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8719 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8722 /* FIXME: Should use here strchrM optab so that ports can optimize
8723 this. */
8724 return 0;
8728 /* Simplify a call to the strrchr builtin.
8730 Return 0 if no simplification was possible, otherwise return the
8731 simplified form of the call as a tree.
8733 The simplified form may be a constant or other expression which
8734 computes the same value, but in a more efficient manner (including
8735 calls to other builtin functions).
8737 The call may contain arguments which need to be evaluated, but
8738 which are not useful to determine the result of the call. In
8739 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8740 COMPOUND_EXPR will be an argument which must be evaluated.
8741 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8742 COMPOUND_EXPR in the chain will contain the tree for the simplified
8743 form of the builtin function call. */
8745 static tree
8746 simplify_builtin_strrchr (tree arglist)
8748 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8749 return 0;
8750 else
8752 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8753 tree fn;
8754 const char *p1;
8756 if (TREE_CODE (s2) != INTEGER_CST)
8757 return 0;
8759 p1 = c_getstr (s1);
8760 if (p1 != NULL)
8762 char c;
8763 const char *r;
8765 if (target_char_cast (s2, &c))
8766 return 0;
8768 r = strrchr (p1, c);
8770 if (r == NULL)
8771 return build_int_cst (TREE_TYPE (s1), 0);
8773 /* Return an offset into the constant string argument. */
8774 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8775 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8778 if (! integer_zerop (s2))
8779 return 0;
8781 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8782 if (!fn)
8783 return 0;
8785 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8786 return build_function_call_expr (fn, arglist);
8790 /* Simplify a call to the strpbrk builtin.
8792 Return 0 if no simplification was possible, otherwise return the
8793 simplified form of the call as a tree.
8795 The simplified form may be a constant or other expression which
8796 computes the same value, but in a more efficient manner (including
8797 calls to other builtin functions).
8799 The call may contain arguments which need to be evaluated, but
8800 which are not useful to determine the result of the call. In
8801 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8802 COMPOUND_EXPR will be an argument which must be evaluated.
8803 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8804 COMPOUND_EXPR in the chain will contain the tree for the simplified
8805 form of the builtin function call. */
8807 static tree
8808 simplify_builtin_strpbrk (tree arglist)
8810 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8811 return 0;
8812 else
8814 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8815 tree fn;
8816 const char *p1, *p2;
8818 p2 = c_getstr (s2);
8819 if (p2 == NULL)
8820 return 0;
8822 p1 = c_getstr (s1);
8823 if (p1 != NULL)
8825 const char *r = strpbrk (p1, p2);
8827 if (r == NULL)
8828 return build_int_cst (TREE_TYPE (s1), 0);
8830 /* Return an offset into the constant string argument. */
8831 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8832 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8835 if (p2[0] == '\0')
8836 /* strpbrk(x, "") == NULL.
8837 Evaluate and ignore s1 in case it had side-effects. */
8838 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8840 if (p2[1] != '\0')
8841 return 0; /* Really call strpbrk. */
8843 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8844 if (!fn)
8845 return 0;
8847 /* New argument list transforming strpbrk(s1, s2) to
8848 strchr(s1, s2[0]). */
8849 arglist = build_tree_list (NULL_TREE,
8850 build_int_cst (NULL_TREE, p2[0]));
8851 arglist = tree_cons (NULL_TREE, s1, arglist);
8852 return build_function_call_expr (fn, arglist);
8856 /* Simplify a call to the strcat builtin.
8858 Return 0 if no simplification was possible, otherwise return the
8859 simplified form of the call as a tree.
8861 The simplified form may be a constant or other expression which
8862 computes the same value, but in a more efficient manner (including
8863 calls to other builtin functions).
8865 The call may contain arguments which need to be evaluated, but
8866 which are not useful to determine the result of the call. In
8867 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8868 COMPOUND_EXPR will be an argument which must be evaluated.
8869 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8870 COMPOUND_EXPR in the chain will contain the tree for the simplified
8871 form of the builtin function call. */
8873 static tree
8874 simplify_builtin_strcat (tree arglist)
8876 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8877 return 0;
8878 else
8880 tree dst = TREE_VALUE (arglist),
8881 src = TREE_VALUE (TREE_CHAIN (arglist));
8882 const char *p = c_getstr (src);
8884 /* If the string length is zero, return the dst parameter. */
8885 if (p && *p == '\0')
8886 return dst;
8888 return 0;
8892 /* Simplify a call to the strncat builtin.
8894 Return 0 if no simplification was possible, otherwise return the
8895 simplified form of the call as a tree.
8897 The simplified form may be a constant or other expression which
8898 computes the same value, but in a more efficient manner (including
8899 calls to other builtin functions).
8901 The call may contain arguments which need to be evaluated, but
8902 which are not useful to determine the result of the call. In
8903 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8904 COMPOUND_EXPR will be an argument which must be evaluated.
8905 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8906 COMPOUND_EXPR in the chain will contain the tree for the simplified
8907 form of the builtin function call. */
8909 static tree
8910 simplify_builtin_strncat (tree arglist)
8912 if (!validate_arglist (arglist,
8913 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8914 return 0;
8915 else
8917 tree dst = TREE_VALUE (arglist);
8918 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8919 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8920 const char *p = c_getstr (src);
8922 /* If the requested length is zero, or the src parameter string
8923 length is zero, return the dst parameter. */
8924 if (integer_zerop (len) || (p && *p == '\0'))
8925 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8927 /* If the requested len is greater than or equal to the string
8928 length, call strcat. */
8929 if (TREE_CODE (len) == INTEGER_CST && p
8930 && compare_tree_int (len, strlen (p)) >= 0)
8932 tree newarglist
8933 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8934 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8936 /* If the replacement _DECL isn't initialized, don't do the
8937 transformation. */
8938 if (!fn)
8939 return 0;
8941 return build_function_call_expr (fn, newarglist);
8943 return 0;
8947 /* Simplify a call to the strspn builtin.
8949 Return 0 if no simplification was possible, otherwise return the
8950 simplified form of the call as a tree.
8952 The simplified form may be a constant or other expression which
8953 computes the same value, but in a more efficient manner (including
8954 calls to other builtin functions).
8956 The call may contain arguments which need to be evaluated, but
8957 which are not useful to determine the result of the call. In
8958 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8959 COMPOUND_EXPR will be an argument which must be evaluated.
8960 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8961 COMPOUND_EXPR in the chain will contain the tree for the simplified
8962 form of the builtin function call. */
8964 static tree
8965 simplify_builtin_strspn (tree arglist)
8967 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8968 return 0;
8969 else
8971 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8972 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8974 /* If both arguments are constants, evaluate at compile-time. */
8975 if (p1 && p2)
8977 const size_t r = strspn (p1, p2);
8978 return size_int (r);
8981 /* If either argument is "", return 0. */
8982 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8983 /* Evaluate and ignore both arguments in case either one has
8984 side-effects. */
8985 return omit_two_operands (integer_type_node, integer_zero_node,
8986 s1, s2);
8987 return 0;
8991 /* Simplify a call to the strcspn builtin.
8993 Return 0 if no simplification was possible, otherwise return the
8994 simplified form of the call as a tree.
8996 The simplified form may be a constant or other expression which
8997 computes the same value, but in a more efficient manner (including
8998 calls to other builtin functions).
9000 The call may contain arguments which need to be evaluated, but
9001 which are not useful to determine the result of the call. In
9002 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9003 COMPOUND_EXPR will be an argument which must be evaluated.
9004 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9005 COMPOUND_EXPR in the chain will contain the tree for the simplified
9006 form of the builtin function call. */
9008 static tree
9009 simplify_builtin_strcspn (tree arglist)
9011 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9012 return 0;
9013 else
9015 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9016 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9018 /* If both arguments are constants, evaluate at compile-time. */
9019 if (p1 && p2)
9021 const size_t r = strcspn (p1, p2);
9022 return size_int (r);
9025 /* If the first argument is "", return 0. */
9026 if (p1 && *p1 == '\0')
9028 /* Evaluate and ignore argument s2 in case it has
9029 side-effects. */
9030 return omit_one_operand (integer_type_node,
9031 integer_zero_node, s2);
9034 /* If the second argument is "", return __builtin_strlen(s1). */
9035 if (p2 && *p2 == '\0')
9037 tree newarglist = build_tree_list (NULL_TREE, s1),
9038 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9040 /* If the replacement _DECL isn't initialized, don't do the
9041 transformation. */
9042 if (!fn)
9043 return 0;
9045 return build_function_call_expr (fn, newarglist);
9047 return 0;
9051 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9052 by the builtin will be ignored. UNLOCKED is true is true if this
9053 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9054 the known length of the string. Return NULL_TREE if no simplification
9055 was possible. */
9057 tree
9058 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9060 tree fn;
9061 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9062 : implicit_built_in_decls[BUILT_IN_FPUTC];
9063 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9064 : implicit_built_in_decls[BUILT_IN_FWRITE];
9066 /* If the return value is used, or the replacement _DECL isn't
9067 initialized, don't do the transformation. */
9068 if (!ignore || !fn_fputc || !fn_fwrite)
9069 return 0;
9071 /* Verify the arguments in the original call. */
9072 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9073 return 0;
9075 if (! len)
9076 len = c_strlen (TREE_VALUE (arglist), 0);
9078 /* Get the length of the string passed to fputs. If the length
9079 can't be determined, punt. */
9080 if (!len
9081 || TREE_CODE (len) != INTEGER_CST)
9082 return 0;
9084 switch (compare_tree_int (len, 1))
9086 case -1: /* length is 0, delete the call entirely . */
9087 return omit_one_operand (integer_type_node, integer_zero_node,
9088 TREE_VALUE (TREE_CHAIN (arglist)));
9090 case 0: /* length is 1, call fputc. */
9092 const char *p = c_getstr (TREE_VALUE (arglist));
9094 if (p != NULL)
9096 /* New argument list transforming fputs(string, stream) to
9097 fputc(string[0], stream). */
9098 arglist = build_tree_list (NULL_TREE,
9099 TREE_VALUE (TREE_CHAIN (arglist)));
9100 arglist = tree_cons (NULL_TREE,
9101 build_int_cst (NULL_TREE, p[0]),
9102 arglist);
9103 fn = fn_fputc;
9104 break;
9107 /* FALLTHROUGH */
9108 case 1: /* length is greater than 1, call fwrite. */
9110 tree string_arg;
9112 /* If optimizing for size keep fputs. */
9113 if (optimize_size)
9114 return 0;
9115 string_arg = TREE_VALUE (arglist);
9116 /* New argument list transforming fputs(string, stream) to
9117 fwrite(string, 1, len, stream). */
9118 arglist = build_tree_list (NULL_TREE,
9119 TREE_VALUE (TREE_CHAIN (arglist)));
9120 arglist = tree_cons (NULL_TREE, len, arglist);
9121 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9122 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9123 fn = fn_fwrite;
9124 break;
9126 default:
9127 gcc_unreachable ();
9130 /* These optimizations are only performed when the result is ignored,
9131 hence there's no need to cast the result to integer_type_node. */
9132 return build_function_call_expr (fn, arglist);
9135 static void
9136 simplify_builtin_va_start (tree arglist)
9138 tree chain = TREE_CHAIN (arglist);
9140 if (TREE_CHAIN (chain))
9141 error ("too many arguments to function `va_start'");
9143 simplify_builtin_next_arg (chain);
9146 static void
9147 simplify_builtin_next_arg (tree arglist)
9149 tree fntype = TREE_TYPE (current_function_decl);
9151 if (TYPE_ARG_TYPES (fntype) == 0
9152 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9153 == void_type_node))
9154 error ("`va_start' used in function with fixed args");
9155 else if (arglist)
9157 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9158 tree arg = TREE_VALUE (arglist);
9160 /* Strip off all nops for the sake of the comparison. This
9161 is not quite the same as STRIP_NOPS. It does more.
9162 We must also strip off INDIRECT_EXPR for C++ reference
9163 parameters. */
9164 while (TREE_CODE (arg) == NOP_EXPR
9165 || TREE_CODE (arg) == CONVERT_EXPR
9166 || TREE_CODE (arg) == NON_LVALUE_EXPR
9167 || TREE_CODE (arg) == INDIRECT_REF)
9168 arg = TREE_OPERAND (arg, 0);
9169 if (arg != last_parm)
9170 warning ("second parameter of `va_start' not last named argument");
9171 TREE_VALUE (arglist) = arg;
9173 else
9174 /* Evidently an out of date version of <stdarg.h>; can't validate
9175 va_start's second argument, but can still work as intended. */
9176 warning ("`__builtin_next_arg' called without an argument");
9180 /* Simplify a call to the sprintf builtin.
9182 Return 0 if no simplification was possible, otherwise return the
9183 simplified form of the call as a tree. If IGNORED is true, it means that
9184 the caller does not use the returned value of the function. */
9186 static tree
9187 simplify_builtin_sprintf (tree arglist, int ignored)
9189 tree call, retval, dest, fmt;
9190 const char *fmt_str = NULL;
9192 /* Verify the required arguments in the original call. We deal with two
9193 types of sprintf() calls: 'sprintf (str, fmt)' and
9194 'sprintf (dest, "%s", orig)'. */
9195 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9196 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9197 VOID_TYPE))
9198 return NULL_TREE;
9200 /* Get the destination string and the format specifier. */
9201 dest = TREE_VALUE (arglist);
9202 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9204 /* Check whether the format is a literal string constant. */
9205 fmt_str = c_getstr (fmt);
9206 if (fmt_str == NULL)
9207 return NULL_TREE;
9209 call = NULL_TREE;
9210 retval = NULL_TREE;
9212 /* If the format doesn't contain % args or %%, use strcpy. */
9213 if (strchr (fmt_str, '%') == NULL)
9215 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9217 if (!fn)
9218 return NULL_TREE;
9220 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9221 'format' is known to contain no % formats. */
9222 arglist = build_tree_list (NULL_TREE, fmt);
9223 arglist = tree_cons (NULL_TREE, dest, arglist);
9224 call = build_function_call_expr (fn, arglist);
9225 if (!ignored)
9226 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9229 /* If the format is "%s", use strcpy if the result isn't used. */
9230 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9232 tree fn, orig;
9233 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9235 if (!fn)
9236 return NULL_TREE;
9238 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9239 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9240 arglist = build_tree_list (NULL_TREE, orig);
9241 arglist = tree_cons (NULL_TREE, dest, arglist);
9242 if (!ignored)
9244 retval = c_strlen (orig, 1);
9245 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9246 return NULL_TREE;
9248 call = build_function_call_expr (fn, arglist);
9251 if (call && retval)
9253 retval = convert
9254 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9255 retval);
9256 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9258 else
9259 return call;