2004-08-18 David Daney <ddaney@avtrex.com>
[official-gcc.git] / gcc / builtins.c
blob65028cf51d96fa08a354e76f24db9ade83209e1c
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_cabs (tree, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_cabs (tree, tree);
151 static tree fold_builtin_trunc (tree);
152 static tree fold_builtin_floor (tree);
153 static tree fold_builtin_ceil (tree);
154 static tree fold_builtin_round (tree);
155 static tree fold_builtin_bitop (tree);
156 static tree fold_builtin_memcpy (tree);
157 static tree fold_builtin_mempcpy (tree);
158 static tree fold_builtin_memmove (tree);
159 static tree fold_builtin_strchr (tree, bool);
160 static tree fold_builtin_memcmp (tree);
161 static tree fold_builtin_strcmp (tree);
162 static tree fold_builtin_strncmp (tree);
163 static tree fold_builtin_signbit (tree);
164 static tree fold_builtin_copysign (tree, tree);
165 static tree fold_builtin_isascii (tree);
166 static tree fold_builtin_toascii (tree);
167 static tree fold_builtin_isdigit (tree);
168 static tree fold_builtin_fabs (tree, tree);
169 static tree fold_builtin_abs (tree, tree);
170 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
171 static tree fold_builtin_1 (tree, bool);
173 static tree simplify_builtin_strpbrk (tree);
174 static tree simplify_builtin_strstr (tree);
175 static tree simplify_builtin_strchr (tree);
176 static tree simplify_builtin_strrchr (tree);
177 static tree simplify_builtin_strcat (tree);
178 static tree simplify_builtin_strncat (tree);
179 static tree simplify_builtin_strspn (tree);
180 static tree simplify_builtin_strcspn (tree);
181 static void simplify_builtin_next_arg (tree);
182 static void simplify_builtin_va_start (tree);
183 static tree simplify_builtin_sprintf (tree, int);
186 /* Return the alignment in bits of EXP, a pointer valued expression.
187 But don't return more than MAX_ALIGN no matter what.
188 The alignment returned is, by default, the alignment of the thing that
189 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
191 Otherwise, look at the expression to see if we can do better, i.e., if the
192 expression is actually pointing at an object whose alignment is tighter. */
194 static int
195 get_pointer_alignment (tree exp, unsigned int max_align)
197 unsigned int align, inner;
199 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
200 return 0;
202 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
203 align = MIN (align, max_align);
205 while (1)
207 switch (TREE_CODE (exp))
209 case NOP_EXPR:
210 case CONVERT_EXPR:
211 case NON_LVALUE_EXPR:
212 exp = TREE_OPERAND (exp, 0);
213 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
214 return align;
216 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
217 align = MIN (inner, max_align);
218 break;
220 case PLUS_EXPR:
221 /* If sum of pointer + int, restrict our maximum alignment to that
222 imposed by the integer. If not, we can't do any better than
223 ALIGN. */
224 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
225 return align;
227 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
228 & (max_align / BITS_PER_UNIT - 1))
229 != 0)
230 max_align >>= 1;
232 exp = TREE_OPERAND (exp, 0);
233 break;
235 case ADDR_EXPR:
236 /* See what we are pointing at and look at its alignment. */
237 exp = TREE_OPERAND (exp, 0);
238 if (TREE_CODE (exp) == FUNCTION_DECL)
239 align = FUNCTION_BOUNDARY;
240 else if (DECL_P (exp))
241 align = DECL_ALIGN (exp);
242 #ifdef CONSTANT_ALIGNMENT
243 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
244 align = CONSTANT_ALIGNMENT (exp, align);
245 #endif
246 return MIN (align, max_align);
248 default:
249 return align;
254 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
255 way, because it could contain a zero byte in the middle.
256 TREE_STRING_LENGTH is the size of the character array, not the string.
258 ONLY_VALUE should be nonzero if the result is not going to be emitted
259 into the instruction stream and zero if it is going to be expanded.
260 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
261 is returned, otherwise NULL, since
262 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
263 evaluate the side-effects.
265 The value returned is of type `ssizetype'.
267 Unfortunately, string_constant can't access the values of const char
268 arrays with initializers, so neither can we do so here. */
270 tree
271 c_strlen (tree src, int only_value)
273 tree offset_node;
274 HOST_WIDE_INT offset;
275 int max;
276 const char *ptr;
278 STRIP_NOPS (src);
279 if (TREE_CODE (src) == COND_EXPR
280 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
282 tree len1, len2;
284 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
285 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
286 if (tree_int_cst_equal (len1, len2))
287 return len1;
290 if (TREE_CODE (src) == COMPOUND_EXPR
291 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
292 return c_strlen (TREE_OPERAND (src, 1), only_value);
294 src = string_constant (src, &offset_node);
295 if (src == 0)
296 return 0;
298 max = TREE_STRING_LENGTH (src) - 1;
299 ptr = TREE_STRING_POINTER (src);
301 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
303 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
304 compute the offset to the following null if we don't know where to
305 start searching for it. */
306 int i;
308 for (i = 0; i < max; i++)
309 if (ptr[i] == 0)
310 return 0;
312 /* We don't know the starting offset, but we do know that the string
313 has no internal zero bytes. We can assume that the offset falls
314 within the bounds of the string; otherwise, the programmer deserves
315 what he gets. Subtract the offset from the length of the string,
316 and return that. This would perhaps not be valid if we were dealing
317 with named arrays in addition to literal string constants. */
319 return size_diffop (size_int (max), offset_node);
322 /* We have a known offset into the string. Start searching there for
323 a null character if we can represent it as a single HOST_WIDE_INT. */
324 if (offset_node == 0)
325 offset = 0;
326 else if (! host_integerp (offset_node, 0))
327 offset = -1;
328 else
329 offset = tree_low_cst (offset_node, 0);
331 /* If the offset is known to be out of bounds, warn, and call strlen at
332 runtime. */
333 if (offset < 0 || offset > max)
335 warning ("offset outside bounds of constant string");
336 return 0;
339 /* Use strlen to search for the first zero byte. Since any strings
340 constructed with build_string will have nulls appended, we win even
341 if we get handed something like (char[4])"abcd".
343 Since OFFSET is our starting index into the string, no further
344 calculation is needed. */
345 return ssize_int (strlen (ptr + offset));
348 /* Return a char pointer for a C string if it is a string constant
349 or sum of string constant and integer constant. */
351 static const char *
352 c_getstr (tree src)
354 tree offset_node;
356 src = string_constant (src, &offset_node);
357 if (src == 0)
358 return 0;
360 if (offset_node == 0)
361 return TREE_STRING_POINTER (src);
362 else if (!host_integerp (offset_node, 1)
363 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
364 return 0;
366 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
369 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
370 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
372 static rtx
373 c_readstr (const char *str, enum machine_mode mode)
375 HOST_WIDE_INT c[2];
376 HOST_WIDE_INT ch;
377 unsigned int i, j;
379 if (GET_MODE_CLASS (mode) != MODE_INT)
380 abort ();
381 c[0] = 0;
382 c[1] = 0;
383 ch = 1;
384 for (i = 0; i < GET_MODE_SIZE (mode); i++)
386 j = i;
387 if (WORDS_BIG_ENDIAN)
388 j = GET_MODE_SIZE (mode) - i - 1;
389 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
390 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
391 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
392 j *= BITS_PER_UNIT;
393 if (j > 2 * HOST_BITS_PER_WIDE_INT)
394 abort ();
395 if (ch)
396 ch = (unsigned char) str[i];
397 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
399 return immed_double_const (c[0], c[1], mode);
402 /* Cast a target constant CST to target CHAR and if that value fits into
403 host char type, return zero and put that value into variable pointed by
404 P. */
406 static int
407 target_char_cast (tree cst, char *p)
409 unsigned HOST_WIDE_INT val, hostval;
411 if (!host_integerp (cst, 1)
412 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
413 return 1;
415 val = tree_low_cst (cst, 1);
416 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
417 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
419 hostval = val;
420 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
421 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
423 if (val != hostval)
424 return 1;
426 *p = hostval;
427 return 0;
430 /* Similar to save_expr, but assumes that arbitrary code is not executed
431 in between the multiple evaluations. In particular, we assume that a
432 non-addressable local variable will not be modified. */
434 static tree
435 builtin_save_expr (tree exp)
437 if (TREE_ADDRESSABLE (exp) == 0
438 && (TREE_CODE (exp) == PARM_DECL
439 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
440 return exp;
442 return save_expr (exp);
445 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
446 times to get the address of either a higher stack frame, or a return
447 address located within it (depending on FNDECL_CODE). */
450 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
451 rtx tem)
453 int i;
455 /* Some machines need special handling before we can access
456 arbitrary frames. For example, on the sparc, we must first flush
457 all register windows to the stack. */
458 #ifdef SETUP_FRAME_ADDRESSES
459 if (count > 0)
460 SETUP_FRAME_ADDRESSES ();
461 #endif
463 /* On the sparc, the return address is not in the frame, it is in a
464 register. There is no way to access it off of the current frame
465 pointer, but it can be accessed off the previous frame pointer by
466 reading the value from the register window save area. */
467 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
468 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
469 count--;
470 #endif
472 /* Scan back COUNT frames to the specified frame. */
473 for (i = 0; i < count; i++)
475 /* Assume the dynamic chain pointer is in the word that the
476 frame address points to, unless otherwise specified. */
477 #ifdef DYNAMIC_CHAIN_ADDRESS
478 tem = DYNAMIC_CHAIN_ADDRESS (tem);
479 #endif
480 tem = memory_address (Pmode, tem);
481 tem = gen_rtx_MEM (Pmode, tem);
482 set_mem_alias_set (tem, get_frame_alias_set ());
483 tem = copy_to_reg (tem);
486 /* For __builtin_frame_address, return what we've got. */
487 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
488 return tem;
490 /* For __builtin_return_address, Get the return address from that
491 frame. */
492 #ifdef RETURN_ADDR_RTX
493 tem = RETURN_ADDR_RTX (count, tem);
494 #else
495 tem = memory_address (Pmode,
496 plus_constant (tem, GET_MODE_SIZE (Pmode)));
497 tem = gen_rtx_MEM (Pmode, tem);
498 set_mem_alias_set (tem, get_frame_alias_set ());
499 #endif
500 return tem;
503 /* Alias set used for setjmp buffer. */
504 static HOST_WIDE_INT setjmp_alias_set = -1;
506 /* Construct the leading half of a __builtin_setjmp call. Control will
507 return to RECEIVER_LABEL. This is used directly by sjlj exception
508 handling code. */
510 void
511 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
513 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
514 rtx stack_save;
515 rtx mem;
517 if (setjmp_alias_set == -1)
518 setjmp_alias_set = new_alias_set ();
520 buf_addr = convert_memory_address (Pmode, buf_addr);
522 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
524 /* We store the frame pointer and the address of receiver_label in
525 the buffer and use the rest of it for the stack save area, which
526 is machine-dependent. */
528 mem = gen_rtx_MEM (Pmode, buf_addr);
529 set_mem_alias_set (mem, setjmp_alias_set);
530 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
532 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
533 set_mem_alias_set (mem, setjmp_alias_set);
535 emit_move_insn (validize_mem (mem),
536 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
538 stack_save = gen_rtx_MEM (sa_mode,
539 plus_constant (buf_addr,
540 2 * GET_MODE_SIZE (Pmode)));
541 set_mem_alias_set (stack_save, setjmp_alias_set);
542 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
544 /* If there is further processing to do, do it. */
545 #ifdef HAVE_builtin_setjmp_setup
546 if (HAVE_builtin_setjmp_setup)
547 emit_insn (gen_builtin_setjmp_setup (buf_addr));
548 #endif
550 /* Tell optimize_save_area_alloca that extra work is going to
551 need to go on during alloca. */
552 current_function_calls_setjmp = 1;
554 /* Set this so all the registers get saved in our frame; we need to be
555 able to copy the saved values for any registers from frames we unwind. */
556 current_function_has_nonlocal_label = 1;
559 /* Construct the trailing part of a __builtin_setjmp call.
560 This is used directly by sjlj exception handling code. */
562 void
563 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
565 /* Clobber the FP when we get here, so we have to make sure it's
566 marked as used by this function. */
567 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
569 /* Mark the static chain as clobbered here so life information
570 doesn't get messed up for it. */
571 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
573 /* Now put in the code to restore the frame pointer, and argument
574 pointer, if needed. */
575 #ifdef HAVE_nonlocal_goto
576 if (! HAVE_nonlocal_goto)
577 #endif
578 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
580 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
581 if (fixed_regs[ARG_POINTER_REGNUM])
583 #ifdef ELIMINABLE_REGS
584 size_t i;
585 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
587 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
588 if (elim_regs[i].from == ARG_POINTER_REGNUM
589 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
590 break;
592 if (i == ARRAY_SIZE (elim_regs))
593 #endif
595 /* Now restore our arg pointer from the address at which it
596 was saved in our stack frame. */
597 emit_move_insn (virtual_incoming_args_rtx,
598 copy_to_reg (get_arg_pointer_save_area (cfun)));
601 #endif
603 #ifdef HAVE_builtin_setjmp_receiver
604 if (HAVE_builtin_setjmp_receiver)
605 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
606 else
607 #endif
608 #ifdef HAVE_nonlocal_goto_receiver
609 if (HAVE_nonlocal_goto_receiver)
610 emit_insn (gen_nonlocal_goto_receiver ());
611 else
612 #endif
613 { /* Nothing */ }
615 /* @@@ This is a kludge. Not all machine descriptions define a blockage
616 insn, but we must not allow the code we just generated to be reordered
617 by scheduling. Specifically, the update of the frame pointer must
618 happen immediately, not later. So emit an ASM_INPUT to act as blockage
619 insn. */
620 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
623 /* __builtin_setjmp is passed a pointer to an array of five words (not
624 all will be used on all machines). It operates similarly to the C
625 library function of the same name, but is more efficient. Much of
626 the code below (and for longjmp) is copied from the handling of
627 non-local gotos.
629 NOTE: This is intended for use by GNAT and the exception handling
630 scheme in the compiler and will only work in the method used by
631 them. */
633 static rtx
634 expand_builtin_setjmp (tree arglist, rtx target)
636 rtx buf_addr, next_lab, cont_lab;
638 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
639 return NULL_RTX;
641 if (target == 0 || !REG_P (target)
642 || REGNO (target) < FIRST_PSEUDO_REGISTER)
643 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
645 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
647 next_lab = gen_label_rtx ();
648 cont_lab = gen_label_rtx ();
650 expand_builtin_setjmp_setup (buf_addr, next_lab);
652 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
653 ensure that pending stack adjustments are flushed. */
654 emit_move_insn (target, const0_rtx);
655 emit_jump (cont_lab);
657 emit_label (next_lab);
659 expand_builtin_setjmp_receiver (next_lab);
661 /* Set TARGET to one. */
662 emit_move_insn (target, const1_rtx);
663 emit_label (cont_lab);
665 /* Tell flow about the strange goings on. Putting `next_lab' on
666 `nonlocal_goto_handler_labels' to indicates that function
667 calls may traverse the arc back to this label. */
669 current_function_has_nonlocal_label = 1;
670 nonlocal_goto_handler_labels
671 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
673 return target;
676 /* __builtin_longjmp is passed a pointer to an array of five words (not
677 all will be used on all machines). It operates similarly to the C
678 library function of the same name, but is more efficient. Much of
679 the code below is copied from the handling of non-local gotos.
681 NOTE: This is intended for use by GNAT and the exception handling
682 scheme in the compiler and will only work in the method used by
683 them. */
685 void
686 expand_builtin_longjmp (rtx buf_addr, rtx value)
688 rtx fp, lab, stack, insn, last;
689 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
691 if (setjmp_alias_set == -1)
692 setjmp_alias_set = new_alias_set ();
694 buf_addr = convert_memory_address (Pmode, buf_addr);
696 buf_addr = force_reg (Pmode, buf_addr);
698 /* We used to store value in static_chain_rtx, but that fails if pointers
699 are smaller than integers. We instead require that the user must pass
700 a second argument of 1, because that is what builtin_setjmp will
701 return. This also makes EH slightly more efficient, since we are no
702 longer copying around a value that we don't care about. */
703 if (value != const1_rtx)
704 abort ();
706 current_function_calls_longjmp = 1;
708 last = get_last_insn ();
709 #ifdef HAVE_builtin_longjmp
710 if (HAVE_builtin_longjmp)
711 emit_insn (gen_builtin_longjmp (buf_addr));
712 else
713 #endif
715 fp = gen_rtx_MEM (Pmode, buf_addr);
716 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
717 GET_MODE_SIZE (Pmode)));
719 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
720 2 * GET_MODE_SIZE (Pmode)));
721 set_mem_alias_set (fp, setjmp_alias_set);
722 set_mem_alias_set (lab, setjmp_alias_set);
723 set_mem_alias_set (stack, setjmp_alias_set);
725 /* Pick up FP, label, and SP from the block and jump. This code is
726 from expand_goto in stmt.c; see there for detailed comments. */
727 #if HAVE_nonlocal_goto
728 if (HAVE_nonlocal_goto)
729 /* We have to pass a value to the nonlocal_goto pattern that will
730 get copied into the static_chain pointer, but it does not matter
731 what that value is, because builtin_setjmp does not use it. */
732 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
733 else
734 #endif
736 lab = copy_to_reg (lab);
738 emit_insn (gen_rtx_CLOBBER (VOIDmode,
739 gen_rtx_MEM (BLKmode,
740 gen_rtx_SCRATCH (VOIDmode))));
741 emit_insn (gen_rtx_CLOBBER (VOIDmode,
742 gen_rtx_MEM (BLKmode,
743 hard_frame_pointer_rtx)));
745 emit_move_insn (hard_frame_pointer_rtx, fp);
746 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
748 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
749 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
750 emit_indirect_jump (lab);
754 /* Search backwards and mark the jump insn as a non-local goto.
755 Note that this precludes the use of __builtin_longjmp to a
756 __builtin_setjmp target in the same function. However, we've
757 already cautioned the user that these functions are for
758 internal exception handling use only. */
759 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
761 if (insn == last)
762 abort ();
763 if (JUMP_P (insn))
765 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
766 REG_NOTES (insn));
767 break;
769 else if (CALL_P (insn))
770 break;
774 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
775 and the address of the save area. */
777 static rtx
778 expand_builtin_nonlocal_goto (tree arglist)
780 tree t_label, t_save_area;
781 rtx r_label, r_save_area, r_fp, r_sp, insn;
783 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
784 return NULL_RTX;
786 t_label = TREE_VALUE (arglist);
787 arglist = TREE_CHAIN (arglist);
788 t_save_area = TREE_VALUE (arglist);
790 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
791 r_label = convert_memory_address (Pmode, r_label);
792 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
793 r_save_area = convert_memory_address (Pmode, r_save_area);
794 r_fp = gen_rtx_MEM (Pmode, r_save_area);
795 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
796 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
798 current_function_has_nonlocal_goto = 1;
800 #if HAVE_nonlocal_goto
801 /* ??? We no longer need to pass the static chain value, afaik. */
802 if (HAVE_nonlocal_goto)
803 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
804 else
805 #endif
807 r_label = copy_to_reg (r_label);
809 emit_insn (gen_rtx_CLOBBER (VOIDmode,
810 gen_rtx_MEM (BLKmode,
811 gen_rtx_SCRATCH (VOIDmode))));
813 emit_insn (gen_rtx_CLOBBER (VOIDmode,
814 gen_rtx_MEM (BLKmode,
815 hard_frame_pointer_rtx)));
817 /* Restore frame pointer for containing function.
818 This sets the actual hard register used for the frame pointer
819 to the location of the function's incoming static chain info.
820 The non-local goto handler will then adjust it to contain the
821 proper value and reload the argument pointer, if needed. */
822 emit_move_insn (hard_frame_pointer_rtx, r_fp);
823 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
825 /* USE of hard_frame_pointer_rtx added for consistency;
826 not clear if really needed. */
827 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
828 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
829 emit_indirect_jump (r_label);
832 /* Search backwards to the jump insn and mark it as a
833 non-local goto. */
834 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
836 if (JUMP_P (insn))
838 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
839 const0_rtx, REG_NOTES (insn));
840 break;
842 else if (CALL_P (insn))
843 break;
846 return const0_rtx;
849 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
850 (not all will be used on all machines) that was passed to __builtin_setjmp.
851 It updates the stack pointer in that block to correspond to the current
852 stack pointer. */
854 static void
855 expand_builtin_update_setjmp_buf (rtx buf_addr)
857 enum machine_mode sa_mode = Pmode;
858 rtx stack_save;
861 #ifdef HAVE_save_stack_nonlocal
862 if (HAVE_save_stack_nonlocal)
863 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
864 #endif
865 #ifdef STACK_SAVEAREA_MODE
866 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
867 #endif
869 stack_save
870 = gen_rtx_MEM (sa_mode,
871 memory_address
872 (sa_mode,
873 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
875 #ifdef HAVE_setjmp
876 if (HAVE_setjmp)
877 emit_insn (gen_setjmp ());
878 #endif
880 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
883 /* Expand a call to __builtin_prefetch. For a target that does not support
884 data prefetch, evaluate the memory address argument in case it has side
885 effects. */
887 static void
888 expand_builtin_prefetch (tree arglist)
890 tree arg0, arg1, arg2;
891 rtx op0, op1, op2;
893 if (!validate_arglist (arglist, POINTER_TYPE, 0))
894 return;
896 arg0 = TREE_VALUE (arglist);
897 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
898 zero (read) and argument 2 (locality) defaults to 3 (high degree of
899 locality). */
900 if (TREE_CHAIN (arglist))
902 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
903 if (TREE_CHAIN (TREE_CHAIN (arglist)))
904 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
905 else
906 arg2 = build_int_cst (NULL_TREE, 3, 0);
908 else
910 arg1 = integer_zero_node;
911 arg2 = build_int_cst (NULL_TREE, 3, 0);
914 /* Argument 0 is an address. */
915 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
917 /* Argument 1 (read/write flag) must be a compile-time constant int. */
918 if (TREE_CODE (arg1) != INTEGER_CST)
920 error ("second arg to `__builtin_prefetch' must be a constant");
921 arg1 = integer_zero_node;
923 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
924 /* Argument 1 must be either zero or one. */
925 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
927 warning ("invalid second arg to __builtin_prefetch; using zero");
928 op1 = const0_rtx;
931 /* Argument 2 (locality) must be a compile-time constant int. */
932 if (TREE_CODE (arg2) != INTEGER_CST)
934 error ("third arg to `__builtin_prefetch' must be a constant");
935 arg2 = integer_zero_node;
937 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
938 /* Argument 2 must be 0, 1, 2, or 3. */
939 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
941 warning ("invalid third arg to __builtin_prefetch; using zero");
942 op2 = const0_rtx;
945 #ifdef HAVE_prefetch
946 if (HAVE_prefetch)
948 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
949 (op0,
950 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
951 || (GET_MODE (op0) != Pmode))
953 op0 = convert_memory_address (Pmode, op0);
954 op0 = force_reg (Pmode, op0);
956 emit_insn (gen_prefetch (op0, op1, op2));
958 #endif
960 /* Don't do anything with direct references to volatile memory, but
961 generate code to handle other side effects. */
962 if (!MEM_P (op0) && side_effects_p (op0))
963 emit_insn (op0);
966 /* Get a MEM rtx for expression EXP which is the address of an operand
967 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
969 static rtx
970 get_memory_rtx (tree exp)
972 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
973 rtx mem;
975 addr = convert_memory_address (Pmode, addr);
977 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
979 /* Get an expression we can use to find the attributes to assign to MEM.
980 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
981 we can. First remove any nops. */
982 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
983 || TREE_CODE (exp) == NON_LVALUE_EXPR)
984 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
985 exp = TREE_OPERAND (exp, 0);
987 if (TREE_CODE (exp) == ADDR_EXPR)
989 exp = TREE_OPERAND (exp, 0);
990 set_mem_attributes (mem, exp, 0);
992 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
994 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
995 /* memcpy, memset and other builtin stringops can alias with anything. */
996 set_mem_alias_set (mem, 0);
999 return mem;
1002 /* Built-in functions to perform an untyped call and return. */
1004 /* For each register that may be used for calling a function, this
1005 gives a mode used to copy the register's value. VOIDmode indicates
1006 the register is not used for calling a function. If the machine
1007 has register windows, this gives only the outbound registers.
1008 INCOMING_REGNO gives the corresponding inbound register. */
1009 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1011 /* For each register that may be used for returning values, this gives
1012 a mode used to copy the register's value. VOIDmode indicates the
1013 register is not used for returning values. If the machine has
1014 register windows, this gives only the outbound registers.
1015 INCOMING_REGNO gives the corresponding inbound register. */
1016 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1018 /* For each register that may be used for calling a function, this
1019 gives the offset of that register into the block returned by
1020 __builtin_apply_args. 0 indicates that the register is not
1021 used for calling a function. */
1022 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1024 /* Return the size required for the block returned by __builtin_apply_args,
1025 and initialize apply_args_mode. */
1027 static int
1028 apply_args_size (void)
1030 static int size = -1;
1031 int align;
1032 unsigned int regno;
1033 enum machine_mode mode;
1035 /* The values computed by this function never change. */
1036 if (size < 0)
1038 /* The first value is the incoming arg-pointer. */
1039 size = GET_MODE_SIZE (Pmode);
1041 /* The second value is the structure value address unless this is
1042 passed as an "invisible" first argument. */
1043 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1044 size += GET_MODE_SIZE (Pmode);
1046 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1047 if (FUNCTION_ARG_REGNO_P (regno))
1049 mode = reg_raw_mode[regno];
1051 if (mode == VOIDmode)
1052 abort ();
1054 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1055 if (size % align != 0)
1056 size = CEIL (size, align) * align;
1057 apply_args_reg_offset[regno] = size;
1058 size += GET_MODE_SIZE (mode);
1059 apply_args_mode[regno] = mode;
1061 else
1063 apply_args_mode[regno] = VOIDmode;
1064 apply_args_reg_offset[regno] = 0;
1067 return size;
1070 /* Return the size required for the block returned by __builtin_apply,
1071 and initialize apply_result_mode. */
1073 static int
1074 apply_result_size (void)
1076 static int size = -1;
1077 int align, regno;
1078 enum machine_mode mode;
1080 /* The values computed by this function never change. */
1081 if (size < 0)
1083 size = 0;
1085 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1086 if (FUNCTION_VALUE_REGNO_P (regno))
1088 mode = reg_raw_mode[regno];
1090 if (mode == VOIDmode)
1091 abort ();
1093 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1094 if (size % align != 0)
1095 size = CEIL (size, align) * align;
1096 size += GET_MODE_SIZE (mode);
1097 apply_result_mode[regno] = mode;
1099 else
1100 apply_result_mode[regno] = VOIDmode;
1102 /* Allow targets that use untyped_call and untyped_return to override
1103 the size so that machine-specific information can be stored here. */
1104 #ifdef APPLY_RESULT_SIZE
1105 size = APPLY_RESULT_SIZE;
1106 #endif
1108 return size;
1111 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1112 /* Create a vector describing the result block RESULT. If SAVEP is true,
1113 the result block is used to save the values; otherwise it is used to
1114 restore the values. */
1116 static rtx
1117 result_vector (int savep, rtx result)
1119 int regno, size, align, nelts;
1120 enum machine_mode mode;
1121 rtx reg, mem;
1122 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1124 size = nelts = 0;
1125 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1126 if ((mode = apply_result_mode[regno]) != VOIDmode)
1128 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1129 if (size % align != 0)
1130 size = CEIL (size, align) * align;
1131 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1132 mem = adjust_address (result, mode, size);
1133 savevec[nelts++] = (savep
1134 ? gen_rtx_SET (VOIDmode, mem, reg)
1135 : gen_rtx_SET (VOIDmode, reg, mem));
1136 size += GET_MODE_SIZE (mode);
1138 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1140 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1142 /* Save the state required to perform an untyped call with the same
1143 arguments as were passed to the current function. */
1145 static rtx
1146 expand_builtin_apply_args_1 (void)
1148 rtx registers, tem;
1149 int size, align, regno;
1150 enum machine_mode mode;
1151 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1153 /* Create a block where the arg-pointer, structure value address,
1154 and argument registers can be saved. */
1155 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1157 /* Walk past the arg-pointer and structure value address. */
1158 size = GET_MODE_SIZE (Pmode);
1159 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1160 size += GET_MODE_SIZE (Pmode);
1162 /* Save each register used in calling a function to the block. */
1163 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1164 if ((mode = apply_args_mode[regno]) != VOIDmode)
1166 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1167 if (size % align != 0)
1168 size = CEIL (size, align) * align;
1170 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1172 emit_move_insn (adjust_address (registers, mode, size), tem);
1173 size += GET_MODE_SIZE (mode);
1176 /* Save the arg pointer to the block. */
1177 tem = copy_to_reg (virtual_incoming_args_rtx);
1178 #ifdef STACK_GROWS_DOWNWARD
1179 /* We need the pointer as the caller actually passed them to us, not
1180 as we might have pretended they were passed. Make sure it's a valid
1181 operand, as emit_move_insn isn't expected to handle a PLUS. */
1183 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1184 NULL_RTX);
1185 #endif
1186 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1188 size = GET_MODE_SIZE (Pmode);
1190 /* Save the structure value address unless this is passed as an
1191 "invisible" first argument. */
1192 if (struct_incoming_value)
1194 emit_move_insn (adjust_address (registers, Pmode, size),
1195 copy_to_reg (struct_incoming_value));
1196 size += GET_MODE_SIZE (Pmode);
1199 /* Return the address of the block. */
1200 return copy_addr_to_reg (XEXP (registers, 0));
1203 /* __builtin_apply_args returns block of memory allocated on
1204 the stack into which is stored the arg pointer, structure
1205 value address, static chain, and all the registers that might
1206 possibly be used in performing a function call. The code is
1207 moved to the start of the function so the incoming values are
1208 saved. */
1210 static rtx
1211 expand_builtin_apply_args (void)
1213 /* Don't do __builtin_apply_args more than once in a function.
1214 Save the result of the first call and reuse it. */
1215 if (apply_args_value != 0)
1216 return apply_args_value;
1218 /* When this function is called, it means that registers must be
1219 saved on entry to this function. So we migrate the
1220 call to the first insn of this function. */
1221 rtx temp;
1222 rtx seq;
1224 start_sequence ();
1225 temp = expand_builtin_apply_args_1 ();
1226 seq = get_insns ();
1227 end_sequence ();
1229 apply_args_value = temp;
1231 /* Put the insns after the NOTE that starts the function.
1232 If this is inside a start_sequence, make the outer-level insn
1233 chain current, so the code is placed at the start of the
1234 function. */
1235 push_topmost_sequence ();
1236 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1237 pop_topmost_sequence ();
1238 return temp;
1242 /* Perform an untyped call and save the state required to perform an
1243 untyped return of whatever value was returned by the given function. */
1245 static rtx
1246 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1248 int size, align, regno;
1249 enum machine_mode mode;
1250 rtx incoming_args, result, reg, dest, src, call_insn;
1251 rtx old_stack_level = 0;
1252 rtx call_fusage = 0;
1253 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1255 arguments = convert_memory_address (Pmode, arguments);
1257 /* Create a block where the return registers can be saved. */
1258 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1260 /* Fetch the arg pointer from the ARGUMENTS block. */
1261 incoming_args = gen_reg_rtx (Pmode);
1262 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1263 #ifndef STACK_GROWS_DOWNWARD
1264 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1265 incoming_args, 0, OPTAB_LIB_WIDEN);
1266 #endif
1268 /* Push a new argument block and copy the arguments. Do not allow
1269 the (potential) memcpy call below to interfere with our stack
1270 manipulations. */
1271 do_pending_stack_adjust ();
1272 NO_DEFER_POP;
1274 /* Save the stack with nonlocal if available. */
1275 #ifdef HAVE_save_stack_nonlocal
1276 if (HAVE_save_stack_nonlocal)
1277 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1278 else
1279 #endif
1280 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1282 /* Allocate a block of memory onto the stack and copy the memory
1283 arguments to the outgoing arguments address. */
1284 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1285 dest = virtual_outgoing_args_rtx;
1286 #ifndef STACK_GROWS_DOWNWARD
1287 if (GET_CODE (argsize) == CONST_INT)
1288 dest = plus_constant (dest, -INTVAL (argsize));
1289 else
1290 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1291 #endif
1292 dest = gen_rtx_MEM (BLKmode, dest);
1293 set_mem_align (dest, PARM_BOUNDARY);
1294 src = gen_rtx_MEM (BLKmode, incoming_args);
1295 set_mem_align (src, PARM_BOUNDARY);
1296 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1298 /* Refer to the argument block. */
1299 apply_args_size ();
1300 arguments = gen_rtx_MEM (BLKmode, arguments);
1301 set_mem_align (arguments, PARM_BOUNDARY);
1303 /* Walk past the arg-pointer and structure value address. */
1304 size = GET_MODE_SIZE (Pmode);
1305 if (struct_value)
1306 size += GET_MODE_SIZE (Pmode);
1308 /* Restore each of the registers previously saved. Make USE insns
1309 for each of these registers for use in making the call. */
1310 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1311 if ((mode = apply_args_mode[regno]) != VOIDmode)
1313 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1314 if (size % align != 0)
1315 size = CEIL (size, align) * align;
1316 reg = gen_rtx_REG (mode, regno);
1317 emit_move_insn (reg, adjust_address (arguments, mode, size));
1318 use_reg (&call_fusage, reg);
1319 size += GET_MODE_SIZE (mode);
1322 /* Restore the structure value address unless this is passed as an
1323 "invisible" first argument. */
1324 size = GET_MODE_SIZE (Pmode);
1325 if (struct_value)
1327 rtx value = gen_reg_rtx (Pmode);
1328 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1329 emit_move_insn (struct_value, value);
1330 if (REG_P (struct_value))
1331 use_reg (&call_fusage, struct_value);
1332 size += GET_MODE_SIZE (Pmode);
1335 /* All arguments and registers used for the call are set up by now! */
1336 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1338 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1339 and we don't want to load it into a register as an optimization,
1340 because prepare_call_address already did it if it should be done. */
1341 if (GET_CODE (function) != SYMBOL_REF)
1342 function = memory_address (FUNCTION_MODE, function);
1344 /* Generate the actual call instruction and save the return value. */
1345 #ifdef HAVE_untyped_call
1346 if (HAVE_untyped_call)
1347 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1348 result, result_vector (1, result)));
1349 else
1350 #endif
1351 #ifdef HAVE_call_value
1352 if (HAVE_call_value)
1354 rtx valreg = 0;
1356 /* Locate the unique return register. It is not possible to
1357 express a call that sets more than one return register using
1358 call_value; use untyped_call for that. In fact, untyped_call
1359 only needs to save the return registers in the given block. */
1360 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1361 if ((mode = apply_result_mode[regno]) != VOIDmode)
1363 if (valreg)
1364 abort (); /* HAVE_untyped_call required. */
1365 valreg = gen_rtx_REG (mode, regno);
1368 emit_call_insn (GEN_CALL_VALUE (valreg,
1369 gen_rtx_MEM (FUNCTION_MODE, function),
1370 const0_rtx, NULL_RTX, const0_rtx));
1372 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1374 else
1375 #endif
1376 abort ();
1378 /* Find the CALL insn we just emitted, and attach the register usage
1379 information. */
1380 call_insn = last_call_insn ();
1381 add_function_usage_to (call_insn, call_fusage);
1383 /* Restore the stack. */
1384 #ifdef HAVE_save_stack_nonlocal
1385 if (HAVE_save_stack_nonlocal)
1386 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1387 else
1388 #endif
1389 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1391 OK_DEFER_POP;
1393 /* Return the address of the result block. */
1394 result = copy_addr_to_reg (XEXP (result, 0));
1395 return convert_memory_address (ptr_mode, result);
1398 /* Perform an untyped return. */
1400 static void
1401 expand_builtin_return (rtx result)
1403 int size, align, regno;
1404 enum machine_mode mode;
1405 rtx reg;
1406 rtx call_fusage = 0;
1408 result = convert_memory_address (Pmode, result);
1410 apply_result_size ();
1411 result = gen_rtx_MEM (BLKmode, result);
1413 #ifdef HAVE_untyped_return
1414 if (HAVE_untyped_return)
1416 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1417 emit_barrier ();
1418 return;
1420 #endif
1422 /* Restore the return value and note that each value is used. */
1423 size = 0;
1424 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1425 if ((mode = apply_result_mode[regno]) != VOIDmode)
1427 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1428 if (size % align != 0)
1429 size = CEIL (size, align) * align;
1430 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1431 emit_move_insn (reg, adjust_address (result, mode, size));
1433 push_to_sequence (call_fusage);
1434 emit_insn (gen_rtx_USE (VOIDmode, reg));
1435 call_fusage = get_insns ();
1436 end_sequence ();
1437 size += GET_MODE_SIZE (mode);
1440 /* Put the USE insns before the return. */
1441 emit_insn (call_fusage);
1443 /* Return whatever values was restored by jumping directly to the end
1444 of the function. */
1445 expand_naked_return ();
1448 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1450 static enum type_class
1451 type_to_class (tree type)
1453 switch (TREE_CODE (type))
1455 case VOID_TYPE: return void_type_class;
1456 case INTEGER_TYPE: return integer_type_class;
1457 case CHAR_TYPE: return char_type_class;
1458 case ENUMERAL_TYPE: return enumeral_type_class;
1459 case BOOLEAN_TYPE: return boolean_type_class;
1460 case POINTER_TYPE: return pointer_type_class;
1461 case REFERENCE_TYPE: return reference_type_class;
1462 case OFFSET_TYPE: return offset_type_class;
1463 case REAL_TYPE: return real_type_class;
1464 case COMPLEX_TYPE: return complex_type_class;
1465 case FUNCTION_TYPE: return function_type_class;
1466 case METHOD_TYPE: return method_type_class;
1467 case RECORD_TYPE: return record_type_class;
1468 case UNION_TYPE:
1469 case QUAL_UNION_TYPE: return union_type_class;
1470 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1471 ? string_type_class : array_type_class);
1472 case SET_TYPE: return set_type_class;
1473 case FILE_TYPE: return file_type_class;
1474 case LANG_TYPE: return lang_type_class;
1475 default: return no_type_class;
1479 /* Expand a call to __builtin_classify_type with arguments found in
1480 ARGLIST. */
1482 static rtx
1483 expand_builtin_classify_type (tree arglist)
1485 if (arglist != 0)
1486 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1487 return GEN_INT (no_type_class);
1490 /* This helper macro, meant to be used in mathfn_built_in below,
1491 determines which among a set of three builtin math functions is
1492 appropriate for a given type mode. The `F' and `L' cases are
1493 automatically generated from the `double' case. */
1494 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1495 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1496 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1497 fcodel = BUILT_IN_MATHFN##L ; break;
1499 /* Return mathematic function equivalent to FN but operating directly
1500 on TYPE, if available. If we can't do the conversion, return zero. */
1501 tree
1502 mathfn_built_in (tree type, enum built_in_function fn)
1504 enum built_in_function fcode, fcodef, fcodel;
1506 switch (fn)
1508 CASE_MATHFN (BUILT_IN_ACOS)
1509 CASE_MATHFN (BUILT_IN_ACOSH)
1510 CASE_MATHFN (BUILT_IN_ASIN)
1511 CASE_MATHFN (BUILT_IN_ASINH)
1512 CASE_MATHFN (BUILT_IN_ATAN)
1513 CASE_MATHFN (BUILT_IN_ATAN2)
1514 CASE_MATHFN (BUILT_IN_ATANH)
1515 CASE_MATHFN (BUILT_IN_CBRT)
1516 CASE_MATHFN (BUILT_IN_CEIL)
1517 CASE_MATHFN (BUILT_IN_COPYSIGN)
1518 CASE_MATHFN (BUILT_IN_COS)
1519 CASE_MATHFN (BUILT_IN_COSH)
1520 CASE_MATHFN (BUILT_IN_DREM)
1521 CASE_MATHFN (BUILT_IN_ERF)
1522 CASE_MATHFN (BUILT_IN_ERFC)
1523 CASE_MATHFN (BUILT_IN_EXP)
1524 CASE_MATHFN (BUILT_IN_EXP10)
1525 CASE_MATHFN (BUILT_IN_EXP2)
1526 CASE_MATHFN (BUILT_IN_EXPM1)
1527 CASE_MATHFN (BUILT_IN_FABS)
1528 CASE_MATHFN (BUILT_IN_FDIM)
1529 CASE_MATHFN (BUILT_IN_FLOOR)
1530 CASE_MATHFN (BUILT_IN_FMA)
1531 CASE_MATHFN (BUILT_IN_FMAX)
1532 CASE_MATHFN (BUILT_IN_FMIN)
1533 CASE_MATHFN (BUILT_IN_FMOD)
1534 CASE_MATHFN (BUILT_IN_FREXP)
1535 CASE_MATHFN (BUILT_IN_GAMMA)
1536 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1537 CASE_MATHFN (BUILT_IN_HYPOT)
1538 CASE_MATHFN (BUILT_IN_ILOGB)
1539 CASE_MATHFN (BUILT_IN_INF)
1540 CASE_MATHFN (BUILT_IN_J0)
1541 CASE_MATHFN (BUILT_IN_J1)
1542 CASE_MATHFN (BUILT_IN_JN)
1543 CASE_MATHFN (BUILT_IN_LDEXP)
1544 CASE_MATHFN (BUILT_IN_LGAMMA)
1545 CASE_MATHFN (BUILT_IN_LLRINT)
1546 CASE_MATHFN (BUILT_IN_LLROUND)
1547 CASE_MATHFN (BUILT_IN_LOG)
1548 CASE_MATHFN (BUILT_IN_LOG10)
1549 CASE_MATHFN (BUILT_IN_LOG1P)
1550 CASE_MATHFN (BUILT_IN_LOG2)
1551 CASE_MATHFN (BUILT_IN_LOGB)
1552 CASE_MATHFN (BUILT_IN_LRINT)
1553 CASE_MATHFN (BUILT_IN_LROUND)
1554 CASE_MATHFN (BUILT_IN_MODF)
1555 CASE_MATHFN (BUILT_IN_NAN)
1556 CASE_MATHFN (BUILT_IN_NANS)
1557 CASE_MATHFN (BUILT_IN_NEARBYINT)
1558 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1559 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1560 CASE_MATHFN (BUILT_IN_POW)
1561 CASE_MATHFN (BUILT_IN_POW10)
1562 CASE_MATHFN (BUILT_IN_REMAINDER)
1563 CASE_MATHFN (BUILT_IN_REMQUO)
1564 CASE_MATHFN (BUILT_IN_RINT)
1565 CASE_MATHFN (BUILT_IN_ROUND)
1566 CASE_MATHFN (BUILT_IN_SCALB)
1567 CASE_MATHFN (BUILT_IN_SCALBLN)
1568 CASE_MATHFN (BUILT_IN_SCALBN)
1569 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1570 CASE_MATHFN (BUILT_IN_SIN)
1571 CASE_MATHFN (BUILT_IN_SINCOS)
1572 CASE_MATHFN (BUILT_IN_SINH)
1573 CASE_MATHFN (BUILT_IN_SQRT)
1574 CASE_MATHFN (BUILT_IN_TAN)
1575 CASE_MATHFN (BUILT_IN_TANH)
1576 CASE_MATHFN (BUILT_IN_TGAMMA)
1577 CASE_MATHFN (BUILT_IN_TRUNC)
1578 CASE_MATHFN (BUILT_IN_Y0)
1579 CASE_MATHFN (BUILT_IN_Y1)
1580 CASE_MATHFN (BUILT_IN_YN)
1582 default:
1583 return 0;
1586 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1587 return implicit_built_in_decls[fcode];
1588 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1589 return implicit_built_in_decls[fcodef];
1590 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1591 return implicit_built_in_decls[fcodel];
1592 else
1593 return 0;
1596 /* If errno must be maintained, expand the RTL to check if the result,
1597 TARGET, of a built-in function call, EXP, is NaN, and if so set
1598 errno to EDOM. */
1600 static void
1601 expand_errno_check (tree exp, rtx target)
1603 rtx lab = gen_label_rtx ();
1605 /* Test the result; if it is NaN, set errno=EDOM because
1606 the argument was not in the domain. */
1607 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1608 0, lab);
1610 #ifdef TARGET_EDOM
1611 /* If this built-in doesn't throw an exception, set errno directly. */
1612 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1614 #ifdef GEN_ERRNO_RTX
1615 rtx errno_rtx = GEN_ERRNO_RTX;
1616 #else
1617 rtx errno_rtx
1618 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1619 #endif
1620 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1621 emit_label (lab);
1622 return;
1624 #endif
1626 /* We can't set errno=EDOM directly; let the library call do it.
1627 Pop the arguments right away in case the call gets deleted. */
1628 NO_DEFER_POP;
1629 expand_call (exp, target, 0);
1630 OK_DEFER_POP;
1631 emit_label (lab);
1635 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1636 Return 0 if a normal call should be emitted rather than expanding the
1637 function in-line. EXP is the expression that is a call to the builtin
1638 function; if convenient, the result should be placed in TARGET.
1639 SUBTARGET may be used as the target for computing one of EXP's operands. */
1641 static rtx
1642 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1644 optab builtin_optab;
1645 rtx op0, insns, before_call;
1646 tree fndecl = get_callee_fndecl (exp);
1647 tree arglist = TREE_OPERAND (exp, 1);
1648 enum machine_mode mode;
1649 bool errno_set = false;
1650 tree arg, narg;
1652 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1653 return 0;
1655 arg = TREE_VALUE (arglist);
1657 switch (DECL_FUNCTION_CODE (fndecl))
1659 case BUILT_IN_SQRT:
1660 case BUILT_IN_SQRTF:
1661 case BUILT_IN_SQRTL:
1662 errno_set = ! tree_expr_nonnegative_p (arg);
1663 builtin_optab = sqrt_optab;
1664 break;
1665 case BUILT_IN_EXP:
1666 case BUILT_IN_EXPF:
1667 case BUILT_IN_EXPL:
1668 errno_set = true; builtin_optab = exp_optab; break;
1669 case BUILT_IN_EXP10:
1670 case BUILT_IN_EXP10F:
1671 case BUILT_IN_EXP10L:
1672 case BUILT_IN_POW10:
1673 case BUILT_IN_POW10F:
1674 case BUILT_IN_POW10L:
1675 errno_set = true; builtin_optab = exp10_optab; break;
1676 case BUILT_IN_EXP2:
1677 case BUILT_IN_EXP2F:
1678 case BUILT_IN_EXP2L:
1679 errno_set = true; builtin_optab = exp2_optab; break;
1680 case BUILT_IN_EXPM1:
1681 case BUILT_IN_EXPM1F:
1682 case BUILT_IN_EXPM1L:
1683 errno_set = true; builtin_optab = expm1_optab; break;
1684 case BUILT_IN_LOGB:
1685 case BUILT_IN_LOGBF:
1686 case BUILT_IN_LOGBL:
1687 errno_set = true; builtin_optab = logb_optab; break;
1688 case BUILT_IN_ILOGB:
1689 case BUILT_IN_ILOGBF:
1690 case BUILT_IN_ILOGBL:
1691 errno_set = true; builtin_optab = ilogb_optab; break;
1692 case BUILT_IN_LOG:
1693 case BUILT_IN_LOGF:
1694 case BUILT_IN_LOGL:
1695 errno_set = true; builtin_optab = log_optab; break;
1696 case BUILT_IN_LOG10:
1697 case BUILT_IN_LOG10F:
1698 case BUILT_IN_LOG10L:
1699 errno_set = true; builtin_optab = log10_optab; break;
1700 case BUILT_IN_LOG2:
1701 case BUILT_IN_LOG2F:
1702 case BUILT_IN_LOG2L:
1703 errno_set = true; builtin_optab = log2_optab; break;
1704 case BUILT_IN_LOG1P:
1705 case BUILT_IN_LOG1PF:
1706 case BUILT_IN_LOG1PL:
1707 errno_set = true; builtin_optab = log1p_optab; break;
1708 case BUILT_IN_ASIN:
1709 case BUILT_IN_ASINF:
1710 case BUILT_IN_ASINL:
1711 builtin_optab = asin_optab; break;
1712 case BUILT_IN_ACOS:
1713 case BUILT_IN_ACOSF:
1714 case BUILT_IN_ACOSL:
1715 builtin_optab = acos_optab; break;
1716 case BUILT_IN_TAN:
1717 case BUILT_IN_TANF:
1718 case BUILT_IN_TANL:
1719 builtin_optab = tan_optab; break;
1720 case BUILT_IN_ATAN:
1721 case BUILT_IN_ATANF:
1722 case BUILT_IN_ATANL:
1723 builtin_optab = atan_optab; break;
1724 case BUILT_IN_FLOOR:
1725 case BUILT_IN_FLOORF:
1726 case BUILT_IN_FLOORL:
1727 builtin_optab = floor_optab; break;
1728 case BUILT_IN_CEIL:
1729 case BUILT_IN_CEILF:
1730 case BUILT_IN_CEILL:
1731 builtin_optab = ceil_optab; break;
1732 case BUILT_IN_TRUNC:
1733 case BUILT_IN_TRUNCF:
1734 case BUILT_IN_TRUNCL:
1735 builtin_optab = btrunc_optab; break;
1736 case BUILT_IN_ROUND:
1737 case BUILT_IN_ROUNDF:
1738 case BUILT_IN_ROUNDL:
1739 builtin_optab = round_optab; break;
1740 case BUILT_IN_NEARBYINT:
1741 case BUILT_IN_NEARBYINTF:
1742 case BUILT_IN_NEARBYINTL:
1743 builtin_optab = nearbyint_optab; break;
1744 default:
1745 abort ();
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 abort ();
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 abort ();
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 abort();
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 switch (DECL_FUNCTION_CODE (fndecl))
2037 case BUILT_IN_SIN:
2038 case BUILT_IN_SINF:
2039 case BUILT_IN_SINL:
2040 if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
2041 abort();
2042 break;
2043 case BUILT_IN_COS:
2044 case BUILT_IN_COSF:
2045 case BUILT_IN_COSL:
2046 if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2047 abort();
2048 break;
2049 default:
2050 abort();
2053 else
2055 target = expand_unop (mode, builtin_optab, op0, target, 0);
2058 if (target != 0)
2060 if (errno_set)
2061 expand_errno_check (exp, target);
2063 /* Output the entire sequence. */
2064 insns = get_insns ();
2065 end_sequence ();
2066 emit_insn (insns);
2067 return target;
2070 /* If we were unable to expand via the builtin, stop the sequence
2071 (without outputting the insns) and call to the library function
2072 with the stabilized argument list. */
2073 end_sequence ();
2076 before_call = get_last_insn ();
2078 target = expand_call (exp, target, target == const0_rtx);
2080 return target;
2083 /* To evaluate powi(x,n), the floating point value x raised to the
2084 constant integer exponent n, we use a hybrid algorithm that
2085 combines the "window method" with look-up tables. For an
2086 introduction to exponentiation algorithms and "addition chains",
2087 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2088 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2089 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2090 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2092 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2093 multiplications to inline before calling the system library's pow
2094 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2095 so this default never requires calling pow, powf or powl. */
2097 #ifndef POWI_MAX_MULTS
2098 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2099 #endif
2101 /* The size of the "optimal power tree" lookup table. All
2102 exponents less than this value are simply looked up in the
2103 powi_table below. This threshold is also used to size the
2104 cache of pseudo registers that hold intermediate results. */
2105 #define POWI_TABLE_SIZE 256
2107 /* The size, in bits of the window, used in the "window method"
2108 exponentiation algorithm. This is equivalent to a radix of
2109 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2110 #define POWI_WINDOW_SIZE 3
2112 /* The following table is an efficient representation of an
2113 "optimal power tree". For each value, i, the corresponding
2114 value, j, in the table states than an optimal evaluation
2115 sequence for calculating pow(x,i) can be found by evaluating
2116 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2117 100 integers is given in Knuth's "Seminumerical algorithms". */
2119 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2121 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2122 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2123 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2124 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2125 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2126 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2127 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2128 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2129 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2130 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2131 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2132 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2133 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2134 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2135 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2136 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2137 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2138 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2139 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2140 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2141 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2142 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2143 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2144 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2145 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2146 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2147 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2148 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2149 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2150 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2151 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2152 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2156 /* Return the number of multiplications required to calculate
2157 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2158 subroutine of powi_cost. CACHE is an array indicating
2159 which exponents have already been calculated. */
2161 static int
2162 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2164 /* If we've already calculated this exponent, then this evaluation
2165 doesn't require any additional multiplications. */
2166 if (cache[n])
2167 return 0;
2169 cache[n] = true;
2170 return powi_lookup_cost (n - powi_table[n], cache)
2171 + powi_lookup_cost (powi_table[n], cache) + 1;
2174 /* Return the number of multiplications required to calculate
2175 powi(x,n) for an arbitrary x, given the exponent N. This
2176 function needs to be kept in sync with expand_powi below. */
2178 static int
2179 powi_cost (HOST_WIDE_INT n)
2181 bool cache[POWI_TABLE_SIZE];
2182 unsigned HOST_WIDE_INT digit;
2183 unsigned HOST_WIDE_INT val;
2184 int result;
2186 if (n == 0)
2187 return 0;
2189 /* Ignore the reciprocal when calculating the cost. */
2190 val = (n < 0) ? -n : n;
2192 /* Initialize the exponent cache. */
2193 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2194 cache[1] = true;
2196 result = 0;
2198 while (val >= POWI_TABLE_SIZE)
2200 if (val & 1)
2202 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2203 result += powi_lookup_cost (digit, cache)
2204 + POWI_WINDOW_SIZE + 1;
2205 val >>= POWI_WINDOW_SIZE;
2207 else
2209 val >>= 1;
2210 result++;
2214 return result + powi_lookup_cost (val, cache);
2217 /* Recursive subroutine of expand_powi. This function takes the array,
2218 CACHE, of already calculated exponents and an exponent N and returns
2219 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2221 static rtx
2222 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2224 unsigned HOST_WIDE_INT digit;
2225 rtx target, result;
2226 rtx op0, op1;
2228 if (n < POWI_TABLE_SIZE)
2230 if (cache[n])
2231 return cache[n];
2233 target = gen_reg_rtx (mode);
2234 cache[n] = target;
2236 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2237 op1 = expand_powi_1 (mode, powi_table[n], cache);
2239 else if (n & 1)
2241 target = gen_reg_rtx (mode);
2242 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2243 op0 = expand_powi_1 (mode, n - digit, cache);
2244 op1 = expand_powi_1 (mode, digit, cache);
2246 else
2248 target = gen_reg_rtx (mode);
2249 op0 = expand_powi_1 (mode, n >> 1, cache);
2250 op1 = op0;
2253 result = expand_mult (mode, op0, op1, target, 0);
2254 if (result != target)
2255 emit_move_insn (target, result);
2256 return target;
2259 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2260 floating point operand in mode MODE, and N is the exponent. This
2261 function needs to be kept in sync with powi_cost above. */
2263 static rtx
2264 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2266 unsigned HOST_WIDE_INT val;
2267 rtx cache[POWI_TABLE_SIZE];
2268 rtx result;
2270 if (n == 0)
2271 return CONST1_RTX (mode);
2273 val = (n < 0) ? -n : n;
2275 memset (cache, 0, sizeof (cache));
2276 cache[1] = x;
2278 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2280 /* If the original exponent was negative, reciprocate the result. */
2281 if (n < 0)
2282 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2283 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2285 return result;
2288 /* Expand a call to the pow built-in mathematical function. Return 0 if
2289 a normal call should be emitted rather than expanding the function
2290 in-line. EXP is the expression that is a call to the builtin
2291 function; if convenient, the result should be placed in TARGET. */
2293 static rtx
2294 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2296 tree arglist = TREE_OPERAND (exp, 1);
2297 tree arg0, arg1;
2299 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2300 return 0;
2302 arg0 = TREE_VALUE (arglist);
2303 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2305 if (TREE_CODE (arg1) == REAL_CST
2306 && ! TREE_CONSTANT_OVERFLOW (arg1))
2308 REAL_VALUE_TYPE cint;
2309 REAL_VALUE_TYPE c;
2310 HOST_WIDE_INT n;
2312 c = TREE_REAL_CST (arg1);
2313 n = real_to_integer (&c);
2314 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2315 if (real_identical (&c, &cint))
2317 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2318 Otherwise, check the number of multiplications required.
2319 Note that pow never sets errno for an integer exponent. */
2320 if ((n >= -1 && n <= 2)
2321 || (flag_unsafe_math_optimizations
2322 && ! optimize_size
2323 && powi_cost (n) <= POWI_MAX_MULTS))
2325 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2326 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2327 op = force_reg (mode, op);
2328 return expand_powi (op, mode, n);
2333 if (! flag_unsafe_math_optimizations)
2334 return NULL_RTX;
2335 return expand_builtin_mathfn_2 (exp, target, subtarget);
2338 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2339 if we failed the caller should emit a normal call, otherwise
2340 try to get the result in TARGET, if convenient. */
2342 static rtx
2343 expand_builtin_strlen (tree arglist, rtx target,
2344 enum machine_mode target_mode)
2346 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2347 return 0;
2348 else
2350 rtx pat;
2351 tree len, src = TREE_VALUE (arglist);
2352 rtx result, src_reg, char_rtx, before_strlen;
2353 enum machine_mode insn_mode = target_mode, char_mode;
2354 enum insn_code icode = CODE_FOR_nothing;
2355 int align;
2357 /* If the length can be computed at compile-time, return it. */
2358 len = c_strlen (src, 0);
2359 if (len)
2360 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2362 /* If the length can be computed at compile-time and is constant
2363 integer, but there are side-effects in src, evaluate
2364 src for side-effects, then return len.
2365 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2366 can be optimized into: i++; x = 3; */
2367 len = c_strlen (src, 1);
2368 if (len && TREE_CODE (len) == INTEGER_CST)
2370 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2371 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2374 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2376 /* If SRC is not a pointer type, don't do this operation inline. */
2377 if (align == 0)
2378 return 0;
2380 /* Bail out if we can't compute strlen in the right mode. */
2381 while (insn_mode != VOIDmode)
2383 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2384 if (icode != CODE_FOR_nothing)
2385 break;
2387 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2389 if (insn_mode == VOIDmode)
2390 return 0;
2392 /* Make a place to write the result of the instruction. */
2393 result = target;
2394 if (! (result != 0
2395 && REG_P (result)
2396 && GET_MODE (result) == insn_mode
2397 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2398 result = gen_reg_rtx (insn_mode);
2400 /* Make a place to hold the source address. We will not expand
2401 the actual source until we are sure that the expansion will
2402 not fail -- there are trees that cannot be expanded twice. */
2403 src_reg = gen_reg_rtx (Pmode);
2405 /* Mark the beginning of the strlen sequence so we can emit the
2406 source operand later. */
2407 before_strlen = get_last_insn ();
2409 char_rtx = const0_rtx;
2410 char_mode = insn_data[(int) icode].operand[2].mode;
2411 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2412 char_mode))
2413 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2415 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2416 char_rtx, GEN_INT (align));
2417 if (! pat)
2418 return 0;
2419 emit_insn (pat);
2421 /* Now that we are assured of success, expand the source. */
2422 start_sequence ();
2423 pat = memory_address (BLKmode,
2424 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2425 if (pat != src_reg)
2426 emit_move_insn (src_reg, pat);
2427 pat = get_insns ();
2428 end_sequence ();
2430 if (before_strlen)
2431 emit_insn_after (pat, before_strlen);
2432 else
2433 emit_insn_before (pat, get_insns ());
2435 /* Return the value in the proper mode for this function. */
2436 if (GET_MODE (result) == target_mode)
2437 target = result;
2438 else if (target != 0)
2439 convert_move (target, result, 0);
2440 else
2441 target = convert_to_mode (target_mode, result, 0);
2443 return target;
2447 /* Expand a call to the strstr builtin. Return 0 if we failed the
2448 caller should emit a normal call, otherwise try to get the result
2449 in TARGET, if convenient (and in mode MODE if that's convenient). */
2451 static rtx
2452 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2454 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2455 return 0;
2456 else
2458 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2459 tree fn, tmp;
2460 const char *p1, *p2;
2462 p2 = c_getstr (s2);
2463 if (p2 == NULL)
2464 return 0;
2466 p1 = c_getstr (s1);
2467 if (p1 != NULL)
2469 const char *r = strstr (p1, p2);
2471 if (r == NULL)
2472 return const0_rtx;
2474 /* Return an offset into the constant string argument. */
2475 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2476 fold_convert (TREE_TYPE (s1),
2477 ssize_int (r - p1))));
2478 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2481 if (p2[0] == '\0')
2482 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2484 if (p2[1] != '\0')
2485 return 0;
2487 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2488 if (!fn)
2489 return 0;
2491 /* New argument list transforming strstr(s1, s2) to
2492 strchr(s1, s2[0]). */
2493 arglist = build_tree_list (NULL_TREE,
2494 build_int_cst (NULL_TREE, p2[0], 0));
2495 arglist = tree_cons (NULL_TREE, s1, arglist);
2496 return expand_expr (build_function_call_expr (fn, arglist),
2497 target, mode, EXPAND_NORMAL);
2501 /* Expand a call to the strchr builtin. Return 0 if we failed the
2502 caller should emit a normal call, otherwise try to get the result
2503 in TARGET, if convenient (and in mode MODE if that's convenient). */
2505 static rtx
2506 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2508 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2509 return 0;
2510 else
2512 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2513 const char *p1;
2515 if (TREE_CODE (s2) != INTEGER_CST)
2516 return 0;
2518 p1 = c_getstr (s1);
2519 if (p1 != NULL)
2521 char c;
2522 const char *r;
2523 tree tmp;
2525 if (target_char_cast (s2, &c))
2526 return 0;
2528 r = strchr (p1, c);
2530 if (r == NULL)
2531 return const0_rtx;
2533 /* Return an offset into the constant string argument. */
2534 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2535 fold_convert (TREE_TYPE (s1),
2536 ssize_int (r - p1))));
2537 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2540 /* FIXME: Should use here strchrM optab so that ports can optimize
2541 this. */
2542 return 0;
2546 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2547 caller should emit a normal call, otherwise try to get the result
2548 in TARGET, if convenient (and in mode MODE if that's convenient). */
2550 static rtx
2551 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2553 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2554 return 0;
2555 else
2557 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2558 tree fn, tmp;
2559 const char *p1;
2561 if (TREE_CODE (s2) != INTEGER_CST)
2562 return 0;
2564 p1 = c_getstr (s1);
2565 if (p1 != NULL)
2567 char c;
2568 const char *r;
2570 if (target_char_cast (s2, &c))
2571 return 0;
2573 r = strrchr (p1, c);
2575 if (r == NULL)
2576 return const0_rtx;
2578 /* Return an offset into the constant string argument. */
2579 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2580 fold_convert (TREE_TYPE (s1),
2581 ssize_int (r - p1))));
2582 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2585 if (! integer_zerop (s2))
2586 return 0;
2588 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2589 if (!fn)
2590 return 0;
2592 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2593 return expand_expr (build_function_call_expr (fn, arglist),
2594 target, mode, EXPAND_NORMAL);
2598 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2599 caller should emit a normal call, otherwise try to get the result
2600 in TARGET, if convenient (and in mode MODE if that's convenient). */
2602 static rtx
2603 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2605 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2606 return 0;
2607 else
2609 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2610 tree fn, tmp;
2611 const char *p1, *p2;
2613 p2 = c_getstr (s2);
2614 if (p2 == NULL)
2615 return 0;
2617 p1 = c_getstr (s1);
2618 if (p1 != NULL)
2620 const char *r = strpbrk (p1, p2);
2622 if (r == NULL)
2623 return const0_rtx;
2625 /* Return an offset into the constant string argument. */
2626 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2627 fold_convert (TREE_TYPE (s1),
2628 ssize_int (r - p1))));
2629 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2632 if (p2[0] == '\0')
2634 /* strpbrk(x, "") == NULL.
2635 Evaluate and ignore the arguments in case they had
2636 side-effects. */
2637 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2638 return const0_rtx;
2641 if (p2[1] != '\0')
2642 return 0; /* Really call strpbrk. */
2644 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2645 if (!fn)
2646 return 0;
2648 /* New argument list transforming strpbrk(s1, s2) to
2649 strchr(s1, s2[0]). */
2650 arglist = build_tree_list (NULL_TREE,
2651 build_int_cst (NULL_TREE, p2[0], 0));
2652 arglist = tree_cons (NULL_TREE, s1, arglist);
2653 return expand_expr (build_function_call_expr (fn, arglist),
2654 target, mode, EXPAND_NORMAL);
2658 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2659 bytes from constant string DATA + OFFSET and return it as target
2660 constant. */
2662 static rtx
2663 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2664 enum machine_mode mode)
2666 const char *str = (const char *) data;
2668 if (offset < 0
2669 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2670 > strlen (str) + 1))
2671 abort (); /* Attempt to read past the end of constant string. */
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 if (insn == 0)
3019 abort ();
3021 emit_insn (insn);
3023 /* movstr is supposed to set end to the address of the NUL
3024 terminator. If the caller requested a mempcpy-like return value,
3025 adjust it. */
3026 if (endp == 1 && target != const0_rtx)
3027 emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3028 end), 1));
3030 return target;
3033 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3034 if we failed the caller should emit a normal call, otherwise try to get
3035 the result in TARGET, if convenient (and in mode MODE if that's
3036 convenient). */
3038 static rtx
3039 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3041 tree fn, len, src, dst;
3043 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3044 return 0;
3046 src = TREE_VALUE (TREE_CHAIN (arglist));
3047 dst = TREE_VALUE (arglist);
3049 /* If SRC and DST are equal (and not volatile), return DST. */
3050 if (operand_equal_p (src, dst, 0))
3051 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3053 len = c_strlen (src, 1);
3054 if (len == 0 || TREE_SIDE_EFFECTS (len))
3055 return expand_movstr (TREE_VALUE (arglist),
3056 TREE_VALUE (TREE_CHAIN (arglist)),
3057 target, /*endp=*/0);
3059 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3060 if (!fn)
3061 return 0;
3063 len = size_binop (PLUS_EXPR, len, ssize_int (1));
3064 arglist = build_tree_list (NULL_TREE, len);
3065 arglist = tree_cons (NULL_TREE, src, arglist);
3066 arglist = tree_cons (NULL_TREE, dst, arglist);
3067 return expand_expr (build_function_call_expr (fn, arglist),
3068 target, mode, EXPAND_NORMAL);
3071 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3072 Return 0 if we failed the caller should emit a normal call,
3073 otherwise try to get the result in TARGET, if convenient (and in
3074 mode MODE if that's convenient). */
3076 static rtx
3077 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3079 /* If return value is ignored, transform stpcpy into strcpy. */
3080 if (target == const0_rtx)
3082 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3083 if (!fn)
3084 return 0;
3086 return expand_expr (build_function_call_expr (fn, arglist),
3087 target, mode, EXPAND_NORMAL);
3090 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3091 return 0;
3092 else
3094 tree dst, src, len, lenp1;
3095 tree narglist;
3096 rtx ret;
3098 /* Ensure we get an actual string whose length can be evaluated at
3099 compile-time, not an expression containing a string. This is
3100 because the latter will potentially produce pessimized code
3101 when used to produce the return value. */
3102 src = TREE_VALUE (TREE_CHAIN (arglist));
3103 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3104 return expand_movstr (TREE_VALUE (arglist),
3105 TREE_VALUE (TREE_CHAIN (arglist)),
3106 target, /*endp=*/2);
3108 dst = TREE_VALUE (arglist);
3109 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3110 narglist = build_tree_list (NULL_TREE, lenp1);
3111 narglist = tree_cons (NULL_TREE, src, narglist);
3112 narglist = tree_cons (NULL_TREE, dst, narglist);
3113 ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3115 if (ret)
3116 return ret;
3118 if (TREE_CODE (len) == INTEGER_CST)
3120 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3122 if (GET_CODE (len_rtx) == CONST_INT)
3124 ret = expand_builtin_strcpy (arglist, target, mode);
3126 if (ret)
3128 if (! target)
3130 if (mode != VOIDmode)
3131 target = gen_reg_rtx (mode);
3132 else
3133 target = gen_reg_rtx (GET_MODE (ret));
3135 if (GET_MODE (target) != GET_MODE (ret))
3136 ret = gen_lowpart (GET_MODE (target), ret);
3138 ret = emit_move_insn (target,
3139 plus_constant (ret,
3140 INTVAL (len_rtx)));
3141 if (! ret)
3142 abort ();
3144 return target;
3149 return expand_movstr (TREE_VALUE (arglist),
3150 TREE_VALUE (TREE_CHAIN (arglist)),
3151 target, /*endp=*/2);
3155 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3156 bytes from constant string DATA + OFFSET and return it as target
3157 constant. */
3159 static rtx
3160 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3161 enum machine_mode mode)
3163 const char *str = (const char *) data;
3165 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3166 return const0_rtx;
3168 return c_readstr (str + offset, mode);
3171 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3172 if we failed the caller should emit a normal call. */
3174 static rtx
3175 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3177 if (!validate_arglist (arglist,
3178 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3179 return 0;
3180 else
3182 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3183 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3184 tree fn;
3186 /* We must be passed a constant len parameter. */
3187 if (TREE_CODE (len) != INTEGER_CST)
3188 return 0;
3190 /* If the len parameter is zero, return the dst parameter. */
3191 if (integer_zerop (len))
3193 /* Evaluate and ignore the src argument in case it has
3194 side-effects. */
3195 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3196 VOIDmode, EXPAND_NORMAL);
3197 /* Return the dst parameter. */
3198 return expand_expr (TREE_VALUE (arglist), target, mode,
3199 EXPAND_NORMAL);
3202 /* Now, we must be passed a constant src ptr parameter. */
3203 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3204 return 0;
3206 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3208 /* We're required to pad with trailing zeros if the requested
3209 len is greater than strlen(s2)+1. In that case try to
3210 use store_by_pieces, if it fails, punt. */
3211 if (tree_int_cst_lt (slen, len))
3213 tree dest = TREE_VALUE (arglist);
3214 unsigned int dest_align
3215 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3216 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3217 rtx dest_mem;
3219 if (!p || dest_align == 0 || !host_integerp (len, 1)
3220 || !can_store_by_pieces (tree_low_cst (len, 1),
3221 builtin_strncpy_read_str,
3222 (void *) p, dest_align))
3223 return 0;
3225 dest_mem = get_memory_rtx (dest);
3226 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3227 builtin_strncpy_read_str,
3228 (void *) p, dest_align, 0);
3229 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3230 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3231 return dest_mem;
3234 /* OK transform into builtin memcpy. */
3235 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3236 if (!fn)
3237 return 0;
3238 return expand_expr (build_function_call_expr (fn, arglist),
3239 target, mode, EXPAND_NORMAL);
3243 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3244 bytes from constant string DATA + OFFSET and return it as target
3245 constant. */
3247 static rtx
3248 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3249 enum machine_mode mode)
3251 const char *c = (const char *) data;
3252 char *p = alloca (GET_MODE_SIZE (mode));
3254 memset (p, *c, GET_MODE_SIZE (mode));
3256 return c_readstr (p, mode);
3259 /* Callback routine for store_by_pieces. Return the RTL of a register
3260 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3261 char value given in the RTL register data. For example, if mode is
3262 4 bytes wide, return the RTL for 0x01010101*data. */
3264 static rtx
3265 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3266 enum machine_mode mode)
3268 rtx target, coeff;
3269 size_t size;
3270 char *p;
3272 size = GET_MODE_SIZE (mode);
3273 if (size == 1)
3274 return (rtx) data;
3276 p = alloca (size);
3277 memset (p, 1, size);
3278 coeff = c_readstr (p, mode);
3280 target = convert_to_mode (mode, (rtx) data, 1);
3281 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3282 return force_reg (mode, target);
3285 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3286 if we failed the caller should emit a normal call, otherwise try to get
3287 the result in TARGET, if convenient (and in mode MODE if that's
3288 convenient). */
3290 static rtx
3291 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3293 if (!validate_arglist (arglist,
3294 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3295 return 0;
3296 else
3298 tree dest = TREE_VALUE (arglist);
3299 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3300 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3301 char c;
3303 unsigned int dest_align
3304 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3305 rtx dest_mem, dest_addr, len_rtx;
3307 /* If DEST is not a pointer type, don't do this
3308 operation in-line. */
3309 if (dest_align == 0)
3310 return 0;
3312 /* If the LEN parameter is zero, return DEST. */
3313 if (integer_zerop (len))
3315 /* Evaluate and ignore VAL in case it has side-effects. */
3316 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3317 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3320 if (TREE_CODE (val) != INTEGER_CST)
3322 rtx val_rtx;
3324 if (!host_integerp (len, 1))
3325 return 0;
3327 if (optimize_size && tree_low_cst (len, 1) > 1)
3328 return 0;
3330 /* Assume that we can memset by pieces if we can store the
3331 * the coefficients by pieces (in the required modes).
3332 * We can't pass builtin_memset_gen_str as that emits RTL. */
3333 c = 1;
3334 if (!can_store_by_pieces (tree_low_cst (len, 1),
3335 builtin_memset_read_str,
3336 &c, dest_align))
3337 return 0;
3339 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3340 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3341 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3342 val_rtx);
3343 dest_mem = get_memory_rtx (dest);
3344 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3345 builtin_memset_gen_str,
3346 val_rtx, dest_align, 0);
3347 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3348 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3349 return dest_mem;
3352 if (target_char_cast (val, &c))
3353 return 0;
3355 if (c)
3357 if (!host_integerp (len, 1))
3358 return 0;
3359 if (!can_store_by_pieces (tree_low_cst (len, 1),
3360 builtin_memset_read_str, &c,
3361 dest_align))
3362 return 0;
3364 dest_mem = get_memory_rtx (dest);
3365 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3366 builtin_memset_read_str,
3367 &c, dest_align, 0);
3368 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3369 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3370 return dest_mem;
3373 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3375 dest_mem = get_memory_rtx (dest);
3376 set_mem_align (dest_mem, dest_align);
3377 dest_addr = clear_storage (dest_mem, len_rtx);
3379 if (dest_addr == 0)
3381 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3382 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3385 return dest_addr;
3389 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3390 if we failed the caller should emit a normal call. */
3392 static rtx
3393 expand_builtin_bzero (tree arglist)
3395 tree dest, size, newarglist;
3397 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3398 return NULL_RTX;
3400 dest = TREE_VALUE (arglist);
3401 size = TREE_VALUE (TREE_CHAIN (arglist));
3403 /* New argument list transforming bzero(ptr x, int y) to
3404 memset(ptr x, int 0, size_t y). This is done this way
3405 so that if it isn't expanded inline, we fallback to
3406 calling bzero instead of memset. */
3408 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3409 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3410 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3412 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3415 /* Expand expression EXP, which is a call to the memcmp built-in function.
3416 ARGLIST is the argument list for this call. Return 0 if we failed and the
3417 caller should emit a normal call, otherwise try to get the result in
3418 TARGET, if convenient (and in mode MODE, if that's convenient). */
3420 static rtx
3421 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3422 enum machine_mode mode)
3424 tree arg1, arg2, len;
3425 const char *p1, *p2;
3427 if (!validate_arglist (arglist,
3428 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3429 return 0;
3431 arg1 = TREE_VALUE (arglist);
3432 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3433 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3435 /* If the len parameter is zero, return zero. */
3436 if (integer_zerop (len))
3438 /* Evaluate and ignore arg1 and arg2 in case they have
3439 side-effects. */
3440 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3441 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3442 return const0_rtx;
3445 /* If both arguments are equal (and not volatile), return zero. */
3446 if (operand_equal_p (arg1, arg2, 0))
3448 /* Evaluate and ignore len in case it has side-effects. */
3449 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3450 return const0_rtx;
3453 p1 = c_getstr (arg1);
3454 p2 = c_getstr (arg2);
3456 /* If all arguments are constant, and the value of len is not greater
3457 than the lengths of arg1 and arg2, evaluate at compile-time. */
3458 if (host_integerp (len, 1) && p1 && p2
3459 && compare_tree_int (len, strlen (p1) + 1) <= 0
3460 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3462 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3464 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3467 /* If len parameter is one, return an expression corresponding to
3468 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3469 if (integer_onep (len))
3471 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3472 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3473 tree ind1 =
3474 fold (build1 (CONVERT_EXPR, integer_type_node,
3475 build1 (INDIRECT_REF, cst_uchar_node,
3476 fold_convert (cst_uchar_ptr_node, arg1))));
3477 tree ind2 =
3478 fold (build1 (CONVERT_EXPR, integer_type_node,
3479 build1 (INDIRECT_REF, cst_uchar_node,
3480 fold_convert (cst_uchar_ptr_node, arg2))));
3481 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3482 return expand_expr (result, target, mode, EXPAND_NORMAL);
3485 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3487 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3488 rtx result;
3489 rtx insn;
3491 int arg1_align
3492 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3493 int arg2_align
3494 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3495 enum machine_mode insn_mode;
3497 #ifdef HAVE_cmpmemsi
3498 if (HAVE_cmpmemsi)
3499 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3500 else
3501 #endif
3502 #ifdef HAVE_cmpstrsi
3503 if (HAVE_cmpstrsi)
3504 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3505 else
3506 #endif
3507 return 0;
3509 /* If we don't have POINTER_TYPE, call the function. */
3510 if (arg1_align == 0 || arg2_align == 0)
3511 return 0;
3513 /* Make a place to write the result of the instruction. */
3514 result = target;
3515 if (! (result != 0
3516 && REG_P (result) && GET_MODE (result) == insn_mode
3517 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3518 result = gen_reg_rtx (insn_mode);
3520 arg1_rtx = get_memory_rtx (arg1);
3521 arg2_rtx = get_memory_rtx (arg2);
3522 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3523 #ifdef HAVE_cmpmemsi
3524 if (HAVE_cmpmemsi)
3525 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3526 GEN_INT (MIN (arg1_align, arg2_align)));
3527 else
3528 #endif
3529 #ifdef HAVE_cmpstrsi
3530 if (HAVE_cmpstrsi)
3531 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3532 GEN_INT (MIN (arg1_align, arg2_align)));
3533 else
3534 #endif
3535 abort ();
3537 if (insn)
3538 emit_insn (insn);
3539 else
3540 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3541 TYPE_MODE (integer_type_node), 3,
3542 XEXP (arg1_rtx, 0), Pmode,
3543 XEXP (arg2_rtx, 0), Pmode,
3544 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3545 TYPE_UNSIGNED (sizetype)),
3546 TYPE_MODE (sizetype));
3548 /* Return the value in the proper mode for this function. */
3549 mode = TYPE_MODE (TREE_TYPE (exp));
3550 if (GET_MODE (result) == mode)
3551 return result;
3552 else if (target != 0)
3554 convert_move (target, result, 0);
3555 return target;
3557 else
3558 return convert_to_mode (mode, result, 0);
3560 #endif
3562 return 0;
3565 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3566 if we failed the caller should emit a normal call, otherwise try to get
3567 the result in TARGET, if convenient. */
3569 static rtx
3570 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3572 tree arglist = TREE_OPERAND (exp, 1);
3573 tree arg1, arg2;
3574 const char *p1, *p2;
3576 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3577 return 0;
3579 arg1 = TREE_VALUE (arglist);
3580 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3582 /* If both arguments are equal (and not volatile), return zero. */
3583 if (operand_equal_p (arg1, arg2, 0))
3584 return const0_rtx;
3586 p1 = c_getstr (arg1);
3587 p2 = c_getstr (arg2);
3589 if (p1 && p2)
3591 const int i = strcmp (p1, p2);
3592 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3595 /* If either arg is "", return an expression corresponding to
3596 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3597 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3599 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3600 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3601 tree ind1 =
3602 fold (build1 (CONVERT_EXPR, integer_type_node,
3603 build1 (INDIRECT_REF, cst_uchar_node,
3604 fold_convert (cst_uchar_ptr_node, arg1))));
3605 tree ind2 =
3606 fold (build1 (CONVERT_EXPR, integer_type_node,
3607 build1 (INDIRECT_REF, cst_uchar_node,
3608 fold_convert (cst_uchar_ptr_node, arg2))));
3609 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3610 return expand_expr (result, target, mode, EXPAND_NORMAL);
3613 #ifdef HAVE_cmpstrsi
3614 if (HAVE_cmpstrsi)
3616 tree len, len1, len2;
3617 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3618 rtx result, insn;
3619 tree fndecl;
3621 int arg1_align
3622 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3623 int arg2_align
3624 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3625 enum machine_mode insn_mode
3626 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3628 len1 = c_strlen (arg1, 1);
3629 len2 = c_strlen (arg2, 1);
3631 if (len1)
3632 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3633 if (len2)
3634 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3636 /* If we don't have a constant length for the first, use the length
3637 of the second, if we know it. We don't require a constant for
3638 this case; some cost analysis could be done if both are available
3639 but neither is constant. For now, assume they're equally cheap,
3640 unless one has side effects. If both strings have constant lengths,
3641 use the smaller. */
3643 if (!len1)
3644 len = len2;
3645 else if (!len2)
3646 len = len1;
3647 else if (TREE_SIDE_EFFECTS (len1))
3648 len = len2;
3649 else if (TREE_SIDE_EFFECTS (len2))
3650 len = len1;
3651 else if (TREE_CODE (len1) != INTEGER_CST)
3652 len = len2;
3653 else if (TREE_CODE (len2) != INTEGER_CST)
3654 len = len1;
3655 else if (tree_int_cst_lt (len1, len2))
3656 len = len1;
3657 else
3658 len = len2;
3660 /* If both arguments have side effects, we cannot optimize. */
3661 if (!len || TREE_SIDE_EFFECTS (len))
3662 return 0;
3664 /* If we don't have POINTER_TYPE, call the function. */
3665 if (arg1_align == 0 || arg2_align == 0)
3666 return 0;
3668 /* Make a place to write the result of the instruction. */
3669 result = target;
3670 if (! (result != 0
3671 && REG_P (result) && GET_MODE (result) == insn_mode
3672 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3673 result = gen_reg_rtx (insn_mode);
3675 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3676 arg1 = builtin_save_expr (arg1);
3677 arg2 = builtin_save_expr (arg2);
3679 arg1_rtx = get_memory_rtx (arg1);
3680 arg2_rtx = get_memory_rtx (arg2);
3681 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3682 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3683 GEN_INT (MIN (arg1_align, arg2_align)));
3684 if (insn)
3686 emit_insn (insn);
3688 /* Return the value in the proper mode for this function. */
3689 mode = TYPE_MODE (TREE_TYPE (exp));
3690 if (GET_MODE (result) == mode)
3691 return result;
3692 if (target == 0)
3693 return convert_to_mode (mode, result, 0);
3694 convert_move (target, result, 0);
3695 return target;
3698 /* Expand the library call ourselves using a stabilized argument
3699 list to avoid re-evaluating the function's arguments twice. */
3700 arglist = build_tree_list (NULL_TREE, arg2);
3701 arglist = tree_cons (NULL_TREE, arg1, arglist);
3702 fndecl = get_callee_fndecl (exp);
3703 exp = build_function_call_expr (fndecl, arglist);
3704 return expand_call (exp, target, target == const0_rtx);
3706 #endif
3707 return 0;
3710 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3711 if we failed the caller should emit a normal call, otherwise try to get
3712 the result in TARGET, if convenient. */
3714 static rtx
3715 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3717 tree arglist = TREE_OPERAND (exp, 1);
3718 tree arg1, arg2, arg3;
3719 const char *p1, *p2;
3721 if (!validate_arglist (arglist,
3722 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3723 return 0;
3725 arg1 = TREE_VALUE (arglist);
3726 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3727 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3729 /* If the len parameter is zero, return zero. */
3730 if (integer_zerop (arg3))
3732 /* Evaluate and ignore arg1 and arg2 in case they have
3733 side-effects. */
3734 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3735 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3736 return const0_rtx;
3739 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3740 if (operand_equal_p (arg1, arg2, 0))
3742 /* Evaluate and ignore arg3 in case it has side-effects. */
3743 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3744 return const0_rtx;
3747 p1 = c_getstr (arg1);
3748 p2 = c_getstr (arg2);
3750 /* If all arguments are constant, evaluate at compile-time. */
3751 if (host_integerp (arg3, 1) && p1 && p2)
3753 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3754 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3757 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3758 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3759 if (host_integerp (arg3, 1)
3760 && (tree_low_cst (arg3, 1) == 1
3761 || (tree_low_cst (arg3, 1) > 1
3762 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3764 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3765 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3766 tree ind1 =
3767 fold (build1 (CONVERT_EXPR, integer_type_node,
3768 build1 (INDIRECT_REF, cst_uchar_node,
3769 fold_convert (cst_uchar_ptr_node, arg1))));
3770 tree ind2 =
3771 fold (build1 (CONVERT_EXPR, integer_type_node,
3772 build1 (INDIRECT_REF, cst_uchar_node,
3773 fold_convert (cst_uchar_ptr_node, arg2))));
3774 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3775 return expand_expr (result, target, mode, EXPAND_NORMAL);
3778 /* If c_strlen can determine an expression for one of the string
3779 lengths, and it doesn't have side effects, then emit cmpstrsi
3780 using length MIN(strlen(string)+1, arg3). */
3781 #ifdef HAVE_cmpstrsi
3782 if (HAVE_cmpstrsi)
3784 tree len, len1, len2;
3785 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3786 rtx result, insn;
3787 tree fndecl;
3789 int arg1_align
3790 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3791 int arg2_align
3792 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3793 enum machine_mode insn_mode
3794 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3796 len1 = c_strlen (arg1, 1);
3797 len2 = c_strlen (arg2, 1);
3799 if (len1)
3800 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3801 if (len2)
3802 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3804 /* If we don't have a constant length for the first, use the length
3805 of the second, if we know it. We don't require a constant for
3806 this case; some cost analysis could be done if both are available
3807 but neither is constant. For now, assume they're equally cheap,
3808 unless one has side effects. If both strings have constant lengths,
3809 use the smaller. */
3811 if (!len1)
3812 len = len2;
3813 else if (!len2)
3814 len = len1;
3815 else if (TREE_SIDE_EFFECTS (len1))
3816 len = len2;
3817 else if (TREE_SIDE_EFFECTS (len2))
3818 len = len1;
3819 else if (TREE_CODE (len1) != INTEGER_CST)
3820 len = len2;
3821 else if (TREE_CODE (len2) != INTEGER_CST)
3822 len = len1;
3823 else if (tree_int_cst_lt (len1, len2))
3824 len = len1;
3825 else
3826 len = len2;
3828 /* If both arguments have side effects, we cannot optimize. */
3829 if (!len || TREE_SIDE_EFFECTS (len))
3830 return 0;
3832 /* The actual new length parameter is MIN(len,arg3). */
3833 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len,
3834 fold_convert (TREE_TYPE (len), arg3)));
3836 /* If we don't have POINTER_TYPE, call the function. */
3837 if (arg1_align == 0 || arg2_align == 0)
3838 return 0;
3840 /* Make a place to write the result of the instruction. */
3841 result = target;
3842 if (! (result != 0
3843 && REG_P (result) && GET_MODE (result) == insn_mode
3844 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3845 result = gen_reg_rtx (insn_mode);
3847 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3848 arg1 = builtin_save_expr (arg1);
3849 arg2 = builtin_save_expr (arg2);
3850 len = builtin_save_expr (len);
3852 arg1_rtx = get_memory_rtx (arg1);
3853 arg2_rtx = get_memory_rtx (arg2);
3854 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3855 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3856 GEN_INT (MIN (arg1_align, arg2_align)));
3857 if (insn)
3859 emit_insn (insn);
3861 /* Return the value in the proper mode for this function. */
3862 mode = TYPE_MODE (TREE_TYPE (exp));
3863 if (GET_MODE (result) == mode)
3864 return result;
3865 if (target == 0)
3866 return convert_to_mode (mode, result, 0);
3867 convert_move (target, result, 0);
3868 return target;
3871 /* Expand the library call ourselves using a stabilized argument
3872 list to avoid re-evaluating the function's arguments twice. */
3873 arglist = build_tree_list (NULL_TREE, len);
3874 arglist = tree_cons (NULL_TREE, arg2, arglist);
3875 arglist = tree_cons (NULL_TREE, arg1, arglist);
3876 fndecl = get_callee_fndecl (exp);
3877 exp = build_function_call_expr (fndecl, arglist);
3878 return expand_call (exp, target, target == const0_rtx);
3880 #endif
3881 return 0;
3884 /* Expand expression EXP, which is a call to the strcat builtin.
3885 Return 0 if we failed the caller should emit a normal call,
3886 otherwise try to get the result in TARGET, if convenient. */
3888 static rtx
3889 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3891 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3892 return 0;
3893 else
3895 tree dst = TREE_VALUE (arglist),
3896 src = TREE_VALUE (TREE_CHAIN (arglist));
3897 const char *p = c_getstr (src);
3899 if (p)
3901 /* If the string length is zero, return the dst parameter. */
3902 if (*p == '\0')
3903 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3904 else if (!optimize_size)
3906 /* Otherwise if !optimize_size, see if we can store by
3907 pieces into (dst + strlen(dst)). */
3908 tree newdst, arglist,
3909 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3911 /* This is the length argument. */
3912 arglist = build_tree_list (NULL_TREE,
3913 fold (size_binop (PLUS_EXPR,
3914 c_strlen (src, 0),
3915 ssize_int (1))));
3916 /* Prepend src argument. */
3917 arglist = tree_cons (NULL_TREE, src, arglist);
3919 /* We're going to use dst more than once. */
3920 dst = builtin_save_expr (dst);
3922 /* Create strlen (dst). */
3923 newdst =
3924 fold (build_function_call_expr (strlen_fn,
3925 build_tree_list (NULL_TREE,
3926 dst)));
3927 /* Create (dst + strlen (dst)). */
3928 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3930 /* Prepend the new dst argument. */
3931 arglist = tree_cons (NULL_TREE, newdst, arglist);
3933 /* We don't want to get turned into a memcpy if the
3934 target is const0_rtx, i.e. when the return value
3935 isn't used. That would produce pessimized code so
3936 pass in a target of zero, it should never actually be
3937 used. If this was successful return the original
3938 dst, not the result of mempcpy. */
3939 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3940 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3941 else
3942 return 0;
3946 return 0;
3950 /* Expand expression EXP, which is a call to the strncat builtin.
3951 Return 0 if we failed the caller should emit a normal call,
3952 otherwise try to get the result in TARGET, if convenient. */
3954 static rtx
3955 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3957 if (!validate_arglist (arglist,
3958 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3959 return 0;
3960 else
3962 tree dst = TREE_VALUE (arglist),
3963 src = TREE_VALUE (TREE_CHAIN (arglist)),
3964 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3965 const char *p = c_getstr (src);
3967 /* If the requested length is zero, or the src parameter string
3968 length is zero, return the dst parameter. */
3969 if (integer_zerop (len) || (p && *p == '\0'))
3971 /* Evaluate and ignore the src and len parameters in case
3972 they have side-effects. */
3973 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3974 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3975 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3978 /* If the requested len is greater than or equal to the string
3979 length, call strcat. */
3980 if (TREE_CODE (len) == INTEGER_CST && p
3981 && compare_tree_int (len, strlen (p)) >= 0)
3983 tree newarglist
3984 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3985 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3987 /* If the replacement _DECL isn't initialized, don't do the
3988 transformation. */
3989 if (!fn)
3990 return 0;
3992 return expand_expr (build_function_call_expr (fn, newarglist),
3993 target, mode, EXPAND_NORMAL);
3995 return 0;
3999 /* Expand expression EXP, which is a call to the strspn builtin.
4000 Return 0 if we failed the caller should emit a normal call,
4001 otherwise try to get the result in TARGET, if convenient. */
4003 static rtx
4004 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4006 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4007 return 0;
4008 else
4010 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4011 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4013 /* If both arguments are constants, evaluate at compile-time. */
4014 if (p1 && p2)
4016 const size_t r = strspn (p1, p2);
4017 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4020 /* If either argument is "", return 0. */
4021 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4023 /* Evaluate and ignore both arguments in case either one has
4024 side-effects. */
4025 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4026 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4027 return const0_rtx;
4029 return 0;
4033 /* Expand expression EXP, which is a call to the strcspn builtin.
4034 Return 0 if we failed the caller should emit a normal call,
4035 otherwise try to get the result in TARGET, if convenient. */
4037 static rtx
4038 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4040 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4041 return 0;
4042 else
4044 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4045 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4047 /* If both arguments are constants, evaluate at compile-time. */
4048 if (p1 && p2)
4050 const size_t r = strcspn (p1, p2);
4051 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4054 /* If the first argument is "", return 0. */
4055 if (p1 && *p1 == '\0')
4057 /* Evaluate and ignore argument s2 in case it has
4058 side-effects. */
4059 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4060 return const0_rtx;
4063 /* If the second argument is "", return __builtin_strlen(s1). */
4064 if (p2 && *p2 == '\0')
4066 tree newarglist = build_tree_list (NULL_TREE, s1),
4067 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4069 /* If the replacement _DECL isn't initialized, don't do the
4070 transformation. */
4071 if (!fn)
4072 return 0;
4074 return expand_expr (build_function_call_expr (fn, newarglist),
4075 target, mode, EXPAND_NORMAL);
4077 return 0;
4081 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4082 if that's convenient. */
4085 expand_builtin_saveregs (void)
4087 rtx val, seq;
4089 /* Don't do __builtin_saveregs more than once in a function.
4090 Save the result of the first call and reuse it. */
4091 if (saveregs_value != 0)
4092 return saveregs_value;
4094 /* When this function is called, it means that registers must be
4095 saved on entry to this function. So we migrate the call to the
4096 first insn of this function. */
4098 start_sequence ();
4100 /* Do whatever the machine needs done in this case. */
4101 val = targetm.calls.expand_builtin_saveregs ();
4103 seq = get_insns ();
4104 end_sequence ();
4106 saveregs_value = val;
4108 /* Put the insns after the NOTE that starts the function. If this
4109 is inside a start_sequence, make the outer-level insn chain current, so
4110 the code is placed at the start of the function. */
4111 push_topmost_sequence ();
4112 emit_insn_after (seq, entry_of_function ());
4113 pop_topmost_sequence ();
4115 return val;
4118 /* __builtin_args_info (N) returns word N of the arg space info
4119 for the current function. The number and meanings of words
4120 is controlled by the definition of CUMULATIVE_ARGS. */
4122 static rtx
4123 expand_builtin_args_info (tree arglist)
4125 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4126 int *word_ptr = (int *) &current_function_args_info;
4128 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4129 abort ();
4131 if (arglist != 0)
4133 if (!host_integerp (TREE_VALUE (arglist), 0))
4134 error ("argument of `__builtin_args_info' must be constant");
4135 else
4137 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4139 if (wordnum < 0 || wordnum >= nwords)
4140 error ("argument of `__builtin_args_info' out of range");
4141 else
4142 return GEN_INT (word_ptr[wordnum]);
4145 else
4146 error ("missing argument in `__builtin_args_info'");
4148 return const0_rtx;
4151 /* Expand ARGLIST, from a call to __builtin_next_arg. */
4153 static rtx
4154 expand_builtin_next_arg (tree arglist)
4156 tree fntype = TREE_TYPE (current_function_decl);
4158 if (TYPE_ARG_TYPES (fntype) == 0
4159 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4160 == void_type_node))
4162 error ("`va_start' used in function with fixed args");
4163 return const0_rtx;
4166 if (arglist)
4168 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4169 tree arg = TREE_VALUE (arglist);
4171 /* Strip off all nops for the sake of the comparison. This
4172 is not quite the same as STRIP_NOPS. It does more.
4173 We must also strip off INDIRECT_EXPR for C++ reference
4174 parameters. */
4175 while (TREE_CODE (arg) == NOP_EXPR
4176 || TREE_CODE (arg) == CONVERT_EXPR
4177 || TREE_CODE (arg) == NON_LVALUE_EXPR
4178 || TREE_CODE (arg) == INDIRECT_REF)
4179 arg = TREE_OPERAND (arg, 0);
4180 if (arg != last_parm)
4181 warning ("second parameter of `va_start' not last named argument");
4183 else
4184 /* Evidently an out of date version of <stdarg.h>; can't validate
4185 va_start's second argument, but can still work as intended. */
4186 warning ("`__builtin_next_arg' called without an argument");
4188 return expand_binop (Pmode, add_optab,
4189 current_function_internal_arg_pointer,
4190 current_function_arg_offset_rtx,
4191 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4194 /* Make it easier for the backends by protecting the valist argument
4195 from multiple evaluations. */
4197 static tree
4198 stabilize_va_list (tree valist, int needs_lvalue)
4200 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4202 if (TREE_SIDE_EFFECTS (valist))
4203 valist = save_expr (valist);
4205 /* For this case, the backends will be expecting a pointer to
4206 TREE_TYPE (va_list_type_node), but it's possible we've
4207 actually been given an array (an actual va_list_type_node).
4208 So fix it. */
4209 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4211 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4212 valist = build_fold_addr_expr_with_type (valist, p1);
4215 else
4217 tree pt;
4219 if (! needs_lvalue)
4221 if (! TREE_SIDE_EFFECTS (valist))
4222 return valist;
4224 pt = build_pointer_type (va_list_type_node);
4225 valist = fold (build1 (ADDR_EXPR, pt, valist));
4226 TREE_SIDE_EFFECTS (valist) = 1;
4229 if (TREE_SIDE_EFFECTS (valist))
4230 valist = save_expr (valist);
4231 valist = build_fold_indirect_ref (valist);
4234 return valist;
4237 /* The "standard" definition of va_list is void*. */
4239 tree
4240 std_build_builtin_va_list (void)
4242 return ptr_type_node;
4245 /* The "standard" implementation of va_start: just assign `nextarg' to
4246 the variable. */
4248 void
4249 std_expand_builtin_va_start (tree valist, rtx nextarg)
4251 tree t;
4253 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4254 make_tree (ptr_type_node, nextarg));
4255 TREE_SIDE_EFFECTS (t) = 1;
4257 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4260 /* Expand ARGLIST, from a call to __builtin_va_start. */
4262 static rtx
4263 expand_builtin_va_start (tree arglist)
4265 rtx nextarg;
4266 tree chain, valist;
4268 chain = TREE_CHAIN (arglist);
4270 if (TREE_CHAIN (chain))
4271 error ("too many arguments to function `va_start'");
4273 nextarg = expand_builtin_next_arg (chain);
4274 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4276 #ifdef EXPAND_BUILTIN_VA_START
4277 EXPAND_BUILTIN_VA_START (valist, nextarg);
4278 #else
4279 std_expand_builtin_va_start (valist, nextarg);
4280 #endif
4282 return const0_rtx;
4285 /* The "standard" implementation of va_arg: read the value from the
4286 current (padded) address and increment by the (padded) size. */
4288 tree
4289 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4291 tree addr, t, type_size, rounded_size, valist_tmp;
4292 unsigned HOST_WIDE_INT align, boundary;
4293 bool indirect;
4295 #ifdef ARGS_GROW_DOWNWARD
4296 /* All of the alignment and movement below is for args-grow-up machines.
4297 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4298 implement their own specialized gimplify_va_arg_expr routines. */
4299 abort ();
4300 #endif
4302 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4303 if (indirect)
4304 type = build_pointer_type (type);
4306 align = PARM_BOUNDARY / BITS_PER_UNIT;
4307 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4309 /* Hoist the valist value into a temporary for the moment. */
4310 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4312 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4313 requires greater alignment, we must perform dynamic alignment. */
4314 if (boundary > align)
4316 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4317 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4318 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4319 gimplify_and_add (t, pre_p);
4321 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4322 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4323 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4324 gimplify_and_add (t, pre_p);
4327 /* Compute the rounded size of the type. */
4328 type_size = size_in_bytes (type);
4329 rounded_size = round_up (type_size, align);
4331 /* Reduce rounded_size so it's sharable with the postqueue. */
4332 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4334 /* Get AP. */
4335 addr = valist_tmp;
4336 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4338 /* Small args are padded downward. */
4339 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4340 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4341 size_binop (MINUS_EXPR, rounded_size, type_size)));
4342 t = fold_convert (TREE_TYPE (addr), t);
4343 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4346 /* Compute new value for AP. */
4347 t = fold_convert (TREE_TYPE (valist), rounded_size);
4348 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4349 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4350 gimplify_and_add (t, pre_p);
4352 addr = fold_convert (build_pointer_type (type), addr);
4354 if (indirect)
4355 addr = build_fold_indirect_ref (addr);
4357 return build_fold_indirect_ref (addr);
4360 /* Return a dummy expression of type TYPE in order to keep going after an
4361 error. */
4363 static tree
4364 dummy_object (tree type)
4366 tree t = convert (build_pointer_type (type), null_pointer_node);
4367 return build1 (INDIRECT_REF, type, t);
4370 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4371 builtin function, but a very special sort of operator. */
4373 enum gimplify_status
4374 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4376 tree promoted_type, want_va_type, have_va_type;
4377 tree valist = TREE_OPERAND (*expr_p, 0);
4378 tree type = TREE_TYPE (*expr_p);
4379 tree t;
4381 /* Verify that valist is of the proper type. */
4382 want_va_type = va_list_type_node;
4383 have_va_type = TREE_TYPE (valist);
4385 if (have_va_type == error_mark_node)
4386 return GS_ERROR;
4388 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4390 /* If va_list is an array type, the argument may have decayed
4391 to a pointer type, e.g. by being passed to another function.
4392 In that case, unwrap both types so that we can compare the
4393 underlying records. */
4394 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4395 || TREE_CODE (have_va_type) == POINTER_TYPE)
4397 want_va_type = TREE_TYPE (want_va_type);
4398 have_va_type = TREE_TYPE (have_va_type);
4402 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4404 error ("first argument to `va_arg' not of type `va_list'");
4405 return GS_ERROR;
4408 /* Generate a diagnostic for requesting data of a type that cannot
4409 be passed through `...' due to type promotion at the call site. */
4410 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4411 != type)
4413 static bool gave_help;
4415 /* Unfortunately, this is merely undefined, rather than a constraint
4416 violation, so we cannot make this an error. If this call is never
4417 executed, the program is still strictly conforming. */
4418 warning ("`%T' is promoted to `%T' when passed through `...'",
4419 type, promoted_type);
4420 if (! gave_help)
4422 gave_help = true;
4423 warning ("(so you should pass `%T' not `%T' to `va_arg')",
4424 promoted_type, type);
4427 /* We can, however, treat "undefined" any way we please.
4428 Call abort to encourage the user to fix the program. */
4429 inform ("if this code is reached, the program will abort");
4430 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4431 NULL);
4432 append_to_statement_list (t, pre_p);
4434 /* This is dead code, but go ahead and finish so that the
4435 mode of the result comes out right. */
4436 *expr_p = dummy_object (type);
4437 return GS_ALL_DONE;
4439 else
4441 /* Make it easier for the backends by protecting the valist argument
4442 from multiple evaluations. */
4443 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4445 /* For this case, the backends will be expecting a pointer to
4446 TREE_TYPE (va_list_type_node), but it's possible we've
4447 actually been given an array (an actual va_list_type_node).
4448 So fix it. */
4449 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4451 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4452 valist = build_fold_addr_expr_with_type (valist, p1);
4454 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4456 else
4457 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4459 if (!targetm.gimplify_va_arg_expr)
4460 /* Once most targets are converted this should abort. */
4461 return GS_ALL_DONE;
4463 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4464 return GS_OK;
4468 /* Expand ARGLIST, from a call to __builtin_va_end. */
4470 static rtx
4471 expand_builtin_va_end (tree arglist)
4473 tree valist = TREE_VALUE (arglist);
4475 /* Evaluate for side effects, if needed. I hate macros that don't
4476 do that. */
4477 if (TREE_SIDE_EFFECTS (valist))
4478 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4480 return const0_rtx;
4483 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4484 builtin rather than just as an assignment in stdarg.h because of the
4485 nastiness of array-type va_list types. */
4487 static rtx
4488 expand_builtin_va_copy (tree arglist)
4490 tree dst, src, t;
4492 dst = TREE_VALUE (arglist);
4493 src = TREE_VALUE (TREE_CHAIN (arglist));
4495 dst = stabilize_va_list (dst, 1);
4496 src = stabilize_va_list (src, 0);
4498 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4500 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4501 TREE_SIDE_EFFECTS (t) = 1;
4502 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4504 else
4506 rtx dstb, srcb, size;
4508 /* Evaluate to pointers. */
4509 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4510 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4511 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4512 VOIDmode, EXPAND_NORMAL);
4514 dstb = convert_memory_address (Pmode, dstb);
4515 srcb = convert_memory_address (Pmode, srcb);
4517 /* "Dereference" to BLKmode memories. */
4518 dstb = gen_rtx_MEM (BLKmode, dstb);
4519 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4520 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4521 srcb = gen_rtx_MEM (BLKmode, srcb);
4522 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4523 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4525 /* Copy. */
4526 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4529 return const0_rtx;
4532 /* Expand a call to one of the builtin functions __builtin_frame_address or
4533 __builtin_return_address. */
4535 static rtx
4536 expand_builtin_frame_address (tree fndecl, tree arglist)
4538 /* The argument must be a nonnegative integer constant.
4539 It counts the number of frames to scan up the stack.
4540 The value is the return address saved in that frame. */
4541 if (arglist == 0)
4542 /* Warning about missing arg was already issued. */
4543 return const0_rtx;
4544 else if (! host_integerp (TREE_VALUE (arglist), 1))
4546 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4547 error ("invalid arg to `__builtin_frame_address'");
4548 else
4549 error ("invalid arg to `__builtin_return_address'");
4550 return const0_rtx;
4552 else
4554 rtx tem
4555 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4556 tree_low_cst (TREE_VALUE (arglist), 1),
4557 hard_frame_pointer_rtx);
4559 /* Some ports cannot access arbitrary stack frames. */
4560 if (tem == NULL)
4562 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4563 warning ("unsupported arg to `__builtin_frame_address'");
4564 else
4565 warning ("unsupported arg to `__builtin_return_address'");
4566 return const0_rtx;
4569 /* For __builtin_frame_address, return what we've got. */
4570 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4571 return tem;
4573 if (!REG_P (tem)
4574 && ! CONSTANT_P (tem))
4575 tem = copy_to_mode_reg (Pmode, tem);
4576 return tem;
4580 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4581 we failed and the caller should emit a normal call, otherwise try to get
4582 the result in TARGET, if convenient. */
4584 static rtx
4585 expand_builtin_alloca (tree arglist, rtx target)
4587 rtx op0;
4588 rtx result;
4590 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4591 should always expand to function calls. These can be intercepted
4592 in libmudflap. */
4593 if (flag_mudflap)
4594 return 0;
4596 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4597 return 0;
4599 /* Compute the argument. */
4600 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4602 /* Allocate the desired space. */
4603 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4604 result = convert_memory_address (ptr_mode, result);
4606 return result;
4609 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4610 Return 0 if a normal call should be emitted rather than expanding the
4611 function in-line. If convenient, the result should be placed in TARGET.
4612 SUBTARGET may be used as the target for computing one of EXP's operands. */
4614 static rtx
4615 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4616 rtx subtarget, optab op_optab)
4618 rtx op0;
4619 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4620 return 0;
4622 /* Compute the argument. */
4623 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4624 /* Compute op, into TARGET if possible.
4625 Set TARGET to wherever the result comes back. */
4626 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4627 op_optab, op0, target, 1);
4628 if (target == 0)
4629 abort ();
4631 return convert_to_mode (target_mode, target, 0);
4634 /* If the string passed to fputs is a constant and is one character
4635 long, we attempt to transform this call into __builtin_fputc(). */
4637 static rtx
4638 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4640 tree len, fn;
4641 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4642 : implicit_built_in_decls[BUILT_IN_FPUTC];
4643 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4644 : implicit_built_in_decls[BUILT_IN_FWRITE];
4646 /* If the return value is used, or the replacement _DECL isn't
4647 initialized, don't do the transformation. */
4648 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4649 return 0;
4651 /* Verify the arguments in the original call. */
4652 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4653 return 0;
4655 /* Get the length of the string passed to fputs. If the length
4656 can't be determined, punt. */
4657 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4658 || TREE_CODE (len) != INTEGER_CST)
4659 return 0;
4661 switch (compare_tree_int (len, 1))
4663 case -1: /* length is 0, delete the call entirely . */
4665 /* Evaluate and ignore the argument in case it has
4666 side-effects. */
4667 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4668 VOIDmode, EXPAND_NORMAL);
4669 return const0_rtx;
4671 case 0: /* length is 1, call fputc. */
4673 const char *p = c_getstr (TREE_VALUE (arglist));
4675 if (p != NULL)
4677 /* New argument list transforming fputs(string, stream) to
4678 fputc(string[0], stream). */
4679 arglist = build_tree_list (NULL_TREE,
4680 TREE_VALUE (TREE_CHAIN (arglist)));
4681 arglist = tree_cons (NULL_TREE,
4682 build_int_cst (NULL_TREE, p[0], 0),
4683 arglist);
4684 fn = fn_fputc;
4685 break;
4688 /* Fall through. */
4689 case 1: /* length is greater than 1, call fwrite. */
4691 tree string_arg;
4693 /* If optimizing for size keep fputs. */
4694 if (optimize_size)
4695 return 0;
4696 string_arg = TREE_VALUE (arglist);
4697 /* New argument list transforming fputs(string, stream) to
4698 fwrite(string, 1, len, stream). */
4699 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4700 arglist = tree_cons (NULL_TREE, len, arglist);
4701 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4702 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4703 fn = fn_fwrite;
4704 break;
4706 default:
4707 abort ();
4710 return expand_expr (build_function_call_expr (fn, arglist),
4711 const0_rtx, VOIDmode, EXPAND_NORMAL);
4714 /* Expand a call to __builtin_expect. We return our argument and emit a
4715 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4716 a non-jump context. */
4718 static rtx
4719 expand_builtin_expect (tree arglist, rtx target)
4721 tree exp, c;
4722 rtx note, rtx_c;
4724 if (arglist == NULL_TREE
4725 || TREE_CHAIN (arglist) == NULL_TREE)
4726 return const0_rtx;
4727 exp = TREE_VALUE (arglist);
4728 c = TREE_VALUE (TREE_CHAIN (arglist));
4730 if (TREE_CODE (c) != INTEGER_CST)
4732 error ("second arg to `__builtin_expect' must be a constant");
4733 c = integer_zero_node;
4736 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4738 /* Don't bother with expected value notes for integral constants. */
4739 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4741 /* We do need to force this into a register so that we can be
4742 moderately sure to be able to correctly interpret the branch
4743 condition later. */
4744 target = force_reg (GET_MODE (target), target);
4746 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4748 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4749 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4752 return target;
4755 /* Like expand_builtin_expect, except do this in a jump context. This is
4756 called from do_jump if the conditional is a __builtin_expect. Return either
4757 a list of insns to emit the jump or NULL if we cannot optimize
4758 __builtin_expect. We need to optimize this at jump time so that machines
4759 like the PowerPC don't turn the test into a SCC operation, and then jump
4760 based on the test being 0/1. */
4763 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4765 tree arglist = TREE_OPERAND (exp, 1);
4766 tree arg0 = TREE_VALUE (arglist);
4767 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4768 rtx ret = NULL_RTX;
4770 /* Only handle __builtin_expect (test, 0) and
4771 __builtin_expect (test, 1). */
4772 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4773 && (integer_zerop (arg1) || integer_onep (arg1)))
4775 rtx insn, drop_through_label, temp;
4777 /* Expand the jump insns. */
4778 start_sequence ();
4779 do_jump (arg0, if_false_label, if_true_label);
4780 ret = get_insns ();
4782 drop_through_label = get_last_insn ();
4783 if (drop_through_label && NOTE_P (drop_through_label))
4784 drop_through_label = prev_nonnote_insn (drop_through_label);
4785 if (drop_through_label && !LABEL_P (drop_through_label))
4786 drop_through_label = NULL_RTX;
4787 end_sequence ();
4789 if (! if_true_label)
4790 if_true_label = drop_through_label;
4791 if (! if_false_label)
4792 if_false_label = drop_through_label;
4794 /* Go through and add the expect's to each of the conditional jumps. */
4795 insn = ret;
4796 while (insn != NULL_RTX)
4798 rtx next = NEXT_INSN (insn);
4800 if (JUMP_P (insn) && any_condjump_p (insn))
4802 rtx ifelse = SET_SRC (pc_set (insn));
4803 rtx then_dest = XEXP (ifelse, 1);
4804 rtx else_dest = XEXP (ifelse, 2);
4805 int taken = -1;
4807 /* First check if we recognize any of the labels. */
4808 if (GET_CODE (then_dest) == LABEL_REF
4809 && XEXP (then_dest, 0) == if_true_label)
4810 taken = 1;
4811 else if (GET_CODE (then_dest) == LABEL_REF
4812 && XEXP (then_dest, 0) == if_false_label)
4813 taken = 0;
4814 else if (GET_CODE (else_dest) == LABEL_REF
4815 && XEXP (else_dest, 0) == if_false_label)
4816 taken = 1;
4817 else if (GET_CODE (else_dest) == LABEL_REF
4818 && XEXP (else_dest, 0) == if_true_label)
4819 taken = 0;
4820 /* Otherwise check where we drop through. */
4821 else if (else_dest == pc_rtx)
4823 if (next && NOTE_P (next))
4824 next = next_nonnote_insn (next);
4826 if (next && JUMP_P (next)
4827 && any_uncondjump_p (next))
4828 temp = XEXP (SET_SRC (pc_set (next)), 0);
4829 else
4830 temp = next;
4832 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4833 else that can't possibly match either target label. */
4834 if (temp == if_false_label)
4835 taken = 1;
4836 else if (temp == if_true_label)
4837 taken = 0;
4839 else if (then_dest == pc_rtx)
4841 if (next && NOTE_P (next))
4842 next = next_nonnote_insn (next);
4844 if (next && JUMP_P (next)
4845 && any_uncondjump_p (next))
4846 temp = XEXP (SET_SRC (pc_set (next)), 0);
4847 else
4848 temp = next;
4850 if (temp == if_false_label)
4851 taken = 0;
4852 else if (temp == if_true_label)
4853 taken = 1;
4856 if (taken != -1)
4858 /* If the test is expected to fail, reverse the
4859 probabilities. */
4860 if (integer_zerop (arg1))
4861 taken = 1 - taken;
4862 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4866 insn = next;
4870 return ret;
4873 void
4874 expand_builtin_trap (void)
4876 #ifdef HAVE_trap
4877 if (HAVE_trap)
4878 emit_insn (gen_trap ());
4879 else
4880 #endif
4881 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4882 emit_barrier ();
4885 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4886 Return 0 if a normal call should be emitted rather than expanding
4887 the function inline. If convenient, the result should be placed
4888 in TARGET. SUBTARGET may be used as the target for computing
4889 the operand. */
4891 static rtx
4892 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4894 enum machine_mode mode;
4895 tree arg;
4896 rtx op0;
4898 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4899 return 0;
4901 arg = TREE_VALUE (arglist);
4902 mode = TYPE_MODE (TREE_TYPE (arg));
4903 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4904 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4907 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4908 Return 0 if a normal call should be emitted rather than expanding
4909 the function inline. If convenient, the result should be placed
4910 in target. */
4912 static rtx
4913 expand_builtin_cabs (tree arglist, rtx target)
4915 enum machine_mode mode;
4916 tree arg;
4917 rtx op0;
4919 if (arglist == 0 || TREE_CHAIN (arglist))
4920 return 0;
4921 arg = TREE_VALUE (arglist);
4922 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4923 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4924 return 0;
4926 mode = TYPE_MODE (TREE_TYPE (arg));
4927 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4928 return expand_complex_abs (mode, op0, target, 0);
4931 /* Create a new constant string literal and return a char* pointer to it.
4932 The STRING_CST value is the LEN characters at STR. */
4933 static tree
4934 build_string_literal (int len, const char *str)
4936 tree t, elem, index, type;
4938 t = build_string (len, str);
4939 elem = build_type_variant (char_type_node, 1, 0);
4940 index = build_index_type (build_int_cst (NULL_TREE, len - 1, 0));
4941 type = build_array_type (elem, index);
4942 TREE_TYPE (t) = type;
4943 TREE_CONSTANT (t) = 1;
4944 TREE_INVARIANT (t) = 1;
4945 TREE_READONLY (t) = 1;
4946 TREE_STATIC (t) = 1;
4948 type = build_pointer_type (type);
4949 t = build1 (ADDR_EXPR, type, t);
4951 type = build_pointer_type (elem);
4952 t = build1 (NOP_EXPR, type, t);
4953 return t;
4956 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4957 Return 0 if a normal call should be emitted rather than transforming
4958 the function inline. If convenient, the result should be placed in
4959 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4960 call. */
4961 static rtx
4962 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4963 bool unlocked)
4965 tree fn_putchar = unlocked
4966 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4967 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4968 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4969 : implicit_built_in_decls[BUILT_IN_PUTS];
4970 const char *fmt_str;
4971 tree fn, fmt, arg;
4973 /* If the return value is used, don't do the transformation. */
4974 if (target != const0_rtx)
4975 return 0;
4977 /* Verify the required arguments in the original call. */
4978 if (! arglist)
4979 return 0;
4980 fmt = TREE_VALUE (arglist);
4981 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4982 return 0;
4983 arglist = TREE_CHAIN (arglist);
4985 /* Check whether the format is a literal string constant. */
4986 fmt_str = c_getstr (fmt);
4987 if (fmt_str == NULL)
4988 return 0;
4990 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4991 if (strcmp (fmt_str, "%s\n") == 0)
4993 if (! arglist
4994 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4995 || TREE_CHAIN (arglist))
4996 return 0;
4997 fn = fn_puts;
4999 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5000 else if (strcmp (fmt_str, "%c") == 0)
5002 if (! arglist
5003 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5004 || TREE_CHAIN (arglist))
5005 return 0;
5006 fn = fn_putchar;
5008 else
5010 /* We can't handle anything else with % args or %% ... yet. */
5011 if (strchr (fmt_str, '%'))
5012 return 0;
5014 if (arglist)
5015 return 0;
5017 /* If the format specifier was "", printf does nothing. */
5018 if (fmt_str[0] == '\0')
5019 return const0_rtx;
5020 /* If the format specifier has length of 1, call putchar. */
5021 if (fmt_str[1] == '\0')
5023 /* Given printf("c"), (where c is any one character,)
5024 convert "c"[0] to an int and pass that to the replacement
5025 function. */
5026 arg = build_int_cst (NULL_TREE, fmt_str[0], 0);
5027 arglist = build_tree_list (NULL_TREE, arg);
5028 fn = fn_putchar;
5030 else
5032 /* If the format specifier was "string\n", call puts("string"). */
5033 size_t len = strlen (fmt_str);
5034 if (fmt_str[len - 1] == '\n')
5036 /* Create a NUL-terminated string that's one char shorter
5037 than the original, stripping off the trailing '\n'. */
5038 char *newstr = alloca (len);
5039 memcpy (newstr, fmt_str, len - 1);
5040 newstr[len - 1] = 0;
5042 arg = build_string_literal (len, newstr);
5043 arglist = build_tree_list (NULL_TREE, arg);
5044 fn = fn_puts;
5046 else
5047 /* We'd like to arrange to call fputs(string,stdout) here,
5048 but we need stdout and don't have a way to get it yet. */
5049 return 0;
5053 if (!fn)
5054 return 0;
5055 return expand_expr (build_function_call_expr (fn, arglist),
5056 target, mode, EXPAND_NORMAL);
5059 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5060 Return 0 if a normal call should be emitted rather than transforming
5061 the function inline. If convenient, the result should be placed in
5062 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5063 call. */
5064 static rtx
5065 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5066 bool unlocked)
5068 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5069 : implicit_built_in_decls[BUILT_IN_FPUTC];
5070 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5071 : implicit_built_in_decls[BUILT_IN_FPUTS];
5072 const char *fmt_str;
5073 tree fn, fmt, fp, arg;
5075 /* If the return value is used, don't do the transformation. */
5076 if (target != const0_rtx)
5077 return 0;
5079 /* Verify the required arguments in the original call. */
5080 if (! arglist)
5081 return 0;
5082 fp = TREE_VALUE (arglist);
5083 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5084 return 0;
5085 arglist = TREE_CHAIN (arglist);
5086 if (! arglist)
5087 return 0;
5088 fmt = TREE_VALUE (arglist);
5089 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5090 return 0;
5091 arglist = TREE_CHAIN (arglist);
5093 /* Check whether the format is a literal string constant. */
5094 fmt_str = c_getstr (fmt);
5095 if (fmt_str == NULL)
5096 return 0;
5098 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5099 if (strcmp (fmt_str, "%s") == 0)
5101 if (! arglist
5102 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5103 || TREE_CHAIN (arglist))
5104 return 0;
5105 arg = TREE_VALUE (arglist);
5106 arglist = build_tree_list (NULL_TREE, fp);
5107 arglist = tree_cons (NULL_TREE, arg, arglist);
5108 fn = fn_fputs;
5110 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5111 else if (strcmp (fmt_str, "%c") == 0)
5113 if (! arglist
5114 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5115 || TREE_CHAIN (arglist))
5116 return 0;
5117 arg = TREE_VALUE (arglist);
5118 arglist = build_tree_list (NULL_TREE, fp);
5119 arglist = tree_cons (NULL_TREE, arg, arglist);
5120 fn = fn_fputc;
5122 else
5124 /* We can't handle anything else with % args or %% ... yet. */
5125 if (strchr (fmt_str, '%'))
5126 return 0;
5128 if (arglist)
5129 return 0;
5131 /* If the format specifier was "", fprintf does nothing. */
5132 if (fmt_str[0] == '\0')
5134 /* Evaluate and ignore FILE* argument for side-effects. */
5135 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5136 return const0_rtx;
5139 /* When "string" doesn't contain %, replace all cases of
5140 fprintf(stream,string) with fputs(string,stream). The fputs
5141 builtin will take care of special cases like length == 1. */
5142 arglist = build_tree_list (NULL_TREE, fp);
5143 arglist = tree_cons (NULL_TREE, fmt, arglist);
5144 fn = fn_fputs;
5147 if (!fn)
5148 return 0;
5149 return expand_expr (build_function_call_expr (fn, arglist),
5150 target, mode, EXPAND_NORMAL);
5153 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5154 a normal call should be emitted rather than expanding the function
5155 inline. If convenient, the result should be placed in TARGET with
5156 mode MODE. */
5158 static rtx
5159 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5161 tree orig_arglist, dest, fmt;
5162 const char *fmt_str;
5164 orig_arglist = arglist;
5166 /* Verify the required arguments in the original call. */
5167 if (! arglist)
5168 return 0;
5169 dest = TREE_VALUE (arglist);
5170 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5171 return 0;
5172 arglist = TREE_CHAIN (arglist);
5173 if (! arglist)
5174 return 0;
5175 fmt = TREE_VALUE (arglist);
5176 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5177 return 0;
5178 arglist = TREE_CHAIN (arglist);
5180 /* Check whether the format is a literal string constant. */
5181 fmt_str = c_getstr (fmt);
5182 if (fmt_str == NULL)
5183 return 0;
5185 /* If the format doesn't contain % args or %%, use strcpy. */
5186 if (strchr (fmt_str, '%') == 0)
5188 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5189 tree exp;
5191 if (arglist || ! fn)
5192 return 0;
5193 expand_expr (build_function_call_expr (fn, orig_arglist),
5194 const0_rtx, VOIDmode, EXPAND_NORMAL);
5195 if (target == const0_rtx)
5196 return const0_rtx;
5197 exp = build_int_cst (NULL_TREE, strlen (fmt_str), 0);
5198 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5200 /* If the format is "%s", use strcpy if the result isn't used. */
5201 else if (strcmp (fmt_str, "%s") == 0)
5203 tree fn, arg, len;
5204 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5206 if (! fn)
5207 return 0;
5209 if (! arglist || TREE_CHAIN (arglist))
5210 return 0;
5211 arg = TREE_VALUE (arglist);
5212 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5213 return 0;
5215 if (target != const0_rtx)
5217 len = c_strlen (arg, 1);
5218 if (! len || TREE_CODE (len) != INTEGER_CST)
5219 return 0;
5221 else
5222 len = NULL_TREE;
5224 arglist = build_tree_list (NULL_TREE, arg);
5225 arglist = tree_cons (NULL_TREE, dest, arglist);
5226 expand_expr (build_function_call_expr (fn, arglist),
5227 const0_rtx, VOIDmode, EXPAND_NORMAL);
5229 if (target == const0_rtx)
5230 return const0_rtx;
5231 return expand_expr (len, target, mode, EXPAND_NORMAL);
5234 return 0;
5237 /* Expand a call to either the entry or exit function profiler. */
5239 static rtx
5240 expand_builtin_profile_func (bool exitp)
5242 rtx this, which;
5244 this = DECL_RTL (current_function_decl);
5245 if (MEM_P (this))
5246 this = XEXP (this, 0);
5247 else
5248 abort ();
5250 if (exitp)
5251 which = profile_function_exit_libfunc;
5252 else
5253 which = profile_function_entry_libfunc;
5255 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5256 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5257 0, hard_frame_pointer_rtx),
5258 Pmode);
5260 return const0_rtx;
5263 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5265 static rtx
5266 round_trampoline_addr (rtx tramp)
5268 rtx temp, addend, mask;
5270 /* If we don't need too much alignment, we'll have been guaranteed
5271 proper alignment by get_trampoline_type. */
5272 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5273 return tramp;
5275 /* Round address up to desired boundary. */
5276 temp = gen_reg_rtx (Pmode);
5277 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5278 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5280 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5281 temp, 0, OPTAB_LIB_WIDEN);
5282 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5283 temp, 0, OPTAB_LIB_WIDEN);
5285 return tramp;
5288 static rtx
5289 expand_builtin_init_trampoline (tree arglist)
5291 tree t_tramp, t_func, t_chain;
5292 rtx r_tramp, r_func, r_chain;
5293 #ifdef TRAMPOLINE_TEMPLATE
5294 rtx blktramp;
5295 #endif
5297 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5298 POINTER_TYPE, VOID_TYPE))
5299 return NULL_RTX;
5301 t_tramp = TREE_VALUE (arglist);
5302 arglist = TREE_CHAIN (arglist);
5303 t_func = TREE_VALUE (arglist);
5304 arglist = TREE_CHAIN (arglist);
5305 t_chain = TREE_VALUE (arglist);
5307 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5308 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5309 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5311 /* Generate insns to initialize the trampoline. */
5312 r_tramp = round_trampoline_addr (r_tramp);
5313 #ifdef TRAMPOLINE_TEMPLATE
5314 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5315 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5316 emit_block_move (blktramp, assemble_trampoline_template (),
5317 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5318 #endif
5319 trampolines_created = 1;
5320 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5322 return const0_rtx;
5325 static rtx
5326 expand_builtin_adjust_trampoline (tree arglist)
5328 rtx tramp;
5330 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5331 return NULL_RTX;
5333 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5334 tramp = round_trampoline_addr (tramp);
5335 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5336 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5337 #endif
5339 return tramp;
5342 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5343 Return NULL_RTX if a normal call should be emitted rather than expanding
5344 the function in-line. EXP is the expression that is a call to the builtin
5345 function; if convenient, the result should be placed in TARGET. */
5347 static rtx
5348 expand_builtin_signbit (tree exp, rtx target)
5350 const struct real_format *fmt;
5351 enum machine_mode fmode, imode, rmode;
5352 HOST_WIDE_INT hi, lo;
5353 tree arg, arglist;
5354 int bitpos;
5355 rtx temp;
5357 arglist = TREE_OPERAND (exp, 1);
5358 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5359 return 0;
5361 arg = TREE_VALUE (arglist);
5362 fmode = TYPE_MODE (TREE_TYPE (arg));
5363 rmode = TYPE_MODE (TREE_TYPE (exp));
5364 fmt = REAL_MODE_FORMAT (fmode);
5366 /* For floating point formats without a sign bit, implement signbit
5367 as "ARG < 0.0". */
5368 if (fmt->signbit < 0)
5370 /* But we can't do this if the format supports signed zero. */
5371 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5372 return 0;
5374 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5375 build_real (TREE_TYPE (arg), dconst0)));
5376 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5379 imode = int_mode_for_mode (fmode);
5380 if (imode == BLKmode)
5381 return 0;
5383 bitpos = fmt->signbit;
5384 /* Handle targets with different FP word orders. */
5385 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5387 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5388 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5389 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5392 /* If the sign bit is not in the lowpart and the floating point format
5393 is wider than an integer, check that is twice the size of an integer
5394 so that we can use gen_highpart below. */
5395 if (bitpos >= GET_MODE_BITSIZE (rmode)
5396 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5397 return 0;
5399 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5400 temp = gen_lowpart (imode, temp);
5402 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5404 if (BYTES_BIG_ENDIAN)
5405 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5406 temp = copy_to_mode_reg (imode, temp);
5407 temp = extract_bit_field (temp, 1, bitpos, 1,
5408 NULL_RTX, rmode, rmode);
5410 else
5412 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5413 temp = gen_lowpart (rmode, temp);
5414 if (bitpos < HOST_BITS_PER_WIDE_INT)
5416 hi = 0;
5417 lo = (HOST_WIDE_INT) 1 << bitpos;
5419 else
5421 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5422 lo = 0;
5425 temp = force_reg (rmode, temp);
5426 temp = expand_binop (rmode, and_optab, temp,
5427 immed_double_const (lo, hi, rmode),
5428 target, 1, OPTAB_LIB_WIDEN);
5430 return temp;
5433 /* Expand fork or exec calls. TARGET is the desired target of the
5434 call. ARGLIST is the list of arguments of the call. FN is the
5435 identificator of the actual function. IGNORE is nonzero if the
5436 value is to be ignored. */
5438 static rtx
5439 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5441 tree id, decl;
5442 tree call;
5444 /* If we are not profiling, just call the function. */
5445 if (!profile_arc_flag)
5446 return NULL_RTX;
5448 /* Otherwise call the wrapper. This should be equivalent for the rest of
5449 compiler, so the code does not diverge, and the wrapper may run the
5450 code necessary for keeping the profiling sane. */
5452 switch (DECL_FUNCTION_CODE (fn))
5454 case BUILT_IN_FORK:
5455 id = get_identifier ("__gcov_fork");
5456 break;
5458 case BUILT_IN_EXECL:
5459 id = get_identifier ("__gcov_execl");
5460 break;
5462 case BUILT_IN_EXECV:
5463 id = get_identifier ("__gcov_execv");
5464 break;
5466 case BUILT_IN_EXECLP:
5467 id = get_identifier ("__gcov_execlp");
5468 break;
5470 case BUILT_IN_EXECLE:
5471 id = get_identifier ("__gcov_execle");
5472 break;
5474 case BUILT_IN_EXECVP:
5475 id = get_identifier ("__gcov_execvp");
5476 break;
5478 case BUILT_IN_EXECVE:
5479 id = get_identifier ("__gcov_execve");
5480 break;
5482 default:
5483 abort ();
5486 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5487 DECL_EXTERNAL (decl) = 1;
5488 TREE_PUBLIC (decl) = 1;
5489 DECL_ARTIFICIAL (decl) = 1;
5490 TREE_NOTHROW (decl) = 1;
5491 call = build_function_call_expr (decl, arglist);
5493 return expand_call (call, target, ignore);
5496 /* Expand an expression EXP that calls a built-in function,
5497 with result going to TARGET if that's convenient
5498 (and in mode MODE if that's convenient).
5499 SUBTARGET may be used as the target for computing one of EXP's operands.
5500 IGNORE is nonzero if the value is to be ignored. */
5503 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5504 int ignore)
5506 tree fndecl = get_callee_fndecl (exp);
5507 tree arglist = TREE_OPERAND (exp, 1);
5508 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5509 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5511 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5512 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5514 /* When not optimizing, generate calls to library functions for a certain
5515 set of builtins. */
5516 if (!optimize
5517 && !CALLED_AS_BUILT_IN (fndecl)
5518 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5519 && fcode != BUILT_IN_ALLOCA)
5520 return expand_call (exp, target, ignore);
5522 /* The built-in function expanders test for target == const0_rtx
5523 to determine whether the function's result will be ignored. */
5524 if (ignore)
5525 target = const0_rtx;
5527 /* If the result of a pure or const built-in function is ignored, and
5528 none of its arguments are volatile, we can avoid expanding the
5529 built-in call and just evaluate the arguments for side-effects. */
5530 if (target == const0_rtx
5531 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5533 bool volatilep = false;
5534 tree arg;
5536 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5537 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5539 volatilep = true;
5540 break;
5543 if (! volatilep)
5545 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5546 expand_expr (TREE_VALUE (arg), const0_rtx,
5547 VOIDmode, EXPAND_NORMAL);
5548 return const0_rtx;
5552 switch (fcode)
5554 case BUILT_IN_FABS:
5555 case BUILT_IN_FABSF:
5556 case BUILT_IN_FABSL:
5557 target = expand_builtin_fabs (arglist, target, subtarget);
5558 if (target)
5559 return target;
5560 break;
5562 case BUILT_IN_CABS:
5563 case BUILT_IN_CABSF:
5564 case BUILT_IN_CABSL:
5565 if (flag_unsafe_math_optimizations)
5567 target = expand_builtin_cabs (arglist, target);
5568 if (target)
5569 return target;
5571 break;
5573 case BUILT_IN_EXP:
5574 case BUILT_IN_EXPF:
5575 case BUILT_IN_EXPL:
5576 case BUILT_IN_EXP10:
5577 case BUILT_IN_EXP10F:
5578 case BUILT_IN_EXP10L:
5579 case BUILT_IN_POW10:
5580 case BUILT_IN_POW10F:
5581 case BUILT_IN_POW10L:
5582 case BUILT_IN_EXP2:
5583 case BUILT_IN_EXP2F:
5584 case BUILT_IN_EXP2L:
5585 case BUILT_IN_EXPM1:
5586 case BUILT_IN_EXPM1F:
5587 case BUILT_IN_EXPM1L:
5588 case BUILT_IN_LOGB:
5589 case BUILT_IN_LOGBF:
5590 case BUILT_IN_LOGBL:
5591 case BUILT_IN_ILOGB:
5592 case BUILT_IN_ILOGBF:
5593 case BUILT_IN_ILOGBL:
5594 case BUILT_IN_LOG:
5595 case BUILT_IN_LOGF:
5596 case BUILT_IN_LOGL:
5597 case BUILT_IN_LOG10:
5598 case BUILT_IN_LOG10F:
5599 case BUILT_IN_LOG10L:
5600 case BUILT_IN_LOG2:
5601 case BUILT_IN_LOG2F:
5602 case BUILT_IN_LOG2L:
5603 case BUILT_IN_LOG1P:
5604 case BUILT_IN_LOG1PF:
5605 case BUILT_IN_LOG1PL:
5606 case BUILT_IN_TAN:
5607 case BUILT_IN_TANF:
5608 case BUILT_IN_TANL:
5609 case BUILT_IN_ASIN:
5610 case BUILT_IN_ASINF:
5611 case BUILT_IN_ASINL:
5612 case BUILT_IN_ACOS:
5613 case BUILT_IN_ACOSF:
5614 case BUILT_IN_ACOSL:
5615 case BUILT_IN_ATAN:
5616 case BUILT_IN_ATANF:
5617 case BUILT_IN_ATANL:
5618 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5619 because of possible accuracy problems. */
5620 if (! flag_unsafe_math_optimizations)
5621 break;
5622 case BUILT_IN_SQRT:
5623 case BUILT_IN_SQRTF:
5624 case BUILT_IN_SQRTL:
5625 case BUILT_IN_FLOOR:
5626 case BUILT_IN_FLOORF:
5627 case BUILT_IN_FLOORL:
5628 case BUILT_IN_CEIL:
5629 case BUILT_IN_CEILF:
5630 case BUILT_IN_CEILL:
5631 case BUILT_IN_TRUNC:
5632 case BUILT_IN_TRUNCF:
5633 case BUILT_IN_TRUNCL:
5634 case BUILT_IN_ROUND:
5635 case BUILT_IN_ROUNDF:
5636 case BUILT_IN_ROUNDL:
5637 case BUILT_IN_NEARBYINT:
5638 case BUILT_IN_NEARBYINTF:
5639 case BUILT_IN_NEARBYINTL:
5640 target = expand_builtin_mathfn (exp, target, subtarget);
5641 if (target)
5642 return target;
5643 break;
5645 case BUILT_IN_POW:
5646 case BUILT_IN_POWF:
5647 case BUILT_IN_POWL:
5648 target = expand_builtin_pow (exp, target, subtarget);
5649 if (target)
5650 return target;
5651 break;
5653 case BUILT_IN_ATAN2:
5654 case BUILT_IN_ATAN2F:
5655 case BUILT_IN_ATAN2L:
5656 case BUILT_IN_FMOD:
5657 case BUILT_IN_FMODF:
5658 case BUILT_IN_FMODL:
5659 case BUILT_IN_DREM:
5660 case BUILT_IN_DREMF:
5661 case BUILT_IN_DREML:
5662 if (! flag_unsafe_math_optimizations)
5663 break;
5664 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5665 if (target)
5666 return target;
5667 break;
5669 case BUILT_IN_SIN:
5670 case BUILT_IN_SINF:
5671 case BUILT_IN_SINL:
5672 case BUILT_IN_COS:
5673 case BUILT_IN_COSF:
5674 case BUILT_IN_COSL:
5675 if (! flag_unsafe_math_optimizations)
5676 break;
5677 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5678 if (target)
5679 return target;
5680 break;
5682 case BUILT_IN_APPLY_ARGS:
5683 return expand_builtin_apply_args ();
5685 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5686 FUNCTION with a copy of the parameters described by
5687 ARGUMENTS, and ARGSIZE. It returns a block of memory
5688 allocated on the stack into which is stored all the registers
5689 that might possibly be used for returning the result of a
5690 function. ARGUMENTS is the value returned by
5691 __builtin_apply_args. ARGSIZE is the number of bytes of
5692 arguments that must be copied. ??? How should this value be
5693 computed? We'll also need a safe worst case value for varargs
5694 functions. */
5695 case BUILT_IN_APPLY:
5696 if (!validate_arglist (arglist, POINTER_TYPE,
5697 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5698 && !validate_arglist (arglist, REFERENCE_TYPE,
5699 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5700 return const0_rtx;
5701 else
5703 int i;
5704 tree t;
5705 rtx ops[3];
5707 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5708 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5710 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5713 /* __builtin_return (RESULT) causes the function to return the
5714 value described by RESULT. RESULT is address of the block of
5715 memory returned by __builtin_apply. */
5716 case BUILT_IN_RETURN:
5717 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5718 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5719 NULL_RTX, VOIDmode, 0));
5720 return const0_rtx;
5722 case BUILT_IN_SAVEREGS:
5723 return expand_builtin_saveregs ();
5725 case BUILT_IN_ARGS_INFO:
5726 return expand_builtin_args_info (arglist);
5728 /* Return the address of the first anonymous stack arg. */
5729 case BUILT_IN_NEXT_ARG:
5730 simplify_builtin_next_arg (arglist);
5731 return expand_builtin_next_arg (arglist);
5733 case BUILT_IN_CLASSIFY_TYPE:
5734 return expand_builtin_classify_type (arglist);
5736 case BUILT_IN_CONSTANT_P:
5737 return const0_rtx;
5739 case BUILT_IN_FRAME_ADDRESS:
5740 case BUILT_IN_RETURN_ADDRESS:
5741 return expand_builtin_frame_address (fndecl, arglist);
5743 /* Returns the address of the area where the structure is returned.
5744 0 otherwise. */
5745 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5746 if (arglist != 0
5747 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5748 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5749 return const0_rtx;
5750 else
5751 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5753 case BUILT_IN_ALLOCA:
5754 target = expand_builtin_alloca (arglist, target);
5755 if (target)
5756 return target;
5757 break;
5759 case BUILT_IN_STACK_SAVE:
5760 return expand_stack_save ();
5762 case BUILT_IN_STACK_RESTORE:
5763 expand_stack_restore (TREE_VALUE (arglist));
5764 return const0_rtx;
5766 case BUILT_IN_FFS:
5767 case BUILT_IN_FFSL:
5768 case BUILT_IN_FFSLL:
5769 case BUILT_IN_FFSIMAX:
5770 target = expand_builtin_unop (target_mode, arglist, target,
5771 subtarget, ffs_optab);
5772 if (target)
5773 return target;
5774 break;
5776 case BUILT_IN_CLZ:
5777 case BUILT_IN_CLZL:
5778 case BUILT_IN_CLZLL:
5779 case BUILT_IN_CLZIMAX:
5780 target = expand_builtin_unop (target_mode, arglist, target,
5781 subtarget, clz_optab);
5782 if (target)
5783 return target;
5784 break;
5786 case BUILT_IN_CTZ:
5787 case BUILT_IN_CTZL:
5788 case BUILT_IN_CTZLL:
5789 case BUILT_IN_CTZIMAX:
5790 target = expand_builtin_unop (target_mode, arglist, target,
5791 subtarget, ctz_optab);
5792 if (target)
5793 return target;
5794 break;
5796 case BUILT_IN_POPCOUNT:
5797 case BUILT_IN_POPCOUNTL:
5798 case BUILT_IN_POPCOUNTLL:
5799 case BUILT_IN_POPCOUNTIMAX:
5800 target = expand_builtin_unop (target_mode, arglist, target,
5801 subtarget, popcount_optab);
5802 if (target)
5803 return target;
5804 break;
5806 case BUILT_IN_PARITY:
5807 case BUILT_IN_PARITYL:
5808 case BUILT_IN_PARITYLL:
5809 case BUILT_IN_PARITYIMAX:
5810 target = expand_builtin_unop (target_mode, arglist, target,
5811 subtarget, parity_optab);
5812 if (target)
5813 return target;
5814 break;
5816 case BUILT_IN_STRLEN:
5817 target = expand_builtin_strlen (arglist, target, target_mode);
5818 if (target)
5819 return target;
5820 break;
5822 case BUILT_IN_STRCPY:
5823 target = expand_builtin_strcpy (arglist, target, mode);
5824 if (target)
5825 return target;
5826 break;
5828 case BUILT_IN_STRNCPY:
5829 target = expand_builtin_strncpy (arglist, target, mode);
5830 if (target)
5831 return target;
5832 break;
5834 case BUILT_IN_STPCPY:
5835 target = expand_builtin_stpcpy (arglist, target, mode);
5836 if (target)
5837 return target;
5838 break;
5840 case BUILT_IN_STRCAT:
5841 target = expand_builtin_strcat (arglist, target, mode);
5842 if (target)
5843 return target;
5844 break;
5846 case BUILT_IN_STRNCAT:
5847 target = expand_builtin_strncat (arglist, target, mode);
5848 if (target)
5849 return target;
5850 break;
5852 case BUILT_IN_STRSPN:
5853 target = expand_builtin_strspn (arglist, target, mode);
5854 if (target)
5855 return target;
5856 break;
5858 case BUILT_IN_STRCSPN:
5859 target = expand_builtin_strcspn (arglist, target, mode);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_STRSTR:
5865 target = expand_builtin_strstr (arglist, target, mode);
5866 if (target)
5867 return target;
5868 break;
5870 case BUILT_IN_STRPBRK:
5871 target = expand_builtin_strpbrk (arglist, target, mode);
5872 if (target)
5873 return target;
5874 break;
5876 case BUILT_IN_INDEX:
5877 case BUILT_IN_STRCHR:
5878 target = expand_builtin_strchr (arglist, target, mode);
5879 if (target)
5880 return target;
5881 break;
5883 case BUILT_IN_RINDEX:
5884 case BUILT_IN_STRRCHR:
5885 target = expand_builtin_strrchr (arglist, target, mode);
5886 if (target)
5887 return target;
5888 break;
5890 case BUILT_IN_MEMCPY:
5891 target = expand_builtin_memcpy (arglist, target, mode);
5892 if (target)
5893 return target;
5894 break;
5896 case BUILT_IN_MEMPCPY:
5897 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5898 if (target)
5899 return target;
5900 break;
5902 case BUILT_IN_MEMMOVE:
5903 target = expand_builtin_memmove (arglist, target, mode);
5904 if (target)
5905 return target;
5906 break;
5908 case BUILT_IN_BCOPY:
5909 target = expand_builtin_bcopy (arglist);
5910 if (target)
5911 return target;
5912 break;
5914 case BUILT_IN_MEMSET:
5915 target = expand_builtin_memset (arglist, target, mode);
5916 if (target)
5917 return target;
5918 break;
5920 case BUILT_IN_BZERO:
5921 target = expand_builtin_bzero (arglist);
5922 if (target)
5923 return target;
5924 break;
5926 case BUILT_IN_STRCMP:
5927 target = expand_builtin_strcmp (exp, target, mode);
5928 if (target)
5929 return target;
5930 break;
5932 case BUILT_IN_STRNCMP:
5933 target = expand_builtin_strncmp (exp, target, mode);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_BCMP:
5939 case BUILT_IN_MEMCMP:
5940 target = expand_builtin_memcmp (exp, arglist, target, mode);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_SETJMP:
5946 target = expand_builtin_setjmp (arglist, target);
5947 if (target)
5948 return target;
5949 break;
5951 /* __builtin_longjmp is passed a pointer to an array of five words.
5952 It's similar to the C library longjmp function but works with
5953 __builtin_setjmp above. */
5954 case BUILT_IN_LONGJMP:
5955 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5956 break;
5957 else
5959 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5960 VOIDmode, 0);
5961 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5962 NULL_RTX, VOIDmode, 0);
5964 if (value != const1_rtx)
5966 error ("__builtin_longjmp second argument must be 1");
5967 return const0_rtx;
5970 expand_builtin_longjmp (buf_addr, value);
5971 return const0_rtx;
5974 case BUILT_IN_NONLOCAL_GOTO:
5975 target = expand_builtin_nonlocal_goto (arglist);
5976 if (target)
5977 return target;
5978 break;
5980 /* This updates the setjmp buffer that is its argument with the value
5981 of the current stack pointer. */
5982 case BUILT_IN_UPDATE_SETJMP_BUF:
5983 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5985 rtx buf_addr
5986 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5988 expand_builtin_update_setjmp_buf (buf_addr);
5989 return const0_rtx;
5991 break;
5993 case BUILT_IN_TRAP:
5994 expand_builtin_trap ();
5995 return const0_rtx;
5997 case BUILT_IN_PRINTF:
5998 target = expand_builtin_printf (arglist, target, mode, false);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_PRINTF_UNLOCKED:
6004 target = expand_builtin_printf (arglist, target, mode, true);
6005 if (target)
6006 return target;
6007 break;
6009 case BUILT_IN_FPUTS:
6010 target = expand_builtin_fputs (arglist, target, false);
6011 if (target)
6012 return target;
6013 break;
6014 case BUILT_IN_FPUTS_UNLOCKED:
6015 target = expand_builtin_fputs (arglist, target, true);
6016 if (target)
6017 return target;
6018 break;
6020 case BUILT_IN_FPRINTF:
6021 target = expand_builtin_fprintf (arglist, target, mode, false);
6022 if (target)
6023 return target;
6024 break;
6026 case BUILT_IN_FPRINTF_UNLOCKED:
6027 target = expand_builtin_fprintf (arglist, target, mode, true);
6028 if (target)
6029 return target;
6030 break;
6032 case BUILT_IN_SPRINTF:
6033 target = expand_builtin_sprintf (arglist, target, mode);
6034 if (target)
6035 return target;
6036 break;
6038 case BUILT_IN_SIGNBIT:
6039 case BUILT_IN_SIGNBITF:
6040 case BUILT_IN_SIGNBITL:
6041 target = expand_builtin_signbit (exp, target);
6042 if (target)
6043 return target;
6044 break;
6046 /* Various hooks for the DWARF 2 __throw routine. */
6047 case BUILT_IN_UNWIND_INIT:
6048 expand_builtin_unwind_init ();
6049 return const0_rtx;
6050 case BUILT_IN_DWARF_CFA:
6051 return virtual_cfa_rtx;
6052 #ifdef DWARF2_UNWIND_INFO
6053 case BUILT_IN_DWARF_SP_COLUMN:
6054 return expand_builtin_dwarf_sp_column ();
6055 case BUILT_IN_INIT_DWARF_REG_SIZES:
6056 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6057 return const0_rtx;
6058 #endif
6059 case BUILT_IN_FROB_RETURN_ADDR:
6060 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6061 case BUILT_IN_EXTRACT_RETURN_ADDR:
6062 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6063 case BUILT_IN_EH_RETURN:
6064 expand_builtin_eh_return (TREE_VALUE (arglist),
6065 TREE_VALUE (TREE_CHAIN (arglist)));
6066 return const0_rtx;
6067 #ifdef EH_RETURN_DATA_REGNO
6068 case BUILT_IN_EH_RETURN_DATA_REGNO:
6069 return expand_builtin_eh_return_data_regno (arglist);
6070 #endif
6071 case BUILT_IN_EXTEND_POINTER:
6072 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6074 case BUILT_IN_VA_START:
6075 case BUILT_IN_STDARG_START:
6076 return expand_builtin_va_start (arglist);
6077 case BUILT_IN_VA_END:
6078 return expand_builtin_va_end (arglist);
6079 case BUILT_IN_VA_COPY:
6080 return expand_builtin_va_copy (arglist);
6081 case BUILT_IN_EXPECT:
6082 return expand_builtin_expect (arglist, target);
6083 case BUILT_IN_PREFETCH:
6084 expand_builtin_prefetch (arglist);
6085 return const0_rtx;
6087 case BUILT_IN_PROFILE_FUNC_ENTER:
6088 return expand_builtin_profile_func (false);
6089 case BUILT_IN_PROFILE_FUNC_EXIT:
6090 return expand_builtin_profile_func (true);
6092 case BUILT_IN_INIT_TRAMPOLINE:
6093 return expand_builtin_init_trampoline (arglist);
6094 case BUILT_IN_ADJUST_TRAMPOLINE:
6095 return expand_builtin_adjust_trampoline (arglist);
6097 case BUILT_IN_FORK:
6098 case BUILT_IN_EXECL:
6099 case BUILT_IN_EXECV:
6100 case BUILT_IN_EXECLP:
6101 case BUILT_IN_EXECLE:
6102 case BUILT_IN_EXECVP:
6103 case BUILT_IN_EXECVE:
6104 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6105 if (target)
6106 return target;
6107 break;
6109 default: /* just do library call, if unknown builtin */
6110 break;
6113 /* The switch statement above can drop through to cause the function
6114 to be called normally. */
6115 return expand_call (exp, target, ignore);
6118 /* Determine whether a tree node represents a call to a built-in
6119 function. If the tree T is a call to a built-in function with
6120 the right number of arguments of the appropriate types, return
6121 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6122 Otherwise the return value is END_BUILTINS. */
6124 enum built_in_function
6125 builtin_mathfn_code (tree t)
6127 tree fndecl, arglist, parmlist;
6128 tree argtype, parmtype;
6130 if (TREE_CODE (t) != CALL_EXPR
6131 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6132 return END_BUILTINS;
6134 fndecl = get_callee_fndecl (t);
6135 if (fndecl == NULL_TREE
6136 || TREE_CODE (fndecl) != FUNCTION_DECL
6137 || ! DECL_BUILT_IN (fndecl)
6138 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6139 return END_BUILTINS;
6141 arglist = TREE_OPERAND (t, 1);
6142 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6143 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6145 /* If a function doesn't take a variable number of arguments,
6146 the last element in the list will have type `void'. */
6147 parmtype = TREE_VALUE (parmlist);
6148 if (VOID_TYPE_P (parmtype))
6150 if (arglist)
6151 return END_BUILTINS;
6152 return DECL_FUNCTION_CODE (fndecl);
6155 if (! arglist)
6156 return END_BUILTINS;
6158 argtype = TREE_TYPE (TREE_VALUE (arglist));
6160 if (SCALAR_FLOAT_TYPE_P (parmtype))
6162 if (! SCALAR_FLOAT_TYPE_P (argtype))
6163 return END_BUILTINS;
6165 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6167 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6168 return END_BUILTINS;
6170 else if (POINTER_TYPE_P (parmtype))
6172 if (! POINTER_TYPE_P (argtype))
6173 return END_BUILTINS;
6175 else if (INTEGRAL_TYPE_P (parmtype))
6177 if (! INTEGRAL_TYPE_P (argtype))
6178 return END_BUILTINS;
6180 else
6181 return END_BUILTINS;
6183 arglist = TREE_CHAIN (arglist);
6186 /* Variable-length argument list. */
6187 return DECL_FUNCTION_CODE (fndecl);
6190 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6191 constant. ARGLIST is the argument list of the call. */
6193 static tree
6194 fold_builtin_constant_p (tree arglist)
6196 if (arglist == 0)
6197 return 0;
6199 arglist = TREE_VALUE (arglist);
6201 /* We return 1 for a numeric type that's known to be a constant
6202 value at compile-time or for an aggregate type that's a
6203 literal constant. */
6204 STRIP_NOPS (arglist);
6206 /* If we know this is a constant, emit the constant of one. */
6207 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6208 || (TREE_CODE (arglist) == CONSTRUCTOR
6209 && TREE_CONSTANT (arglist))
6210 || (TREE_CODE (arglist) == ADDR_EXPR
6211 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6212 return integer_one_node;
6214 /* If this expression has side effects, show we don't know it to be a
6215 constant. Likewise if it's a pointer or aggregate type since in
6216 those case we only want literals, since those are only optimized
6217 when generating RTL, not later.
6218 And finally, if we are compiling an initializer, not code, we
6219 need to return a definite result now; there's not going to be any
6220 more optimization done. */
6221 if (TREE_SIDE_EFFECTS (arglist)
6222 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6223 || POINTER_TYPE_P (TREE_TYPE (arglist))
6224 || cfun == 0)
6225 return integer_zero_node;
6227 return 0;
6230 /* Fold a call to __builtin_expect, if we expect that a comparison against
6231 the argument will fold to a constant. In practice, this means a true
6232 constant or the address of a non-weak symbol. ARGLIST is the argument
6233 list of the call. */
6235 static tree
6236 fold_builtin_expect (tree arglist)
6238 tree arg, inner;
6240 if (arglist == 0)
6241 return 0;
6243 arg = TREE_VALUE (arglist);
6245 /* If the argument isn't invariant, then there's nothing we can do. */
6246 if (!TREE_INVARIANT (arg))
6247 return 0;
6249 /* If we're looking at an address of a weak decl, then do not fold. */
6250 inner = arg;
6251 STRIP_NOPS (inner);
6252 if (TREE_CODE (inner) == ADDR_EXPR)
6256 inner = TREE_OPERAND (inner, 0);
6258 while (TREE_CODE (inner) == COMPONENT_REF
6259 || TREE_CODE (inner) == ARRAY_REF);
6260 if (DECL_P (inner) && DECL_WEAK (inner))
6261 return 0;
6264 /* Otherwise, ARG already has the proper type for the return value. */
6265 return arg;
6268 /* Fold a call to __builtin_classify_type. */
6270 static tree
6271 fold_builtin_classify_type (tree arglist)
6273 if (arglist == 0)
6274 return build_int_cst (NULL_TREE, no_type_class, 0);
6276 return build_int_cst (NULL_TREE,
6277 type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6280 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6282 static tree
6283 fold_builtin_inf (tree type, int warn)
6285 REAL_VALUE_TYPE real;
6287 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6288 warning ("target format does not support infinity");
6290 real_inf (&real);
6291 return build_real (type, real);
6294 /* Fold a call to __builtin_nan or __builtin_nans. */
6296 static tree
6297 fold_builtin_nan (tree arglist, tree type, int quiet)
6299 REAL_VALUE_TYPE real;
6300 const char *str;
6302 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6303 return 0;
6304 str = c_getstr (TREE_VALUE (arglist));
6305 if (!str)
6306 return 0;
6308 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6309 return 0;
6311 return build_real (type, real);
6314 /* Return true if the floating point expression T has an integer value.
6315 We also allow +Inf, -Inf and NaN to be considered integer values. */
6317 static bool
6318 integer_valued_real_p (tree t)
6320 switch (TREE_CODE (t))
6322 case FLOAT_EXPR:
6323 return true;
6325 case ABS_EXPR:
6326 case SAVE_EXPR:
6327 case NON_LVALUE_EXPR:
6328 return integer_valued_real_p (TREE_OPERAND (t, 0));
6330 case COMPOUND_EXPR:
6331 case MODIFY_EXPR:
6332 case BIND_EXPR:
6333 return integer_valued_real_p (TREE_OPERAND (t, 1));
6335 case PLUS_EXPR:
6336 case MINUS_EXPR:
6337 case MULT_EXPR:
6338 case MIN_EXPR:
6339 case MAX_EXPR:
6340 return integer_valued_real_p (TREE_OPERAND (t, 0))
6341 && integer_valued_real_p (TREE_OPERAND (t, 1));
6343 case COND_EXPR:
6344 return integer_valued_real_p (TREE_OPERAND (t, 1))
6345 && integer_valued_real_p (TREE_OPERAND (t, 2));
6347 case REAL_CST:
6348 if (! TREE_CONSTANT_OVERFLOW (t))
6350 REAL_VALUE_TYPE c, cint;
6352 c = TREE_REAL_CST (t);
6353 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6354 return real_identical (&c, &cint);
6357 case NOP_EXPR:
6359 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6360 if (TREE_CODE (type) == INTEGER_TYPE)
6361 return true;
6362 if (TREE_CODE (type) == REAL_TYPE)
6363 return integer_valued_real_p (TREE_OPERAND (t, 0));
6364 break;
6367 case CALL_EXPR:
6368 switch (builtin_mathfn_code (t))
6370 case BUILT_IN_CEIL:
6371 case BUILT_IN_CEILF:
6372 case BUILT_IN_CEILL:
6373 case BUILT_IN_FLOOR:
6374 case BUILT_IN_FLOORF:
6375 case BUILT_IN_FLOORL:
6376 case BUILT_IN_NEARBYINT:
6377 case BUILT_IN_NEARBYINTF:
6378 case BUILT_IN_NEARBYINTL:
6379 case BUILT_IN_RINT:
6380 case BUILT_IN_RINTF:
6381 case BUILT_IN_RINTL:
6382 case BUILT_IN_ROUND:
6383 case BUILT_IN_ROUNDF:
6384 case BUILT_IN_ROUNDL:
6385 case BUILT_IN_TRUNC:
6386 case BUILT_IN_TRUNCF:
6387 case BUILT_IN_TRUNCL:
6388 return true;
6390 default:
6391 break;
6393 break;
6395 default:
6396 break;
6398 return false;
6401 /* EXP is assumed to be builtin call where truncation can be propagated
6402 across (for instance floor((double)f) == (double)floorf (f).
6403 Do the transformation. */
6405 static tree
6406 fold_trunc_transparent_mathfn (tree exp)
6408 tree fndecl = get_callee_fndecl (exp);
6409 tree arglist = TREE_OPERAND (exp, 1);
6410 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6411 tree arg;
6413 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6414 return 0;
6416 arg = TREE_VALUE (arglist);
6417 /* Integer rounding functions are idempotent. */
6418 if (fcode == builtin_mathfn_code (arg))
6419 return arg;
6421 /* If argument is already integer valued, and we don't need to worry
6422 about setting errno, there's no need to perform rounding. */
6423 if (! flag_errno_math && integer_valued_real_p (arg))
6424 return arg;
6426 if (optimize)
6428 tree arg0 = strip_float_extensions (arg);
6429 tree ftype = TREE_TYPE (exp);
6430 tree newtype = TREE_TYPE (arg0);
6431 tree decl;
6433 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6434 && (decl = mathfn_built_in (newtype, fcode)))
6436 arglist =
6437 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6438 return fold_convert (ftype,
6439 build_function_call_expr (decl, arglist));
6442 return 0;
6445 /* EXP is assumed to be builtin call which can narrow the FP type of
6446 the argument, for instance lround((double)f) -> lroundf (f). */
6448 static tree
6449 fold_fixed_mathfn (tree exp)
6451 tree fndecl = get_callee_fndecl (exp);
6452 tree arglist = TREE_OPERAND (exp, 1);
6453 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6454 tree arg;
6456 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6457 return 0;
6459 arg = TREE_VALUE (arglist);
6461 /* If argument is already integer valued, and we don't need to worry
6462 about setting errno, there's no need to perform rounding. */
6463 if (! flag_errno_math && integer_valued_real_p (arg))
6464 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6466 if (optimize)
6468 tree ftype = TREE_TYPE (arg);
6469 tree arg0 = strip_float_extensions (arg);
6470 tree newtype = TREE_TYPE (arg0);
6471 tree decl;
6473 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6474 && (decl = mathfn_built_in (newtype, fcode)))
6476 arglist =
6477 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6478 return build_function_call_expr (decl, arglist);
6481 return 0;
6484 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6485 is the argument list and TYPE is the return type. Return
6486 NULL_TREE if no if no simplification can be made. */
6488 static tree
6489 fold_builtin_cabs (tree arglist, tree type)
6491 tree arg;
6493 if (!arglist || TREE_CHAIN (arglist))
6494 return NULL_TREE;
6496 arg = TREE_VALUE (arglist);
6497 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6498 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6499 return NULL_TREE;
6501 /* Evaluate cabs of a constant at compile-time. */
6502 if (flag_unsafe_math_optimizations
6503 && TREE_CODE (arg) == COMPLEX_CST
6504 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6505 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6506 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6507 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6509 REAL_VALUE_TYPE r, i;
6511 r = TREE_REAL_CST (TREE_REALPART (arg));
6512 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6514 real_arithmetic (&r, MULT_EXPR, &r, &r);
6515 real_arithmetic (&i, MULT_EXPR, &i, &i);
6516 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6517 if (real_sqrt (&r, TYPE_MODE (type), &r)
6518 || ! flag_trapping_math)
6519 return build_real (type, r);
6522 /* If either part is zero, cabs is fabs of the other. */
6523 if (TREE_CODE (arg) == COMPLEX_EXPR
6524 && real_zerop (TREE_OPERAND (arg, 0)))
6525 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6526 if (TREE_CODE (arg) == COMPLEX_EXPR
6527 && real_zerop (TREE_OPERAND (arg, 1)))
6528 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6530 if (flag_unsafe_math_optimizations)
6532 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6534 if (sqrtfn != NULL_TREE)
6536 tree rpart, ipart, result, arglist;
6538 arg = builtin_save_expr (arg);
6540 rpart = fold (build1 (REALPART_EXPR, type, arg));
6541 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6543 rpart = builtin_save_expr (rpart);
6544 ipart = builtin_save_expr (ipart);
6546 result = fold (build2 (PLUS_EXPR, type,
6547 fold (build2 (MULT_EXPR, type,
6548 rpart, rpart)),
6549 fold (build2 (MULT_EXPR, type,
6550 ipart, ipart))));
6552 arglist = build_tree_list (NULL_TREE, result);
6553 return build_function_call_expr (sqrtfn, arglist);
6557 return NULL_TREE;
6560 /* Fold function call to builtin trunc, truncf or truncl. Return
6561 NULL_TREE if no simplification can be made. */
6563 static tree
6564 fold_builtin_trunc (tree exp)
6566 tree arglist = TREE_OPERAND (exp, 1);
6567 tree arg;
6569 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6570 return 0;
6572 /* Optimize trunc of constant value. */
6573 arg = TREE_VALUE (arglist);
6574 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6576 REAL_VALUE_TYPE r, x;
6577 tree type = TREE_TYPE (exp);
6579 x = TREE_REAL_CST (arg);
6580 real_trunc (&r, TYPE_MODE (type), &x);
6581 return build_real (type, r);
6584 return fold_trunc_transparent_mathfn (exp);
6587 /* Fold function call to builtin floor, floorf or floorl. Return
6588 NULL_TREE if no simplification can be made. */
6590 static tree
6591 fold_builtin_floor (tree exp)
6593 tree arglist = TREE_OPERAND (exp, 1);
6594 tree arg;
6596 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6597 return 0;
6599 /* Optimize floor of constant value. */
6600 arg = TREE_VALUE (arglist);
6601 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6603 REAL_VALUE_TYPE x;
6605 x = TREE_REAL_CST (arg);
6606 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6608 tree type = TREE_TYPE (exp);
6609 REAL_VALUE_TYPE r;
6611 real_floor (&r, TYPE_MODE (type), &x);
6612 return build_real (type, r);
6616 return fold_trunc_transparent_mathfn (exp);
6619 /* Fold function call to builtin ceil, ceilf or ceill. Return
6620 NULL_TREE if no simplification can be made. */
6622 static tree
6623 fold_builtin_ceil (tree exp)
6625 tree arglist = TREE_OPERAND (exp, 1);
6626 tree arg;
6628 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6629 return 0;
6631 /* Optimize ceil of constant value. */
6632 arg = TREE_VALUE (arglist);
6633 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6635 REAL_VALUE_TYPE x;
6637 x = TREE_REAL_CST (arg);
6638 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6640 tree type = TREE_TYPE (exp);
6641 REAL_VALUE_TYPE r;
6643 real_ceil (&r, TYPE_MODE (type), &x);
6644 return build_real (type, r);
6648 return fold_trunc_transparent_mathfn (exp);
6651 /* Fold function call to builtin round, roundf or roundl. Return
6652 NULL_TREE if no simplification can be made. */
6654 static tree
6655 fold_builtin_round (tree exp)
6657 tree arglist = TREE_OPERAND (exp, 1);
6658 tree arg;
6660 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6661 return 0;
6663 /* Optimize round of constant value. */
6664 arg = TREE_VALUE (arglist);
6665 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6667 REAL_VALUE_TYPE x;
6669 x = TREE_REAL_CST (arg);
6670 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6672 tree type = TREE_TYPE (exp);
6673 REAL_VALUE_TYPE r;
6675 real_round (&r, TYPE_MODE (type), &x);
6676 return build_real (type, r);
6680 return fold_trunc_transparent_mathfn (exp);
6683 /* Fold function call to builtin lround, lroundf or lroundl (or the
6684 corresponding long long versions). Return NULL_TREE if no
6685 simplification can be made. */
6687 static tree
6688 fold_builtin_lround (tree exp)
6690 tree arglist = TREE_OPERAND (exp, 1);
6691 tree arg;
6693 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6694 return 0;
6696 /* Optimize lround of constant value. */
6697 arg = TREE_VALUE (arglist);
6698 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6700 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6702 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6704 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6705 HOST_WIDE_INT hi, lo;
6706 REAL_VALUE_TYPE r;
6708 real_round (&r, TYPE_MODE (ftype), &x);
6709 REAL_VALUE_TO_INT (&lo, &hi, r);
6710 result = build_int_cst (NULL_TREE, lo, hi);
6711 if (int_fits_type_p (result, itype))
6712 return fold_convert (itype, result);
6716 return fold_fixed_mathfn (exp);
6719 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6720 and their long and long long variants (i.e. ffsl and ffsll).
6721 Return NULL_TREE if no simplification can be made. */
6723 static tree
6724 fold_builtin_bitop (tree exp)
6726 tree fndecl = get_callee_fndecl (exp);
6727 tree arglist = TREE_OPERAND (exp, 1);
6728 tree arg;
6730 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6731 return NULL_TREE;
6733 /* Optimize for constant argument. */
6734 arg = TREE_VALUE (arglist);
6735 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6737 HOST_WIDE_INT hi, width, result;
6738 unsigned HOST_WIDE_INT lo;
6739 tree type;
6741 type = TREE_TYPE (arg);
6742 width = TYPE_PRECISION (type);
6743 lo = TREE_INT_CST_LOW (arg);
6745 /* Clear all the bits that are beyond the type's precision. */
6746 if (width > HOST_BITS_PER_WIDE_INT)
6748 hi = TREE_INT_CST_HIGH (arg);
6749 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6750 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6752 else
6754 hi = 0;
6755 if (width < HOST_BITS_PER_WIDE_INT)
6756 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6759 switch (DECL_FUNCTION_CODE (fndecl))
6761 case BUILT_IN_FFS:
6762 case BUILT_IN_FFSL:
6763 case BUILT_IN_FFSLL:
6764 if (lo != 0)
6765 result = exact_log2 (lo & -lo) + 1;
6766 else if (hi != 0)
6767 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6768 else
6769 result = 0;
6770 break;
6772 case BUILT_IN_CLZ:
6773 case BUILT_IN_CLZL:
6774 case BUILT_IN_CLZLL:
6775 if (hi != 0)
6776 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6777 else if (lo != 0)
6778 result = width - floor_log2 (lo) - 1;
6779 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6780 result = width;
6781 break;
6783 case BUILT_IN_CTZ:
6784 case BUILT_IN_CTZL:
6785 case BUILT_IN_CTZLL:
6786 if (lo != 0)
6787 result = exact_log2 (lo & -lo);
6788 else if (hi != 0)
6789 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6790 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6791 result = width;
6792 break;
6794 case BUILT_IN_POPCOUNT:
6795 case BUILT_IN_POPCOUNTL:
6796 case BUILT_IN_POPCOUNTLL:
6797 result = 0;
6798 while (lo)
6799 result++, lo &= lo - 1;
6800 while (hi)
6801 result++, hi &= hi - 1;
6802 break;
6804 case BUILT_IN_PARITY:
6805 case BUILT_IN_PARITYL:
6806 case BUILT_IN_PARITYLL:
6807 result = 0;
6808 while (lo)
6809 result++, lo &= lo - 1;
6810 while (hi)
6811 result++, hi &= hi - 1;
6812 result &= 1;
6813 break;
6815 default:
6816 abort();
6819 return build_int_cst (TREE_TYPE (exp), result, 0);
6822 return NULL_TREE;
6825 /* Return true if EXPR is the real constant contained in VALUE. */
6827 static bool
6828 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6830 STRIP_NOPS (expr);
6832 return ((TREE_CODE (expr) == REAL_CST
6833 && ! TREE_CONSTANT_OVERFLOW (expr)
6834 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6835 || (TREE_CODE (expr) == COMPLEX_CST
6836 && real_dconstp (TREE_REALPART (expr), value)
6837 && real_zerop (TREE_IMAGPART (expr))));
6840 /* A subroutine of fold_builtin to fold the various logarithmic
6841 functions. EXP is the CALL_EXPR of a call to a builtin logN
6842 function. VALUE is the base of the logN function. */
6844 static tree
6845 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6847 tree arglist = TREE_OPERAND (exp, 1);
6849 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6851 tree fndecl = get_callee_fndecl (exp);
6852 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6853 tree arg = TREE_VALUE (arglist);
6854 const enum built_in_function fcode = builtin_mathfn_code (arg);
6856 /* Optimize logN(1.0) = 0.0. */
6857 if (real_onep (arg))
6858 return build_real (type, dconst0);
6860 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6861 exactly, then only do this if flag_unsafe_math_optimizations. */
6862 if (exact_real_truncate (TYPE_MODE (type), value)
6863 || flag_unsafe_math_optimizations)
6865 const REAL_VALUE_TYPE value_truncate =
6866 real_value_truncate (TYPE_MODE (type), *value);
6867 if (real_dconstp (arg, &value_truncate))
6868 return build_real (type, dconst1);
6871 /* Special case, optimize logN(expN(x)) = x. */
6872 if (flag_unsafe_math_optimizations
6873 && ((value == &dconste
6874 && (fcode == BUILT_IN_EXP
6875 || fcode == BUILT_IN_EXPF
6876 || fcode == BUILT_IN_EXPL))
6877 || (value == &dconst2
6878 && (fcode == BUILT_IN_EXP2
6879 || fcode == BUILT_IN_EXP2F
6880 || fcode == BUILT_IN_EXP2L))
6881 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6882 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6884 /* Optimize logN(func()) for various exponential functions. We
6885 want to determine the value "x" and the power "exponent" in
6886 order to transform logN(x**exponent) into exponent*logN(x). */
6887 if (flag_unsafe_math_optimizations)
6889 tree exponent = 0, x = 0;
6891 switch (fcode)
6893 case BUILT_IN_EXP:
6894 case BUILT_IN_EXPF:
6895 case BUILT_IN_EXPL:
6896 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6897 x = build_real (type,
6898 real_value_truncate (TYPE_MODE (type), dconste));
6899 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6900 break;
6901 case BUILT_IN_EXP2:
6902 case BUILT_IN_EXP2F:
6903 case BUILT_IN_EXP2L:
6904 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6905 x = build_real (type, dconst2);
6906 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6907 break;
6908 case BUILT_IN_EXP10:
6909 case BUILT_IN_EXP10F:
6910 case BUILT_IN_EXP10L:
6911 case BUILT_IN_POW10:
6912 case BUILT_IN_POW10F:
6913 case BUILT_IN_POW10L:
6914 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6915 x = build_real (type, dconst10);
6916 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6917 break;
6918 case BUILT_IN_SQRT:
6919 case BUILT_IN_SQRTF:
6920 case BUILT_IN_SQRTL:
6921 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6922 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6923 exponent = build_real (type, dconsthalf);
6924 break;
6925 case BUILT_IN_CBRT:
6926 case BUILT_IN_CBRTF:
6927 case BUILT_IN_CBRTL:
6928 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6929 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6930 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6931 dconstthird));
6932 break;
6933 case BUILT_IN_POW:
6934 case BUILT_IN_POWF:
6935 case BUILT_IN_POWL:
6936 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6937 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6938 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6939 break;
6940 default:
6941 break;
6944 /* Now perform the optimization. */
6945 if (x && exponent)
6947 tree logfn;
6948 arglist = build_tree_list (NULL_TREE, x);
6949 logfn = build_function_call_expr (fndecl, arglist);
6950 return fold (build2 (MULT_EXPR, type, exponent, logfn));
6955 return 0;
6958 /* A subroutine of fold_builtin to fold the various exponent
6959 functions. EXP is the CALL_EXPR of a call to a builtin function.
6960 VALUE is the value which will be raised to a power. */
6962 static tree
6963 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6965 tree arglist = TREE_OPERAND (exp, 1);
6967 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6969 tree fndecl = get_callee_fndecl (exp);
6970 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6971 tree arg = TREE_VALUE (arglist);
6973 /* Optimize exp*(0.0) = 1.0. */
6974 if (real_zerop (arg))
6975 return build_real (type, dconst1);
6977 /* Optimize expN(1.0) = N. */
6978 if (real_onep (arg))
6980 REAL_VALUE_TYPE cst;
6982 real_convert (&cst, TYPE_MODE (type), value);
6983 return build_real (type, cst);
6986 /* Attempt to evaluate expN(integer) at compile-time. */
6987 if (flag_unsafe_math_optimizations
6988 && TREE_CODE (arg) == REAL_CST
6989 && ! TREE_CONSTANT_OVERFLOW (arg))
6991 REAL_VALUE_TYPE cint;
6992 REAL_VALUE_TYPE c;
6993 HOST_WIDE_INT n;
6995 c = TREE_REAL_CST (arg);
6996 n = real_to_integer (&c);
6997 real_from_integer (&cint, VOIDmode, n,
6998 n < 0 ? -1 : 0, 0);
6999 if (real_identical (&c, &cint))
7001 REAL_VALUE_TYPE x;
7003 real_powi (&x, TYPE_MODE (type), value, n);
7004 return build_real (type, x);
7008 /* Optimize expN(logN(x)) = x. */
7009 if (flag_unsafe_math_optimizations)
7011 const enum built_in_function fcode = builtin_mathfn_code (arg);
7013 if ((value == &dconste
7014 && (fcode == BUILT_IN_LOG
7015 || fcode == BUILT_IN_LOGF
7016 || fcode == BUILT_IN_LOGL))
7017 || (value == &dconst2
7018 && (fcode == BUILT_IN_LOG2
7019 || fcode == BUILT_IN_LOG2F
7020 || fcode == BUILT_IN_LOG2L))
7021 || (value == &dconst10
7022 && (fcode == BUILT_IN_LOG10
7023 || fcode == BUILT_IN_LOG10F
7024 || fcode == BUILT_IN_LOG10L)))
7025 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7029 return 0;
7032 /* Fold function call to builtin memcpy. Return
7033 NULL_TREE if no simplification can be made. */
7035 static tree
7036 fold_builtin_memcpy (tree exp)
7038 tree arglist = TREE_OPERAND (exp, 1);
7039 tree dest, src, len;
7041 if (!validate_arglist (arglist,
7042 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7043 return 0;
7045 dest = TREE_VALUE (arglist);
7046 src = TREE_VALUE (TREE_CHAIN (arglist));
7047 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7049 /* If the LEN parameter is zero, return DEST. */
7050 if (integer_zerop (len))
7051 return omit_one_operand (TREE_TYPE (exp), dest, src);
7053 /* If SRC and DEST are the same (and not volatile), return DEST. */
7054 if (operand_equal_p (src, dest, 0))
7055 return omit_one_operand (TREE_TYPE (exp), dest, len);
7057 return 0;
7060 /* Fold function call to builtin mempcpy. Return
7061 NULL_TREE if no simplification can be made. */
7063 static tree
7064 fold_builtin_mempcpy (tree exp)
7066 tree arglist = TREE_OPERAND (exp, 1);
7067 tree dest, src, len;
7069 if (!validate_arglist (arglist,
7070 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7071 return 0;
7073 dest = TREE_VALUE (arglist);
7074 src = TREE_VALUE (TREE_CHAIN (arglist));
7075 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7077 /* If the LEN parameter is zero, return DEST. */
7078 if (integer_zerop (len))
7079 return omit_one_operand (TREE_TYPE (exp), dest, src);
7081 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7082 if (operand_equal_p (src, dest, 0))
7084 tree temp = fold_convert (TREE_TYPE (dest), len);
7085 temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7086 return fold_convert (TREE_TYPE (exp), temp);
7089 return 0;
7092 /* Fold function call to builtin memmove. Return
7093 NULL_TREE if no simplification can be made. */
7095 static tree
7096 fold_builtin_memmove (tree exp)
7098 tree arglist = TREE_OPERAND (exp, 1);
7099 tree dest, src, len;
7101 if (!validate_arglist (arglist,
7102 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7103 return 0;
7105 dest = TREE_VALUE (arglist);
7106 src = TREE_VALUE (TREE_CHAIN (arglist));
7107 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7109 /* If the LEN parameter is zero, return DEST. */
7110 if (integer_zerop (len))
7111 return omit_one_operand (TREE_TYPE (exp), dest, src);
7113 /* If SRC and DEST are the same (and not volatile), return DEST. */
7114 if (operand_equal_p (src, dest, 0))
7115 return omit_one_operand (TREE_TYPE (exp), dest, len);
7117 return 0;
7120 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7121 the length of the string to be copied. Return NULL_TREE if no
7122 simplification can be made. */
7124 tree
7125 fold_builtin_strcpy (tree exp, tree len)
7127 tree arglist = TREE_OPERAND (exp, 1);
7128 tree dest, src, fn;
7130 if (!validate_arglist (arglist,
7131 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7132 return 0;
7134 dest = TREE_VALUE (arglist);
7135 src = TREE_VALUE (TREE_CHAIN (arglist));
7137 /* If SRC and DEST are the same (and not volatile), return DEST. */
7138 if (operand_equal_p (src, dest, 0))
7139 return fold_convert (TREE_TYPE (exp), dest);
7141 if (optimize_size)
7142 return 0;
7144 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7145 if (!fn)
7146 return 0;
7148 if (!len)
7150 len = c_strlen (src, 1);
7151 if (! len || TREE_SIDE_EFFECTS (len))
7152 return 0;
7155 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7156 arglist = build_tree_list (NULL_TREE, len);
7157 arglist = tree_cons (NULL_TREE, src, arglist);
7158 arglist = tree_cons (NULL_TREE, dest, arglist);
7159 return fold_convert (TREE_TYPE (exp),
7160 build_function_call_expr (fn, arglist));
7163 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7164 the length of the source string. Return NULL_TREE if no simplification
7165 can be made. */
7167 tree
7168 fold_builtin_strncpy (tree exp, tree slen)
7170 tree arglist = TREE_OPERAND (exp, 1);
7171 tree dest, src, len, fn;
7173 if (!validate_arglist (arglist,
7174 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7175 return 0;
7177 dest = TREE_VALUE (arglist);
7178 src = TREE_VALUE (TREE_CHAIN (arglist));
7179 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7181 /* If the LEN parameter is zero, return DEST. */
7182 if (integer_zerop (len))
7183 return omit_one_operand (TREE_TYPE (exp), dest, src);
7185 /* We can't compare slen with len as constants below if len is not a
7186 constant. */
7187 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7188 return 0;
7190 if (!slen)
7191 slen = c_strlen (src, 1);
7193 /* Now, we must be passed a constant src ptr parameter. */
7194 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7195 return 0;
7197 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7199 /* We do not support simplification of this case, though we do
7200 support it when expanding trees into RTL. */
7201 /* FIXME: generate a call to __builtin_memset. */
7202 if (tree_int_cst_lt (slen, len))
7203 return 0;
7205 /* OK transform into builtin memcpy. */
7206 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7207 if (!fn)
7208 return 0;
7209 return fold_convert (TREE_TYPE (exp),
7210 build_function_call_expr (fn, arglist));
7213 /* Fold function call to builtin strchr and strrchr.
7214 Return NULL_TREE if no simplification can be made. */
7216 static tree
7217 fold_builtin_strchr (tree exp, bool actually_strrchr)
7219 tree arglist = TREE_OPERAND (exp, 1);
7220 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7221 return 0;
7222 else
7224 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7225 const char *p1;
7227 if (TREE_CODE (s2) != INTEGER_CST)
7228 return 0;
7230 p1 = c_getstr (s1);
7231 if (p1 != NULL)
7233 char c;
7234 const char *r;
7236 if (target_char_cast (s2, &c))
7237 return 0;
7239 r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7241 if (r == NULL)
7242 return fold_convert (TREE_TYPE (s1), integer_zero_node);
7244 /* Return an offset into the constant string argument. */
7245 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7246 s1, fold_convert (TREE_TYPE (s1),
7247 ssize_int (r - p1))));
7250 if (actually_strrchr)
7252 tree fn;
7254 if (!integer_zerop (s2))
7255 return 0;
7257 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7258 if (!fn)
7259 return 0;
7261 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
7262 return build_function_call_expr (fn, arglist);
7265 return 0;
7269 /* Fold function call to builtin memcmp. Return
7270 NULL_TREE if no simplification can be made. */
7272 static tree
7273 fold_builtin_memcmp (tree arglist)
7275 tree arg1, arg2, len;
7276 const char *p1, *p2;
7278 if (!validate_arglist (arglist,
7279 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7280 return 0;
7282 arg1 = TREE_VALUE (arglist);
7283 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7284 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7286 /* If the LEN parameter is zero, return zero. */
7287 if (integer_zerop (len))
7288 return omit_two_operands (integer_type_node, integer_zero_node,
7289 arg1, arg2);
7291 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7292 if (operand_equal_p (arg1, arg2, 0))
7293 return omit_one_operand (integer_type_node, integer_zero_node, len);
7295 p1 = c_getstr (arg1);
7296 p2 = c_getstr (arg2);
7298 /* If all arguments are constant, and the value of len is not greater
7299 than the lengths of arg1 and arg2, evaluate at compile-time. */
7300 if (host_integerp (len, 1) && p1 && p2
7301 && compare_tree_int (len, strlen (p1) + 1) <= 0
7302 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7304 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7306 if (r > 0)
7307 return integer_one_node;
7308 else if (r < 0)
7309 return integer_minus_one_node;
7310 else
7311 return integer_zero_node;
7314 /* If len parameter is one, return an expression corresponding to
7315 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7316 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7318 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7319 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7320 tree ind1 = fold_convert (integer_type_node,
7321 build1 (INDIRECT_REF, cst_uchar_node,
7322 fold_convert (cst_uchar_ptr_node,
7323 arg1)));
7324 tree ind2 = fold_convert (integer_type_node,
7325 build1 (INDIRECT_REF, cst_uchar_node,
7326 fold_convert (cst_uchar_ptr_node,
7327 arg2)));
7328 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7331 return 0;
7334 /* Fold function call to builtin strcmp. Return
7335 NULL_TREE if no simplification can be made. */
7337 static tree
7338 fold_builtin_strcmp (tree arglist)
7340 tree arg1, arg2;
7341 const char *p1, *p2;
7343 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7344 return 0;
7346 arg1 = TREE_VALUE (arglist);
7347 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7349 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7350 if (operand_equal_p (arg1, arg2, 0))
7351 return integer_zero_node;
7353 p1 = c_getstr (arg1);
7354 p2 = c_getstr (arg2);
7356 if (p1 && p2)
7358 const int i = strcmp (p1, p2);
7359 if (i < 0)
7360 return integer_minus_one_node;
7361 else if (i > 0)
7362 return integer_one_node;
7363 else
7364 return integer_zero_node;
7367 /* If the second arg is "", return *(const unsigned char*)arg1. */
7368 if (p2 && *p2 == '\0')
7370 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7371 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7372 return fold_convert (integer_type_node,
7373 build1 (INDIRECT_REF, cst_uchar_node,
7374 fold_convert (cst_uchar_ptr_node,
7375 arg1)));
7378 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7379 if (p1 && *p1 == '\0')
7381 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7382 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7383 tree temp = fold_convert (integer_type_node,
7384 build1 (INDIRECT_REF, cst_uchar_node,
7385 fold_convert (cst_uchar_ptr_node,
7386 arg2)));
7387 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7390 return 0;
7393 /* Fold function call to builtin strncmp. Return
7394 NULL_TREE if no simplification can be made. */
7396 static tree
7397 fold_builtin_strncmp (tree arglist)
7399 tree arg1, arg2, len;
7400 const char *p1, *p2;
7402 if (!validate_arglist (arglist,
7403 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7404 return 0;
7406 arg1 = TREE_VALUE (arglist);
7407 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7408 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7410 /* If the LEN parameter is zero, return zero. */
7411 if (integer_zerop (len))
7412 return omit_two_operands (integer_type_node, integer_zero_node,
7413 arg1, arg2);
7415 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7416 if (operand_equal_p (arg1, arg2, 0))
7417 return omit_one_operand (integer_type_node, integer_zero_node, len);
7419 p1 = c_getstr (arg1);
7420 p2 = c_getstr (arg2);
7422 if (host_integerp (len, 1) && p1 && p2)
7424 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7425 if (i > 0)
7426 return integer_one_node;
7427 else if (i < 0)
7428 return integer_minus_one_node;
7429 else
7430 return integer_zero_node;
7433 /* If the second arg is "", and the length is greater than zero,
7434 return *(const unsigned char*)arg1. */
7435 if (p2 && *p2 == '\0'
7436 && TREE_CODE (len) == INTEGER_CST
7437 && tree_int_cst_sgn (len) == 1)
7439 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7440 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7441 return fold_convert (integer_type_node,
7442 build1 (INDIRECT_REF, cst_uchar_node,
7443 fold_convert (cst_uchar_ptr_node,
7444 arg1)));
7447 /* If the first arg is "", and the length is greater than zero,
7448 return -*(const unsigned char*)arg2. */
7449 if (p1 && *p1 == '\0'
7450 && TREE_CODE (len) == INTEGER_CST
7451 && tree_int_cst_sgn (len) == 1)
7453 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7454 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7455 tree temp = fold_convert (integer_type_node,
7456 build1 (INDIRECT_REF, cst_uchar_node,
7457 fold_convert (cst_uchar_ptr_node,
7458 arg2)));
7459 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7462 /* If len parameter is one, return an expression corresponding to
7463 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7464 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7466 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7467 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7468 tree ind1 = fold_convert (integer_type_node,
7469 build1 (INDIRECT_REF, cst_uchar_node,
7470 fold_convert (cst_uchar_ptr_node,
7471 arg1)));
7472 tree ind2 = fold_convert (integer_type_node,
7473 build1 (INDIRECT_REF, cst_uchar_node,
7474 fold_convert (cst_uchar_ptr_node,
7475 arg2)));
7476 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7479 return 0;
7482 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7483 NULL_TREE if no simplification can be made. */
7485 static tree
7486 fold_builtin_signbit (tree exp)
7488 tree arglist = TREE_OPERAND (exp, 1);
7489 tree arg, temp;
7491 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7492 return NULL_TREE;
7494 arg = TREE_VALUE (arglist);
7496 /* If ARG is a compile-time constant, determine the result. */
7497 if (TREE_CODE (arg) == REAL_CST
7498 && !TREE_CONSTANT_OVERFLOW (arg))
7500 REAL_VALUE_TYPE c;
7502 c = TREE_REAL_CST (arg);
7503 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7504 return fold_convert (TREE_TYPE (exp), temp);
7507 /* If ARG is non-negative, the result is always zero. */
7508 if (tree_expr_nonnegative_p (arg))
7509 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7511 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7512 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7513 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7514 build_real (TREE_TYPE (arg), dconst0)));
7516 return NULL_TREE;
7519 /* Fold function call to builtin copysign, copysignf or copysignl.
7520 Return NULL_TREE if no simplification can be made. */
7522 static tree
7523 fold_builtin_copysign (tree arglist, tree type)
7525 tree arg1, arg2;
7527 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7528 return NULL_TREE;
7530 arg1 = TREE_VALUE (arglist);
7531 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7533 /* copysign(X,X) is X. */
7534 if (operand_equal_p (arg1, arg2, 0))
7535 return fold_convert (type, arg1);
7537 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7538 if (TREE_CODE (arg1) == REAL_CST
7539 && TREE_CODE (arg2) == REAL_CST
7540 && !TREE_CONSTANT_OVERFLOW (arg1)
7541 && !TREE_CONSTANT_OVERFLOW (arg2))
7543 REAL_VALUE_TYPE c1, c2;
7545 c1 = TREE_REAL_CST (arg1);
7546 c2 = TREE_REAL_CST (arg2);
7547 real_copysign (&c1, &c2);
7548 return build_real (type, c1);
7549 c1.sign = c2.sign;
7552 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7553 Remember to evaluate Y for side-effects. */
7554 if (tree_expr_nonnegative_p (arg2))
7555 return omit_one_operand (type,
7556 fold (build1 (ABS_EXPR, type, arg1)),
7557 arg2);
7559 return NULL_TREE;
7562 /* Fold a call to builtin isascii. */
7564 static tree
7565 fold_builtin_isascii (tree arglist)
7567 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7568 return 0;
7569 else
7571 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7572 tree arg = TREE_VALUE (arglist);
7574 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7575 build_int_cst (NULL_TREE,
7576 ~ (unsigned HOST_WIDE_INT) 0x7f,
7577 ~ (HOST_WIDE_INT) 0));
7578 arg = fold (build2 (EQ_EXPR, integer_type_node,
7579 arg, integer_zero_node));
7581 if (in_gimple_form && !TREE_CONSTANT (arg))
7582 return NULL_TREE;
7583 else
7584 return arg;
7588 /* Fold a call to builtin toascii. */
7590 static tree
7591 fold_builtin_toascii (tree arglist)
7593 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7594 return 0;
7595 else
7597 /* Transform toascii(c) -> (c & 0x7f). */
7598 tree arg = TREE_VALUE (arglist);
7600 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7601 build_int_cst (NULL_TREE, 0x7f, 0)));
7605 /* Fold a call to builtin isdigit. */
7607 static tree
7608 fold_builtin_isdigit (tree arglist)
7610 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7611 return 0;
7612 else
7614 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7615 /* According to the C standard, isdigit is unaffected by locale. */
7616 tree arg = TREE_VALUE (arglist);
7617 arg = fold_convert (unsigned_type_node, arg);
7618 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7619 build_int_cst (unsigned_type_node, TARGET_DIGIT0, 0));
7620 arg = build2 (LE_EXPR, integer_type_node, arg,
7621 build_int_cst (unsigned_type_node, 9, 0));
7622 arg = fold (arg);
7623 if (in_gimple_form && !TREE_CONSTANT (arg))
7624 return NULL_TREE;
7625 else
7626 return arg;
7630 /* Fold a call to fabs, fabsf or fabsl. */
7632 static tree
7633 fold_builtin_fabs (tree arglist, tree type)
7635 tree arg;
7637 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7638 return 0;
7640 arg = TREE_VALUE (arglist);
7641 if (TREE_CODE (arg) == REAL_CST)
7642 return fold_abs_const (arg, type);
7643 return fold (build1 (ABS_EXPR, type, arg));
7646 /* Fold a call to abs, labs, llabs or imaxabs. */
7648 static tree
7649 fold_builtin_abs (tree arglist, tree type)
7651 tree arg;
7653 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7654 return 0;
7656 arg = TREE_VALUE (arglist);
7657 if (TREE_CODE (arg) == INTEGER_CST)
7658 return fold_abs_const (arg, type);
7659 return fold (build1 (ABS_EXPR, type, arg));
7662 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7663 EXP is the CALL_EXPR for the call. */
7665 static tree
7666 fold_builtin_classify (tree exp, int builtin_index)
7668 tree fndecl = get_callee_fndecl (exp);
7669 tree arglist = TREE_OPERAND (exp, 1);
7670 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7671 tree arg;
7672 REAL_VALUE_TYPE r;
7674 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7676 /* Check that we have exactly one argument. */
7677 if (arglist == 0)
7679 error ("too few arguments to function `%s'",
7680 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7681 return error_mark_node;
7683 else if (TREE_CHAIN (arglist) != 0)
7685 error ("too many arguments to function `%s'",
7686 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7687 return error_mark_node;
7689 else
7691 error ("non-floating-point argument to function `%s'",
7692 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7693 return error_mark_node;
7697 arg = TREE_VALUE (arglist);
7698 switch (builtin_index)
7700 case BUILT_IN_ISINF:
7701 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7702 return omit_one_operand (type, integer_zero_node, arg);
7704 if (TREE_CODE (arg) == REAL_CST)
7706 r = TREE_REAL_CST (arg);
7707 if (real_isinf (&r))
7708 return real_compare (GT_EXPR, &r, &dconst0)
7709 ? integer_one_node : integer_minus_one_node;
7710 else
7711 return integer_zero_node;
7714 return NULL_TREE;
7716 case BUILT_IN_FINITE:
7717 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7718 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7719 return omit_one_operand (type, integer_zero_node, arg);
7721 if (TREE_CODE (arg) == REAL_CST)
7723 r = TREE_REAL_CST (arg);
7724 return real_isinf (&r) || real_isnan (&r)
7725 ? integer_zero_node : integer_one_node;
7728 return NULL_TREE;
7730 case BUILT_IN_ISNAN:
7731 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7732 return omit_one_operand (type, integer_zero_node, arg);
7734 if (TREE_CODE (arg) == REAL_CST)
7736 r = TREE_REAL_CST (arg);
7737 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7740 arg = builtin_save_expr (arg);
7741 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7743 default:
7744 abort ();
7748 /* Fold a call to an unordered comparison function such as
7749 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7750 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7751 the opposite of the desired result. UNORDERED_CODE is used
7752 for modes that can hold NaNs and ORDERED_CODE is used for
7753 the rest. */
7755 static tree
7756 fold_builtin_unordered_cmp (tree exp,
7757 enum tree_code unordered_code,
7758 enum tree_code ordered_code)
7760 tree fndecl = get_callee_fndecl (exp);
7761 tree arglist = TREE_OPERAND (exp, 1);
7762 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7763 enum tree_code code;
7764 tree arg0, arg1;
7766 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7768 enum tree_code code0, code1;
7769 tree type0, type1;
7770 tree cmp_type = 0;
7772 /* Check that we have exactly two arguments. */
7773 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7775 error ("too few arguments to function `%s'",
7776 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7777 return error_mark_node;
7779 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7781 error ("too many arguments to function `%s'",
7782 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7783 return error_mark_node;
7786 arg0 = TREE_VALUE (arglist);
7787 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7789 type0 = TREE_TYPE (arg0);
7790 type1 = TREE_TYPE (arg1);
7792 code0 = TREE_CODE (type0);
7793 code1 = TREE_CODE (type1);
7795 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7796 /* Choose the wider of two real types. */
7797 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7798 ? type0 : type1;
7799 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7800 cmp_type = type0;
7801 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7802 cmp_type = type1;
7803 else
7805 error ("non-floating-point argument to function `%s'",
7806 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7807 return error_mark_node;
7810 arg0 = fold_convert (cmp_type, arg0);
7811 arg1 = fold_convert (cmp_type, arg1);
7813 else
7815 arg0 = TREE_VALUE (arglist);
7816 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7819 if (unordered_code == UNORDERED_EXPR)
7821 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7822 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7823 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7826 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7827 : ordered_code;
7828 return fold (build1 (TRUTH_NOT_EXPR, type,
7829 fold (build2 (code, type, arg0, arg1))));
7832 /* Used by constant folding to simplify calls to builtin functions. EXP is
7833 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7834 result of the function call is ignored. This function returns NULL_TREE
7835 if no simplification was possible. */
7837 static tree
7838 fold_builtin_1 (tree exp, bool ignore)
7840 tree fndecl = get_callee_fndecl (exp);
7841 tree arglist = TREE_OPERAND (exp, 1);
7842 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7844 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7845 return 0;
7847 switch (DECL_FUNCTION_CODE (fndecl))
7849 case BUILT_IN_CONSTANT_P:
7850 return fold_builtin_constant_p (arglist);
7852 case BUILT_IN_EXPECT:
7853 return fold_builtin_expect (arglist);
7855 case BUILT_IN_CLASSIFY_TYPE:
7856 return fold_builtin_classify_type (arglist);
7858 case BUILT_IN_STRLEN:
7859 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7861 tree len = c_strlen (TREE_VALUE (arglist), 0);
7862 if (len)
7864 /* Convert from the internal "sizetype" type to "size_t". */
7865 if (size_type_node)
7866 len = fold_convert (size_type_node, len);
7867 return len;
7870 break;
7872 case BUILT_IN_FABS:
7873 case BUILT_IN_FABSF:
7874 case BUILT_IN_FABSL:
7875 return fold_builtin_fabs (arglist, type);
7877 case BUILT_IN_ABS:
7878 case BUILT_IN_LABS:
7879 case BUILT_IN_LLABS:
7880 case BUILT_IN_IMAXABS:
7881 return fold_builtin_abs (arglist, type);
7883 case BUILT_IN_CONJ:
7884 case BUILT_IN_CONJF:
7885 case BUILT_IN_CONJL:
7886 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7887 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7888 break;
7890 case BUILT_IN_CREAL:
7891 case BUILT_IN_CREALF:
7892 case BUILT_IN_CREALL:
7893 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7894 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7895 TREE_VALUE (arglist))));
7896 break;
7898 case BUILT_IN_CIMAG:
7899 case BUILT_IN_CIMAGF:
7900 case BUILT_IN_CIMAGL:
7901 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7902 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7903 TREE_VALUE (arglist))));
7904 break;
7906 case BUILT_IN_CABS:
7907 case BUILT_IN_CABSF:
7908 case BUILT_IN_CABSL:
7909 return fold_builtin_cabs (arglist, type);
7911 case BUILT_IN_SQRT:
7912 case BUILT_IN_SQRTF:
7913 case BUILT_IN_SQRTL:
7914 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7916 enum built_in_function fcode;
7917 tree arg = TREE_VALUE (arglist);
7919 /* Optimize sqrt of constant value. */
7920 if (TREE_CODE (arg) == REAL_CST
7921 && ! TREE_CONSTANT_OVERFLOW (arg))
7923 REAL_VALUE_TYPE r, x;
7925 x = TREE_REAL_CST (arg);
7926 if (real_sqrt (&r, TYPE_MODE (type), &x)
7927 || (!flag_trapping_math && !flag_errno_math))
7928 return build_real (type, r);
7931 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7932 fcode = builtin_mathfn_code (arg);
7933 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7935 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7936 arg = fold (build2 (MULT_EXPR, type,
7937 TREE_VALUE (TREE_OPERAND (arg, 1)),
7938 build_real (type, dconsthalf)));
7939 arglist = build_tree_list (NULL_TREE, arg);
7940 return build_function_call_expr (expfn, arglist);
7943 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7944 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7946 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7948 if (powfn)
7950 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7951 tree tree_root;
7952 /* The inner root was either sqrt or cbrt. */
7953 REAL_VALUE_TYPE dconstroot =
7954 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7956 /* Adjust for the outer root. */
7957 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7958 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7959 tree_root = build_real (type, dconstroot);
7960 arglist = tree_cons (NULL_TREE, arg0,
7961 build_tree_list (NULL_TREE, tree_root));
7962 return build_function_call_expr (powfn, arglist);
7966 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
7967 if (flag_unsafe_math_optimizations
7968 && (fcode == BUILT_IN_POW
7969 || fcode == BUILT_IN_POWF
7970 || fcode == BUILT_IN_POWL))
7972 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7973 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7974 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7975 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7976 build_real (type, dconsthalf)));
7977 arglist = tree_cons (NULL_TREE, arg0,
7978 build_tree_list (NULL_TREE, narg1));
7979 return build_function_call_expr (powfn, arglist);
7982 break;
7984 case BUILT_IN_CBRT:
7985 case BUILT_IN_CBRTF:
7986 case BUILT_IN_CBRTL:
7987 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7989 tree arg = TREE_VALUE (arglist);
7990 const enum built_in_function fcode = builtin_mathfn_code (arg);
7992 /* Optimize cbrt of constant value. */
7993 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7994 return arg;
7996 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7997 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7999 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8000 const REAL_VALUE_TYPE third_trunc =
8001 real_value_truncate (TYPE_MODE (type), dconstthird);
8002 arg = fold (build2 (MULT_EXPR, type,
8003 TREE_VALUE (TREE_OPERAND (arg, 1)),
8004 build_real (type, third_trunc)));
8005 arglist = build_tree_list (NULL_TREE, arg);
8006 return build_function_call_expr (expfn, arglist);
8009 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
8010 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8011 x is negative pow will error but cbrt won't. */
8012 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8014 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8016 if (powfn)
8018 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8019 tree tree_root;
8020 REAL_VALUE_TYPE dconstroot = dconstthird;
8022 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8023 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8024 tree_root = build_real (type, dconstroot);
8025 arglist = tree_cons (NULL_TREE, arg0,
8026 build_tree_list (NULL_TREE, tree_root));
8027 return build_function_call_expr (powfn, arglist);
8032 break;
8034 case BUILT_IN_SIN:
8035 case BUILT_IN_SINF:
8036 case BUILT_IN_SINL:
8037 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8039 tree arg = TREE_VALUE (arglist);
8041 /* Optimize sin(0.0) = 0.0. */
8042 if (real_zerop (arg))
8043 return arg;
8045 break;
8047 case BUILT_IN_COS:
8048 case BUILT_IN_COSF:
8049 case BUILT_IN_COSL:
8050 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8052 tree arg = TREE_VALUE (arglist);
8054 /* Optimize cos(0.0) = 1.0. */
8055 if (real_zerop (arg))
8056 return build_real (type, dconst1);
8058 /* Optimize cos(-x) into cos(x). */
8059 if (TREE_CODE (arg) == NEGATE_EXPR)
8061 tree arglist = build_tree_list (NULL_TREE,
8062 TREE_OPERAND (arg, 0));
8063 return build_function_call_expr (fndecl, arglist);
8066 break;
8068 case BUILT_IN_EXP:
8069 case BUILT_IN_EXPF:
8070 case BUILT_IN_EXPL:
8071 return fold_builtin_exponent (exp, &dconste);
8073 case BUILT_IN_EXP2:
8074 case BUILT_IN_EXP2F:
8075 case BUILT_IN_EXP2L:
8076 return fold_builtin_exponent (exp, &dconst2);
8078 case BUILT_IN_EXP10:
8079 case BUILT_IN_EXP10F:
8080 case BUILT_IN_EXP10L:
8081 case BUILT_IN_POW10:
8082 case BUILT_IN_POW10F:
8083 case BUILT_IN_POW10L:
8084 return fold_builtin_exponent (exp, &dconst10);
8086 case BUILT_IN_LOG:
8087 case BUILT_IN_LOGF:
8088 case BUILT_IN_LOGL:
8089 return fold_builtin_logarithm (exp, &dconste);
8091 case BUILT_IN_LOG2:
8092 case BUILT_IN_LOG2F:
8093 case BUILT_IN_LOG2L:
8094 return fold_builtin_logarithm (exp, &dconst2);
8096 case BUILT_IN_LOG10:
8097 case BUILT_IN_LOG10F:
8098 case BUILT_IN_LOG10L:
8099 return fold_builtin_logarithm (exp, &dconst10);
8101 case BUILT_IN_TAN:
8102 case BUILT_IN_TANF:
8103 case BUILT_IN_TANL:
8104 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8106 enum built_in_function fcode;
8107 tree arg = TREE_VALUE (arglist);
8109 /* Optimize tan(0.0) = 0.0. */
8110 if (real_zerop (arg))
8111 return arg;
8113 /* Optimize tan(atan(x)) = x. */
8114 fcode = builtin_mathfn_code (arg);
8115 if (flag_unsafe_math_optimizations
8116 && (fcode == BUILT_IN_ATAN
8117 || fcode == BUILT_IN_ATANF
8118 || fcode == BUILT_IN_ATANL))
8119 return TREE_VALUE (TREE_OPERAND (arg, 1));
8121 break;
8123 case BUILT_IN_ATAN:
8124 case BUILT_IN_ATANF:
8125 case BUILT_IN_ATANL:
8126 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8128 tree arg = TREE_VALUE (arglist);
8130 /* Optimize atan(0.0) = 0.0. */
8131 if (real_zerop (arg))
8132 return arg;
8134 /* Optimize atan(1.0) = pi/4. */
8135 if (real_onep (arg))
8137 REAL_VALUE_TYPE cst;
8139 real_convert (&cst, TYPE_MODE (type), &dconstpi);
8140 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8141 return build_real (type, cst);
8144 break;
8146 case BUILT_IN_POW:
8147 case BUILT_IN_POWF:
8148 case BUILT_IN_POWL:
8149 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8151 enum built_in_function fcode;
8152 tree arg0 = TREE_VALUE (arglist);
8153 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8155 /* Optimize pow(1.0,y) = 1.0. */
8156 if (real_onep (arg0))
8157 return omit_one_operand (type, build_real (type, dconst1), arg1);
8159 if (TREE_CODE (arg1) == REAL_CST
8160 && ! TREE_CONSTANT_OVERFLOW (arg1))
8162 REAL_VALUE_TYPE c;
8163 c = TREE_REAL_CST (arg1);
8165 /* Optimize pow(x,0.0) = 1.0. */
8166 if (REAL_VALUES_EQUAL (c, dconst0))
8167 return omit_one_operand (type, build_real (type, dconst1),
8168 arg0);
8170 /* Optimize pow(x,1.0) = x. */
8171 if (REAL_VALUES_EQUAL (c, dconst1))
8172 return arg0;
8174 /* Optimize pow(x,-1.0) = 1.0/x. */
8175 if (REAL_VALUES_EQUAL (c, dconstm1))
8176 return fold (build2 (RDIV_EXPR, type,
8177 build_real (type, dconst1), arg0));
8179 /* Optimize pow(x,0.5) = sqrt(x). */
8180 if (flag_unsafe_math_optimizations
8181 && REAL_VALUES_EQUAL (c, dconsthalf))
8183 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8185 if (sqrtfn != NULL_TREE)
8187 tree arglist = build_tree_list (NULL_TREE, arg0);
8188 return build_function_call_expr (sqrtfn, arglist);
8192 /* Attempt to evaluate pow at compile-time. */
8193 if (TREE_CODE (arg0) == REAL_CST
8194 && ! TREE_CONSTANT_OVERFLOW (arg0))
8196 REAL_VALUE_TYPE cint;
8197 HOST_WIDE_INT n;
8199 n = real_to_integer (&c);
8200 real_from_integer (&cint, VOIDmode, n,
8201 n < 0 ? -1 : 0, 0);
8202 if (real_identical (&c, &cint))
8204 REAL_VALUE_TYPE x;
8205 bool inexact;
8207 x = TREE_REAL_CST (arg0);
8208 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8209 if (flag_unsafe_math_optimizations || !inexact)
8210 return build_real (type, x);
8215 /* Optimize pow(expN(x),y) = expN(x*y). */
8216 fcode = builtin_mathfn_code (arg0);
8217 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8219 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8220 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8221 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8222 arglist = build_tree_list (NULL_TREE, arg);
8223 return build_function_call_expr (expfn, arglist);
8226 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8227 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8229 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8230 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8231 build_real (type, dconsthalf)));
8233 arglist = tree_cons (NULL_TREE, narg0,
8234 build_tree_list (NULL_TREE, narg1));
8235 return build_function_call_expr (fndecl, arglist);
8238 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8239 if (flag_unsafe_math_optimizations
8240 && (fcode == BUILT_IN_POW
8241 || fcode == BUILT_IN_POWF
8242 || fcode == BUILT_IN_POWL))
8244 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8245 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8246 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8247 arglist = tree_cons (NULL_TREE, arg00,
8248 build_tree_list (NULL_TREE, narg1));
8249 return build_function_call_expr (fndecl, arglist);
8252 break;
8254 case BUILT_IN_INF:
8255 case BUILT_IN_INFF:
8256 case BUILT_IN_INFL:
8257 return fold_builtin_inf (type, true);
8259 case BUILT_IN_HUGE_VAL:
8260 case BUILT_IN_HUGE_VALF:
8261 case BUILT_IN_HUGE_VALL:
8262 return fold_builtin_inf (type, false);
8264 case BUILT_IN_NAN:
8265 case BUILT_IN_NANF:
8266 case BUILT_IN_NANL:
8267 return fold_builtin_nan (arglist, type, true);
8269 case BUILT_IN_NANS:
8270 case BUILT_IN_NANSF:
8271 case BUILT_IN_NANSL:
8272 return fold_builtin_nan (arglist, type, false);
8274 case BUILT_IN_FLOOR:
8275 case BUILT_IN_FLOORF:
8276 case BUILT_IN_FLOORL:
8277 return fold_builtin_floor (exp);
8279 case BUILT_IN_CEIL:
8280 case BUILT_IN_CEILF:
8281 case BUILT_IN_CEILL:
8282 return fold_builtin_ceil (exp);
8284 case BUILT_IN_TRUNC:
8285 case BUILT_IN_TRUNCF:
8286 case BUILT_IN_TRUNCL:
8287 return fold_builtin_trunc (exp);
8289 case BUILT_IN_ROUND:
8290 case BUILT_IN_ROUNDF:
8291 case BUILT_IN_ROUNDL:
8292 return fold_builtin_round (exp);
8294 case BUILT_IN_NEARBYINT:
8295 case BUILT_IN_NEARBYINTF:
8296 case BUILT_IN_NEARBYINTL:
8297 case BUILT_IN_RINT:
8298 case BUILT_IN_RINTF:
8299 case BUILT_IN_RINTL:
8300 return fold_trunc_transparent_mathfn (exp);
8302 case BUILT_IN_LROUND:
8303 case BUILT_IN_LROUNDF:
8304 case BUILT_IN_LROUNDL:
8305 case BUILT_IN_LLROUND:
8306 case BUILT_IN_LLROUNDF:
8307 case BUILT_IN_LLROUNDL:
8308 return fold_builtin_lround (exp);
8310 case BUILT_IN_LRINT:
8311 case BUILT_IN_LRINTF:
8312 case BUILT_IN_LRINTL:
8313 case BUILT_IN_LLRINT:
8314 case BUILT_IN_LLRINTF:
8315 case BUILT_IN_LLRINTL:
8316 return fold_fixed_mathfn (exp);
8318 case BUILT_IN_FFS:
8319 case BUILT_IN_FFSL:
8320 case BUILT_IN_FFSLL:
8321 case BUILT_IN_CLZ:
8322 case BUILT_IN_CLZL:
8323 case BUILT_IN_CLZLL:
8324 case BUILT_IN_CTZ:
8325 case BUILT_IN_CTZL:
8326 case BUILT_IN_CTZLL:
8327 case BUILT_IN_POPCOUNT:
8328 case BUILT_IN_POPCOUNTL:
8329 case BUILT_IN_POPCOUNTLL:
8330 case BUILT_IN_PARITY:
8331 case BUILT_IN_PARITYL:
8332 case BUILT_IN_PARITYLL:
8333 return fold_builtin_bitop (exp);
8335 case BUILT_IN_MEMCPY:
8336 return fold_builtin_memcpy (exp);
8338 case BUILT_IN_MEMPCPY:
8339 return fold_builtin_mempcpy (exp);
8341 case BUILT_IN_MEMMOVE:
8342 return fold_builtin_memmove (exp);
8344 case BUILT_IN_STRCPY:
8345 return fold_builtin_strcpy (exp, NULL_TREE);
8347 case BUILT_IN_STRNCPY:
8348 return fold_builtin_strncpy (exp, NULL_TREE);
8350 case BUILT_IN_INDEX:
8351 case BUILT_IN_STRCHR:
8352 return fold_builtin_strchr (exp, false);
8354 case BUILT_IN_RINDEX:
8355 case BUILT_IN_STRRCHR:
8356 return fold_builtin_strchr (exp, true);
8358 case BUILT_IN_MEMCMP:
8359 return fold_builtin_memcmp (arglist);
8361 case BUILT_IN_STRCMP:
8362 return fold_builtin_strcmp (arglist);
8364 case BUILT_IN_STRNCMP:
8365 return fold_builtin_strncmp (arglist);
8367 case BUILT_IN_SIGNBIT:
8368 case BUILT_IN_SIGNBITF:
8369 case BUILT_IN_SIGNBITL:
8370 return fold_builtin_signbit (exp);
8372 case BUILT_IN_ISASCII:
8373 return fold_builtin_isascii (arglist);
8375 case BUILT_IN_TOASCII:
8376 return fold_builtin_toascii (arglist);
8378 case BUILT_IN_ISDIGIT:
8379 return fold_builtin_isdigit (arglist);
8381 case BUILT_IN_COPYSIGN:
8382 case BUILT_IN_COPYSIGNF:
8383 case BUILT_IN_COPYSIGNL:
8384 return fold_builtin_copysign (arglist, type);
8386 case BUILT_IN_FINITE:
8387 case BUILT_IN_FINITEF:
8388 case BUILT_IN_FINITEL:
8389 return fold_builtin_classify (exp, BUILT_IN_FINITE);
8391 case BUILT_IN_ISINF:
8392 case BUILT_IN_ISINFF:
8393 case BUILT_IN_ISINFL:
8394 return fold_builtin_classify (exp, BUILT_IN_ISINF);
8396 case BUILT_IN_ISNAN:
8397 case BUILT_IN_ISNANF:
8398 case BUILT_IN_ISNANL:
8399 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8401 case BUILT_IN_ISGREATER:
8402 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8403 case BUILT_IN_ISGREATEREQUAL:
8404 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8405 case BUILT_IN_ISLESS:
8406 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8407 case BUILT_IN_ISLESSEQUAL:
8408 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8409 case BUILT_IN_ISLESSGREATER:
8410 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8411 case BUILT_IN_ISUNORDERED:
8412 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8414 case BUILT_IN_FPUTS:
8415 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8417 case BUILT_IN_FPUTS_UNLOCKED:
8418 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8420 default:
8421 break;
8424 return 0;
8427 /* A wrapper function for builtin folding that prevents warnings for
8428 "statement without effect" and the like, caused by removing the
8429 call node earlier than the warning is generated. */
8431 tree
8432 fold_builtin (tree exp, bool ignore)
8434 exp = fold_builtin_1 (exp, ignore);
8435 if (exp)
8437 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8438 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8439 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8440 TREE_NO_WARNING (exp) = 1;
8442 return exp;
8445 /* Conveniently construct a function call expression. */
8447 tree
8448 build_function_call_expr (tree fn, tree arglist)
8450 tree call_expr;
8452 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8453 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8454 call_expr, arglist, NULL_TREE);
8455 return fold (call_expr);
8458 /* This function validates the types of a function call argument list
8459 represented as a tree chain of parameters against a specified list
8460 of tree_codes. If the last specifier is a 0, that represents an
8461 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8463 static int
8464 validate_arglist (tree arglist, ...)
8466 enum tree_code code;
8467 int res = 0;
8468 va_list ap;
8470 va_start (ap, arglist);
8474 code = va_arg (ap, enum tree_code);
8475 switch (code)
8477 case 0:
8478 /* This signifies an ellipses, any further arguments are all ok. */
8479 res = 1;
8480 goto end;
8481 case VOID_TYPE:
8482 /* This signifies an endlink, if no arguments remain, return
8483 true, otherwise return false. */
8484 res = arglist == 0;
8485 goto end;
8486 default:
8487 /* If no parameters remain or the parameter's code does not
8488 match the specified code, return false. Otherwise continue
8489 checking any remaining arguments. */
8490 if (arglist == 0
8491 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8492 goto end;
8493 break;
8495 arglist = TREE_CHAIN (arglist);
8497 while (1);
8499 /* We need gotos here since we can only have one VA_CLOSE in a
8500 function. */
8501 end: ;
8502 va_end (ap);
8504 return res;
8507 /* Default target-specific builtin expander that does nothing. */
8510 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8511 rtx target ATTRIBUTE_UNUSED,
8512 rtx subtarget ATTRIBUTE_UNUSED,
8513 enum machine_mode mode ATTRIBUTE_UNUSED,
8514 int ignore ATTRIBUTE_UNUSED)
8516 return NULL_RTX;
8519 /* Returns true is EXP represents data that would potentially reside
8520 in a readonly section. */
8522 static bool
8523 readonly_data_expr (tree exp)
8525 STRIP_NOPS (exp);
8527 if (TREE_CODE (exp) != ADDR_EXPR)
8528 return false;
8530 exp = get_base_address (TREE_OPERAND (exp, 0));
8531 if (!exp)
8532 return false;
8534 /* Make sure we call decl_readonly_section only for trees it
8535 can handle (since it returns true for everything it doesn't
8536 understand). */
8537 if (TREE_CODE (exp) == STRING_CST
8538 || TREE_CODE (exp) == CONSTRUCTOR
8539 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8540 return decl_readonly_section (exp, 0);
8541 else
8542 return false;
8545 /* Front-end to the simplify_builtin_XXX routines.
8547 EXP is a call to a builtin function. If possible try to simplify
8548 that into a constant, expression or call to a more efficient
8549 builtin function.
8551 If IGNORE is nonzero, then the result of this builtin function
8552 call is ignored.
8554 If simplification is possible, return the simplified tree, otherwise
8555 return NULL_TREE. */
8557 tree
8558 simplify_builtin (tree exp, int ignore)
8560 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8561 tree arglist = TREE_OPERAND (exp, 1);
8562 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8563 tree val;
8565 switch (fcode)
8567 case BUILT_IN_FPUTS:
8568 val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8569 break;
8570 case BUILT_IN_FPUTS_UNLOCKED:
8571 val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8572 break;
8573 case BUILT_IN_STRSTR:
8574 val = simplify_builtin_strstr (arglist);
8575 break;
8576 case BUILT_IN_STRCAT:
8577 val = simplify_builtin_strcat (arglist);
8578 break;
8579 case BUILT_IN_STRNCAT:
8580 val = simplify_builtin_strncat (arglist);
8581 break;
8582 case BUILT_IN_STRSPN:
8583 val = simplify_builtin_strspn (arglist);
8584 break;
8585 case BUILT_IN_STRCSPN:
8586 val = simplify_builtin_strcspn (arglist);
8587 break;
8588 case BUILT_IN_STRCHR:
8589 case BUILT_IN_INDEX:
8590 val = simplify_builtin_strchr (arglist);
8591 break;
8592 case BUILT_IN_STRRCHR:
8593 case BUILT_IN_RINDEX:
8594 val = simplify_builtin_strrchr (arglist);
8595 break;
8596 case BUILT_IN_STRCPY:
8597 val = fold_builtin_strcpy (exp, NULL_TREE);
8598 break;
8599 case BUILT_IN_STRNCPY:
8600 val = fold_builtin_strncpy (exp, NULL_TREE);
8601 break;
8602 case BUILT_IN_STRCMP:
8603 val = fold_builtin_strcmp (arglist);
8604 break;
8605 case BUILT_IN_STRNCMP:
8606 val = fold_builtin_strncmp (arglist);
8607 break;
8608 case BUILT_IN_STRPBRK:
8609 val = simplify_builtin_strpbrk (arglist);
8610 break;
8611 case BUILT_IN_BCMP:
8612 case BUILT_IN_MEMCMP:
8613 val = fold_builtin_memcmp (arglist);
8614 break;
8615 case BUILT_IN_VA_START:
8616 simplify_builtin_va_start (arglist);
8617 val = NULL_TREE;
8618 break;
8619 case BUILT_IN_SPRINTF:
8620 val = simplify_builtin_sprintf (arglist, ignore);
8621 break;
8622 case BUILT_IN_CONSTANT_P:
8623 val = fold_builtin_constant_p (arglist);
8624 /* Gimplification will pull the CALL_EXPR for the builtin out of
8625 an if condition. When not optimizing, we'll not CSE it back.
8626 To avoid link error types of regressions, return false now. */
8627 if (!val && !optimize)
8628 val = integer_zero_node;
8629 break;
8630 default:
8631 val = NULL_TREE;
8632 break;
8635 if (val)
8636 val = fold_convert (TREE_TYPE (exp), val);
8637 return val;
8640 /* Simplify a call to the strstr builtin.
8642 Return 0 if no simplification was possible, otherwise return the
8643 simplified form of the call as a tree.
8645 The simplified form may be a constant or other expression which
8646 computes the same value, but in a more efficient manner (including
8647 calls to other builtin functions).
8649 The call may contain arguments which need to be evaluated, but
8650 which are not useful to determine the result of the call. In
8651 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8652 COMPOUND_EXPR will be an argument which must be evaluated.
8653 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8654 COMPOUND_EXPR in the chain will contain the tree for the simplified
8655 form of the builtin function call. */
8657 static tree
8658 simplify_builtin_strstr (tree arglist)
8660 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8661 return 0;
8662 else
8664 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8665 tree fn;
8666 const char *p1, *p2;
8668 p2 = c_getstr (s2);
8669 if (p2 == NULL)
8670 return 0;
8672 p1 = c_getstr (s1);
8673 if (p1 != NULL)
8675 const char *r = strstr (p1, p2);
8677 if (r == NULL)
8678 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8680 /* Return an offset into the constant string argument. */
8681 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8682 s1, fold_convert (TREE_TYPE (s1),
8683 ssize_int (r - p1))));
8686 if (p2[0] == '\0')
8687 return s1;
8689 if (p2[1] != '\0')
8690 return 0;
8692 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8693 if (!fn)
8694 return 0;
8696 /* New argument list transforming strstr(s1, s2) to
8697 strchr(s1, s2[0]). */
8698 arglist = build_tree_list (NULL_TREE,
8699 build_int_cst (NULL_TREE, p2[0], 0));
8700 arglist = tree_cons (NULL_TREE, s1, arglist);
8701 return build_function_call_expr (fn, arglist);
8705 /* Simplify a call to the strstr builtin.
8707 Return 0 if no simplification was possible, otherwise return the
8708 simplified form of the call as a tree.
8710 The simplified form may be a constant or other expression which
8711 computes the same value, but in a more efficient manner (including
8712 calls to other builtin functions).
8714 The call may contain arguments which need to be evaluated, but
8715 which are not useful to determine the result of the call. In
8716 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8717 COMPOUND_EXPR will be an argument which must be evaluated.
8718 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8719 COMPOUND_EXPR in the chain will contain the tree for the simplified
8720 form of the builtin function call. */
8722 static tree
8723 simplify_builtin_strchr (tree arglist)
8725 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8726 return 0;
8727 else
8729 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8730 const char *p1;
8732 if (TREE_CODE (s2) != INTEGER_CST)
8733 return 0;
8735 p1 = c_getstr (s1);
8736 if (p1 != NULL)
8738 char c;
8739 const char *r;
8741 if (target_char_cast (s2, &c))
8742 return 0;
8744 r = strchr (p1, c);
8746 if (r == NULL)
8747 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8749 /* Return an offset into the constant string argument. */
8750 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8751 s1, fold_convert (TREE_TYPE (s1),
8752 ssize_int (r - p1))));
8755 /* FIXME: Should use here strchrM optab so that ports can optimize
8756 this. */
8757 return 0;
8761 /* Simplify a call to the strrchr builtin.
8763 Return 0 if no simplification was possible, otherwise return the
8764 simplified form of the call as a tree.
8766 The simplified form may be a constant or other expression which
8767 computes the same value, but in a more efficient manner (including
8768 calls to other builtin functions).
8770 The call may contain arguments which need to be evaluated, but
8771 which are not useful to determine the result of the call. In
8772 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8773 COMPOUND_EXPR will be an argument which must be evaluated.
8774 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8775 COMPOUND_EXPR in the chain will contain the tree for the simplified
8776 form of the builtin function call. */
8778 static tree
8779 simplify_builtin_strrchr (tree arglist)
8781 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8782 return 0;
8783 else
8785 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8786 tree fn;
8787 const char *p1;
8789 if (TREE_CODE (s2) != INTEGER_CST)
8790 return 0;
8792 p1 = c_getstr (s1);
8793 if (p1 != NULL)
8795 char c;
8796 const char *r;
8798 if (target_char_cast (s2, &c))
8799 return 0;
8801 r = strrchr (p1, c);
8803 if (r == NULL)
8804 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8806 /* Return an offset into the constant string argument. */
8807 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8808 s1, fold_convert (TREE_TYPE (s1),
8809 ssize_int (r - p1))));
8812 if (! integer_zerop (s2))
8813 return 0;
8815 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8816 if (!fn)
8817 return 0;
8819 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8820 return build_function_call_expr (fn, arglist);
8824 /* Simplify a call to the strpbrk builtin.
8826 Return 0 if no simplification was possible, otherwise return the
8827 simplified form of the call as a tree.
8829 The simplified form may be a constant or other expression which
8830 computes the same value, but in a more efficient manner (including
8831 calls to other builtin functions).
8833 The call may contain arguments which need to be evaluated, but
8834 which are not useful to determine the result of the call. In
8835 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8836 COMPOUND_EXPR will be an argument which must be evaluated.
8837 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8838 COMPOUND_EXPR in the chain will contain the tree for the simplified
8839 form of the builtin function call. */
8841 static tree
8842 simplify_builtin_strpbrk (tree arglist)
8844 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8845 return 0;
8846 else
8848 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8849 tree fn;
8850 const char *p1, *p2;
8852 p2 = c_getstr (s2);
8853 if (p2 == NULL)
8854 return 0;
8856 p1 = c_getstr (s1);
8857 if (p1 != NULL)
8859 const char *r = strpbrk (p1, p2);
8861 if (r == NULL)
8862 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8864 /* Return an offset into the constant string argument. */
8865 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8866 s1, fold_convert (TREE_TYPE (s1),
8867 ssize_int (r - p1))));
8870 if (p2[0] == '\0')
8871 /* strpbrk(x, "") == NULL.
8872 Evaluate and ignore s1 in case it had side-effects. */
8873 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8875 if (p2[1] != '\0')
8876 return 0; /* Really call strpbrk. */
8878 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8879 if (!fn)
8880 return 0;
8882 /* New argument list transforming strpbrk(s1, s2) to
8883 strchr(s1, s2[0]). */
8884 arglist = build_tree_list (NULL_TREE,
8885 build_int_cst (NULL_TREE, p2[0], 0));
8886 arglist = tree_cons (NULL_TREE, s1, arglist);
8887 return build_function_call_expr (fn, arglist);
8891 /* Simplify a call to the strcat builtin.
8893 Return 0 if no simplification was possible, otherwise return the
8894 simplified form of the call as a tree.
8896 The simplified form may be a constant or other expression which
8897 computes the same value, but in a more efficient manner (including
8898 calls to other builtin functions).
8900 The call may contain arguments which need to be evaluated, but
8901 which are not useful to determine the result of the call. In
8902 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8903 COMPOUND_EXPR will be an argument which must be evaluated.
8904 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8905 COMPOUND_EXPR in the chain will contain the tree for the simplified
8906 form of the builtin function call. */
8908 static tree
8909 simplify_builtin_strcat (tree arglist)
8911 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8912 return 0;
8913 else
8915 tree dst = TREE_VALUE (arglist),
8916 src = TREE_VALUE (TREE_CHAIN (arglist));
8917 const char *p = c_getstr (src);
8919 /* If the string length is zero, return the dst parameter. */
8920 if (p && *p == '\0')
8921 return dst;
8923 return 0;
8927 /* Simplify a call to the strncat builtin.
8929 Return 0 if no simplification was possible, otherwise return the
8930 simplified form of the call as a tree.
8932 The simplified form may be a constant or other expression which
8933 computes the same value, but in a more efficient manner (including
8934 calls to other builtin functions).
8936 The call may contain arguments which need to be evaluated, but
8937 which are not useful to determine the result of the call. In
8938 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8939 COMPOUND_EXPR will be an argument which must be evaluated.
8940 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8941 COMPOUND_EXPR in the chain will contain the tree for the simplified
8942 form of the builtin function call. */
8944 static tree
8945 simplify_builtin_strncat (tree arglist)
8947 if (!validate_arglist (arglist,
8948 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8949 return 0;
8950 else
8952 tree dst = TREE_VALUE (arglist);
8953 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8954 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8955 const char *p = c_getstr (src);
8957 /* If the requested length is zero, or the src parameter string
8958 length is zero, return the dst parameter. */
8959 if (integer_zerop (len) || (p && *p == '\0'))
8960 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8962 /* If the requested len is greater than or equal to the string
8963 length, call strcat. */
8964 if (TREE_CODE (len) == INTEGER_CST && p
8965 && compare_tree_int (len, strlen (p)) >= 0)
8967 tree newarglist
8968 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8969 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8971 /* If the replacement _DECL isn't initialized, don't do the
8972 transformation. */
8973 if (!fn)
8974 return 0;
8976 return build_function_call_expr (fn, newarglist);
8978 return 0;
8982 /* Simplify a call to the strspn builtin.
8984 Return 0 if no simplification was possible, otherwise return the
8985 simplified form of the call as a tree.
8987 The simplified form may be a constant or other expression which
8988 computes the same value, but in a more efficient manner (including
8989 calls to other builtin functions).
8991 The call may contain arguments which need to be evaluated, but
8992 which are not useful to determine the result of the call. In
8993 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8994 COMPOUND_EXPR will be an argument which must be evaluated.
8995 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8996 COMPOUND_EXPR in the chain will contain the tree for the simplified
8997 form of the builtin function call. */
8999 static tree
9000 simplify_builtin_strspn (tree arglist)
9002 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9003 return 0;
9004 else
9006 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9007 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9009 /* If both arguments are constants, evaluate at compile-time. */
9010 if (p1 && p2)
9012 const size_t r = strspn (p1, p2);
9013 return size_int (r);
9016 /* If either argument is "", return 0. */
9017 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9018 /* Evaluate and ignore both arguments in case either one has
9019 side-effects. */
9020 return omit_two_operands (integer_type_node, integer_zero_node,
9021 s1, s2);
9022 return 0;
9026 /* Simplify a call to the strcspn builtin.
9028 Return 0 if no simplification was possible, otherwise return the
9029 simplified form of the call as a tree.
9031 The simplified form may be a constant or other expression which
9032 computes the same value, but in a more efficient manner (including
9033 calls to other builtin functions).
9035 The call may contain arguments which need to be evaluated, but
9036 which are not useful to determine the result of the call. In
9037 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9038 COMPOUND_EXPR will be an argument which must be evaluated.
9039 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9040 COMPOUND_EXPR in the chain will contain the tree for the simplified
9041 form of the builtin function call. */
9043 static tree
9044 simplify_builtin_strcspn (tree arglist)
9046 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9047 return 0;
9048 else
9050 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9051 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9053 /* If both arguments are constants, evaluate at compile-time. */
9054 if (p1 && p2)
9056 const size_t r = strcspn (p1, p2);
9057 return size_int (r);
9060 /* If the first argument is "", return 0. */
9061 if (p1 && *p1 == '\0')
9063 /* Evaluate and ignore argument s2 in case it has
9064 side-effects. */
9065 return omit_one_operand (integer_type_node,
9066 integer_zero_node, s2);
9069 /* If the second argument is "", return __builtin_strlen(s1). */
9070 if (p2 && *p2 == '\0')
9072 tree newarglist = build_tree_list (NULL_TREE, s1),
9073 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9075 /* If the replacement _DECL isn't initialized, don't do the
9076 transformation. */
9077 if (!fn)
9078 return 0;
9080 return build_function_call_expr (fn, newarglist);
9082 return 0;
9086 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9087 by the builtin will be ignored. UNLOCKED is true is true if this
9088 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9089 the known length of the string. Return NULL_TREE if no simplification
9090 was possible. */
9092 tree
9093 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9095 tree fn;
9096 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9097 : implicit_built_in_decls[BUILT_IN_FPUTC];
9098 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9099 : implicit_built_in_decls[BUILT_IN_FWRITE];
9101 /* If the return value is used, or the replacement _DECL isn't
9102 initialized, don't do the transformation. */
9103 if (!ignore || !fn_fputc || !fn_fwrite)
9104 return 0;
9106 /* Verify the arguments in the original call. */
9107 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9108 return 0;
9110 if (! len)
9111 len = c_strlen (TREE_VALUE (arglist), 0);
9113 /* Get the length of the string passed to fputs. If the length
9114 can't be determined, punt. */
9115 if (!len
9116 || TREE_CODE (len) != INTEGER_CST)
9117 return 0;
9119 switch (compare_tree_int (len, 1))
9121 case -1: /* length is 0, delete the call entirely . */
9122 return omit_one_operand (integer_type_node, integer_zero_node,
9123 TREE_VALUE (TREE_CHAIN (arglist)));
9125 case 0: /* length is 1, call fputc. */
9127 const char *p = c_getstr (TREE_VALUE (arglist));
9129 if (p != NULL)
9131 /* New argument list transforming fputs(string, stream) to
9132 fputc(string[0], stream). */
9133 arglist = build_tree_list (NULL_TREE,
9134 TREE_VALUE (TREE_CHAIN (arglist)));
9135 arglist = tree_cons (NULL_TREE,
9136 build_int_cst (NULL_TREE, p[0], 0),
9137 arglist);
9138 fn = fn_fputc;
9139 break;
9142 /* FALLTHROUGH */
9143 case 1: /* length is greater than 1, call fwrite. */
9145 tree string_arg;
9147 /* If optimizing for size keep fputs. */
9148 if (optimize_size)
9149 return 0;
9150 string_arg = TREE_VALUE (arglist);
9151 /* New argument list transforming fputs(string, stream) to
9152 fwrite(string, 1, len, stream). */
9153 arglist = build_tree_list (NULL_TREE,
9154 TREE_VALUE (TREE_CHAIN (arglist)));
9155 arglist = tree_cons (NULL_TREE, len, arglist);
9156 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9157 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9158 fn = fn_fwrite;
9159 break;
9161 default:
9162 abort ();
9165 /* These optimizations are only performed when the result is ignored,
9166 hence there's no need to cast the result to integer_type_node. */
9167 return build_function_call_expr (fn, arglist);
9170 static void
9171 simplify_builtin_va_start (tree arglist)
9173 tree chain = TREE_CHAIN (arglist);
9175 if (TREE_CHAIN (chain))
9176 error ("too many arguments to function `va_start'");
9178 simplify_builtin_next_arg (chain);
9181 static void
9182 simplify_builtin_next_arg (tree arglist)
9184 tree fntype = TREE_TYPE (current_function_decl);
9186 if (TYPE_ARG_TYPES (fntype) == 0
9187 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9188 == void_type_node))
9189 error ("`va_start' used in function with fixed args");
9190 else if (arglist)
9192 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9193 tree arg = TREE_VALUE (arglist);
9195 /* Strip off all nops for the sake of the comparison. This
9196 is not quite the same as STRIP_NOPS. It does more.
9197 We must also strip off INDIRECT_EXPR for C++ reference
9198 parameters. */
9199 while (TREE_CODE (arg) == NOP_EXPR
9200 || TREE_CODE (arg) == CONVERT_EXPR
9201 || TREE_CODE (arg) == NON_LVALUE_EXPR
9202 || TREE_CODE (arg) == INDIRECT_REF)
9203 arg = TREE_OPERAND (arg, 0);
9204 if (arg != last_parm)
9205 warning ("second parameter of `va_start' not last named argument");
9206 TREE_VALUE (arglist) = arg;
9208 else
9209 /* Evidently an out of date version of <stdarg.h>; can't validate
9210 va_start's second argument, but can still work as intended. */
9211 warning ("`__builtin_next_arg' called without an argument");
9215 /* Simplify a call to the sprintf builtin.
9217 Return 0 if no simplification was possible, otherwise return the
9218 simplified form of the call as a tree. If IGNORED is true, it means that
9219 the caller does not use the returned value of the function. */
9221 static tree
9222 simplify_builtin_sprintf (tree arglist, int ignored)
9224 tree call, retval, dest, fmt;
9225 const char *fmt_str = NULL;
9227 /* Verify the required arguments in the original call. We deal with two
9228 types of sprintf() calls: 'sprintf (str, fmt)' and
9229 'sprintf (dest, "%s", orig)'. */
9230 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9231 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9232 VOID_TYPE))
9233 return NULL_TREE;
9235 /* Get the destination string and the format specifier. */
9236 dest = TREE_VALUE (arglist);
9237 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9239 /* Check whether the format is a literal string constant. */
9240 fmt_str = c_getstr (fmt);
9241 if (fmt_str == NULL)
9242 return NULL_TREE;
9244 call = NULL_TREE;
9245 retval = NULL_TREE;
9247 /* If the format doesn't contain % args or %%, use strcpy. */
9248 if (strchr (fmt_str, '%') == NULL)
9250 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9252 if (!fn)
9253 return NULL_TREE;
9255 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9256 'format' is known to contain no % formats. */
9257 arglist = build_tree_list (NULL_TREE, fmt);
9258 arglist = tree_cons (NULL_TREE, dest, arglist);
9259 call = build_function_call_expr (fn, arglist);
9260 if (!ignored)
9261 retval = build_int_cst (NULL_TREE, strlen (fmt_str), 0);
9264 /* If the format is "%s", use strcpy if the result isn't used. */
9265 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9267 tree fn, orig;
9268 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9270 if (!fn)
9271 return NULL_TREE;
9273 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9274 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9275 arglist = build_tree_list (NULL_TREE, orig);
9276 arglist = tree_cons (NULL_TREE, dest, arglist);
9277 if (!ignored)
9279 retval = c_strlen (orig, 1);
9280 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9281 return NULL_TREE;
9283 call = build_function_call_expr (fn, arglist);
9286 if (call && retval)
9288 retval = convert
9289 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9290 retval);
9291 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9293 else
9294 return call;