2004-12-07 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / builtins.c
blob7b4ef520f40eb5d3e1b6f28243ad6a9bba07bc00
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #define CALLED_AS_BUILT_IN(NODE) \
52 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
54 #ifndef PAD_VARARGS_DOWN
55 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 #endif
58 /* Define the names of the builtin function types and codes. */
59 const char *const built_in_class_names[4]
60 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
62 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
63 const char *const built_in_names[(int) END_BUILTINS] =
65 #include "builtins.def"
67 #undef DEF_BUILTIN
69 /* Setup an array of _DECL trees, make sure each element is
70 initialized to NULL_TREE. */
71 tree built_in_decls[(int) END_BUILTINS];
72 /* Declarations used when constructing the builtin implicitly in the compiler.
73 It may be NULL_TREE when this is invalid (for instance runtime is not
74 required to implement the function call in all cases). */
75 tree implicit_built_in_decls[(int) END_BUILTINS];
77 static int get_pointer_alignment (tree, unsigned int);
78 static const char *c_getstr (tree);
79 static rtx c_readstr (const char *, enum machine_mode);
80 static int target_char_cast (tree, char *);
81 static rtx get_memory_rtx (tree);
82 static tree build_string_literal (int, const char *);
83 static int apply_args_size (void);
84 static int apply_result_size (void);
85 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
86 static rtx result_vector (int, rtx);
87 #endif
88 static rtx expand_builtin_setjmp (tree, rtx);
89 static void expand_builtin_update_setjmp_buf (rtx);
90 static void expand_builtin_prefetch (tree);
91 static rtx expand_builtin_apply_args (void);
92 static rtx expand_builtin_apply_args_1 (void);
93 static rtx expand_builtin_apply (rtx, rtx, rtx);
94 static void expand_builtin_return (rtx);
95 static enum type_class type_to_class (tree);
96 static rtx expand_builtin_classify_type (tree);
97 static void expand_errno_check (tree, rtx);
98 static rtx expand_builtin_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
101 static rtx expand_builtin_args_info (tree);
102 static rtx expand_builtin_next_arg (tree);
103 static rtx expand_builtin_va_start (tree);
104 static rtx expand_builtin_va_end (tree);
105 static rtx expand_builtin_va_copy (tree);
106 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
109 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
110 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
116 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_bcopy (tree, tree);
118 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
120 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
122 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_bzero (tree);
126 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
131 static rtx expand_builtin_alloca (tree, rtx);
132 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
133 static rtx expand_builtin_frame_address (tree, tree);
134 static rtx expand_builtin_fputs (tree, rtx, bool);
135 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
137 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
138 static tree stabilize_va_list (tree, int);
139 static rtx expand_builtin_expect (tree, rtx);
140 static tree fold_builtin_constant_p (tree);
141 static tree fold_builtin_classify_type (tree);
142 static tree fold_builtin_strlen (tree);
143 static tree fold_builtin_inf (tree, int);
144 static tree fold_builtin_nan (tree, tree, int);
145 static int validate_arglist (tree, ...);
146 static bool integer_valued_real_p (tree);
147 static tree fold_trunc_transparent_mathfn (tree);
148 static bool readonly_data_expr (tree);
149 static rtx expand_builtin_fabs (tree, rtx, rtx);
150 static rtx expand_builtin_signbit (tree, rtx);
151 static tree fold_builtin_cabs (tree, tree);
152 static tree fold_builtin_sqrt (tree, tree);
153 static tree fold_builtin_cbrt (tree, tree);
154 static tree fold_builtin_pow (tree, tree, tree);
155 static tree fold_builtin_sin (tree);
156 static tree fold_builtin_cos (tree, tree, tree);
157 static tree fold_builtin_tan (tree);
158 static tree fold_builtin_atan (tree, tree);
159 static tree fold_builtin_trunc (tree);
160 static tree fold_builtin_floor (tree);
161 static tree fold_builtin_ceil (tree);
162 static tree fold_builtin_round (tree);
163 static tree fold_builtin_bitop (tree);
164 static tree fold_builtin_memcpy (tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree);
172 static tree fold_builtin_copysign (tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
179 static tree fold_builtin_1 (tree, bool);
181 static tree fold_builtin_strpbrk (tree);
182 static tree fold_builtin_strstr (tree);
183 static tree fold_builtin_strrchr (tree);
184 static tree fold_builtin_strcat (tree);
185 static tree fold_builtin_strncat (tree);
186 static tree fold_builtin_strspn (tree);
187 static tree fold_builtin_strcspn (tree);
188 static tree fold_builtin_sprintf (tree, int);
191 /* Return the alignment in bits of EXP, a pointer valued expression.
192 But don't return more than MAX_ALIGN no matter what.
193 The alignment returned is, by default, the alignment of the thing that
194 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
196 Otherwise, look at the expression to see if we can do better, i.e., if the
197 expression is actually pointing at an object whose alignment is tighter. */
199 static int
200 get_pointer_alignment (tree exp, unsigned int max_align)
202 unsigned int align, inner;
204 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
205 return 0;
207 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
208 align = MIN (align, max_align);
210 while (1)
212 switch (TREE_CODE (exp))
214 case NOP_EXPR:
215 case CONVERT_EXPR:
216 case NON_LVALUE_EXPR:
217 exp = TREE_OPERAND (exp, 0);
218 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
219 return align;
221 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
222 align = MIN (inner, max_align);
223 break;
225 case PLUS_EXPR:
226 /* If sum of pointer + int, restrict our maximum alignment to that
227 imposed by the integer. If not, we can't do any better than
228 ALIGN. */
229 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
230 return align;
232 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
233 & (max_align / BITS_PER_UNIT - 1))
234 != 0)
235 max_align >>= 1;
237 exp = TREE_OPERAND (exp, 0);
238 break;
240 case ADDR_EXPR:
241 /* See what we are pointing at and look at its alignment. */
242 exp = TREE_OPERAND (exp, 0);
243 if (TREE_CODE (exp) == FUNCTION_DECL)
244 align = FUNCTION_BOUNDARY;
245 else if (DECL_P (exp))
246 align = DECL_ALIGN (exp);
247 #ifdef CONSTANT_ALIGNMENT
248 else if (CONSTANT_CLASS_P (exp))
249 align = CONSTANT_ALIGNMENT (exp, align);
250 #endif
251 return MIN (align, max_align);
253 default:
254 return align;
259 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
260 way, because it could contain a zero byte in the middle.
261 TREE_STRING_LENGTH is the size of the character array, not the string.
263 ONLY_VALUE should be nonzero if the result is not going to be emitted
264 into the instruction stream and zero if it is going to be expanded.
265 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
266 is returned, otherwise NULL, since
267 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
268 evaluate the side-effects.
270 The value returned is of type `ssizetype'.
272 Unfortunately, string_constant can't access the values of const char
273 arrays with initializers, so neither can we do so here. */
275 tree
276 c_strlen (tree src, int only_value)
278 tree offset_node;
279 HOST_WIDE_INT offset;
280 int max;
281 const char *ptr;
283 STRIP_NOPS (src);
284 if (TREE_CODE (src) == COND_EXPR
285 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
287 tree len1, len2;
289 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
290 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
291 if (tree_int_cst_equal (len1, len2))
292 return len1;
295 if (TREE_CODE (src) == COMPOUND_EXPR
296 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
297 return c_strlen (TREE_OPERAND (src, 1), only_value);
299 src = string_constant (src, &offset_node);
300 if (src == 0)
301 return 0;
303 max = TREE_STRING_LENGTH (src) - 1;
304 ptr = TREE_STRING_POINTER (src);
306 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
308 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
309 compute the offset to the following null if we don't know where to
310 start searching for it. */
311 int i;
313 for (i = 0; i < max; i++)
314 if (ptr[i] == 0)
315 return 0;
317 /* We don't know the starting offset, but we do know that the string
318 has no internal zero bytes. We can assume that the offset falls
319 within the bounds of the string; otherwise, the programmer deserves
320 what he gets. Subtract the offset from the length of the string,
321 and return that. This would perhaps not be valid if we were dealing
322 with named arrays in addition to literal string constants. */
324 return size_diffop (size_int (max), offset_node);
327 /* We have a known offset into the string. Start searching there for
328 a null character if we can represent it as a single HOST_WIDE_INT. */
329 if (offset_node == 0)
330 offset = 0;
331 else if (! host_integerp (offset_node, 0))
332 offset = -1;
333 else
334 offset = tree_low_cst (offset_node, 0);
336 /* If the offset is known to be out of bounds, warn, and call strlen at
337 runtime. */
338 if (offset < 0 || offset > max)
340 warning ("offset outside bounds of constant string");
341 return 0;
344 /* Use strlen to search for the first zero byte. Since any strings
345 constructed with build_string will have nulls appended, we win even
346 if we get handed something like (char[4])"abcd".
348 Since OFFSET is our starting index into the string, no further
349 calculation is needed. */
350 return ssize_int (strlen (ptr + offset));
353 /* Return a char pointer for a C string if it is a string constant
354 or sum of string constant and integer constant. */
356 static const char *
357 c_getstr (tree src)
359 tree offset_node;
361 src = string_constant (src, &offset_node);
362 if (src == 0)
363 return 0;
365 if (offset_node == 0)
366 return TREE_STRING_POINTER (src);
367 else if (!host_integerp (offset_node, 1)
368 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
369 return 0;
371 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
374 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
375 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
377 static rtx
378 c_readstr (const char *str, enum machine_mode mode)
380 HOST_WIDE_INT c[2];
381 HOST_WIDE_INT ch;
382 unsigned int i, j;
384 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
386 c[0] = 0;
387 c[1] = 0;
388 ch = 1;
389 for (i = 0; i < GET_MODE_SIZE (mode); i++)
391 j = i;
392 if (WORDS_BIG_ENDIAN)
393 j = GET_MODE_SIZE (mode) - i - 1;
394 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
395 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
396 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
397 j *= BITS_PER_UNIT;
398 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
400 if (ch)
401 ch = (unsigned char) str[i];
402 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
404 return immed_double_const (c[0], c[1], mode);
407 /* Cast a target constant CST to target CHAR and if that value fits into
408 host char type, return zero and put that value into variable pointed by
409 P. */
411 static int
412 target_char_cast (tree cst, char *p)
414 unsigned HOST_WIDE_INT val, hostval;
416 if (!host_integerp (cst, 1)
417 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
418 return 1;
420 val = tree_low_cst (cst, 1);
421 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
422 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
424 hostval = val;
425 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
426 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
428 if (val != hostval)
429 return 1;
431 *p = hostval;
432 return 0;
435 /* Similar to save_expr, but assumes that arbitrary code is not executed
436 in between the multiple evaluations. In particular, we assume that a
437 non-addressable local variable will not be modified. */
439 static tree
440 builtin_save_expr (tree exp)
442 if (TREE_ADDRESSABLE (exp) == 0
443 && (TREE_CODE (exp) == PARM_DECL
444 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
445 return exp;
447 return save_expr (exp);
450 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
451 times to get the address of either a higher stack frame, or a return
452 address located within it (depending on FNDECL_CODE). */
454 static rtx
455 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
456 rtx tem)
458 int i;
460 /* Some machines need special handling before we can access
461 arbitrary frames. For example, on the sparc, we must first flush
462 all register windows to the stack. */
463 #ifdef SETUP_FRAME_ADDRESSES
464 if (count > 0)
465 SETUP_FRAME_ADDRESSES ();
466 #endif
468 /* On the sparc, the return address is not in the frame, it is in a
469 register. There is no way to access it off of the current frame
470 pointer, but it can be accessed off the previous frame pointer by
471 reading the value from the register window save area. */
472 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
473 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
474 count--;
475 #endif
477 /* Scan back COUNT frames to the specified frame. */
478 for (i = 0; i < count; i++)
480 /* Assume the dynamic chain pointer is in the word that the
481 frame address points to, unless otherwise specified. */
482 #ifdef DYNAMIC_CHAIN_ADDRESS
483 tem = DYNAMIC_CHAIN_ADDRESS (tem);
484 #endif
485 tem = memory_address (Pmode, tem);
486 tem = gen_rtx_MEM (Pmode, tem);
487 set_mem_alias_set (tem, get_frame_alias_set ());
488 tem = copy_to_reg (tem);
491 /* For __builtin_frame_address, return what we've got. */
492 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
493 return tem;
495 /* For __builtin_return_address, Get the return address from that
496 frame. */
497 #ifdef RETURN_ADDR_RTX
498 tem = RETURN_ADDR_RTX (count, tem);
499 #else
500 tem = memory_address (Pmode,
501 plus_constant (tem, GET_MODE_SIZE (Pmode)));
502 tem = gen_rtx_MEM (Pmode, tem);
503 set_mem_alias_set (tem, get_frame_alias_set ());
504 #endif
505 return tem;
508 /* Alias set used for setjmp buffer. */
509 static HOST_WIDE_INT setjmp_alias_set = -1;
511 /* Construct the leading half of a __builtin_setjmp call. Control will
512 return to RECEIVER_LABEL. This is used directly by sjlj exception
513 handling code. */
515 void
516 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
518 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
519 rtx stack_save;
520 rtx mem;
522 if (setjmp_alias_set == -1)
523 setjmp_alias_set = new_alias_set ();
525 buf_addr = convert_memory_address (Pmode, buf_addr);
527 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
529 /* We store the frame pointer and the address of receiver_label in
530 the buffer and use the rest of it for the stack save area, which
531 is machine-dependent. */
533 mem = gen_rtx_MEM (Pmode, buf_addr);
534 set_mem_alias_set (mem, setjmp_alias_set);
535 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
537 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
538 set_mem_alias_set (mem, setjmp_alias_set);
540 emit_move_insn (validize_mem (mem),
541 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
543 stack_save = gen_rtx_MEM (sa_mode,
544 plus_constant (buf_addr,
545 2 * GET_MODE_SIZE (Pmode)));
546 set_mem_alias_set (stack_save, setjmp_alias_set);
547 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
549 /* If there is further processing to do, do it. */
550 #ifdef HAVE_builtin_setjmp_setup
551 if (HAVE_builtin_setjmp_setup)
552 emit_insn (gen_builtin_setjmp_setup (buf_addr));
553 #endif
555 /* Tell optimize_save_area_alloca that extra work is going to
556 need to go on during alloca. */
557 current_function_calls_setjmp = 1;
559 /* Set this so all the registers get saved in our frame; we need to be
560 able to copy the saved values for any registers from frames we unwind. */
561 current_function_has_nonlocal_label = 1;
564 /* Construct the trailing part of a __builtin_setjmp call.
565 This is used directly by sjlj exception handling code. */
567 void
568 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
570 /* Clobber the FP when we get here, so we have to make sure it's
571 marked as used by this function. */
572 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
574 /* Mark the static chain as clobbered here so life information
575 doesn't get messed up for it. */
576 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
578 /* Now put in the code to restore the frame pointer, and argument
579 pointer, if needed. */
580 #ifdef HAVE_nonlocal_goto
581 if (! HAVE_nonlocal_goto)
582 #endif
583 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
585 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
586 if (fixed_regs[ARG_POINTER_REGNUM])
588 #ifdef ELIMINABLE_REGS
589 size_t i;
590 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
592 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
593 if (elim_regs[i].from == ARG_POINTER_REGNUM
594 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
595 break;
597 if (i == ARRAY_SIZE (elim_regs))
598 #endif
600 /* Now restore our arg pointer from the address at which it
601 was saved in our stack frame. */
602 emit_move_insn (virtual_incoming_args_rtx,
603 copy_to_reg (get_arg_pointer_save_area (cfun)));
606 #endif
608 #ifdef HAVE_builtin_setjmp_receiver
609 if (HAVE_builtin_setjmp_receiver)
610 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
611 else
612 #endif
613 #ifdef HAVE_nonlocal_goto_receiver
614 if (HAVE_nonlocal_goto_receiver)
615 emit_insn (gen_nonlocal_goto_receiver ());
616 else
617 #endif
618 { /* Nothing */ }
620 /* @@@ This is a kludge. Not all machine descriptions define a blockage
621 insn, but we must not allow the code we just generated to be reordered
622 by scheduling. Specifically, the update of the frame pointer must
623 happen immediately, not later. So emit an ASM_INPUT to act as blockage
624 insn. */
625 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
628 /* __builtin_setjmp is passed a pointer to an array of five words (not
629 all will be used on all machines). It operates similarly to the C
630 library function of the same name, but is more efficient. Much of
631 the code below (and for longjmp) is copied from the handling of
632 non-local gotos.
634 NOTE: This is intended for use by GNAT and the exception handling
635 scheme in the compiler and will only work in the method used by
636 them. */
638 static rtx
639 expand_builtin_setjmp (tree arglist, rtx target)
641 rtx buf_addr, next_lab, cont_lab;
643 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
644 return NULL_RTX;
646 if (target == 0 || !REG_P (target)
647 || REGNO (target) < FIRST_PSEUDO_REGISTER)
648 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
650 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
652 next_lab = gen_label_rtx ();
653 cont_lab = gen_label_rtx ();
655 expand_builtin_setjmp_setup (buf_addr, next_lab);
657 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
658 ensure that pending stack adjustments are flushed. */
659 emit_move_insn (target, const0_rtx);
660 emit_jump (cont_lab);
662 emit_label (next_lab);
664 expand_builtin_setjmp_receiver (next_lab);
666 /* Set TARGET to one. */
667 emit_move_insn (target, const1_rtx);
668 emit_label (cont_lab);
670 /* Tell flow about the strange goings on. Putting `next_lab' on
671 `nonlocal_goto_handler_labels' to indicates that function
672 calls may traverse the arc back to this label. */
674 current_function_has_nonlocal_label = 1;
675 nonlocal_goto_handler_labels
676 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
678 return target;
681 /* __builtin_longjmp is passed a pointer to an array of five words (not
682 all will be used on all machines). It operates similarly to the C
683 library function of the same name, but is more efficient. Much of
684 the code below is copied from the handling of non-local gotos.
686 NOTE: This is intended for use by GNAT and the exception handling
687 scheme in the compiler and will only work in the method used by
688 them. */
690 static void
691 expand_builtin_longjmp (rtx buf_addr, rtx value)
693 rtx fp, lab, stack, insn, last;
694 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
696 if (setjmp_alias_set == -1)
697 setjmp_alias_set = new_alias_set ();
699 buf_addr = convert_memory_address (Pmode, buf_addr);
701 buf_addr = force_reg (Pmode, buf_addr);
703 /* We used to store value in static_chain_rtx, but that fails if pointers
704 are smaller than integers. We instead require that the user must pass
705 a second argument of 1, because that is what builtin_setjmp will
706 return. This also makes EH slightly more efficient, since we are no
707 longer copying around a value that we don't care about. */
708 gcc_assert (value == const1_rtx);
710 last = get_last_insn ();
711 #ifdef HAVE_builtin_longjmp
712 if (HAVE_builtin_longjmp)
713 emit_insn (gen_builtin_longjmp (buf_addr));
714 else
715 #endif
717 fp = gen_rtx_MEM (Pmode, buf_addr);
718 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
719 GET_MODE_SIZE (Pmode)));
721 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
722 2 * GET_MODE_SIZE (Pmode)));
723 set_mem_alias_set (fp, setjmp_alias_set);
724 set_mem_alias_set (lab, setjmp_alias_set);
725 set_mem_alias_set (stack, setjmp_alias_set);
727 /* Pick up FP, label, and SP from the block and jump. This code is
728 from expand_goto in stmt.c; see there for detailed comments. */
729 #if HAVE_nonlocal_goto
730 if (HAVE_nonlocal_goto)
731 /* We have to pass a value to the nonlocal_goto pattern that will
732 get copied into the static_chain pointer, but it does not matter
733 what that value is, because builtin_setjmp does not use it. */
734 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
735 else
736 #endif
738 lab = copy_to_reg (lab);
740 emit_insn (gen_rtx_CLOBBER (VOIDmode,
741 gen_rtx_MEM (BLKmode,
742 gen_rtx_SCRATCH (VOIDmode))));
743 emit_insn (gen_rtx_CLOBBER (VOIDmode,
744 gen_rtx_MEM (BLKmode,
745 hard_frame_pointer_rtx)));
747 emit_move_insn (hard_frame_pointer_rtx, fp);
748 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
750 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
751 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
752 emit_indirect_jump (lab);
756 /* Search backwards and mark the jump insn as a non-local goto.
757 Note that this precludes the use of __builtin_longjmp to a
758 __builtin_setjmp target in the same function. However, we've
759 already cautioned the user that these functions are for
760 internal exception handling use only. */
761 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
763 gcc_assert (insn != last);
765 if (JUMP_P (insn))
767 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
768 REG_NOTES (insn));
769 break;
771 else if (CALL_P (insn))
772 break;
776 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
777 and the address of the save area. */
779 static rtx
780 expand_builtin_nonlocal_goto (tree arglist)
782 tree t_label, t_save_area;
783 rtx r_label, r_save_area, r_fp, r_sp, insn;
785 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
786 return NULL_RTX;
788 t_label = TREE_VALUE (arglist);
789 arglist = TREE_CHAIN (arglist);
790 t_save_area = TREE_VALUE (arglist);
792 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
793 r_label = convert_memory_address (Pmode, r_label);
794 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
795 r_save_area = convert_memory_address (Pmode, r_save_area);
796 r_fp = gen_rtx_MEM (Pmode, r_save_area);
797 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
798 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
800 current_function_has_nonlocal_goto = 1;
802 #if HAVE_nonlocal_goto
803 /* ??? We no longer need to pass the static chain value, afaik. */
804 if (HAVE_nonlocal_goto)
805 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
806 else
807 #endif
809 r_label = copy_to_reg (r_label);
811 emit_insn (gen_rtx_CLOBBER (VOIDmode,
812 gen_rtx_MEM (BLKmode,
813 gen_rtx_SCRATCH (VOIDmode))));
815 emit_insn (gen_rtx_CLOBBER (VOIDmode,
816 gen_rtx_MEM (BLKmode,
817 hard_frame_pointer_rtx)));
819 /* Restore frame pointer for containing function.
820 This sets the actual hard register used for the frame pointer
821 to the location of the function's incoming static chain info.
822 The non-local goto handler will then adjust it to contain the
823 proper value and reload the argument pointer, if needed. */
824 emit_move_insn (hard_frame_pointer_rtx, r_fp);
825 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
827 /* USE of hard_frame_pointer_rtx added for consistency;
828 not clear if really needed. */
829 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
830 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
831 emit_indirect_jump (r_label);
834 /* Search backwards to the jump insn and mark it as a
835 non-local goto. */
836 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
838 if (JUMP_P (insn))
840 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
841 const0_rtx, REG_NOTES (insn));
842 break;
844 else if (CALL_P (insn))
845 break;
848 return const0_rtx;
851 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
852 (not all will be used on all machines) that was passed to __builtin_setjmp.
853 It updates the stack pointer in that block to correspond to the current
854 stack pointer. */
856 static void
857 expand_builtin_update_setjmp_buf (rtx buf_addr)
859 enum machine_mode sa_mode = Pmode;
860 rtx stack_save;
863 #ifdef HAVE_save_stack_nonlocal
864 if (HAVE_save_stack_nonlocal)
865 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
866 #endif
867 #ifdef STACK_SAVEAREA_MODE
868 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
869 #endif
871 stack_save
872 = gen_rtx_MEM (sa_mode,
873 memory_address
874 (sa_mode,
875 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
877 #ifdef HAVE_setjmp
878 if (HAVE_setjmp)
879 emit_insn (gen_setjmp ());
880 #endif
882 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
885 /* Expand a call to __builtin_prefetch. For a target that does not support
886 data prefetch, evaluate the memory address argument in case it has side
887 effects. */
889 static void
890 expand_builtin_prefetch (tree arglist)
892 tree arg0, arg1, arg2;
893 rtx op0, op1, op2;
895 if (!validate_arglist (arglist, POINTER_TYPE, 0))
896 return;
898 arg0 = TREE_VALUE (arglist);
899 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
900 zero (read) and argument 2 (locality) defaults to 3 (high degree of
901 locality). */
902 if (TREE_CHAIN (arglist))
904 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
905 if (TREE_CHAIN (TREE_CHAIN (arglist)))
906 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
907 else
908 arg2 = build_int_cst (NULL_TREE, 3);
910 else
912 arg1 = integer_zero_node;
913 arg2 = build_int_cst (NULL_TREE, 3);
916 /* Argument 0 is an address. */
917 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
919 /* Argument 1 (read/write flag) must be a compile-time constant int. */
920 if (TREE_CODE (arg1) != INTEGER_CST)
922 error ("second argument to %<__builtin_prefetch%> must be a constant");
923 arg1 = integer_zero_node;
925 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
926 /* Argument 1 must be either zero or one. */
927 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
929 warning ("invalid second argument to %<__builtin_prefetch%>;"
930 " using zero");
931 op1 = const0_rtx;
934 /* Argument 2 (locality) must be a compile-time constant int. */
935 if (TREE_CODE (arg2) != INTEGER_CST)
937 error ("third argument to %<__builtin_prefetch%> must be a constant");
938 arg2 = integer_zero_node;
940 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
941 /* Argument 2 must be 0, 1, 2, or 3. */
942 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
944 warning ("invalid third argument to %<__builtin_prefetch%>; using zero");
945 op2 = const0_rtx;
948 #ifdef HAVE_prefetch
949 if (HAVE_prefetch)
951 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
952 (op0,
953 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
954 || (GET_MODE (op0) != Pmode))
956 op0 = convert_memory_address (Pmode, op0);
957 op0 = force_reg (Pmode, op0);
959 emit_insn (gen_prefetch (op0, op1, op2));
961 #endif
963 /* Don't do anything with direct references to volatile memory, but
964 generate code to handle other side effects. */
965 if (!MEM_P (op0) && side_effects_p (op0))
966 emit_insn (op0);
969 /* Get a MEM rtx for expression EXP which is the address of an operand
970 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
972 static rtx
973 get_memory_rtx (tree exp)
975 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
976 rtx mem;
978 addr = convert_memory_address (Pmode, addr);
980 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
982 /* Get an expression we can use to find the attributes to assign to MEM.
983 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
984 we can. First remove any nops. */
985 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
986 || TREE_CODE (exp) == NON_LVALUE_EXPR)
987 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
988 exp = TREE_OPERAND (exp, 0);
990 if (TREE_CODE (exp) == ADDR_EXPR)
991 exp = TREE_OPERAND (exp, 0);
992 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
993 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
994 else
995 exp = NULL;
997 /* Honor attributes derived from exp, except for the alias set
998 (as builtin stringops may alias with anything) and the size
999 (as stringops may access multiple array elements). */
1000 if (exp)
1002 set_mem_attributes (mem, exp, 0);
1003 set_mem_alias_set (mem, 0);
1004 set_mem_size (mem, NULL_RTX);
1007 return mem;
1010 /* Built-in functions to perform an untyped call and return. */
1012 /* For each register that may be used for calling a function, this
1013 gives a mode used to copy the register's value. VOIDmode indicates
1014 the register is not used for calling a function. If the machine
1015 has register windows, this gives only the outbound registers.
1016 INCOMING_REGNO gives the corresponding inbound register. */
1017 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1019 /* For each register that may be used for returning values, this gives
1020 a mode used to copy the register's value. VOIDmode indicates the
1021 register is not used for returning values. If the machine has
1022 register windows, this gives only the outbound registers.
1023 INCOMING_REGNO gives the corresponding inbound register. */
1024 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1026 /* For each register that may be used for calling a function, this
1027 gives the offset of that register into the block returned by
1028 __builtin_apply_args. 0 indicates that the register is not
1029 used for calling a function. */
1030 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1032 /* Return the size required for the block returned by __builtin_apply_args,
1033 and initialize apply_args_mode. */
1035 static int
1036 apply_args_size (void)
1038 static int size = -1;
1039 int align;
1040 unsigned int regno;
1041 enum machine_mode mode;
1043 /* The values computed by this function never change. */
1044 if (size < 0)
1046 /* The first value is the incoming arg-pointer. */
1047 size = GET_MODE_SIZE (Pmode);
1049 /* The second value is the structure value address unless this is
1050 passed as an "invisible" first argument. */
1051 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1052 size += GET_MODE_SIZE (Pmode);
1054 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1055 if (FUNCTION_ARG_REGNO_P (regno))
1057 mode = reg_raw_mode[regno];
1059 gcc_assert (mode != VOIDmode);
1061 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1062 if (size % align != 0)
1063 size = CEIL (size, align) * align;
1064 apply_args_reg_offset[regno] = size;
1065 size += GET_MODE_SIZE (mode);
1066 apply_args_mode[regno] = mode;
1068 else
1070 apply_args_mode[regno] = VOIDmode;
1071 apply_args_reg_offset[regno] = 0;
1074 return size;
1077 /* Return the size required for the block returned by __builtin_apply,
1078 and initialize apply_result_mode. */
1080 static int
1081 apply_result_size (void)
1083 static int size = -1;
1084 int align, regno;
1085 enum machine_mode mode;
1087 /* The values computed by this function never change. */
1088 if (size < 0)
1090 size = 0;
1092 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1093 if (FUNCTION_VALUE_REGNO_P (regno))
1095 mode = reg_raw_mode[regno];
1097 gcc_assert (mode != VOIDmode);
1099 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1100 if (size % align != 0)
1101 size = CEIL (size, align) * align;
1102 size += GET_MODE_SIZE (mode);
1103 apply_result_mode[regno] = mode;
1105 else
1106 apply_result_mode[regno] = VOIDmode;
1108 /* Allow targets that use untyped_call and untyped_return to override
1109 the size so that machine-specific information can be stored here. */
1110 #ifdef APPLY_RESULT_SIZE
1111 size = APPLY_RESULT_SIZE;
1112 #endif
1114 return size;
1117 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1118 /* Create a vector describing the result block RESULT. If SAVEP is true,
1119 the result block is used to save the values; otherwise it is used to
1120 restore the values. */
1122 static rtx
1123 result_vector (int savep, rtx result)
1125 int regno, size, align, nelts;
1126 enum machine_mode mode;
1127 rtx reg, mem;
1128 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1130 size = nelts = 0;
1131 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1132 if ((mode = apply_result_mode[regno]) != VOIDmode)
1134 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1135 if (size % align != 0)
1136 size = CEIL (size, align) * align;
1137 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1138 mem = adjust_address (result, mode, size);
1139 savevec[nelts++] = (savep
1140 ? gen_rtx_SET (VOIDmode, mem, reg)
1141 : gen_rtx_SET (VOIDmode, reg, mem));
1142 size += GET_MODE_SIZE (mode);
1144 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1146 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1148 /* Save the state required to perform an untyped call with the same
1149 arguments as were passed to the current function. */
1151 static rtx
1152 expand_builtin_apply_args_1 (void)
1154 rtx registers, tem;
1155 int size, align, regno;
1156 enum machine_mode mode;
1157 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1159 /* Create a block where the arg-pointer, structure value address,
1160 and argument registers can be saved. */
1161 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1163 /* Walk past the arg-pointer and structure value address. */
1164 size = GET_MODE_SIZE (Pmode);
1165 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1166 size += GET_MODE_SIZE (Pmode);
1168 /* Save each register used in calling a function to the block. */
1169 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1170 if ((mode = apply_args_mode[regno]) != VOIDmode)
1172 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1173 if (size % align != 0)
1174 size = CEIL (size, align) * align;
1176 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1178 emit_move_insn (adjust_address (registers, mode, size), tem);
1179 size += GET_MODE_SIZE (mode);
1182 /* Save the arg pointer to the block. */
1183 tem = copy_to_reg (virtual_incoming_args_rtx);
1184 #ifdef STACK_GROWS_DOWNWARD
1185 /* We need the pointer as the caller actually passed them to us, not
1186 as we might have pretended they were passed. Make sure it's a valid
1187 operand, as emit_move_insn isn't expected to handle a PLUS. */
1189 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1190 NULL_RTX);
1191 #endif
1192 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1194 size = GET_MODE_SIZE (Pmode);
1196 /* Save the structure value address unless this is passed as an
1197 "invisible" first argument. */
1198 if (struct_incoming_value)
1200 emit_move_insn (adjust_address (registers, Pmode, size),
1201 copy_to_reg (struct_incoming_value));
1202 size += GET_MODE_SIZE (Pmode);
1205 /* Return the address of the block. */
1206 return copy_addr_to_reg (XEXP (registers, 0));
1209 /* __builtin_apply_args returns block of memory allocated on
1210 the stack into which is stored the arg pointer, structure
1211 value address, static chain, and all the registers that might
1212 possibly be used in performing a function call. The code is
1213 moved to the start of the function so the incoming values are
1214 saved. */
1216 static rtx
1217 expand_builtin_apply_args (void)
1219 /* Don't do __builtin_apply_args more than once in a function.
1220 Save the result of the first call and reuse it. */
1221 if (apply_args_value != 0)
1222 return apply_args_value;
1224 /* When this function is called, it means that registers must be
1225 saved on entry to this function. So we migrate the
1226 call to the first insn of this function. */
1227 rtx temp;
1228 rtx seq;
1230 start_sequence ();
1231 temp = expand_builtin_apply_args_1 ();
1232 seq = get_insns ();
1233 end_sequence ();
1235 apply_args_value = temp;
1237 /* Put the insns after the NOTE that starts the function.
1238 If this is inside a start_sequence, make the outer-level insn
1239 chain current, so the code is placed at the start of the
1240 function. */
1241 push_topmost_sequence ();
1242 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1243 pop_topmost_sequence ();
1244 return temp;
1248 /* Perform an untyped call and save the state required to perform an
1249 untyped return of whatever value was returned by the given function. */
1251 static rtx
1252 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1254 int size, align, regno;
1255 enum machine_mode mode;
1256 rtx incoming_args, result, reg, dest, src, call_insn;
1257 rtx old_stack_level = 0;
1258 rtx call_fusage = 0;
1259 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1261 arguments = convert_memory_address (Pmode, arguments);
1263 /* Create a block where the return registers can be saved. */
1264 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1266 /* Fetch the arg pointer from the ARGUMENTS block. */
1267 incoming_args = gen_reg_rtx (Pmode);
1268 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1269 #ifndef STACK_GROWS_DOWNWARD
1270 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1271 incoming_args, 0, OPTAB_LIB_WIDEN);
1272 #endif
1274 /* Push a new argument block and copy the arguments. Do not allow
1275 the (potential) memcpy call below to interfere with our stack
1276 manipulations. */
1277 do_pending_stack_adjust ();
1278 NO_DEFER_POP;
1280 /* Save the stack with nonlocal if available. */
1281 #ifdef HAVE_save_stack_nonlocal
1282 if (HAVE_save_stack_nonlocal)
1283 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1284 else
1285 #endif
1286 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1288 /* Allocate a block of memory onto the stack and copy the memory
1289 arguments to the outgoing arguments address. */
1290 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1291 dest = virtual_outgoing_args_rtx;
1292 #ifndef STACK_GROWS_DOWNWARD
1293 if (GET_CODE (argsize) == CONST_INT)
1294 dest = plus_constant (dest, -INTVAL (argsize));
1295 else
1296 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1297 #endif
1298 dest = gen_rtx_MEM (BLKmode, dest);
1299 set_mem_align (dest, PARM_BOUNDARY);
1300 src = gen_rtx_MEM (BLKmode, incoming_args);
1301 set_mem_align (src, PARM_BOUNDARY);
1302 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1304 /* Refer to the argument block. */
1305 apply_args_size ();
1306 arguments = gen_rtx_MEM (BLKmode, arguments);
1307 set_mem_align (arguments, PARM_BOUNDARY);
1309 /* Walk past the arg-pointer and structure value address. */
1310 size = GET_MODE_SIZE (Pmode);
1311 if (struct_value)
1312 size += GET_MODE_SIZE (Pmode);
1314 /* Restore each of the registers previously saved. Make USE insns
1315 for each of these registers for use in making the call. */
1316 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1317 if ((mode = apply_args_mode[regno]) != VOIDmode)
1319 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1320 if (size % align != 0)
1321 size = CEIL (size, align) * align;
1322 reg = gen_rtx_REG (mode, regno);
1323 emit_move_insn (reg, adjust_address (arguments, mode, size));
1324 use_reg (&call_fusage, reg);
1325 size += GET_MODE_SIZE (mode);
1328 /* Restore the structure value address unless this is passed as an
1329 "invisible" first argument. */
1330 size = GET_MODE_SIZE (Pmode);
1331 if (struct_value)
1333 rtx value = gen_reg_rtx (Pmode);
1334 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1335 emit_move_insn (struct_value, value);
1336 if (REG_P (struct_value))
1337 use_reg (&call_fusage, struct_value);
1338 size += GET_MODE_SIZE (Pmode);
1341 /* All arguments and registers used for the call are set up by now! */
1342 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1344 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1345 and we don't want to load it into a register as an optimization,
1346 because prepare_call_address already did it if it should be done. */
1347 if (GET_CODE (function) != SYMBOL_REF)
1348 function = memory_address (FUNCTION_MODE, function);
1350 /* Generate the actual call instruction and save the return value. */
1351 #ifdef HAVE_untyped_call
1352 if (HAVE_untyped_call)
1353 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1354 result, result_vector (1, result)));
1355 else
1356 #endif
1357 #ifdef HAVE_call_value
1358 if (HAVE_call_value)
1360 rtx valreg = 0;
1362 /* Locate the unique return register. It is not possible to
1363 express a call that sets more than one return register using
1364 call_value; use untyped_call for that. In fact, untyped_call
1365 only needs to save the return registers in the given block. */
1366 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1367 if ((mode = apply_result_mode[regno]) != VOIDmode)
1369 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1371 valreg = gen_rtx_REG (mode, regno);
1374 emit_call_insn (GEN_CALL_VALUE (valreg,
1375 gen_rtx_MEM (FUNCTION_MODE, function),
1376 const0_rtx, NULL_RTX, const0_rtx));
1378 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1380 else
1381 #endif
1382 gcc_unreachable ();
1384 /* Find the CALL insn we just emitted, and attach the register usage
1385 information. */
1386 call_insn = last_call_insn ();
1387 add_function_usage_to (call_insn, call_fusage);
1389 /* Restore the stack. */
1390 #ifdef HAVE_save_stack_nonlocal
1391 if (HAVE_save_stack_nonlocal)
1392 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1393 else
1394 #endif
1395 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1397 OK_DEFER_POP;
1399 /* Return the address of the result block. */
1400 result = copy_addr_to_reg (XEXP (result, 0));
1401 return convert_memory_address (ptr_mode, result);
1404 /* Perform an untyped return. */
1406 static void
1407 expand_builtin_return (rtx result)
1409 int size, align, regno;
1410 enum machine_mode mode;
1411 rtx reg;
1412 rtx call_fusage = 0;
1414 result = convert_memory_address (Pmode, result);
1416 apply_result_size ();
1417 result = gen_rtx_MEM (BLKmode, result);
1419 #ifdef HAVE_untyped_return
1420 if (HAVE_untyped_return)
1422 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1423 emit_barrier ();
1424 return;
1426 #endif
1428 /* Restore the return value and note that each value is used. */
1429 size = 0;
1430 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1431 if ((mode = apply_result_mode[regno]) != VOIDmode)
1433 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1434 if (size % align != 0)
1435 size = CEIL (size, align) * align;
1436 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1437 emit_move_insn (reg, adjust_address (result, mode, size));
1439 push_to_sequence (call_fusage);
1440 emit_insn (gen_rtx_USE (VOIDmode, reg));
1441 call_fusage = get_insns ();
1442 end_sequence ();
1443 size += GET_MODE_SIZE (mode);
1446 /* Put the USE insns before the return. */
1447 emit_insn (call_fusage);
1449 /* Return whatever values was restored by jumping directly to the end
1450 of the function. */
1451 expand_naked_return ();
1454 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1456 static enum type_class
1457 type_to_class (tree type)
1459 switch (TREE_CODE (type))
1461 case VOID_TYPE: return void_type_class;
1462 case INTEGER_TYPE: return integer_type_class;
1463 case CHAR_TYPE: return char_type_class;
1464 case ENUMERAL_TYPE: return enumeral_type_class;
1465 case BOOLEAN_TYPE: return boolean_type_class;
1466 case POINTER_TYPE: return pointer_type_class;
1467 case REFERENCE_TYPE: return reference_type_class;
1468 case OFFSET_TYPE: return offset_type_class;
1469 case REAL_TYPE: return real_type_class;
1470 case COMPLEX_TYPE: return complex_type_class;
1471 case FUNCTION_TYPE: return function_type_class;
1472 case METHOD_TYPE: return method_type_class;
1473 case RECORD_TYPE: return record_type_class;
1474 case UNION_TYPE:
1475 case QUAL_UNION_TYPE: return union_type_class;
1476 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1477 ? string_type_class : array_type_class);
1478 case SET_TYPE: return set_type_class;
1479 case FILE_TYPE: return file_type_class;
1480 case LANG_TYPE: return lang_type_class;
1481 default: return no_type_class;
1485 /* Expand a call to __builtin_classify_type with arguments found in
1486 ARGLIST. */
1488 static rtx
1489 expand_builtin_classify_type (tree arglist)
1491 if (arglist != 0)
1492 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1493 return GEN_INT (no_type_class);
1496 /* This helper macro, meant to be used in mathfn_built_in below,
1497 determines which among a set of three builtin math functions is
1498 appropriate for a given type mode. The `F' and `L' cases are
1499 automatically generated from the `double' case. */
1500 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1501 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1502 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1503 fcodel = BUILT_IN_MATHFN##L ; break;
1505 /* Return mathematic function equivalent to FN but operating directly
1506 on TYPE, if available. If we can't do the conversion, return zero. */
1507 tree
1508 mathfn_built_in (tree type, enum built_in_function fn)
1510 enum built_in_function fcode, fcodef, fcodel;
1512 switch (fn)
1514 CASE_MATHFN (BUILT_IN_ACOS)
1515 CASE_MATHFN (BUILT_IN_ACOSH)
1516 CASE_MATHFN (BUILT_IN_ASIN)
1517 CASE_MATHFN (BUILT_IN_ASINH)
1518 CASE_MATHFN (BUILT_IN_ATAN)
1519 CASE_MATHFN (BUILT_IN_ATAN2)
1520 CASE_MATHFN (BUILT_IN_ATANH)
1521 CASE_MATHFN (BUILT_IN_CBRT)
1522 CASE_MATHFN (BUILT_IN_CEIL)
1523 CASE_MATHFN (BUILT_IN_COPYSIGN)
1524 CASE_MATHFN (BUILT_IN_COS)
1525 CASE_MATHFN (BUILT_IN_COSH)
1526 CASE_MATHFN (BUILT_IN_DREM)
1527 CASE_MATHFN (BUILT_IN_ERF)
1528 CASE_MATHFN (BUILT_IN_ERFC)
1529 CASE_MATHFN (BUILT_IN_EXP)
1530 CASE_MATHFN (BUILT_IN_EXP10)
1531 CASE_MATHFN (BUILT_IN_EXP2)
1532 CASE_MATHFN (BUILT_IN_EXPM1)
1533 CASE_MATHFN (BUILT_IN_FABS)
1534 CASE_MATHFN (BUILT_IN_FDIM)
1535 CASE_MATHFN (BUILT_IN_FLOOR)
1536 CASE_MATHFN (BUILT_IN_FMA)
1537 CASE_MATHFN (BUILT_IN_FMAX)
1538 CASE_MATHFN (BUILT_IN_FMIN)
1539 CASE_MATHFN (BUILT_IN_FMOD)
1540 CASE_MATHFN (BUILT_IN_FREXP)
1541 CASE_MATHFN (BUILT_IN_GAMMA)
1542 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1543 CASE_MATHFN (BUILT_IN_HYPOT)
1544 CASE_MATHFN (BUILT_IN_ILOGB)
1545 CASE_MATHFN (BUILT_IN_INF)
1546 CASE_MATHFN (BUILT_IN_J0)
1547 CASE_MATHFN (BUILT_IN_J1)
1548 CASE_MATHFN (BUILT_IN_JN)
1549 CASE_MATHFN (BUILT_IN_LDEXP)
1550 CASE_MATHFN (BUILT_IN_LGAMMA)
1551 CASE_MATHFN (BUILT_IN_LLRINT)
1552 CASE_MATHFN (BUILT_IN_LLROUND)
1553 CASE_MATHFN (BUILT_IN_LOG)
1554 CASE_MATHFN (BUILT_IN_LOG10)
1555 CASE_MATHFN (BUILT_IN_LOG1P)
1556 CASE_MATHFN (BUILT_IN_LOG2)
1557 CASE_MATHFN (BUILT_IN_LOGB)
1558 CASE_MATHFN (BUILT_IN_LRINT)
1559 CASE_MATHFN (BUILT_IN_LROUND)
1560 CASE_MATHFN (BUILT_IN_MODF)
1561 CASE_MATHFN (BUILT_IN_NAN)
1562 CASE_MATHFN (BUILT_IN_NANS)
1563 CASE_MATHFN (BUILT_IN_NEARBYINT)
1564 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1565 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1566 CASE_MATHFN (BUILT_IN_POW)
1567 CASE_MATHFN (BUILT_IN_POW10)
1568 CASE_MATHFN (BUILT_IN_REMAINDER)
1569 CASE_MATHFN (BUILT_IN_REMQUO)
1570 CASE_MATHFN (BUILT_IN_RINT)
1571 CASE_MATHFN (BUILT_IN_ROUND)
1572 CASE_MATHFN (BUILT_IN_SCALB)
1573 CASE_MATHFN (BUILT_IN_SCALBLN)
1574 CASE_MATHFN (BUILT_IN_SCALBN)
1575 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1576 CASE_MATHFN (BUILT_IN_SIN)
1577 CASE_MATHFN (BUILT_IN_SINCOS)
1578 CASE_MATHFN (BUILT_IN_SINH)
1579 CASE_MATHFN (BUILT_IN_SQRT)
1580 CASE_MATHFN (BUILT_IN_TAN)
1581 CASE_MATHFN (BUILT_IN_TANH)
1582 CASE_MATHFN (BUILT_IN_TGAMMA)
1583 CASE_MATHFN (BUILT_IN_TRUNC)
1584 CASE_MATHFN (BUILT_IN_Y0)
1585 CASE_MATHFN (BUILT_IN_Y1)
1586 CASE_MATHFN (BUILT_IN_YN)
1588 default:
1589 return 0;
1592 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1593 return implicit_built_in_decls[fcode];
1594 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1595 return implicit_built_in_decls[fcodef];
1596 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1597 return implicit_built_in_decls[fcodel];
1598 else
1599 return 0;
1602 /* If errno must be maintained, expand the RTL to check if the result,
1603 TARGET, of a built-in function call, EXP, is NaN, and if so set
1604 errno to EDOM. */
1606 static void
1607 expand_errno_check (tree exp, rtx target)
1609 rtx lab = gen_label_rtx ();
1611 /* Test the result; if it is NaN, set errno=EDOM because
1612 the argument was not in the domain. */
1613 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1614 0, lab);
1616 #ifdef TARGET_EDOM
1617 /* If this built-in doesn't throw an exception, set errno directly. */
1618 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1620 #ifdef GEN_ERRNO_RTX
1621 rtx errno_rtx = GEN_ERRNO_RTX;
1622 #else
1623 rtx errno_rtx
1624 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1625 #endif
1626 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1627 emit_label (lab);
1628 return;
1630 #endif
1632 /* We can't set errno=EDOM directly; let the library call do it.
1633 Pop the arguments right away in case the call gets deleted. */
1634 NO_DEFER_POP;
1635 expand_call (exp, target, 0);
1636 OK_DEFER_POP;
1637 emit_label (lab);
1641 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1642 Return 0 if a normal call should be emitted rather than expanding the
1643 function in-line. EXP is the expression that is a call to the builtin
1644 function; if convenient, the result should be placed in TARGET.
1645 SUBTARGET may be used as the target for computing one of EXP's operands. */
1647 static rtx
1648 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1650 optab builtin_optab;
1651 rtx op0, insns, before_call;
1652 tree fndecl = get_callee_fndecl (exp);
1653 tree arglist = TREE_OPERAND (exp, 1);
1654 enum machine_mode mode;
1655 bool errno_set = false;
1656 tree arg, narg;
1658 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1659 return 0;
1661 arg = TREE_VALUE (arglist);
1663 switch (DECL_FUNCTION_CODE (fndecl))
1665 case BUILT_IN_SQRT:
1666 case BUILT_IN_SQRTF:
1667 case BUILT_IN_SQRTL:
1668 errno_set = ! tree_expr_nonnegative_p (arg);
1669 builtin_optab = sqrt_optab;
1670 break;
1671 case BUILT_IN_EXP:
1672 case BUILT_IN_EXPF:
1673 case BUILT_IN_EXPL:
1674 errno_set = true; builtin_optab = exp_optab; break;
1675 case BUILT_IN_EXP10:
1676 case BUILT_IN_EXP10F:
1677 case BUILT_IN_EXP10L:
1678 case BUILT_IN_POW10:
1679 case BUILT_IN_POW10F:
1680 case BUILT_IN_POW10L:
1681 errno_set = true; builtin_optab = exp10_optab; break;
1682 case BUILT_IN_EXP2:
1683 case BUILT_IN_EXP2F:
1684 case BUILT_IN_EXP2L:
1685 errno_set = true; builtin_optab = exp2_optab; break;
1686 case BUILT_IN_EXPM1:
1687 case BUILT_IN_EXPM1F:
1688 case BUILT_IN_EXPM1L:
1689 errno_set = true; builtin_optab = expm1_optab; break;
1690 case BUILT_IN_LOGB:
1691 case BUILT_IN_LOGBF:
1692 case BUILT_IN_LOGBL:
1693 errno_set = true; builtin_optab = logb_optab; break;
1694 case BUILT_IN_ILOGB:
1695 case BUILT_IN_ILOGBF:
1696 case BUILT_IN_ILOGBL:
1697 errno_set = true; builtin_optab = ilogb_optab; break;
1698 case BUILT_IN_LOG:
1699 case BUILT_IN_LOGF:
1700 case BUILT_IN_LOGL:
1701 errno_set = true; builtin_optab = log_optab; break;
1702 case BUILT_IN_LOG10:
1703 case BUILT_IN_LOG10F:
1704 case BUILT_IN_LOG10L:
1705 errno_set = true; builtin_optab = log10_optab; break;
1706 case BUILT_IN_LOG2:
1707 case BUILT_IN_LOG2F:
1708 case BUILT_IN_LOG2L:
1709 errno_set = true; builtin_optab = log2_optab; break;
1710 case BUILT_IN_LOG1P:
1711 case BUILT_IN_LOG1PF:
1712 case BUILT_IN_LOG1PL:
1713 errno_set = true; builtin_optab = log1p_optab; break;
1714 case BUILT_IN_ASIN:
1715 case BUILT_IN_ASINF:
1716 case BUILT_IN_ASINL:
1717 builtin_optab = asin_optab; break;
1718 case BUILT_IN_ACOS:
1719 case BUILT_IN_ACOSF:
1720 case BUILT_IN_ACOSL:
1721 builtin_optab = acos_optab; break;
1722 case BUILT_IN_TAN:
1723 case BUILT_IN_TANF:
1724 case BUILT_IN_TANL:
1725 builtin_optab = tan_optab; break;
1726 case BUILT_IN_ATAN:
1727 case BUILT_IN_ATANF:
1728 case BUILT_IN_ATANL:
1729 builtin_optab = atan_optab; break;
1730 case BUILT_IN_FLOOR:
1731 case BUILT_IN_FLOORF:
1732 case BUILT_IN_FLOORL:
1733 builtin_optab = floor_optab; break;
1734 case BUILT_IN_CEIL:
1735 case BUILT_IN_CEILF:
1736 case BUILT_IN_CEILL:
1737 builtin_optab = ceil_optab; break;
1738 case BUILT_IN_TRUNC:
1739 case BUILT_IN_TRUNCF:
1740 case BUILT_IN_TRUNCL:
1741 builtin_optab = btrunc_optab; break;
1742 case BUILT_IN_ROUND:
1743 case BUILT_IN_ROUNDF:
1744 case BUILT_IN_ROUNDL:
1745 builtin_optab = round_optab; break;
1746 case BUILT_IN_NEARBYINT:
1747 case BUILT_IN_NEARBYINTF:
1748 case BUILT_IN_NEARBYINTL:
1749 builtin_optab = nearbyint_optab; break;
1750 case BUILT_IN_RINT:
1751 case BUILT_IN_RINTF:
1752 case BUILT_IN_RINTL:
1753 builtin_optab = rint_optab; break;
1754 default:
1755 gcc_unreachable ();
1758 /* Make a suitable register to place result in. */
1759 mode = TYPE_MODE (TREE_TYPE (exp));
1761 if (! flag_errno_math || ! HONOR_NANS (mode))
1762 errno_set = false;
1764 /* Before working hard, check whether the instruction is available. */
1765 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1767 target = gen_reg_rtx (mode);
1769 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1770 need to expand the argument again. This way, we will not perform
1771 side-effects more the once. */
1772 narg = builtin_save_expr (arg);
1773 if (narg != arg)
1775 arglist = build_tree_list (NULL_TREE, arg);
1776 exp = build_function_call_expr (fndecl, arglist);
1779 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1781 start_sequence ();
1783 /* Compute into TARGET.
1784 Set TARGET to wherever the result comes back. */
1785 target = expand_unop (mode, builtin_optab, op0, target, 0);
1787 if (target != 0)
1789 if (errno_set)
1790 expand_errno_check (exp, target);
1792 /* Output the entire sequence. */
1793 insns = get_insns ();
1794 end_sequence ();
1795 emit_insn (insns);
1796 return target;
1799 /* If we were unable to expand via the builtin, stop the sequence
1800 (without outputting the insns) and call to the library function
1801 with the stabilized argument list. */
1802 end_sequence ();
1805 before_call = get_last_insn ();
1807 target = expand_call (exp, target, target == const0_rtx);
1809 /* If this is a sqrt operation and we don't care about errno, try to
1810 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1811 This allows the semantics of the libcall to be visible to the RTL
1812 optimizers. */
1813 if (builtin_optab == sqrt_optab && !errno_set)
1815 /* Search backwards through the insns emitted by expand_call looking
1816 for the instruction with the REG_RETVAL note. */
1817 rtx last = get_last_insn ();
1818 while (last != before_call)
1820 if (find_reg_note (last, REG_RETVAL, NULL))
1822 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1823 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1824 two elements, i.e. symbol_ref(sqrt) and the operand. */
1825 if (note
1826 && GET_CODE (note) == EXPR_LIST
1827 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1828 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1829 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1831 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1832 /* Check operand is a register with expected mode. */
1833 if (operand
1834 && REG_P (operand)
1835 && GET_MODE (operand) == mode)
1837 /* Replace the REG_EQUAL note with a SQRT rtx. */
1838 rtx equiv = gen_rtx_SQRT (mode, operand);
1839 set_unique_reg_note (last, REG_EQUAL, equiv);
1842 break;
1844 last = PREV_INSN (last);
1848 return target;
1851 /* Expand a call to the builtin binary math functions (pow and atan2).
1852 Return 0 if a normal call should be emitted rather than expanding the
1853 function in-line. EXP is the expression that is a call to the builtin
1854 function; if convenient, the result should be placed in TARGET.
1855 SUBTARGET may be used as the target for computing one of EXP's
1856 operands. */
1858 static rtx
1859 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1861 optab builtin_optab;
1862 rtx op0, op1, insns;
1863 tree fndecl = get_callee_fndecl (exp);
1864 tree arglist = TREE_OPERAND (exp, 1);
1865 tree arg0, arg1, temp, narg;
1866 enum machine_mode mode;
1867 bool errno_set = true;
1868 bool stable = true;
1870 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1871 return 0;
1873 arg0 = TREE_VALUE (arglist);
1874 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1876 switch (DECL_FUNCTION_CODE (fndecl))
1878 case BUILT_IN_POW:
1879 case BUILT_IN_POWF:
1880 case BUILT_IN_POWL:
1881 builtin_optab = pow_optab; break;
1882 case BUILT_IN_ATAN2:
1883 case BUILT_IN_ATAN2F:
1884 case BUILT_IN_ATAN2L:
1885 builtin_optab = atan2_optab; break;
1886 case BUILT_IN_FMOD:
1887 case BUILT_IN_FMODF:
1888 case BUILT_IN_FMODL:
1889 builtin_optab = fmod_optab; break;
1890 case BUILT_IN_DREM:
1891 case BUILT_IN_DREMF:
1892 case BUILT_IN_DREML:
1893 builtin_optab = drem_optab; break;
1894 default:
1895 gcc_unreachable ();
1898 /* Make a suitable register to place result in. */
1899 mode = TYPE_MODE (TREE_TYPE (exp));
1901 /* Before working hard, check whether the instruction is available. */
1902 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1903 return 0;
1905 target = gen_reg_rtx (mode);
1907 if (! flag_errno_math || ! HONOR_NANS (mode))
1908 errno_set = false;
1910 /* Always stabilize the argument list. */
1911 narg = builtin_save_expr (arg1);
1912 if (narg != arg1)
1914 temp = build_tree_list (NULL_TREE, narg);
1915 stable = false;
1917 else
1918 temp = TREE_CHAIN (arglist);
1920 narg = builtin_save_expr (arg0);
1921 if (narg != arg0)
1923 arglist = tree_cons (NULL_TREE, narg, temp);
1924 stable = false;
1926 else if (! stable)
1927 arglist = tree_cons (NULL_TREE, arg0, temp);
1929 if (! stable)
1930 exp = build_function_call_expr (fndecl, arglist);
1932 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1933 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1935 start_sequence ();
1937 /* Compute into TARGET.
1938 Set TARGET to wherever the result comes back. */
1939 target = expand_binop (mode, builtin_optab, op0, op1,
1940 target, 0, OPTAB_DIRECT);
1942 /* If we were unable to expand via the builtin, stop the sequence
1943 (without outputting the insns) and call to the library function
1944 with the stabilized argument list. */
1945 if (target == 0)
1947 end_sequence ();
1948 return expand_call (exp, target, target == const0_rtx);
1951 if (errno_set)
1952 expand_errno_check (exp, target);
1954 /* Output the entire sequence. */
1955 insns = get_insns ();
1956 end_sequence ();
1957 emit_insn (insns);
1959 return target;
1962 /* Expand a call to the builtin sin and cos math functions.
1963 Return 0 if a normal call should be emitted rather than expanding the
1964 function in-line. EXP is the expression that is a call to the builtin
1965 function; if convenient, the result should be placed in TARGET.
1966 SUBTARGET may be used as the target for computing one of EXP's
1967 operands. */
1969 static rtx
1970 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1972 optab builtin_optab;
1973 rtx op0, insns, before_call;
1974 tree fndecl = get_callee_fndecl (exp);
1975 tree arglist = TREE_OPERAND (exp, 1);
1976 enum machine_mode mode;
1977 bool errno_set = false;
1978 tree arg, narg;
1980 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1981 return 0;
1983 arg = TREE_VALUE (arglist);
1985 switch (DECL_FUNCTION_CODE (fndecl))
1987 case BUILT_IN_SIN:
1988 case BUILT_IN_SINF:
1989 case BUILT_IN_SINL:
1990 case BUILT_IN_COS:
1991 case BUILT_IN_COSF:
1992 case BUILT_IN_COSL:
1993 builtin_optab = sincos_optab; break;
1994 default:
1995 gcc_unreachable ();
1998 /* Make a suitable register to place result in. */
1999 mode = TYPE_MODE (TREE_TYPE (exp));
2001 if (! flag_errno_math || ! HONOR_NANS (mode))
2002 errno_set = false;
2004 /* Check if sincos insn is available, otherwise fallback
2005 to sin or cos insn. */
2006 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2007 switch (DECL_FUNCTION_CODE (fndecl))
2009 case BUILT_IN_SIN:
2010 case BUILT_IN_SINF:
2011 case BUILT_IN_SINL:
2012 builtin_optab = sin_optab; break;
2013 case BUILT_IN_COS:
2014 case BUILT_IN_COSF:
2015 case BUILT_IN_COSL:
2016 builtin_optab = cos_optab; break;
2017 default:
2018 gcc_unreachable ();
2022 /* Before working hard, check whether the instruction is available. */
2023 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2025 target = gen_reg_rtx (mode);
2027 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2028 need to expand the argument again. This way, we will not perform
2029 side-effects more the once. */
2030 narg = save_expr (arg);
2031 if (narg != arg)
2033 arglist = build_tree_list (NULL_TREE, arg);
2034 exp = build_function_call_expr (fndecl, arglist);
2037 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2039 start_sequence ();
2041 /* Compute into TARGET.
2042 Set TARGET to wherever the result comes back. */
2043 if (builtin_optab == sincos_optab)
2045 int result;
2047 switch (DECL_FUNCTION_CODE (fndecl))
2049 case BUILT_IN_SIN:
2050 case BUILT_IN_SINF:
2051 case BUILT_IN_SINL:
2052 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2053 break;
2054 case BUILT_IN_COS:
2055 case BUILT_IN_COSF:
2056 case BUILT_IN_COSL:
2057 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2058 break;
2059 default:
2060 gcc_unreachable ();
2062 gcc_assert (result);
2064 else
2066 target = expand_unop (mode, builtin_optab, op0, target, 0);
2069 if (target != 0)
2071 if (errno_set)
2072 expand_errno_check (exp, target);
2074 /* Output the entire sequence. */
2075 insns = get_insns ();
2076 end_sequence ();
2077 emit_insn (insns);
2078 return target;
2081 /* If we were unable to expand via the builtin, stop the sequence
2082 (without outputting the insns) and call to the library function
2083 with the stabilized argument list. */
2084 end_sequence ();
2087 before_call = get_last_insn ();
2089 target = expand_call (exp, target, target == const0_rtx);
2091 return target;
2094 /* To evaluate powi(x,n), the floating point value x raised to the
2095 constant integer exponent n, we use a hybrid algorithm that
2096 combines the "window method" with look-up tables. For an
2097 introduction to exponentiation algorithms and "addition chains",
2098 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2099 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2100 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2101 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2103 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2104 multiplications to inline before calling the system library's pow
2105 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2106 so this default never requires calling pow, powf or powl. */
2108 #ifndef POWI_MAX_MULTS
2109 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2110 #endif
2112 /* The size of the "optimal power tree" lookup table. All
2113 exponents less than this value are simply looked up in the
2114 powi_table below. This threshold is also used to size the
2115 cache of pseudo registers that hold intermediate results. */
2116 #define POWI_TABLE_SIZE 256
2118 /* The size, in bits of the window, used in the "window method"
2119 exponentiation algorithm. This is equivalent to a radix of
2120 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2121 #define POWI_WINDOW_SIZE 3
2123 /* The following table is an efficient representation of an
2124 "optimal power tree". For each value, i, the corresponding
2125 value, j, in the table states than an optimal evaluation
2126 sequence for calculating pow(x,i) can be found by evaluating
2127 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2128 100 integers is given in Knuth's "Seminumerical algorithms". */
2130 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2132 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2133 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2134 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2135 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2136 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2137 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2138 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2139 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2140 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2141 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2142 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2143 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2144 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2145 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2146 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2147 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2148 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2149 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2150 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2151 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2152 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2153 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2154 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2155 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2156 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2157 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2158 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2159 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2160 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2161 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2162 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2163 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2167 /* Return the number of multiplications required to calculate
2168 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2169 subroutine of powi_cost. CACHE is an array indicating
2170 which exponents have already been calculated. */
2172 static int
2173 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2175 /* If we've already calculated this exponent, then this evaluation
2176 doesn't require any additional multiplications. */
2177 if (cache[n])
2178 return 0;
2180 cache[n] = true;
2181 return powi_lookup_cost (n - powi_table[n], cache)
2182 + powi_lookup_cost (powi_table[n], cache) + 1;
2185 /* Return the number of multiplications required to calculate
2186 powi(x,n) for an arbitrary x, given the exponent N. This
2187 function needs to be kept in sync with expand_powi below. */
2189 static int
2190 powi_cost (HOST_WIDE_INT n)
2192 bool cache[POWI_TABLE_SIZE];
2193 unsigned HOST_WIDE_INT digit;
2194 unsigned HOST_WIDE_INT val;
2195 int result;
2197 if (n == 0)
2198 return 0;
2200 /* Ignore the reciprocal when calculating the cost. */
2201 val = (n < 0) ? -n : n;
2203 /* Initialize the exponent cache. */
2204 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2205 cache[1] = true;
2207 result = 0;
2209 while (val >= POWI_TABLE_SIZE)
2211 if (val & 1)
2213 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2214 result += powi_lookup_cost (digit, cache)
2215 + POWI_WINDOW_SIZE + 1;
2216 val >>= POWI_WINDOW_SIZE;
2218 else
2220 val >>= 1;
2221 result++;
2225 return result + powi_lookup_cost (val, cache);
2228 /* Recursive subroutine of expand_powi. This function takes the array,
2229 CACHE, of already calculated exponents and an exponent N and returns
2230 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2232 static rtx
2233 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2235 unsigned HOST_WIDE_INT digit;
2236 rtx target, result;
2237 rtx op0, op1;
2239 if (n < POWI_TABLE_SIZE)
2241 if (cache[n])
2242 return cache[n];
2244 target = gen_reg_rtx (mode);
2245 cache[n] = target;
2247 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2248 op1 = expand_powi_1 (mode, powi_table[n], cache);
2250 else if (n & 1)
2252 target = gen_reg_rtx (mode);
2253 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2254 op0 = expand_powi_1 (mode, n - digit, cache);
2255 op1 = expand_powi_1 (mode, digit, cache);
2257 else
2259 target = gen_reg_rtx (mode);
2260 op0 = expand_powi_1 (mode, n >> 1, cache);
2261 op1 = op0;
2264 result = expand_mult (mode, op0, op1, target, 0);
2265 if (result != target)
2266 emit_move_insn (target, result);
2267 return target;
2270 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2271 floating point operand in mode MODE, and N is the exponent. This
2272 function needs to be kept in sync with powi_cost above. */
2274 static rtx
2275 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2277 unsigned HOST_WIDE_INT val;
2278 rtx cache[POWI_TABLE_SIZE];
2279 rtx result;
2281 if (n == 0)
2282 return CONST1_RTX (mode);
2284 val = (n < 0) ? -n : n;
2286 memset (cache, 0, sizeof (cache));
2287 cache[1] = x;
2289 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2291 /* If the original exponent was negative, reciprocate the result. */
2292 if (n < 0)
2293 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2294 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2296 return result;
2299 /* Expand a call to the pow built-in mathematical function. Return 0 if
2300 a normal call should be emitted rather than expanding the function
2301 in-line. EXP is the expression that is a call to the builtin
2302 function; if convenient, the result should be placed in TARGET. */
2304 static rtx
2305 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2307 tree arglist = TREE_OPERAND (exp, 1);
2308 tree arg0, arg1;
2310 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2311 return 0;
2313 arg0 = TREE_VALUE (arglist);
2314 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2316 if (TREE_CODE (arg1) == REAL_CST
2317 && ! TREE_CONSTANT_OVERFLOW (arg1))
2319 REAL_VALUE_TYPE cint;
2320 REAL_VALUE_TYPE c;
2321 HOST_WIDE_INT n;
2323 c = TREE_REAL_CST (arg1);
2324 n = real_to_integer (&c);
2325 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2326 if (real_identical (&c, &cint))
2328 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2329 Otherwise, check the number of multiplications required.
2330 Note that pow never sets errno for an integer exponent. */
2331 if ((n >= -1 && n <= 2)
2332 || (flag_unsafe_math_optimizations
2333 && ! optimize_size
2334 && powi_cost (n) <= POWI_MAX_MULTS))
2336 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2337 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2338 op = force_reg (mode, op);
2339 return expand_powi (op, mode, n);
2344 if (! flag_unsafe_math_optimizations)
2345 return NULL_RTX;
2346 return expand_builtin_mathfn_2 (exp, target, subtarget);
2349 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2350 if we failed the caller should emit a normal call, otherwise
2351 try to get the result in TARGET, if convenient. */
2353 static rtx
2354 expand_builtin_strlen (tree arglist, rtx target,
2355 enum machine_mode target_mode)
2357 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2358 return 0;
2359 else
2361 rtx pat;
2362 tree len, src = TREE_VALUE (arglist);
2363 rtx result, src_reg, char_rtx, before_strlen;
2364 enum machine_mode insn_mode = target_mode, char_mode;
2365 enum insn_code icode = CODE_FOR_nothing;
2366 int align;
2368 /* If the length can be computed at compile-time, return it. */
2369 len = c_strlen (src, 0);
2370 if (len)
2371 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2373 /* If the length can be computed at compile-time and is constant
2374 integer, but there are side-effects in src, evaluate
2375 src for side-effects, then return len.
2376 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2377 can be optimized into: i++; x = 3; */
2378 len = c_strlen (src, 1);
2379 if (len && TREE_CODE (len) == INTEGER_CST)
2381 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2382 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2385 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2387 /* If SRC is not a pointer type, don't do this operation inline. */
2388 if (align == 0)
2389 return 0;
2391 /* Bail out if we can't compute strlen in the right mode. */
2392 while (insn_mode != VOIDmode)
2394 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2395 if (icode != CODE_FOR_nothing)
2396 break;
2398 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2400 if (insn_mode == VOIDmode)
2401 return 0;
2403 /* Make a place to write the result of the instruction. */
2404 result = target;
2405 if (! (result != 0
2406 && REG_P (result)
2407 && GET_MODE (result) == insn_mode
2408 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2409 result = gen_reg_rtx (insn_mode);
2411 /* Make a place to hold the source address. We will not expand
2412 the actual source until we are sure that the expansion will
2413 not fail -- there are trees that cannot be expanded twice. */
2414 src_reg = gen_reg_rtx (Pmode);
2416 /* Mark the beginning of the strlen sequence so we can emit the
2417 source operand later. */
2418 before_strlen = get_last_insn ();
2420 char_rtx = const0_rtx;
2421 char_mode = insn_data[(int) icode].operand[2].mode;
2422 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2423 char_mode))
2424 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2426 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2427 char_rtx, GEN_INT (align));
2428 if (! pat)
2429 return 0;
2430 emit_insn (pat);
2432 /* Now that we are assured of success, expand the source. */
2433 start_sequence ();
2434 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2435 if (pat != src_reg)
2436 emit_move_insn (src_reg, pat);
2437 pat = get_insns ();
2438 end_sequence ();
2440 if (before_strlen)
2441 emit_insn_after (pat, before_strlen);
2442 else
2443 emit_insn_before (pat, get_insns ());
2445 /* Return the value in the proper mode for this function. */
2446 if (GET_MODE (result) == target_mode)
2447 target = result;
2448 else if (target != 0)
2449 convert_move (target, result, 0);
2450 else
2451 target = convert_to_mode (target_mode, result, 0);
2453 return target;
2457 /* Expand a call to the strstr builtin. Return 0 if we failed the
2458 caller should emit a normal call, otherwise try to get the result
2459 in TARGET, if convenient (and in mode MODE if that's convenient). */
2461 static rtx
2462 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2464 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2466 tree result = fold_builtin_strstr (arglist);
2467 if (result)
2468 return expand_expr (result, target, mode, EXPAND_NORMAL);
2470 return 0;
2473 /* Expand a call to the strchr builtin. Return 0 if we failed the
2474 caller should emit a normal call, otherwise try to get the result
2475 in TARGET, if convenient (and in mode MODE if that's convenient). */
2477 static rtx
2478 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2480 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2482 tree result = fold_builtin_strchr (arglist);
2483 if (result)
2484 return expand_expr (result, target, mode, EXPAND_NORMAL);
2486 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2488 return 0;
2491 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2492 caller should emit a normal call, otherwise try to get the result
2493 in TARGET, if convenient (and in mode MODE if that's convenient). */
2495 static rtx
2496 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2498 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2500 tree result = fold_builtin_strrchr (arglist);
2501 if (result)
2502 return expand_expr (result, target, mode, EXPAND_NORMAL);
2504 return 0;
2507 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2508 caller should emit a normal call, otherwise try to get the result
2509 in TARGET, if convenient (and in mode MODE if that's convenient). */
2511 static rtx
2512 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2514 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2516 tree result = fold_builtin_strpbrk (arglist);
2517 if (result)
2518 return expand_expr (result, target, mode, EXPAND_NORMAL);
2520 return 0;
2523 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2524 bytes from constant string DATA + OFFSET and return it as target
2525 constant. */
2527 static rtx
2528 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2529 enum machine_mode mode)
2531 const char *str = (const char *) data;
2533 gcc_assert (offset >= 0
2534 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2535 <= strlen (str) + 1));
2537 return c_readstr (str + offset, mode);
2540 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2541 Return 0 if we failed, the caller should emit a normal call,
2542 otherwise try to get the result in TARGET, if convenient (and in
2543 mode MODE if that's convenient). */
2544 static rtx
2545 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2547 tree arglist = TREE_OPERAND (exp, 1);
2548 if (!validate_arglist (arglist,
2549 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2550 return 0;
2551 else
2553 tree dest = TREE_VALUE (arglist);
2554 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2555 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2556 const char *src_str;
2557 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2558 unsigned int dest_align
2559 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2560 rtx dest_mem, src_mem, dest_addr, len_rtx;
2561 tree result = fold_builtin_memcpy (exp);
2563 if (result)
2564 return expand_expr (result, target, mode, EXPAND_NORMAL);
2566 /* If DEST is not a pointer type, call the normal function. */
2567 if (dest_align == 0)
2568 return 0;
2570 /* If either SRC is not a pointer type, don't do this
2571 operation in-line. */
2572 if (src_align == 0)
2573 return 0;
2575 dest_mem = get_memory_rtx (dest);
2576 set_mem_align (dest_mem, dest_align);
2577 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2578 src_str = c_getstr (src);
2580 /* If SRC is a string constant and block move would be done
2581 by pieces, we can avoid loading the string from memory
2582 and only stored the computed constants. */
2583 if (src_str
2584 && GET_CODE (len_rtx) == CONST_INT
2585 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2586 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2587 (void *) src_str, dest_align))
2589 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2590 builtin_memcpy_read_str,
2591 (void *) src_str, dest_align, 0);
2592 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2593 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2594 return dest_mem;
2597 src_mem = get_memory_rtx (src);
2598 set_mem_align (src_mem, src_align);
2600 /* Copy word part most expediently. */
2601 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2602 BLOCK_OP_NORMAL);
2604 if (dest_addr == 0)
2606 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2607 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2609 return dest_addr;
2613 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2614 Return 0 if we failed the caller should emit a normal call,
2615 otherwise try to get the result in TARGET, if convenient (and in
2616 mode MODE if that's convenient). If ENDP is 0 return the
2617 destination pointer, if ENDP is 1 return the end pointer ala
2618 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2619 stpcpy. */
2621 static rtx
2622 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2623 int endp)
2625 if (!validate_arglist (arglist,
2626 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2627 return 0;
2628 /* If return value is ignored, transform mempcpy into memcpy. */
2629 else if (target == const0_rtx)
2631 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2633 if (!fn)
2634 return 0;
2636 return expand_expr (build_function_call_expr (fn, arglist),
2637 target, mode, EXPAND_NORMAL);
2639 else
2641 tree dest = TREE_VALUE (arglist);
2642 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2643 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2644 const char *src_str;
2645 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2646 unsigned int dest_align
2647 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2648 rtx dest_mem, src_mem, len_rtx;
2649 tree result = fold_builtin_mempcpy (arglist, type, endp);
2651 if (result)
2652 return expand_expr (result, target, mode, EXPAND_NORMAL);
2654 /* If either SRC or DEST is not a pointer type, don't do this
2655 operation in-line. */
2656 if (dest_align == 0 || src_align == 0)
2657 return 0;
2659 /* If LEN is not constant, call the normal function. */
2660 if (! host_integerp (len, 1))
2661 return 0;
2663 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2664 src_str = c_getstr (src);
2666 /* If SRC is a string constant and block move would be done
2667 by pieces, we can avoid loading the string from memory
2668 and only stored the computed constants. */
2669 if (src_str
2670 && GET_CODE (len_rtx) == CONST_INT
2671 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2672 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2673 (void *) src_str, dest_align))
2675 dest_mem = get_memory_rtx (dest);
2676 set_mem_align (dest_mem, dest_align);
2677 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2678 builtin_memcpy_read_str,
2679 (void *) src_str, dest_align, endp);
2680 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2681 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2682 return dest_mem;
2685 if (GET_CODE (len_rtx) == CONST_INT
2686 && can_move_by_pieces (INTVAL (len_rtx),
2687 MIN (dest_align, src_align)))
2689 dest_mem = get_memory_rtx (dest);
2690 set_mem_align (dest_mem, dest_align);
2691 src_mem = get_memory_rtx (src);
2692 set_mem_align (src_mem, src_align);
2693 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2694 MIN (dest_align, src_align), endp);
2695 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2696 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2697 return dest_mem;
2700 return 0;
2704 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2705 if we failed the caller should emit a normal call. */
2707 static rtx
2708 expand_builtin_memmove (tree arglist, tree type, rtx target,
2709 enum machine_mode mode)
2711 if (!validate_arglist (arglist,
2712 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2713 return 0;
2714 else
2716 tree dest = TREE_VALUE (arglist);
2717 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2718 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2720 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2721 unsigned int dest_align
2722 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2723 tree result = fold_builtin_memmove (arglist, type);
2725 if (result)
2726 return expand_expr (result, target, mode, EXPAND_NORMAL);
2728 /* If DEST is not a pointer type, call the normal function. */
2729 if (dest_align == 0)
2730 return 0;
2732 /* If either SRC is not a pointer type, don't do this
2733 operation in-line. */
2734 if (src_align == 0)
2735 return 0;
2737 /* If src is categorized for a readonly section we can use
2738 normal memcpy. */
2739 if (readonly_data_expr (src))
2741 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2742 if (!fn)
2743 return 0;
2744 return expand_expr (build_function_call_expr (fn, arglist),
2745 target, mode, EXPAND_NORMAL);
2748 /* If length is 1 and we can expand memcpy call inline,
2749 it is ok to use memcpy as well. */
2750 if (integer_onep (len))
2752 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
2753 /*endp=*/0);
2754 if (ret)
2755 return ret;
2758 /* Otherwise, call the normal function. */
2759 return 0;
2763 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2764 if we failed the caller should emit a normal call. */
2766 static rtx
2767 expand_builtin_bcopy (tree arglist, tree type)
2769 tree src, dest, size, newarglist;
2771 if (!validate_arglist (arglist,
2772 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2773 return NULL_RTX;
2775 src = TREE_VALUE (arglist);
2776 dest = TREE_VALUE (TREE_CHAIN (arglist));
2777 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2779 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2780 memmove(ptr y, ptr x, size_t z). This is done this way
2781 so that if it isn't expanded inline, we fallback to
2782 calling bcopy instead of memmove. */
2784 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2785 newarglist = tree_cons (NULL_TREE, src, newarglist);
2786 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2788 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
2791 #ifndef HAVE_movstr
2792 # define HAVE_movstr 0
2793 # define CODE_FOR_movstr CODE_FOR_nothing
2794 #endif
2796 /* Expand into a movstr instruction, if one is available. Return 0 if
2797 we failed, the caller should emit a normal call, otherwise try to
2798 get the result in TARGET, if convenient. If ENDP is 0 return the
2799 destination pointer, if ENDP is 1 return the end pointer ala
2800 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2801 stpcpy. */
2803 static rtx
2804 expand_movstr (tree dest, tree src, rtx target, int endp)
2806 rtx end;
2807 rtx dest_mem;
2808 rtx src_mem;
2809 rtx insn;
2810 const struct insn_data * data;
2812 if (!HAVE_movstr)
2813 return 0;
2815 dest_mem = get_memory_rtx (dest);
2816 src_mem = get_memory_rtx (src);
2817 if (!endp)
2819 target = force_reg (Pmode, XEXP (dest_mem, 0));
2820 dest_mem = replace_equiv_address (dest_mem, target);
2821 end = gen_reg_rtx (Pmode);
2823 else
2825 if (target == 0 || target == const0_rtx)
2827 end = gen_reg_rtx (Pmode);
2828 if (target == 0)
2829 target = end;
2831 else
2832 end = target;
2835 data = insn_data + CODE_FOR_movstr;
2837 if (data->operand[0].mode != VOIDmode)
2838 end = gen_lowpart (data->operand[0].mode, end);
2840 insn = data->genfun (end, dest_mem, src_mem);
2842 gcc_assert (insn);
2844 emit_insn (insn);
2846 /* movstr is supposed to set end to the address of the NUL
2847 terminator. If the caller requested a mempcpy-like return value,
2848 adjust it. */
2849 if (endp == 1 && target != const0_rtx)
2851 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
2852 emit_move_insn (target, force_operand (tem, NULL_RTX));
2855 return target;
2858 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2859 if we failed the caller should emit a normal call, otherwise try to get
2860 the result in TARGET, if convenient (and in mode MODE if that's
2861 convenient). */
2863 static rtx
2864 expand_builtin_strcpy (tree exp, rtx target, enum machine_mode mode)
2866 tree arglist = TREE_OPERAND (exp, 1);
2867 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2869 tree result = fold_builtin_strcpy (exp, 0);
2870 if (result)
2871 return expand_expr (result, target, mode, EXPAND_NORMAL);
2873 return expand_movstr (TREE_VALUE (arglist),
2874 TREE_VALUE (TREE_CHAIN (arglist)),
2875 target, /*endp=*/0);
2877 return 0;
2880 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2881 Return 0 if we failed the caller should emit a normal call,
2882 otherwise try to get the result in TARGET, if convenient (and in
2883 mode MODE if that's convenient). */
2885 static rtx
2886 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
2888 tree arglist = TREE_OPERAND (exp, 1);
2889 /* If return value is ignored, transform stpcpy into strcpy. */
2890 if (target == const0_rtx)
2892 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2893 if (!fn)
2894 return 0;
2896 return expand_expr (build_function_call_expr (fn, arglist),
2897 target, mode, EXPAND_NORMAL);
2900 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2901 return 0;
2902 else
2904 tree dst, src, len, lenp1;
2905 tree narglist;
2906 rtx ret;
2908 /* Ensure we get an actual string whose length can be evaluated at
2909 compile-time, not an expression containing a string. This is
2910 because the latter will potentially produce pessimized code
2911 when used to produce the return value. */
2912 src = TREE_VALUE (TREE_CHAIN (arglist));
2913 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2914 return expand_movstr (TREE_VALUE (arglist),
2915 TREE_VALUE (TREE_CHAIN (arglist)),
2916 target, /*endp=*/2);
2918 dst = TREE_VALUE (arglist);
2919 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
2920 narglist = build_tree_list (NULL_TREE, lenp1);
2921 narglist = tree_cons (NULL_TREE, src, narglist);
2922 narglist = tree_cons (NULL_TREE, dst, narglist);
2923 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
2924 target, mode, /*endp=*/2);
2926 if (ret)
2927 return ret;
2929 if (TREE_CODE (len) == INTEGER_CST)
2931 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2933 if (GET_CODE (len_rtx) == CONST_INT)
2935 ret = expand_builtin_strcpy (exp, target, mode);
2937 if (ret)
2939 if (! target)
2941 if (mode != VOIDmode)
2942 target = gen_reg_rtx (mode);
2943 else
2944 target = gen_reg_rtx (GET_MODE (ret));
2946 if (GET_MODE (target) != GET_MODE (ret))
2947 ret = gen_lowpart (GET_MODE (target), ret);
2949 ret = plus_constant (ret, INTVAL (len_rtx));
2950 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
2951 gcc_assert (ret);
2953 return target;
2958 return expand_movstr (TREE_VALUE (arglist),
2959 TREE_VALUE (TREE_CHAIN (arglist)),
2960 target, /*endp=*/2);
2964 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2965 bytes from constant string DATA + OFFSET and return it as target
2966 constant. */
2968 static rtx
2969 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2970 enum machine_mode mode)
2972 const char *str = (const char *) data;
2974 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2975 return const0_rtx;
2977 return c_readstr (str + offset, mode);
2980 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2981 if we failed the caller should emit a normal call. */
2983 static rtx
2984 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
2986 tree arglist = TREE_OPERAND (exp, 1);
2987 if (validate_arglist (arglist,
2988 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2990 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2991 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2992 tree result = fold_builtin_strncpy (exp, slen);
2994 if (result)
2995 return expand_expr (result, target, mode, EXPAND_NORMAL);
2997 /* We must be passed a constant len and src parameter. */
2998 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
2999 return 0;
3001 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3003 /* We're required to pad with trailing zeros if the requested
3004 len is greater than strlen(s2)+1. In that case try to
3005 use store_by_pieces, if it fails, punt. */
3006 if (tree_int_cst_lt (slen, len))
3008 tree dest = TREE_VALUE (arglist);
3009 unsigned int dest_align
3010 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3011 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3012 rtx dest_mem;
3014 if (!p || dest_align == 0 || !host_integerp (len, 1)
3015 || !can_store_by_pieces (tree_low_cst (len, 1),
3016 builtin_strncpy_read_str,
3017 (void *) p, dest_align))
3018 return 0;
3020 dest_mem = get_memory_rtx (dest);
3021 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3022 builtin_strncpy_read_str,
3023 (void *) p, dest_align, 0);
3024 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3025 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3026 return dest_mem;
3029 return 0;
3032 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3033 bytes from constant string DATA + OFFSET and return it as target
3034 constant. */
3036 static rtx
3037 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3038 enum machine_mode mode)
3040 const char *c = (const char *) data;
3041 char *p = alloca (GET_MODE_SIZE (mode));
3043 memset (p, *c, GET_MODE_SIZE (mode));
3045 return c_readstr (p, mode);
3048 /* Callback routine for store_by_pieces. Return the RTL of a register
3049 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3050 char value given in the RTL register data. For example, if mode is
3051 4 bytes wide, return the RTL for 0x01010101*data. */
3053 static rtx
3054 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3055 enum machine_mode mode)
3057 rtx target, coeff;
3058 size_t size;
3059 char *p;
3061 size = GET_MODE_SIZE (mode);
3062 if (size == 1)
3063 return (rtx) data;
3065 p = alloca (size);
3066 memset (p, 1, size);
3067 coeff = c_readstr (p, mode);
3069 target = convert_to_mode (mode, (rtx) data, 1);
3070 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3071 return force_reg (mode, target);
3074 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3075 if we failed the caller should emit a normal call, otherwise try to get
3076 the result in TARGET, if convenient (and in mode MODE if that's
3077 convenient). */
3079 static rtx
3080 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3082 if (!validate_arglist (arglist,
3083 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3084 return 0;
3085 else
3087 tree dest = TREE_VALUE (arglist);
3088 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3089 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3090 char c;
3092 unsigned int dest_align
3093 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3094 rtx dest_mem, dest_addr, len_rtx;
3096 /* If DEST is not a pointer type, don't do this
3097 operation in-line. */
3098 if (dest_align == 0)
3099 return 0;
3101 /* If the LEN parameter is zero, return DEST. */
3102 if (integer_zerop (len))
3104 /* Evaluate and ignore VAL in case it has side-effects. */
3105 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3106 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3109 if (TREE_CODE (val) != INTEGER_CST)
3111 rtx val_rtx;
3113 if (!host_integerp (len, 1))
3114 return 0;
3116 if (optimize_size && tree_low_cst (len, 1) > 1)
3117 return 0;
3119 /* Assume that we can memset by pieces if we can store the
3120 * the coefficients by pieces (in the required modes).
3121 * We can't pass builtin_memset_gen_str as that emits RTL. */
3122 c = 1;
3123 if (!can_store_by_pieces (tree_low_cst (len, 1),
3124 builtin_memset_read_str,
3125 &c, dest_align))
3126 return 0;
3128 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3129 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3130 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3131 val_rtx);
3132 dest_mem = get_memory_rtx (dest);
3133 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3134 builtin_memset_gen_str,
3135 val_rtx, dest_align, 0);
3136 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3137 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3138 return dest_mem;
3141 if (target_char_cast (val, &c))
3142 return 0;
3144 if (c)
3146 if (!host_integerp (len, 1))
3147 return 0;
3148 if (!can_store_by_pieces (tree_low_cst (len, 1),
3149 builtin_memset_read_str, &c,
3150 dest_align))
3151 return 0;
3153 dest_mem = get_memory_rtx (dest);
3154 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3155 builtin_memset_read_str,
3156 &c, dest_align, 0);
3157 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3158 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3159 return dest_mem;
3162 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3164 dest_mem = get_memory_rtx (dest);
3165 set_mem_align (dest_mem, dest_align);
3166 dest_addr = clear_storage (dest_mem, len_rtx);
3168 if (dest_addr == 0)
3170 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3171 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3174 return dest_addr;
3178 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3179 if we failed the caller should emit a normal call. */
3181 static rtx
3182 expand_builtin_bzero (tree arglist)
3184 tree dest, size, newarglist;
3186 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3187 return NULL_RTX;
3189 dest = TREE_VALUE (arglist);
3190 size = TREE_VALUE (TREE_CHAIN (arglist));
3192 /* New argument list transforming bzero(ptr x, int y) to
3193 memset(ptr x, int 0, size_t y). This is done this way
3194 so that if it isn't expanded inline, we fallback to
3195 calling bzero instead of memset. */
3197 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3198 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3199 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3201 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3204 /* Expand expression EXP, which is a call to the memcmp built-in function.
3205 ARGLIST is the argument list for this call. Return 0 if we failed and the
3206 caller should emit a normal call, otherwise try to get the result in
3207 TARGET, if convenient (and in mode MODE, if that's convenient). */
3209 static rtx
3210 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3211 enum machine_mode mode)
3213 if (!validate_arglist (arglist,
3214 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3215 return 0;
3216 else
3218 tree result = fold_builtin_memcmp (arglist);
3219 if (result)
3220 return expand_expr (result, target, mode, EXPAND_NORMAL);
3223 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3225 tree arg1 = TREE_VALUE (arglist);
3226 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3227 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3228 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3229 rtx result;
3230 rtx insn;
3232 int arg1_align
3233 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3234 int arg2_align
3235 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3236 enum machine_mode insn_mode;
3238 #ifdef HAVE_cmpmemsi
3239 if (HAVE_cmpmemsi)
3240 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3241 else
3242 #endif
3243 #ifdef HAVE_cmpstrsi
3244 if (HAVE_cmpstrsi)
3245 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3246 else
3247 #endif
3248 return 0;
3250 /* If we don't have POINTER_TYPE, call the function. */
3251 if (arg1_align == 0 || arg2_align == 0)
3252 return 0;
3254 /* Make a place to write the result of the instruction. */
3255 result = target;
3256 if (! (result != 0
3257 && REG_P (result) && GET_MODE (result) == insn_mode
3258 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3259 result = gen_reg_rtx (insn_mode);
3261 arg1_rtx = get_memory_rtx (arg1);
3262 arg2_rtx = get_memory_rtx (arg2);
3263 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3265 /* Set MEM_SIZE as appropriate. */
3266 if (GET_CODE (arg3_rtx) == CONST_INT)
3268 set_mem_size (arg1_rtx, arg3_rtx);
3269 set_mem_size (arg2_rtx, arg3_rtx);
3272 #ifdef HAVE_cmpmemsi
3273 if (HAVE_cmpmemsi)
3274 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3275 GEN_INT (MIN (arg1_align, arg2_align)));
3276 else
3277 #endif
3278 #ifdef HAVE_cmpstrsi
3279 if (HAVE_cmpstrsi)
3280 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3281 GEN_INT (MIN (arg1_align, arg2_align)));
3282 else
3283 #endif
3284 gcc_unreachable ();
3286 if (insn)
3287 emit_insn (insn);
3288 else
3289 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3290 TYPE_MODE (integer_type_node), 3,
3291 XEXP (arg1_rtx, 0), Pmode,
3292 XEXP (arg2_rtx, 0), Pmode,
3293 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3294 TYPE_UNSIGNED (sizetype)),
3295 TYPE_MODE (sizetype));
3297 /* Return the value in the proper mode for this function. */
3298 mode = TYPE_MODE (TREE_TYPE (exp));
3299 if (GET_MODE (result) == mode)
3300 return result;
3301 else if (target != 0)
3303 convert_move (target, result, 0);
3304 return target;
3306 else
3307 return convert_to_mode (mode, result, 0);
3309 #endif
3311 return 0;
3314 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3315 if we failed the caller should emit a normal call, otherwise try to get
3316 the result in TARGET, if convenient. */
3318 static rtx
3319 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3321 tree arglist = TREE_OPERAND (exp, 1);
3323 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3324 return 0;
3325 else
3327 tree result = fold_builtin_strcmp (arglist);
3328 if (result)
3329 return expand_expr (result, target, mode, EXPAND_NORMAL);
3332 #ifdef HAVE_cmpstrsi
3333 if (HAVE_cmpstrsi)
3335 tree arg1 = TREE_VALUE (arglist);
3336 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3337 tree len, len1, len2;
3338 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3339 rtx result, insn;
3340 tree fndecl;
3342 int arg1_align
3343 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3344 int arg2_align
3345 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3346 enum machine_mode insn_mode
3347 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3349 len1 = c_strlen (arg1, 1);
3350 len2 = c_strlen (arg2, 1);
3352 if (len1)
3353 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3354 if (len2)
3355 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3357 /* If we don't have a constant length for the first, use the length
3358 of the second, if we know it. We don't require a constant for
3359 this case; some cost analysis could be done if both are available
3360 but neither is constant. For now, assume they're equally cheap,
3361 unless one has side effects. If both strings have constant lengths,
3362 use the smaller. */
3364 if (!len1)
3365 len = len2;
3366 else if (!len2)
3367 len = len1;
3368 else if (TREE_SIDE_EFFECTS (len1))
3369 len = len2;
3370 else if (TREE_SIDE_EFFECTS (len2))
3371 len = len1;
3372 else if (TREE_CODE (len1) != INTEGER_CST)
3373 len = len2;
3374 else if (TREE_CODE (len2) != INTEGER_CST)
3375 len = len1;
3376 else if (tree_int_cst_lt (len1, len2))
3377 len = len1;
3378 else
3379 len = len2;
3381 /* If both arguments have side effects, we cannot optimize. */
3382 if (!len || TREE_SIDE_EFFECTS (len))
3383 return 0;
3385 /* If we don't have POINTER_TYPE, call the function. */
3386 if (arg1_align == 0 || arg2_align == 0)
3387 return 0;
3389 /* Make a place to write the result of the instruction. */
3390 result = target;
3391 if (! (result != 0
3392 && REG_P (result) && GET_MODE (result) == insn_mode
3393 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3394 result = gen_reg_rtx (insn_mode);
3396 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3397 arg1 = builtin_save_expr (arg1);
3398 arg2 = builtin_save_expr (arg2);
3400 arg1_rtx = get_memory_rtx (arg1);
3401 arg2_rtx = get_memory_rtx (arg2);
3402 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3403 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3404 GEN_INT (MIN (arg1_align, arg2_align)));
3405 if (insn)
3407 emit_insn (insn);
3409 /* Return the value in the proper mode for this function. */
3410 mode = TYPE_MODE (TREE_TYPE (exp));
3411 if (GET_MODE (result) == mode)
3412 return result;
3413 if (target == 0)
3414 return convert_to_mode (mode, result, 0);
3415 convert_move (target, result, 0);
3416 return target;
3419 /* Expand the library call ourselves using a stabilized argument
3420 list to avoid re-evaluating the function's arguments twice. */
3421 arglist = build_tree_list (NULL_TREE, arg2);
3422 arglist = tree_cons (NULL_TREE, arg1, arglist);
3423 fndecl = get_callee_fndecl (exp);
3424 exp = build_function_call_expr (fndecl, arglist);
3425 return expand_call (exp, target, target == const0_rtx);
3427 #endif
3428 return 0;
3431 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3432 if we failed the caller should emit a normal call, otherwise try to get
3433 the result in TARGET, if convenient. */
3435 static rtx
3436 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3438 tree arglist = TREE_OPERAND (exp, 1);
3440 if (!validate_arglist (arglist,
3441 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3442 return 0;
3443 else
3445 tree result = fold_builtin_strncmp (arglist);
3446 if (result)
3447 return expand_expr (result, target, mode, EXPAND_NORMAL);
3450 /* If c_strlen can determine an expression for one of the string
3451 lengths, and it doesn't have side effects, then emit cmpstrsi
3452 using length MIN(strlen(string)+1, arg3). */
3453 #ifdef HAVE_cmpstrsi
3454 if (HAVE_cmpstrsi)
3456 tree arg1 = TREE_VALUE (arglist);
3457 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3458 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3459 tree len, len1, len2;
3460 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3461 rtx result, insn;
3462 tree fndecl;
3464 int arg1_align
3465 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3466 int arg2_align
3467 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3468 enum machine_mode insn_mode
3469 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3471 len1 = c_strlen (arg1, 1);
3472 len2 = c_strlen (arg2, 1);
3474 if (len1)
3475 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3476 if (len2)
3477 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3479 /* If we don't have a constant length for the first, use the length
3480 of the second, if we know it. We don't require a constant for
3481 this case; some cost analysis could be done if both are available
3482 but neither is constant. For now, assume they're equally cheap,
3483 unless one has side effects. If both strings have constant lengths,
3484 use the smaller. */
3486 if (!len1)
3487 len = len2;
3488 else if (!len2)
3489 len = len1;
3490 else if (TREE_SIDE_EFFECTS (len1))
3491 len = len2;
3492 else if (TREE_SIDE_EFFECTS (len2))
3493 len = len1;
3494 else if (TREE_CODE (len1) != INTEGER_CST)
3495 len = len2;
3496 else if (TREE_CODE (len2) != INTEGER_CST)
3497 len = len1;
3498 else if (tree_int_cst_lt (len1, len2))
3499 len = len1;
3500 else
3501 len = len2;
3503 /* If both arguments have side effects, we cannot optimize. */
3504 if (!len || TREE_SIDE_EFFECTS (len))
3505 return 0;
3507 /* The actual new length parameter is MIN(len,arg3). */
3508 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len,
3509 fold_convert (TREE_TYPE (len), arg3)));
3511 /* If we don't have POINTER_TYPE, call the function. */
3512 if (arg1_align == 0 || arg2_align == 0)
3513 return 0;
3515 /* Make a place to write the result of the instruction. */
3516 result = target;
3517 if (! (result != 0
3518 && REG_P (result) && GET_MODE (result) == insn_mode
3519 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3520 result = gen_reg_rtx (insn_mode);
3522 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3523 arg1 = builtin_save_expr (arg1);
3524 arg2 = builtin_save_expr (arg2);
3525 len = builtin_save_expr (len);
3527 arg1_rtx = get_memory_rtx (arg1);
3528 arg2_rtx = get_memory_rtx (arg2);
3529 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3530 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3531 GEN_INT (MIN (arg1_align, arg2_align)));
3532 if (insn)
3534 emit_insn (insn);
3536 /* Return the value in the proper mode for this function. */
3537 mode = TYPE_MODE (TREE_TYPE (exp));
3538 if (GET_MODE (result) == mode)
3539 return result;
3540 if (target == 0)
3541 return convert_to_mode (mode, result, 0);
3542 convert_move (target, result, 0);
3543 return target;
3546 /* Expand the library call ourselves using a stabilized argument
3547 list to avoid re-evaluating the function's arguments twice. */
3548 arglist = build_tree_list (NULL_TREE, len);
3549 arglist = tree_cons (NULL_TREE, arg2, arglist);
3550 arglist = tree_cons (NULL_TREE, arg1, arglist);
3551 fndecl = get_callee_fndecl (exp);
3552 exp = build_function_call_expr (fndecl, arglist);
3553 return expand_call (exp, target, target == const0_rtx);
3555 #endif
3556 return 0;
3559 /* Expand expression EXP, which is a call to the strcat builtin.
3560 Return 0 if we failed the caller should emit a normal call,
3561 otherwise try to get the result in TARGET, if convenient. */
3563 static rtx
3564 expand_builtin_strcat (tree arglist, tree type, rtx target, enum machine_mode mode)
3566 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3567 return 0;
3568 else
3570 tree dst = TREE_VALUE (arglist),
3571 src = TREE_VALUE (TREE_CHAIN (arglist));
3572 const char *p = c_getstr (src);
3574 if (p)
3576 /* If the string length is zero, return the dst parameter. */
3577 if (*p == '\0')
3578 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3579 else if (!optimize_size)
3581 /* Otherwise if !optimize_size, see if we can store by
3582 pieces into (dst + strlen(dst)). */
3583 tree newdst, arglist,
3584 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3586 /* This is the length argument. */
3587 arglist = build_tree_list (NULL_TREE,
3588 fold (size_binop (PLUS_EXPR,
3589 c_strlen (src, 0),
3590 ssize_int (1))));
3591 /* Prepend src argument. */
3592 arglist = tree_cons (NULL_TREE, src, arglist);
3594 /* We're going to use dst more than once. */
3595 dst = builtin_save_expr (dst);
3597 /* Create strlen (dst). */
3598 newdst =
3599 fold (build_function_call_expr (strlen_fn,
3600 build_tree_list (NULL_TREE,
3601 dst)));
3602 /* Create (dst + strlen (dst)). */
3603 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3605 /* Prepend the new dst argument. */
3606 arglist = tree_cons (NULL_TREE, newdst, arglist);
3608 /* We don't want to get turned into a memcpy if the
3609 target is const0_rtx, i.e. when the return value
3610 isn't used. That would produce pessimized code so
3611 pass in a target of zero, it should never actually be
3612 used. If this was successful return the original
3613 dst, not the result of mempcpy. */
3614 if (expand_builtin_mempcpy (arglist, type, /*target=*/0, mode, /*endp=*/0))
3615 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3616 else
3617 return 0;
3621 return 0;
3625 /* Expand expression EXP, which is a call to the strncat builtin.
3626 Return 0 if we failed the caller should emit a normal call,
3627 otherwise try to get the result in TARGET, if convenient. */
3629 static rtx
3630 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3632 if (validate_arglist (arglist,
3633 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3635 tree result = fold_builtin_strncat (arglist);
3636 if (result)
3637 return expand_expr (result, target, mode, EXPAND_NORMAL);
3639 return 0;
3642 /* Expand expression EXP, which is a call to the strspn builtin.
3643 Return 0 if we failed the caller should emit a normal call,
3644 otherwise try to get the result in TARGET, if convenient. */
3646 static rtx
3647 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3649 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3651 tree result = fold_builtin_strspn (arglist);
3652 if (result)
3653 return expand_expr (result, target, mode, EXPAND_NORMAL);
3655 return 0;
3658 /* Expand expression EXP, which is a call to the strcspn builtin.
3659 Return 0 if we failed the caller should emit a normal call,
3660 otherwise try to get the result in TARGET, if convenient. */
3662 static rtx
3663 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3665 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3667 tree result = fold_builtin_strcspn (arglist);
3668 if (result)
3669 return expand_expr (result, target, mode, EXPAND_NORMAL);
3671 return 0;
3674 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3675 if that's convenient. */
3678 expand_builtin_saveregs (void)
3680 rtx val, seq;
3682 /* Don't do __builtin_saveregs more than once in a function.
3683 Save the result of the first call and reuse it. */
3684 if (saveregs_value != 0)
3685 return saveregs_value;
3687 /* When this function is called, it means that registers must be
3688 saved on entry to this function. So we migrate the call to the
3689 first insn of this function. */
3691 start_sequence ();
3693 /* Do whatever the machine needs done in this case. */
3694 val = targetm.calls.expand_builtin_saveregs ();
3696 seq = get_insns ();
3697 end_sequence ();
3699 saveregs_value = val;
3701 /* Put the insns after the NOTE that starts the function. If this
3702 is inside a start_sequence, make the outer-level insn chain current, so
3703 the code is placed at the start of the function. */
3704 push_topmost_sequence ();
3705 emit_insn_after (seq, entry_of_function ());
3706 pop_topmost_sequence ();
3708 return val;
3711 /* __builtin_args_info (N) returns word N of the arg space info
3712 for the current function. The number and meanings of words
3713 is controlled by the definition of CUMULATIVE_ARGS. */
3715 static rtx
3716 expand_builtin_args_info (tree arglist)
3718 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3719 int *word_ptr = (int *) &current_function_args_info;
3721 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
3723 if (arglist != 0)
3725 if (!host_integerp (TREE_VALUE (arglist), 0))
3726 error ("argument of %<__builtin_args_info%> must be constant");
3727 else
3729 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3731 if (wordnum < 0 || wordnum >= nwords)
3732 error ("argument of %<__builtin_args_info%> out of range");
3733 else
3734 return GEN_INT (word_ptr[wordnum]);
3737 else
3738 error ("missing argument in %<__builtin_args_info%>");
3740 return const0_rtx;
3743 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3745 static rtx
3746 expand_builtin_next_arg (tree arglist)
3748 tree fntype = TREE_TYPE (current_function_decl);
3750 if (TYPE_ARG_TYPES (fntype) == 0
3751 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3752 == void_type_node))
3754 error ("%<va_start%> used in function with fixed args");
3755 return const0_rtx;
3758 if (arglist)
3760 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3761 tree arg = TREE_VALUE (arglist);
3763 /* Strip off all nops for the sake of the comparison. This
3764 is not quite the same as STRIP_NOPS. It does more.
3765 We must also strip off INDIRECT_EXPR for C++ reference
3766 parameters. */
3767 while (TREE_CODE (arg) == NOP_EXPR
3768 || TREE_CODE (arg) == CONVERT_EXPR
3769 || TREE_CODE (arg) == NON_LVALUE_EXPR
3770 || TREE_CODE (arg) == INDIRECT_REF)
3771 arg = TREE_OPERAND (arg, 0);
3772 if (arg != last_parm)
3773 warning ("second parameter of %<va_start%> not last named argument");
3775 else
3776 /* Evidently an out of date version of <stdarg.h>; can't validate
3777 va_start's second argument, but can still work as intended. */
3778 warning ("%<__builtin_next_arg%> called without an argument");
3780 return expand_binop (Pmode, add_optab,
3781 current_function_internal_arg_pointer,
3782 current_function_arg_offset_rtx,
3783 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3786 /* Make it easier for the backends by protecting the valist argument
3787 from multiple evaluations. */
3789 static tree
3790 stabilize_va_list (tree valist, int needs_lvalue)
3792 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3794 if (TREE_SIDE_EFFECTS (valist))
3795 valist = save_expr (valist);
3797 /* For this case, the backends will be expecting a pointer to
3798 TREE_TYPE (va_list_type_node), but it's possible we've
3799 actually been given an array (an actual va_list_type_node).
3800 So fix it. */
3801 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3803 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3804 valist = build_fold_addr_expr_with_type (valist, p1);
3807 else
3809 tree pt;
3811 if (! needs_lvalue)
3813 if (! TREE_SIDE_EFFECTS (valist))
3814 return valist;
3816 pt = build_pointer_type (va_list_type_node);
3817 valist = fold (build1 (ADDR_EXPR, pt, valist));
3818 TREE_SIDE_EFFECTS (valist) = 1;
3821 if (TREE_SIDE_EFFECTS (valist))
3822 valist = save_expr (valist);
3823 valist = build_fold_indirect_ref (valist);
3826 return valist;
3829 /* The "standard" definition of va_list is void*. */
3831 tree
3832 std_build_builtin_va_list (void)
3834 return ptr_type_node;
3837 /* The "standard" implementation of va_start: just assign `nextarg' to
3838 the variable. */
3840 void
3841 std_expand_builtin_va_start (tree valist, rtx nextarg)
3843 tree t;
3845 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
3846 make_tree (ptr_type_node, nextarg));
3847 TREE_SIDE_EFFECTS (t) = 1;
3849 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3852 /* Expand ARGLIST, from a call to __builtin_va_start. */
3854 static rtx
3855 expand_builtin_va_start (tree arglist)
3857 rtx nextarg;
3858 tree chain, valist;
3860 chain = TREE_CHAIN (arglist);
3862 if (!chain)
3864 error ("too few arguments to function %<va_start%>");
3865 return const0_rtx;
3867 if (TREE_CHAIN (chain))
3868 error ("too many arguments to function %<va_start%>");
3870 if (fold_builtin_next_arg (chain))
3872 return const0_rtx;
3875 nextarg = expand_builtin_next_arg (chain);
3876 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3878 #ifdef EXPAND_BUILTIN_VA_START
3879 EXPAND_BUILTIN_VA_START (valist, nextarg);
3880 #else
3881 std_expand_builtin_va_start (valist, nextarg);
3882 #endif
3884 return const0_rtx;
3887 /* The "standard" implementation of va_arg: read the value from the
3888 current (padded) address and increment by the (padded) size. */
3890 tree
3891 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3893 tree addr, t, type_size, rounded_size, valist_tmp;
3894 unsigned HOST_WIDE_INT align, boundary;
3895 bool indirect;
3897 #ifdef ARGS_GROW_DOWNWARD
3898 /* All of the alignment and movement below is for args-grow-up machines.
3899 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
3900 implement their own specialized gimplify_va_arg_expr routines. */
3901 gcc_unreachable ();
3902 #endif
3904 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
3905 if (indirect)
3906 type = build_pointer_type (type);
3908 align = PARM_BOUNDARY / BITS_PER_UNIT;
3909 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
3911 /* Hoist the valist value into a temporary for the moment. */
3912 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
3914 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
3915 requires greater alignment, we must perform dynamic alignment. */
3916 if (boundary > align)
3918 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
3919 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3920 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
3921 gimplify_and_add (t, pre_p);
3923 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
3924 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3925 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
3926 gimplify_and_add (t, pre_p);
3929 /* Compute the rounded size of the type. */
3930 type_size = size_in_bytes (type);
3931 rounded_size = round_up (type_size, align);
3933 /* Reduce rounded_size so it's sharable with the postqueue. */
3934 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
3936 /* Get AP. */
3937 addr = valist_tmp;
3938 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
3940 /* Small args are padded downward. */
3941 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
3942 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
3943 size_binop (MINUS_EXPR, rounded_size, type_size)));
3944 t = fold_convert (TREE_TYPE (addr), t);
3945 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
3948 /* Compute new value for AP. */
3949 t = fold_convert (TREE_TYPE (valist), rounded_size);
3950 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
3951 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
3952 gimplify_and_add (t, pre_p);
3954 addr = fold_convert (build_pointer_type (type), addr);
3956 if (indirect)
3957 addr = build_va_arg_indirect_ref (addr);
3959 return build_va_arg_indirect_ref (addr);
3962 /* Build an indirect-ref expression over the given TREE, which represents a
3963 piece of a va_arg() expansion. */
3964 tree
3965 build_va_arg_indirect_ref (tree addr)
3967 addr = build_fold_indirect_ref (addr);
3969 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
3970 mf_mark (addr);
3972 return addr;
3975 /* Return a dummy expression of type TYPE in order to keep going after an
3976 error. */
3978 static tree
3979 dummy_object (tree type)
3981 tree t = convert (build_pointer_type (type), null_pointer_node);
3982 return build1 (INDIRECT_REF, type, t);
3985 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
3986 builtin function, but a very special sort of operator. */
3988 enum gimplify_status
3989 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
3991 tree promoted_type, want_va_type, have_va_type;
3992 tree valist = TREE_OPERAND (*expr_p, 0);
3993 tree type = TREE_TYPE (*expr_p);
3994 tree t;
3996 /* Verify that valist is of the proper type. */
3997 want_va_type = va_list_type_node;
3998 have_va_type = TREE_TYPE (valist);
4000 if (have_va_type == error_mark_node)
4001 return GS_ERROR;
4003 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4005 /* If va_list is an array type, the argument may have decayed
4006 to a pointer type, e.g. by being passed to another function.
4007 In that case, unwrap both types so that we can compare the
4008 underlying records. */
4009 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4010 || TREE_CODE (have_va_type) == POINTER_TYPE)
4012 want_va_type = TREE_TYPE (want_va_type);
4013 have_va_type = TREE_TYPE (have_va_type);
4017 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4019 error ("first argument to %<va_arg%> not of type %<va_list%>");
4020 return GS_ERROR;
4023 /* Generate a diagnostic for requesting data of a type that cannot
4024 be passed through `...' due to type promotion at the call site. */
4025 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4026 != type)
4028 static bool gave_help;
4030 /* Unfortunately, this is merely undefined, rather than a constraint
4031 violation, so we cannot make this an error. If this call is never
4032 executed, the program is still strictly conforming. */
4033 warning ("%qT is promoted to %qT when passed through %<...%>",
4034 type, promoted_type);
4035 if (! gave_help)
4037 gave_help = true;
4038 warning ("(so you should pass %qT not %qT to %<va_arg%>)",
4039 promoted_type, type);
4042 /* We can, however, treat "undefined" any way we please.
4043 Call abort to encourage the user to fix the program. */
4044 inform ("if this code is reached, the program will abort");
4045 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4046 NULL);
4047 append_to_statement_list (t, pre_p);
4049 /* This is dead code, but go ahead and finish so that the
4050 mode of the result comes out right. */
4051 *expr_p = dummy_object (type);
4052 return GS_ALL_DONE;
4054 else
4056 /* Make it easier for the backends by protecting the valist argument
4057 from multiple evaluations. */
4058 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4060 /* For this case, the backends will be expecting a pointer to
4061 TREE_TYPE (va_list_type_node), but it's possible we've
4062 actually been given an array (an actual va_list_type_node).
4063 So fix it. */
4064 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4066 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4067 valist = build_fold_addr_expr_with_type (valist, p1);
4069 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4071 else
4072 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4074 if (!targetm.gimplify_va_arg_expr)
4075 /* Once most targets are converted this should abort. */
4076 return GS_ALL_DONE;
4078 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4079 return GS_OK;
4083 /* Expand ARGLIST, from a call to __builtin_va_end. */
4085 static rtx
4086 expand_builtin_va_end (tree arglist)
4088 tree valist = TREE_VALUE (arglist);
4090 /* Evaluate for side effects, if needed. I hate macros that don't
4091 do that. */
4092 if (TREE_SIDE_EFFECTS (valist))
4093 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4095 return const0_rtx;
4098 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4099 builtin rather than just as an assignment in stdarg.h because of the
4100 nastiness of array-type va_list types. */
4102 static rtx
4103 expand_builtin_va_copy (tree arglist)
4105 tree dst, src, t;
4107 dst = TREE_VALUE (arglist);
4108 src = TREE_VALUE (TREE_CHAIN (arglist));
4110 dst = stabilize_va_list (dst, 1);
4111 src = stabilize_va_list (src, 0);
4113 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4115 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4116 TREE_SIDE_EFFECTS (t) = 1;
4117 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4119 else
4121 rtx dstb, srcb, size;
4123 /* Evaluate to pointers. */
4124 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4125 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4126 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4127 VOIDmode, EXPAND_NORMAL);
4129 dstb = convert_memory_address (Pmode, dstb);
4130 srcb = convert_memory_address (Pmode, srcb);
4132 /* "Dereference" to BLKmode memories. */
4133 dstb = gen_rtx_MEM (BLKmode, dstb);
4134 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4135 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4136 srcb = gen_rtx_MEM (BLKmode, srcb);
4137 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4138 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4140 /* Copy. */
4141 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4144 return const0_rtx;
4147 /* Expand a call to one of the builtin functions __builtin_frame_address or
4148 __builtin_return_address. */
4150 static rtx
4151 expand_builtin_frame_address (tree fndecl, tree arglist)
4153 /* The argument must be a nonnegative integer constant.
4154 It counts the number of frames to scan up the stack.
4155 The value is the return address saved in that frame. */
4156 if (arglist == 0)
4157 /* Warning about missing arg was already issued. */
4158 return const0_rtx;
4159 else if (! host_integerp (TREE_VALUE (arglist), 1))
4161 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4162 error ("invalid argument to %<__builtin_frame_address%>");
4163 else
4164 error ("invalid argument to %<__builtin_return_address%>");
4165 return const0_rtx;
4167 else
4169 rtx tem
4170 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4171 tree_low_cst (TREE_VALUE (arglist), 1),
4172 hard_frame_pointer_rtx);
4174 /* Some ports cannot access arbitrary stack frames. */
4175 if (tem == NULL)
4177 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4178 warning ("unsupported argument to %<__builtin_frame_address%>");
4179 else
4180 warning ("unsupported argument to %<__builtin_return_address%>");
4181 return const0_rtx;
4184 /* For __builtin_frame_address, return what we've got. */
4185 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4186 return tem;
4188 if (!REG_P (tem)
4189 && ! CONSTANT_P (tem))
4190 tem = copy_to_mode_reg (Pmode, tem);
4191 return tem;
4195 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4196 we failed and the caller should emit a normal call, otherwise try to get
4197 the result in TARGET, if convenient. */
4199 static rtx
4200 expand_builtin_alloca (tree arglist, rtx target)
4202 rtx op0;
4203 rtx result;
4205 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4206 should always expand to function calls. These can be intercepted
4207 in libmudflap. */
4208 if (flag_mudflap)
4209 return 0;
4211 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4212 return 0;
4214 /* Compute the argument. */
4215 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4217 /* Allocate the desired space. */
4218 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4219 result = convert_memory_address (ptr_mode, result);
4221 return result;
4224 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4225 Return 0 if a normal call should be emitted rather than expanding the
4226 function in-line. If convenient, the result should be placed in TARGET.
4227 SUBTARGET may be used as the target for computing one of EXP's operands. */
4229 static rtx
4230 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4231 rtx subtarget, optab op_optab)
4233 rtx op0;
4234 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4235 return 0;
4237 /* Compute the argument. */
4238 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4239 /* Compute op, into TARGET if possible.
4240 Set TARGET to wherever the result comes back. */
4241 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4242 op_optab, op0, target, 1);
4243 gcc_assert (target);
4245 return convert_to_mode (target_mode, target, 0);
4248 /* If the string passed to fputs is a constant and is one character
4249 long, we attempt to transform this call into __builtin_fputc(). */
4251 static rtx
4252 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4254 /* Verify the arguments in the original call. */
4255 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4257 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4258 unlocked, NULL_TREE);
4259 if (result)
4260 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4262 return 0;
4265 /* Expand a call to __builtin_expect. We return our argument and emit a
4266 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4267 a non-jump context. */
4269 static rtx
4270 expand_builtin_expect (tree arglist, rtx target)
4272 tree exp, c;
4273 rtx note, rtx_c;
4275 if (arglist == NULL_TREE
4276 || TREE_CHAIN (arglist) == NULL_TREE)
4277 return const0_rtx;
4278 exp = TREE_VALUE (arglist);
4279 c = TREE_VALUE (TREE_CHAIN (arglist));
4281 if (TREE_CODE (c) != INTEGER_CST)
4283 error ("second argument to %<__builtin_expect%> must be a constant");
4284 c = integer_zero_node;
4287 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4289 /* Don't bother with expected value notes for integral constants. */
4290 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4292 /* We do need to force this into a register so that we can be
4293 moderately sure to be able to correctly interpret the branch
4294 condition later. */
4295 target = force_reg (GET_MODE (target), target);
4297 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4299 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4300 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4303 return target;
4306 /* Like expand_builtin_expect, except do this in a jump context. This is
4307 called from do_jump if the conditional is a __builtin_expect. Return either
4308 a list of insns to emit the jump or NULL if we cannot optimize
4309 __builtin_expect. We need to optimize this at jump time so that machines
4310 like the PowerPC don't turn the test into a SCC operation, and then jump
4311 based on the test being 0/1. */
4314 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4316 tree arglist = TREE_OPERAND (exp, 1);
4317 tree arg0 = TREE_VALUE (arglist);
4318 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4319 rtx ret = NULL_RTX;
4321 /* Only handle __builtin_expect (test, 0) and
4322 __builtin_expect (test, 1). */
4323 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4324 && (integer_zerop (arg1) || integer_onep (arg1)))
4326 rtx insn, drop_through_label, temp;
4328 /* Expand the jump insns. */
4329 start_sequence ();
4330 do_jump (arg0, if_false_label, if_true_label);
4331 ret = get_insns ();
4333 drop_through_label = get_last_insn ();
4334 if (drop_through_label && NOTE_P (drop_through_label))
4335 drop_through_label = prev_nonnote_insn (drop_through_label);
4336 if (drop_through_label && !LABEL_P (drop_through_label))
4337 drop_through_label = NULL_RTX;
4338 end_sequence ();
4340 if (! if_true_label)
4341 if_true_label = drop_through_label;
4342 if (! if_false_label)
4343 if_false_label = drop_through_label;
4345 /* Go through and add the expect's to each of the conditional jumps. */
4346 insn = ret;
4347 while (insn != NULL_RTX)
4349 rtx next = NEXT_INSN (insn);
4351 if (JUMP_P (insn) && any_condjump_p (insn))
4353 rtx ifelse = SET_SRC (pc_set (insn));
4354 rtx then_dest = XEXP (ifelse, 1);
4355 rtx else_dest = XEXP (ifelse, 2);
4356 int taken = -1;
4358 /* First check if we recognize any of the labels. */
4359 if (GET_CODE (then_dest) == LABEL_REF
4360 && XEXP (then_dest, 0) == if_true_label)
4361 taken = 1;
4362 else if (GET_CODE (then_dest) == LABEL_REF
4363 && XEXP (then_dest, 0) == if_false_label)
4364 taken = 0;
4365 else if (GET_CODE (else_dest) == LABEL_REF
4366 && XEXP (else_dest, 0) == if_false_label)
4367 taken = 1;
4368 else if (GET_CODE (else_dest) == LABEL_REF
4369 && XEXP (else_dest, 0) == if_true_label)
4370 taken = 0;
4371 /* Otherwise check where we drop through. */
4372 else if (else_dest == pc_rtx)
4374 if (next && NOTE_P (next))
4375 next = next_nonnote_insn (next);
4377 if (next && JUMP_P (next)
4378 && any_uncondjump_p (next))
4379 temp = XEXP (SET_SRC (pc_set (next)), 0);
4380 else
4381 temp = next;
4383 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4384 else that can't possibly match either target label. */
4385 if (temp == if_false_label)
4386 taken = 1;
4387 else if (temp == if_true_label)
4388 taken = 0;
4390 else if (then_dest == pc_rtx)
4392 if (next && NOTE_P (next))
4393 next = next_nonnote_insn (next);
4395 if (next && JUMP_P (next)
4396 && any_uncondjump_p (next))
4397 temp = XEXP (SET_SRC (pc_set (next)), 0);
4398 else
4399 temp = next;
4401 if (temp == if_false_label)
4402 taken = 0;
4403 else if (temp == if_true_label)
4404 taken = 1;
4407 if (taken != -1)
4409 /* If the test is expected to fail, reverse the
4410 probabilities. */
4411 if (integer_zerop (arg1))
4412 taken = 1 - taken;
4413 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4417 insn = next;
4421 return ret;
4424 static void
4425 expand_builtin_trap (void)
4427 #ifdef HAVE_trap
4428 if (HAVE_trap)
4429 emit_insn (gen_trap ());
4430 else
4431 #endif
4432 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4433 emit_barrier ();
4436 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4437 Return 0 if a normal call should be emitted rather than expanding
4438 the function inline. If convenient, the result should be placed
4439 in TARGET. SUBTARGET may be used as the target for computing
4440 the operand. */
4442 static rtx
4443 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4445 enum machine_mode mode;
4446 tree arg;
4447 rtx op0;
4449 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4450 return 0;
4452 arg = TREE_VALUE (arglist);
4453 mode = TYPE_MODE (TREE_TYPE (arg));
4454 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4455 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4458 /* Create a new constant string literal and return a char* pointer to it.
4459 The STRING_CST value is the LEN characters at STR. */
4460 static tree
4461 build_string_literal (int len, const char *str)
4463 tree t, elem, index, type;
4465 t = build_string (len, str);
4466 elem = build_type_variant (char_type_node, 1, 0);
4467 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4468 type = build_array_type (elem, index);
4469 TREE_TYPE (t) = type;
4470 TREE_CONSTANT (t) = 1;
4471 TREE_INVARIANT (t) = 1;
4472 TREE_READONLY (t) = 1;
4473 TREE_STATIC (t) = 1;
4475 type = build_pointer_type (type);
4476 t = build1 (ADDR_EXPR, type, t);
4478 type = build_pointer_type (elem);
4479 t = build1 (NOP_EXPR, type, t);
4480 return t;
4483 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4484 Return 0 if a normal call should be emitted rather than transforming
4485 the function inline. If convenient, the result should be placed in
4486 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4487 call. */
4488 static rtx
4489 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4490 bool unlocked)
4492 tree fn_putchar = unlocked
4493 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4494 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4495 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4496 : implicit_built_in_decls[BUILT_IN_PUTS];
4497 const char *fmt_str;
4498 tree fn, fmt, arg;
4500 /* If the return value is used, don't do the transformation. */
4501 if (target != const0_rtx)
4502 return 0;
4504 /* Verify the required arguments in the original call. */
4505 if (! arglist)
4506 return 0;
4507 fmt = TREE_VALUE (arglist);
4508 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4509 return 0;
4510 arglist = TREE_CHAIN (arglist);
4512 /* Check whether the format is a literal string constant. */
4513 fmt_str = c_getstr (fmt);
4514 if (fmt_str == NULL)
4515 return 0;
4517 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4518 if (strcmp (fmt_str, "%s\n") == 0)
4520 if (! arglist
4521 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4522 || TREE_CHAIN (arglist))
4523 return 0;
4524 fn = fn_puts;
4526 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4527 else if (strcmp (fmt_str, "%c") == 0)
4529 if (! arglist
4530 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4531 || TREE_CHAIN (arglist))
4532 return 0;
4533 fn = fn_putchar;
4535 else
4537 /* We can't handle anything else with % args or %% ... yet. */
4538 if (strchr (fmt_str, '%'))
4539 return 0;
4541 if (arglist)
4542 return 0;
4544 /* If the format specifier was "", printf does nothing. */
4545 if (fmt_str[0] == '\0')
4546 return const0_rtx;
4547 /* If the format specifier has length of 1, call putchar. */
4548 if (fmt_str[1] == '\0')
4550 /* Given printf("c"), (where c is any one character,)
4551 convert "c"[0] to an int and pass that to the replacement
4552 function. */
4553 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4554 arglist = build_tree_list (NULL_TREE, arg);
4555 fn = fn_putchar;
4557 else
4559 /* If the format specifier was "string\n", call puts("string"). */
4560 size_t len = strlen (fmt_str);
4561 if (fmt_str[len - 1] == '\n')
4563 /* Create a NUL-terminated string that's one char shorter
4564 than the original, stripping off the trailing '\n'. */
4565 char *newstr = alloca (len);
4566 memcpy (newstr, fmt_str, len - 1);
4567 newstr[len - 1] = 0;
4569 arg = build_string_literal (len, newstr);
4570 arglist = build_tree_list (NULL_TREE, arg);
4571 fn = fn_puts;
4573 else
4574 /* We'd like to arrange to call fputs(string,stdout) here,
4575 but we need stdout and don't have a way to get it yet. */
4576 return 0;
4580 if (!fn)
4581 return 0;
4582 return expand_expr (build_function_call_expr (fn, arglist),
4583 target, mode, EXPAND_NORMAL);
4586 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4587 Return 0 if a normal call should be emitted rather than transforming
4588 the function inline. If convenient, the result should be placed in
4589 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4590 call. */
4591 static rtx
4592 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4593 bool unlocked)
4595 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4596 : implicit_built_in_decls[BUILT_IN_FPUTC];
4597 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4598 : implicit_built_in_decls[BUILT_IN_FPUTS];
4599 const char *fmt_str;
4600 tree fn, fmt, fp, arg;
4602 /* If the return value is used, don't do the transformation. */
4603 if (target != const0_rtx)
4604 return 0;
4606 /* Verify the required arguments in the original call. */
4607 if (! arglist)
4608 return 0;
4609 fp = TREE_VALUE (arglist);
4610 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4611 return 0;
4612 arglist = TREE_CHAIN (arglist);
4613 if (! arglist)
4614 return 0;
4615 fmt = TREE_VALUE (arglist);
4616 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4617 return 0;
4618 arglist = TREE_CHAIN (arglist);
4620 /* Check whether the format is a literal string constant. */
4621 fmt_str = c_getstr (fmt);
4622 if (fmt_str == NULL)
4623 return 0;
4625 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4626 if (strcmp (fmt_str, "%s") == 0)
4628 if (! arglist
4629 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4630 || TREE_CHAIN (arglist))
4631 return 0;
4632 arg = TREE_VALUE (arglist);
4633 arglist = build_tree_list (NULL_TREE, fp);
4634 arglist = tree_cons (NULL_TREE, arg, arglist);
4635 fn = fn_fputs;
4637 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4638 else if (strcmp (fmt_str, "%c") == 0)
4640 if (! arglist
4641 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4642 || TREE_CHAIN (arglist))
4643 return 0;
4644 arg = TREE_VALUE (arglist);
4645 arglist = build_tree_list (NULL_TREE, fp);
4646 arglist = tree_cons (NULL_TREE, arg, arglist);
4647 fn = fn_fputc;
4649 else
4651 /* We can't handle anything else with % args or %% ... yet. */
4652 if (strchr (fmt_str, '%'))
4653 return 0;
4655 if (arglist)
4656 return 0;
4658 /* If the format specifier was "", fprintf does nothing. */
4659 if (fmt_str[0] == '\0')
4661 /* Evaluate and ignore FILE* argument for side-effects. */
4662 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4663 return const0_rtx;
4666 /* When "string" doesn't contain %, replace all cases of
4667 fprintf(stream,string) with fputs(string,stream). The fputs
4668 builtin will take care of special cases like length == 1. */
4669 arglist = build_tree_list (NULL_TREE, fp);
4670 arglist = tree_cons (NULL_TREE, fmt, arglist);
4671 fn = fn_fputs;
4674 if (!fn)
4675 return 0;
4676 return expand_expr (build_function_call_expr (fn, arglist),
4677 target, mode, EXPAND_NORMAL);
4680 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4681 a normal call should be emitted rather than expanding the function
4682 inline. If convenient, the result should be placed in TARGET with
4683 mode MODE. */
4685 static rtx
4686 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4688 tree orig_arglist, dest, fmt;
4689 const char *fmt_str;
4691 orig_arglist = arglist;
4693 /* Verify the required arguments in the original call. */
4694 if (! arglist)
4695 return 0;
4696 dest = TREE_VALUE (arglist);
4697 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4698 return 0;
4699 arglist = TREE_CHAIN (arglist);
4700 if (! arglist)
4701 return 0;
4702 fmt = TREE_VALUE (arglist);
4703 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4704 return 0;
4705 arglist = TREE_CHAIN (arglist);
4707 /* Check whether the format is a literal string constant. */
4708 fmt_str = c_getstr (fmt);
4709 if (fmt_str == NULL)
4710 return 0;
4712 /* If the format doesn't contain % args or %%, use strcpy. */
4713 if (strchr (fmt_str, '%') == 0)
4715 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4716 tree exp;
4718 if (arglist || ! fn)
4719 return 0;
4720 expand_expr (build_function_call_expr (fn, orig_arglist),
4721 const0_rtx, VOIDmode, EXPAND_NORMAL);
4722 if (target == const0_rtx)
4723 return const0_rtx;
4724 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
4725 return expand_expr (exp, target, mode, EXPAND_NORMAL);
4727 /* If the format is "%s", use strcpy if the result isn't used. */
4728 else if (strcmp (fmt_str, "%s") == 0)
4730 tree fn, arg, len;
4731 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4733 if (! fn)
4734 return 0;
4736 if (! arglist || TREE_CHAIN (arglist))
4737 return 0;
4738 arg = TREE_VALUE (arglist);
4739 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4740 return 0;
4742 if (target != const0_rtx)
4744 len = c_strlen (arg, 1);
4745 if (! len || TREE_CODE (len) != INTEGER_CST)
4746 return 0;
4748 else
4749 len = NULL_TREE;
4751 arglist = build_tree_list (NULL_TREE, arg);
4752 arglist = tree_cons (NULL_TREE, dest, arglist);
4753 expand_expr (build_function_call_expr (fn, arglist),
4754 const0_rtx, VOIDmode, EXPAND_NORMAL);
4756 if (target == const0_rtx)
4757 return const0_rtx;
4758 return expand_expr (len, target, mode, EXPAND_NORMAL);
4761 return 0;
4764 /* Expand a call to either the entry or exit function profiler. */
4766 static rtx
4767 expand_builtin_profile_func (bool exitp)
4769 rtx this, which;
4771 this = DECL_RTL (current_function_decl);
4772 gcc_assert (MEM_P (this));
4773 this = XEXP (this, 0);
4775 if (exitp)
4776 which = profile_function_exit_libfunc;
4777 else
4778 which = profile_function_entry_libfunc;
4780 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
4781 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
4782 0, hard_frame_pointer_rtx),
4783 Pmode);
4785 return const0_rtx;
4788 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
4790 static rtx
4791 round_trampoline_addr (rtx tramp)
4793 rtx temp, addend, mask;
4795 /* If we don't need too much alignment, we'll have been guaranteed
4796 proper alignment by get_trampoline_type. */
4797 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4798 return tramp;
4800 /* Round address up to desired boundary. */
4801 temp = gen_reg_rtx (Pmode);
4802 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4803 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4805 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
4806 temp, 0, OPTAB_LIB_WIDEN);
4807 tramp = expand_simple_binop (Pmode, AND, temp, mask,
4808 temp, 0, OPTAB_LIB_WIDEN);
4810 return tramp;
4813 static rtx
4814 expand_builtin_init_trampoline (tree arglist)
4816 tree t_tramp, t_func, t_chain;
4817 rtx r_tramp, r_func, r_chain;
4818 #ifdef TRAMPOLINE_TEMPLATE
4819 rtx blktramp;
4820 #endif
4822 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
4823 POINTER_TYPE, VOID_TYPE))
4824 return NULL_RTX;
4826 t_tramp = TREE_VALUE (arglist);
4827 arglist = TREE_CHAIN (arglist);
4828 t_func = TREE_VALUE (arglist);
4829 arglist = TREE_CHAIN (arglist);
4830 t_chain = TREE_VALUE (arglist);
4832 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
4833 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
4834 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
4836 /* Generate insns to initialize the trampoline. */
4837 r_tramp = round_trampoline_addr (r_tramp);
4838 #ifdef TRAMPOLINE_TEMPLATE
4839 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
4840 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
4841 emit_block_move (blktramp, assemble_trampoline_template (),
4842 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4843 #endif
4844 trampolines_created = 1;
4845 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
4847 return const0_rtx;
4850 static rtx
4851 expand_builtin_adjust_trampoline (tree arglist)
4853 rtx tramp;
4855 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4856 return NULL_RTX;
4858 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4859 tramp = round_trampoline_addr (tramp);
4860 #ifdef TRAMPOLINE_ADJUST_ADDRESS
4861 TRAMPOLINE_ADJUST_ADDRESS (tramp);
4862 #endif
4864 return tramp;
4867 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4868 Return NULL_RTX if a normal call should be emitted rather than expanding
4869 the function in-line. EXP is the expression that is a call to the builtin
4870 function; if convenient, the result should be placed in TARGET. */
4872 static rtx
4873 expand_builtin_signbit (tree exp, rtx target)
4875 const struct real_format *fmt;
4876 enum machine_mode fmode, imode, rmode;
4877 HOST_WIDE_INT hi, lo;
4878 tree arg, arglist;
4879 int bitpos;
4880 rtx temp;
4882 arglist = TREE_OPERAND (exp, 1);
4883 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4884 return 0;
4886 arg = TREE_VALUE (arglist);
4887 fmode = TYPE_MODE (TREE_TYPE (arg));
4888 rmode = TYPE_MODE (TREE_TYPE (exp));
4889 fmt = REAL_MODE_FORMAT (fmode);
4891 /* For floating point formats without a sign bit, implement signbit
4892 as "ARG < 0.0". */
4893 if (fmt->signbit < 0)
4895 /* But we can't do this if the format supports signed zero. */
4896 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4897 return 0;
4899 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
4900 build_real (TREE_TYPE (arg), dconst0)));
4901 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4904 imode = int_mode_for_mode (fmode);
4905 if (imode == BLKmode)
4906 return 0;
4908 bitpos = fmt->signbit;
4909 /* Handle targets with different FP word orders. */
4910 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4912 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4913 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4914 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4917 /* If the sign bit is not in the lowpart and the floating point format
4918 is wider than an integer, check that is twice the size of an integer
4919 so that we can use gen_highpart below. */
4920 if (bitpos >= GET_MODE_BITSIZE (rmode)
4921 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4922 return 0;
4924 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4925 temp = gen_lowpart (imode, temp);
4927 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4929 if (BYTES_BIG_ENDIAN)
4930 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
4931 temp = copy_to_mode_reg (imode, temp);
4932 temp = extract_bit_field (temp, 1, bitpos, 1,
4933 NULL_RTX, rmode, rmode);
4935 else
4937 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
4938 temp = gen_lowpart (rmode, temp);
4939 if (bitpos < HOST_BITS_PER_WIDE_INT)
4941 hi = 0;
4942 lo = (HOST_WIDE_INT) 1 << bitpos;
4944 else
4946 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
4947 lo = 0;
4950 temp = force_reg (rmode, temp);
4951 temp = expand_binop (rmode, and_optab, temp,
4952 immed_double_const (lo, hi, rmode),
4953 target, 1, OPTAB_LIB_WIDEN);
4955 return temp;
4958 /* Expand fork or exec calls. TARGET is the desired target of the
4959 call. ARGLIST is the list of arguments of the call. FN is the
4960 identificator of the actual function. IGNORE is nonzero if the
4961 value is to be ignored. */
4963 static rtx
4964 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
4966 tree id, decl;
4967 tree call;
4969 /* If we are not profiling, just call the function. */
4970 if (!profile_arc_flag)
4971 return NULL_RTX;
4973 /* Otherwise call the wrapper. This should be equivalent for the rest of
4974 compiler, so the code does not diverge, and the wrapper may run the
4975 code necessary for keeping the profiling sane. */
4977 switch (DECL_FUNCTION_CODE (fn))
4979 case BUILT_IN_FORK:
4980 id = get_identifier ("__gcov_fork");
4981 break;
4983 case BUILT_IN_EXECL:
4984 id = get_identifier ("__gcov_execl");
4985 break;
4987 case BUILT_IN_EXECV:
4988 id = get_identifier ("__gcov_execv");
4989 break;
4991 case BUILT_IN_EXECLP:
4992 id = get_identifier ("__gcov_execlp");
4993 break;
4995 case BUILT_IN_EXECLE:
4996 id = get_identifier ("__gcov_execle");
4997 break;
4999 case BUILT_IN_EXECVP:
5000 id = get_identifier ("__gcov_execvp");
5001 break;
5003 case BUILT_IN_EXECVE:
5004 id = get_identifier ("__gcov_execve");
5005 break;
5007 default:
5008 gcc_unreachable ();
5011 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5012 DECL_EXTERNAL (decl) = 1;
5013 TREE_PUBLIC (decl) = 1;
5014 DECL_ARTIFICIAL (decl) = 1;
5015 TREE_NOTHROW (decl) = 1;
5016 call = build_function_call_expr (decl, arglist);
5018 return expand_call (call, target, ignore);
5021 /* Expand an expression EXP that calls a built-in function,
5022 with result going to TARGET if that's convenient
5023 (and in mode MODE if that's convenient).
5024 SUBTARGET may be used as the target for computing one of EXP's operands.
5025 IGNORE is nonzero if the value is to be ignored. */
5028 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5029 int ignore)
5031 tree fndecl = get_callee_fndecl (exp);
5032 tree arglist = TREE_OPERAND (exp, 1);
5033 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5034 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5036 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5037 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5039 /* When not optimizing, generate calls to library functions for a certain
5040 set of builtins. */
5041 if (!optimize
5042 && !CALLED_AS_BUILT_IN (fndecl)
5043 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5044 && fcode != BUILT_IN_ALLOCA)
5045 return expand_call (exp, target, ignore);
5047 /* The built-in function expanders test for target == const0_rtx
5048 to determine whether the function's result will be ignored. */
5049 if (ignore)
5050 target = const0_rtx;
5052 /* If the result of a pure or const built-in function is ignored, and
5053 none of its arguments are volatile, we can avoid expanding the
5054 built-in call and just evaluate the arguments for side-effects. */
5055 if (target == const0_rtx
5056 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5058 bool volatilep = false;
5059 tree arg;
5061 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5062 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5064 volatilep = true;
5065 break;
5068 if (! volatilep)
5070 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5071 expand_expr (TREE_VALUE (arg), const0_rtx,
5072 VOIDmode, EXPAND_NORMAL);
5073 return const0_rtx;
5077 switch (fcode)
5079 case BUILT_IN_FABS:
5080 case BUILT_IN_FABSF:
5081 case BUILT_IN_FABSL:
5082 target = expand_builtin_fabs (arglist, target, subtarget);
5083 if (target)
5084 return target;
5085 break;
5087 /* Just do a normal library call if we were unable to fold
5088 the values. */
5089 case BUILT_IN_CABS:
5090 case BUILT_IN_CABSF:
5091 case BUILT_IN_CABSL:
5092 break;
5094 case BUILT_IN_EXP:
5095 case BUILT_IN_EXPF:
5096 case BUILT_IN_EXPL:
5097 case BUILT_IN_EXP10:
5098 case BUILT_IN_EXP10F:
5099 case BUILT_IN_EXP10L:
5100 case BUILT_IN_POW10:
5101 case BUILT_IN_POW10F:
5102 case BUILT_IN_POW10L:
5103 case BUILT_IN_EXP2:
5104 case BUILT_IN_EXP2F:
5105 case BUILT_IN_EXP2L:
5106 case BUILT_IN_EXPM1:
5107 case BUILT_IN_EXPM1F:
5108 case BUILT_IN_EXPM1L:
5109 case BUILT_IN_LOGB:
5110 case BUILT_IN_LOGBF:
5111 case BUILT_IN_LOGBL:
5112 case BUILT_IN_ILOGB:
5113 case BUILT_IN_ILOGBF:
5114 case BUILT_IN_ILOGBL:
5115 case BUILT_IN_LOG:
5116 case BUILT_IN_LOGF:
5117 case BUILT_IN_LOGL:
5118 case BUILT_IN_LOG10:
5119 case BUILT_IN_LOG10F:
5120 case BUILT_IN_LOG10L:
5121 case BUILT_IN_LOG2:
5122 case BUILT_IN_LOG2F:
5123 case BUILT_IN_LOG2L:
5124 case BUILT_IN_LOG1P:
5125 case BUILT_IN_LOG1PF:
5126 case BUILT_IN_LOG1PL:
5127 case BUILT_IN_TAN:
5128 case BUILT_IN_TANF:
5129 case BUILT_IN_TANL:
5130 case BUILT_IN_ASIN:
5131 case BUILT_IN_ASINF:
5132 case BUILT_IN_ASINL:
5133 case BUILT_IN_ACOS:
5134 case BUILT_IN_ACOSF:
5135 case BUILT_IN_ACOSL:
5136 case BUILT_IN_ATAN:
5137 case BUILT_IN_ATANF:
5138 case BUILT_IN_ATANL:
5139 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5140 because of possible accuracy problems. */
5141 if (! flag_unsafe_math_optimizations)
5142 break;
5143 case BUILT_IN_SQRT:
5144 case BUILT_IN_SQRTF:
5145 case BUILT_IN_SQRTL:
5146 case BUILT_IN_FLOOR:
5147 case BUILT_IN_FLOORF:
5148 case BUILT_IN_FLOORL:
5149 case BUILT_IN_CEIL:
5150 case BUILT_IN_CEILF:
5151 case BUILT_IN_CEILL:
5152 case BUILT_IN_TRUNC:
5153 case BUILT_IN_TRUNCF:
5154 case BUILT_IN_TRUNCL:
5155 case BUILT_IN_ROUND:
5156 case BUILT_IN_ROUNDF:
5157 case BUILT_IN_ROUNDL:
5158 case BUILT_IN_NEARBYINT:
5159 case BUILT_IN_NEARBYINTF:
5160 case BUILT_IN_NEARBYINTL:
5161 case BUILT_IN_RINT:
5162 case BUILT_IN_RINTF:
5163 case BUILT_IN_RINTL:
5164 target = expand_builtin_mathfn (exp, target, subtarget);
5165 if (target)
5166 return target;
5167 break;
5169 case BUILT_IN_POW:
5170 case BUILT_IN_POWF:
5171 case BUILT_IN_POWL:
5172 target = expand_builtin_pow (exp, target, subtarget);
5173 if (target)
5174 return target;
5175 break;
5177 case BUILT_IN_ATAN2:
5178 case BUILT_IN_ATAN2F:
5179 case BUILT_IN_ATAN2L:
5180 case BUILT_IN_FMOD:
5181 case BUILT_IN_FMODF:
5182 case BUILT_IN_FMODL:
5183 case BUILT_IN_DREM:
5184 case BUILT_IN_DREMF:
5185 case BUILT_IN_DREML:
5186 if (! flag_unsafe_math_optimizations)
5187 break;
5188 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5189 if (target)
5190 return target;
5191 break;
5193 case BUILT_IN_SIN:
5194 case BUILT_IN_SINF:
5195 case BUILT_IN_SINL:
5196 case BUILT_IN_COS:
5197 case BUILT_IN_COSF:
5198 case BUILT_IN_COSL:
5199 if (! flag_unsafe_math_optimizations)
5200 break;
5201 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5202 if (target)
5203 return target;
5204 break;
5206 case BUILT_IN_APPLY_ARGS:
5207 return expand_builtin_apply_args ();
5209 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5210 FUNCTION with a copy of the parameters described by
5211 ARGUMENTS, and ARGSIZE. It returns a block of memory
5212 allocated on the stack into which is stored all the registers
5213 that might possibly be used for returning the result of a
5214 function. ARGUMENTS is the value returned by
5215 __builtin_apply_args. ARGSIZE is the number of bytes of
5216 arguments that must be copied. ??? How should this value be
5217 computed? We'll also need a safe worst case value for varargs
5218 functions. */
5219 case BUILT_IN_APPLY:
5220 if (!validate_arglist (arglist, POINTER_TYPE,
5221 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5222 && !validate_arglist (arglist, REFERENCE_TYPE,
5223 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5224 return const0_rtx;
5225 else
5227 int i;
5228 tree t;
5229 rtx ops[3];
5231 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5232 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5234 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5237 /* __builtin_return (RESULT) causes the function to return the
5238 value described by RESULT. RESULT is address of the block of
5239 memory returned by __builtin_apply. */
5240 case BUILT_IN_RETURN:
5241 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5242 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5243 NULL_RTX, VOIDmode, 0));
5244 return const0_rtx;
5246 case BUILT_IN_SAVEREGS:
5247 return expand_builtin_saveregs ();
5249 case BUILT_IN_ARGS_INFO:
5250 return expand_builtin_args_info (arglist);
5252 /* Return the address of the first anonymous stack arg. */
5253 case BUILT_IN_NEXT_ARG:
5254 if (fold_builtin_next_arg (arglist))
5255 return const0_rtx;
5256 return expand_builtin_next_arg (arglist);
5258 case BUILT_IN_CLASSIFY_TYPE:
5259 return expand_builtin_classify_type (arglist);
5261 case BUILT_IN_CONSTANT_P:
5262 return const0_rtx;
5264 case BUILT_IN_FRAME_ADDRESS:
5265 case BUILT_IN_RETURN_ADDRESS:
5266 return expand_builtin_frame_address (fndecl, arglist);
5268 /* Returns the address of the area where the structure is returned.
5269 0 otherwise. */
5270 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5271 if (arglist != 0
5272 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5273 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5274 return const0_rtx;
5275 else
5276 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5278 case BUILT_IN_ALLOCA:
5279 target = expand_builtin_alloca (arglist, target);
5280 if (target)
5281 return target;
5282 break;
5284 case BUILT_IN_STACK_SAVE:
5285 return expand_stack_save ();
5287 case BUILT_IN_STACK_RESTORE:
5288 expand_stack_restore (TREE_VALUE (arglist));
5289 return const0_rtx;
5291 case BUILT_IN_FFS:
5292 case BUILT_IN_FFSL:
5293 case BUILT_IN_FFSLL:
5294 case BUILT_IN_FFSIMAX:
5295 target = expand_builtin_unop (target_mode, arglist, target,
5296 subtarget, ffs_optab);
5297 if (target)
5298 return target;
5299 break;
5301 case BUILT_IN_CLZ:
5302 case BUILT_IN_CLZL:
5303 case BUILT_IN_CLZLL:
5304 case BUILT_IN_CLZIMAX:
5305 target = expand_builtin_unop (target_mode, arglist, target,
5306 subtarget, clz_optab);
5307 if (target)
5308 return target;
5309 break;
5311 case BUILT_IN_CTZ:
5312 case BUILT_IN_CTZL:
5313 case BUILT_IN_CTZLL:
5314 case BUILT_IN_CTZIMAX:
5315 target = expand_builtin_unop (target_mode, arglist, target,
5316 subtarget, ctz_optab);
5317 if (target)
5318 return target;
5319 break;
5321 case BUILT_IN_POPCOUNT:
5322 case BUILT_IN_POPCOUNTL:
5323 case BUILT_IN_POPCOUNTLL:
5324 case BUILT_IN_POPCOUNTIMAX:
5325 target = expand_builtin_unop (target_mode, arglist, target,
5326 subtarget, popcount_optab);
5327 if (target)
5328 return target;
5329 break;
5331 case BUILT_IN_PARITY:
5332 case BUILT_IN_PARITYL:
5333 case BUILT_IN_PARITYLL:
5334 case BUILT_IN_PARITYIMAX:
5335 target = expand_builtin_unop (target_mode, arglist, target,
5336 subtarget, parity_optab);
5337 if (target)
5338 return target;
5339 break;
5341 case BUILT_IN_STRLEN:
5342 target = expand_builtin_strlen (arglist, target, target_mode);
5343 if (target)
5344 return target;
5345 break;
5347 case BUILT_IN_STRCPY:
5348 target = expand_builtin_strcpy (exp, target, mode);
5349 if (target)
5350 return target;
5351 break;
5353 case BUILT_IN_STRNCPY:
5354 target = expand_builtin_strncpy (exp, target, mode);
5355 if (target)
5356 return target;
5357 break;
5359 case BUILT_IN_STPCPY:
5360 target = expand_builtin_stpcpy (exp, target, mode);
5361 if (target)
5362 return target;
5363 break;
5365 case BUILT_IN_STRCAT:
5366 target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
5367 if (target)
5368 return target;
5369 break;
5371 case BUILT_IN_STRNCAT:
5372 target = expand_builtin_strncat (arglist, target, mode);
5373 if (target)
5374 return target;
5375 break;
5377 case BUILT_IN_STRSPN:
5378 target = expand_builtin_strspn (arglist, target, mode);
5379 if (target)
5380 return target;
5381 break;
5383 case BUILT_IN_STRCSPN:
5384 target = expand_builtin_strcspn (arglist, target, mode);
5385 if (target)
5386 return target;
5387 break;
5389 case BUILT_IN_STRSTR:
5390 target = expand_builtin_strstr (arglist, target, mode);
5391 if (target)
5392 return target;
5393 break;
5395 case BUILT_IN_STRPBRK:
5396 target = expand_builtin_strpbrk (arglist, target, mode);
5397 if (target)
5398 return target;
5399 break;
5401 case BUILT_IN_INDEX:
5402 case BUILT_IN_STRCHR:
5403 target = expand_builtin_strchr (arglist, target, mode);
5404 if (target)
5405 return target;
5406 break;
5408 case BUILT_IN_RINDEX:
5409 case BUILT_IN_STRRCHR:
5410 target = expand_builtin_strrchr (arglist, target, mode);
5411 if (target)
5412 return target;
5413 break;
5415 case BUILT_IN_MEMCPY:
5416 target = expand_builtin_memcpy (exp, target, mode);
5417 if (target)
5418 return target;
5419 break;
5421 case BUILT_IN_MEMPCPY:
5422 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5423 if (target)
5424 return target;
5425 break;
5427 case BUILT_IN_MEMMOVE:
5428 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5429 if (target)
5430 return target;
5431 break;
5433 case BUILT_IN_BCOPY:
5434 target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5435 if (target)
5436 return target;
5437 break;
5439 case BUILT_IN_MEMSET:
5440 target = expand_builtin_memset (arglist, target, mode);
5441 if (target)
5442 return target;
5443 break;
5445 case BUILT_IN_BZERO:
5446 target = expand_builtin_bzero (arglist);
5447 if (target)
5448 return target;
5449 break;
5451 case BUILT_IN_STRCMP:
5452 target = expand_builtin_strcmp (exp, target, mode);
5453 if (target)
5454 return target;
5455 break;
5457 case BUILT_IN_STRNCMP:
5458 target = expand_builtin_strncmp (exp, target, mode);
5459 if (target)
5460 return target;
5461 break;
5463 case BUILT_IN_BCMP:
5464 case BUILT_IN_MEMCMP:
5465 target = expand_builtin_memcmp (exp, arglist, target, mode);
5466 if (target)
5467 return target;
5468 break;
5470 case BUILT_IN_SETJMP:
5471 target = expand_builtin_setjmp (arglist, target);
5472 if (target)
5473 return target;
5474 break;
5476 /* __builtin_longjmp is passed a pointer to an array of five words.
5477 It's similar to the C library longjmp function but works with
5478 __builtin_setjmp above. */
5479 case BUILT_IN_LONGJMP:
5480 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5481 break;
5482 else
5484 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5485 VOIDmode, 0);
5486 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5487 NULL_RTX, VOIDmode, 0);
5489 if (value != const1_rtx)
5491 error ("%<__builtin_longjmp%> second argument must be 1");
5492 return const0_rtx;
5495 expand_builtin_longjmp (buf_addr, value);
5496 return const0_rtx;
5499 case BUILT_IN_NONLOCAL_GOTO:
5500 target = expand_builtin_nonlocal_goto (arglist);
5501 if (target)
5502 return target;
5503 break;
5505 /* This updates the setjmp buffer that is its argument with the value
5506 of the current stack pointer. */
5507 case BUILT_IN_UPDATE_SETJMP_BUF:
5508 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5510 rtx buf_addr
5511 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5513 expand_builtin_update_setjmp_buf (buf_addr);
5514 return const0_rtx;
5516 break;
5518 case BUILT_IN_TRAP:
5519 expand_builtin_trap ();
5520 return const0_rtx;
5522 case BUILT_IN_PRINTF:
5523 target = expand_builtin_printf (arglist, target, mode, false);
5524 if (target)
5525 return target;
5526 break;
5528 case BUILT_IN_PRINTF_UNLOCKED:
5529 target = expand_builtin_printf (arglist, target, mode, true);
5530 if (target)
5531 return target;
5532 break;
5534 case BUILT_IN_FPUTS:
5535 target = expand_builtin_fputs (arglist, target, false);
5536 if (target)
5537 return target;
5538 break;
5539 case BUILT_IN_FPUTS_UNLOCKED:
5540 target = expand_builtin_fputs (arglist, target, true);
5541 if (target)
5542 return target;
5543 break;
5545 case BUILT_IN_FPRINTF:
5546 target = expand_builtin_fprintf (arglist, target, mode, false);
5547 if (target)
5548 return target;
5549 break;
5551 case BUILT_IN_FPRINTF_UNLOCKED:
5552 target = expand_builtin_fprintf (arglist, target, mode, true);
5553 if (target)
5554 return target;
5555 break;
5557 case BUILT_IN_SPRINTF:
5558 target = expand_builtin_sprintf (arglist, target, mode);
5559 if (target)
5560 return target;
5561 break;
5563 case BUILT_IN_SIGNBIT:
5564 case BUILT_IN_SIGNBITF:
5565 case BUILT_IN_SIGNBITL:
5566 target = expand_builtin_signbit (exp, target);
5567 if (target)
5568 return target;
5569 break;
5571 /* Various hooks for the DWARF 2 __throw routine. */
5572 case BUILT_IN_UNWIND_INIT:
5573 expand_builtin_unwind_init ();
5574 return const0_rtx;
5575 case BUILT_IN_DWARF_CFA:
5576 return virtual_cfa_rtx;
5577 #ifdef DWARF2_UNWIND_INFO
5578 case BUILT_IN_DWARF_SP_COLUMN:
5579 return expand_builtin_dwarf_sp_column ();
5580 case BUILT_IN_INIT_DWARF_REG_SIZES:
5581 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5582 return const0_rtx;
5583 #endif
5584 case BUILT_IN_FROB_RETURN_ADDR:
5585 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5586 case BUILT_IN_EXTRACT_RETURN_ADDR:
5587 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5588 case BUILT_IN_EH_RETURN:
5589 expand_builtin_eh_return (TREE_VALUE (arglist),
5590 TREE_VALUE (TREE_CHAIN (arglist)));
5591 return const0_rtx;
5592 #ifdef EH_RETURN_DATA_REGNO
5593 case BUILT_IN_EH_RETURN_DATA_REGNO:
5594 return expand_builtin_eh_return_data_regno (arglist);
5595 #endif
5596 case BUILT_IN_EXTEND_POINTER:
5597 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5599 case BUILT_IN_VA_START:
5600 case BUILT_IN_STDARG_START:
5601 return expand_builtin_va_start (arglist);
5602 case BUILT_IN_VA_END:
5603 return expand_builtin_va_end (arglist);
5604 case BUILT_IN_VA_COPY:
5605 return expand_builtin_va_copy (arglist);
5606 case BUILT_IN_EXPECT:
5607 return expand_builtin_expect (arglist, target);
5608 case BUILT_IN_PREFETCH:
5609 expand_builtin_prefetch (arglist);
5610 return const0_rtx;
5612 case BUILT_IN_PROFILE_FUNC_ENTER:
5613 return expand_builtin_profile_func (false);
5614 case BUILT_IN_PROFILE_FUNC_EXIT:
5615 return expand_builtin_profile_func (true);
5617 case BUILT_IN_INIT_TRAMPOLINE:
5618 return expand_builtin_init_trampoline (arglist);
5619 case BUILT_IN_ADJUST_TRAMPOLINE:
5620 return expand_builtin_adjust_trampoline (arglist);
5622 case BUILT_IN_FORK:
5623 case BUILT_IN_EXECL:
5624 case BUILT_IN_EXECV:
5625 case BUILT_IN_EXECLP:
5626 case BUILT_IN_EXECLE:
5627 case BUILT_IN_EXECVP:
5628 case BUILT_IN_EXECVE:
5629 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5630 if (target)
5631 return target;
5632 break;
5634 default: /* just do library call, if unknown builtin */
5635 break;
5638 /* The switch statement above can drop through to cause the function
5639 to be called normally. */
5640 return expand_call (exp, target, ignore);
5643 /* Determine whether a tree node represents a call to a built-in
5644 function. If the tree T is a call to a built-in function with
5645 the right number of arguments of the appropriate types, return
5646 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5647 Otherwise the return value is END_BUILTINS. */
5649 enum built_in_function
5650 builtin_mathfn_code (tree t)
5652 tree fndecl, arglist, parmlist;
5653 tree argtype, parmtype;
5655 if (TREE_CODE (t) != CALL_EXPR
5656 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5657 return END_BUILTINS;
5659 fndecl = get_callee_fndecl (t);
5660 if (fndecl == NULL_TREE
5661 || TREE_CODE (fndecl) != FUNCTION_DECL
5662 || ! DECL_BUILT_IN (fndecl)
5663 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5664 return END_BUILTINS;
5666 arglist = TREE_OPERAND (t, 1);
5667 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5668 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5670 /* If a function doesn't take a variable number of arguments,
5671 the last element in the list will have type `void'. */
5672 parmtype = TREE_VALUE (parmlist);
5673 if (VOID_TYPE_P (parmtype))
5675 if (arglist)
5676 return END_BUILTINS;
5677 return DECL_FUNCTION_CODE (fndecl);
5680 if (! arglist)
5681 return END_BUILTINS;
5683 argtype = TREE_TYPE (TREE_VALUE (arglist));
5685 if (SCALAR_FLOAT_TYPE_P (parmtype))
5687 if (! SCALAR_FLOAT_TYPE_P (argtype))
5688 return END_BUILTINS;
5690 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5692 if (! COMPLEX_FLOAT_TYPE_P (argtype))
5693 return END_BUILTINS;
5695 else if (POINTER_TYPE_P (parmtype))
5697 if (! POINTER_TYPE_P (argtype))
5698 return END_BUILTINS;
5700 else if (INTEGRAL_TYPE_P (parmtype))
5702 if (! INTEGRAL_TYPE_P (argtype))
5703 return END_BUILTINS;
5705 else
5706 return END_BUILTINS;
5708 arglist = TREE_CHAIN (arglist);
5711 /* Variable-length argument list. */
5712 return DECL_FUNCTION_CODE (fndecl);
5715 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5716 constant. ARGLIST is the argument list of the call. */
5718 static tree
5719 fold_builtin_constant_p (tree arglist)
5721 if (arglist == 0)
5722 return 0;
5724 arglist = TREE_VALUE (arglist);
5726 /* We return 1 for a numeric type that's known to be a constant
5727 value at compile-time or for an aggregate type that's a
5728 literal constant. */
5729 STRIP_NOPS (arglist);
5731 /* If we know this is a constant, emit the constant of one. */
5732 if (CONSTANT_CLASS_P (arglist)
5733 || (TREE_CODE (arglist) == CONSTRUCTOR
5734 && TREE_CONSTANT (arglist))
5735 || (TREE_CODE (arglist) == ADDR_EXPR
5736 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5737 return integer_one_node;
5739 /* If this expression has side effects, show we don't know it to be a
5740 constant. Likewise if it's a pointer or aggregate type since in
5741 those case we only want literals, since those are only optimized
5742 when generating RTL, not later.
5743 And finally, if we are compiling an initializer, not code, we
5744 need to return a definite result now; there's not going to be any
5745 more optimization done. */
5746 if (TREE_SIDE_EFFECTS (arglist)
5747 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5748 || POINTER_TYPE_P (TREE_TYPE (arglist))
5749 || cfun == 0)
5750 return integer_zero_node;
5752 return 0;
5755 /* Fold a call to __builtin_expect, if we expect that a comparison against
5756 the argument will fold to a constant. In practice, this means a true
5757 constant or the address of a non-weak symbol. ARGLIST is the argument
5758 list of the call. */
5760 static tree
5761 fold_builtin_expect (tree arglist)
5763 tree arg, inner;
5765 if (arglist == 0)
5766 return 0;
5768 arg = TREE_VALUE (arglist);
5770 /* If the argument isn't invariant, then there's nothing we can do. */
5771 if (!TREE_INVARIANT (arg))
5772 return 0;
5774 /* If we're looking at an address of a weak decl, then do not fold. */
5775 inner = arg;
5776 STRIP_NOPS (inner);
5777 if (TREE_CODE (inner) == ADDR_EXPR)
5781 inner = TREE_OPERAND (inner, 0);
5783 while (TREE_CODE (inner) == COMPONENT_REF
5784 || TREE_CODE (inner) == ARRAY_REF);
5785 if (DECL_P (inner) && DECL_WEAK (inner))
5786 return 0;
5789 /* Otherwise, ARG already has the proper type for the return value. */
5790 return arg;
5793 /* Fold a call to __builtin_classify_type. */
5795 static tree
5796 fold_builtin_classify_type (tree arglist)
5798 if (arglist == 0)
5799 return build_int_cst (NULL_TREE, no_type_class);
5801 return build_int_cst (NULL_TREE,
5802 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
5805 /* Fold a call to __builtin_strlen. */
5807 static tree
5808 fold_builtin_strlen (tree arglist)
5810 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5811 return NULL_TREE;
5812 else
5814 tree len = c_strlen (TREE_VALUE (arglist), 0);
5816 if (len)
5818 /* Convert from the internal "sizetype" type to "size_t". */
5819 if (size_type_node)
5820 len = fold_convert (size_type_node, len);
5821 return len;
5824 return NULL_TREE;
5828 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5830 static tree
5831 fold_builtin_inf (tree type, int warn)
5833 REAL_VALUE_TYPE real;
5835 /* __builtin_inff is intended to be usable to define INFINITY on all
5836 targets. If an infinity is not available, INFINITY expands "to a
5837 positive constant of type float that overflows at translation
5838 time", footnote "In this case, using INFINITY will violate the
5839 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
5840 Thus we pedwarn to ensure this constraint violation is
5841 diagnosed. */
5842 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5843 pedwarn ("target format does not support infinity");
5845 real_inf (&real);
5846 return build_real (type, real);
5849 /* Fold a call to __builtin_nan or __builtin_nans. */
5851 static tree
5852 fold_builtin_nan (tree arglist, tree type, int quiet)
5854 REAL_VALUE_TYPE real;
5855 const char *str;
5857 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5858 return 0;
5859 str = c_getstr (TREE_VALUE (arglist));
5860 if (!str)
5861 return 0;
5863 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5864 return 0;
5866 return build_real (type, real);
5869 /* Return true if the floating point expression T has an integer value.
5870 We also allow +Inf, -Inf and NaN to be considered integer values. */
5872 static bool
5873 integer_valued_real_p (tree t)
5875 switch (TREE_CODE (t))
5877 case FLOAT_EXPR:
5878 return true;
5880 case ABS_EXPR:
5881 case SAVE_EXPR:
5882 case NON_LVALUE_EXPR:
5883 return integer_valued_real_p (TREE_OPERAND (t, 0));
5885 case COMPOUND_EXPR:
5886 case MODIFY_EXPR:
5887 case BIND_EXPR:
5888 return integer_valued_real_p (TREE_OPERAND (t, 1));
5890 case PLUS_EXPR:
5891 case MINUS_EXPR:
5892 case MULT_EXPR:
5893 case MIN_EXPR:
5894 case MAX_EXPR:
5895 return integer_valued_real_p (TREE_OPERAND (t, 0))
5896 && integer_valued_real_p (TREE_OPERAND (t, 1));
5898 case COND_EXPR:
5899 return integer_valued_real_p (TREE_OPERAND (t, 1))
5900 && integer_valued_real_p (TREE_OPERAND (t, 2));
5902 case REAL_CST:
5903 if (! TREE_CONSTANT_OVERFLOW (t))
5905 REAL_VALUE_TYPE c, cint;
5907 c = TREE_REAL_CST (t);
5908 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5909 return real_identical (&c, &cint);
5912 case NOP_EXPR:
5914 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5915 if (TREE_CODE (type) == INTEGER_TYPE)
5916 return true;
5917 if (TREE_CODE (type) == REAL_TYPE)
5918 return integer_valued_real_p (TREE_OPERAND (t, 0));
5919 break;
5922 case CALL_EXPR:
5923 switch (builtin_mathfn_code (t))
5925 case BUILT_IN_CEIL:
5926 case BUILT_IN_CEILF:
5927 case BUILT_IN_CEILL:
5928 case BUILT_IN_FLOOR:
5929 case BUILT_IN_FLOORF:
5930 case BUILT_IN_FLOORL:
5931 case BUILT_IN_NEARBYINT:
5932 case BUILT_IN_NEARBYINTF:
5933 case BUILT_IN_NEARBYINTL:
5934 case BUILT_IN_RINT:
5935 case BUILT_IN_RINTF:
5936 case BUILT_IN_RINTL:
5937 case BUILT_IN_ROUND:
5938 case BUILT_IN_ROUNDF:
5939 case BUILT_IN_ROUNDL:
5940 case BUILT_IN_TRUNC:
5941 case BUILT_IN_TRUNCF:
5942 case BUILT_IN_TRUNCL:
5943 return true;
5945 default:
5946 break;
5948 break;
5950 default:
5951 break;
5953 return false;
5956 /* EXP is assumed to be builtin call where truncation can be propagated
5957 across (for instance floor((double)f) == (double)floorf (f).
5958 Do the transformation. */
5960 static tree
5961 fold_trunc_transparent_mathfn (tree exp)
5963 tree fndecl = get_callee_fndecl (exp);
5964 tree arglist = TREE_OPERAND (exp, 1);
5965 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5966 tree arg;
5968 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5969 return 0;
5971 arg = TREE_VALUE (arglist);
5972 /* Integer rounding functions are idempotent. */
5973 if (fcode == builtin_mathfn_code (arg))
5974 return arg;
5976 /* If argument is already integer valued, and we don't need to worry
5977 about setting errno, there's no need to perform rounding. */
5978 if (! flag_errno_math && integer_valued_real_p (arg))
5979 return arg;
5981 if (optimize)
5983 tree arg0 = strip_float_extensions (arg);
5984 tree ftype = TREE_TYPE (exp);
5985 tree newtype = TREE_TYPE (arg0);
5986 tree decl;
5988 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5989 && (decl = mathfn_built_in (newtype, fcode)))
5991 arglist =
5992 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
5993 return fold_convert (ftype,
5994 build_function_call_expr (decl, arglist));
5997 return 0;
6000 /* EXP is assumed to be builtin call which can narrow the FP type of
6001 the argument, for instance lround((double)f) -> lroundf (f). */
6003 static tree
6004 fold_fixed_mathfn (tree exp)
6006 tree fndecl = get_callee_fndecl (exp);
6007 tree arglist = TREE_OPERAND (exp, 1);
6008 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6009 tree arg;
6011 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6012 return 0;
6014 arg = TREE_VALUE (arglist);
6016 /* If argument is already integer valued, and we don't need to worry
6017 about setting errno, there's no need to perform rounding. */
6018 if (! flag_errno_math && integer_valued_real_p (arg))
6019 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6021 if (optimize)
6023 tree ftype = TREE_TYPE (arg);
6024 tree arg0 = strip_float_extensions (arg);
6025 tree newtype = TREE_TYPE (arg0);
6026 tree decl;
6028 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6029 && (decl = mathfn_built_in (newtype, fcode)))
6031 arglist =
6032 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6033 return build_function_call_expr (decl, arglist);
6036 return 0;
6039 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6040 is the argument list and TYPE is the return type. Return
6041 NULL_TREE if no if no simplification can be made. */
6043 static tree
6044 fold_builtin_cabs (tree arglist, tree type)
6046 tree arg;
6048 if (!arglist || TREE_CHAIN (arglist))
6049 return NULL_TREE;
6051 arg = TREE_VALUE (arglist);
6052 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6053 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6054 return NULL_TREE;
6056 /* Evaluate cabs of a constant at compile-time. */
6057 if (flag_unsafe_math_optimizations
6058 && TREE_CODE (arg) == COMPLEX_CST
6059 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6060 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6061 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6062 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6064 REAL_VALUE_TYPE r, i;
6066 r = TREE_REAL_CST (TREE_REALPART (arg));
6067 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6069 real_arithmetic (&r, MULT_EXPR, &r, &r);
6070 real_arithmetic (&i, MULT_EXPR, &i, &i);
6071 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6072 if (real_sqrt (&r, TYPE_MODE (type), &r)
6073 || ! flag_trapping_math)
6074 return build_real (type, r);
6077 /* If either part is zero, cabs is fabs of the other. */
6078 if (TREE_CODE (arg) == COMPLEX_EXPR
6079 && real_zerop (TREE_OPERAND (arg, 0)))
6080 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6081 if (TREE_CODE (arg) == COMPLEX_EXPR
6082 && real_zerop (TREE_OPERAND (arg, 1)))
6083 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6085 /* Don't do this when optimizing for size. */
6086 if (flag_unsafe_math_optimizations
6087 && optimize && !optimize_size)
6089 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6091 if (sqrtfn != NULL_TREE)
6093 tree rpart, ipart, result, arglist;
6095 arg = builtin_save_expr (arg);
6097 rpart = fold (build1 (REALPART_EXPR, type, arg));
6098 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6100 rpart = builtin_save_expr (rpart);
6101 ipart = builtin_save_expr (ipart);
6103 result = fold (build2 (PLUS_EXPR, type,
6104 fold (build2 (MULT_EXPR, type,
6105 rpart, rpart)),
6106 fold (build2 (MULT_EXPR, type,
6107 ipart, ipart))));
6109 arglist = build_tree_list (NULL_TREE, result);
6110 return build_function_call_expr (sqrtfn, arglist);
6114 return NULL_TREE;
6117 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6118 NULL_TREE if no simplification can be made. */
6120 static tree
6121 fold_builtin_sqrt (tree arglist, tree type)
6124 enum built_in_function fcode;
6125 tree arg = TREE_VALUE (arglist);
6127 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6128 return NULL_TREE;
6130 /* Optimize sqrt of constant value. */
6131 if (TREE_CODE (arg) == REAL_CST
6132 && ! TREE_CONSTANT_OVERFLOW (arg))
6134 REAL_VALUE_TYPE r, x;
6136 x = TREE_REAL_CST (arg);
6137 if (real_sqrt (&r, TYPE_MODE (type), &x)
6138 || (!flag_trapping_math && !flag_errno_math))
6139 return build_real (type, r);
6142 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6143 fcode = builtin_mathfn_code (arg);
6144 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6146 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6147 arg = fold (build2 (MULT_EXPR, type,
6148 TREE_VALUE (TREE_OPERAND (arg, 1)),
6149 build_real (type, dconsthalf)));
6150 arglist = build_tree_list (NULL_TREE, arg);
6151 return build_function_call_expr (expfn, arglist);
6154 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6155 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6157 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6159 if (powfn)
6161 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6162 tree tree_root;
6163 /* The inner root was either sqrt or cbrt. */
6164 REAL_VALUE_TYPE dconstroot =
6165 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6167 /* Adjust for the outer root. */
6168 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6169 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6170 tree_root = build_real (type, dconstroot);
6171 arglist = tree_cons (NULL_TREE, arg0,
6172 build_tree_list (NULL_TREE, tree_root));
6173 return build_function_call_expr (powfn, arglist);
6177 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6178 if (flag_unsafe_math_optimizations
6179 && (fcode == BUILT_IN_POW
6180 || fcode == BUILT_IN_POWF
6181 || fcode == BUILT_IN_POWL))
6183 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6184 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6185 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6186 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6187 build_real (type, dconsthalf)));
6188 arglist = tree_cons (NULL_TREE, arg0,
6189 build_tree_list (NULL_TREE, narg1));
6190 return build_function_call_expr (powfn, arglist);
6193 return NULL_TREE;
6196 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6197 NULL_TREE if no simplification can be made. */
6198 static tree
6199 fold_builtin_cbrt (tree arglist, tree type)
6201 tree arg = TREE_VALUE (arglist);
6202 const enum built_in_function fcode = builtin_mathfn_code (arg);
6204 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6205 return NULL_TREE;
6207 /* Optimize cbrt of constant value. */
6208 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6209 return arg;
6211 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6212 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6214 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6215 const REAL_VALUE_TYPE third_trunc =
6216 real_value_truncate (TYPE_MODE (type), dconstthird);
6217 arg = fold (build2 (MULT_EXPR, type,
6218 TREE_VALUE (TREE_OPERAND (arg, 1)),
6219 build_real (type, third_trunc)));
6220 arglist = build_tree_list (NULL_TREE, arg);
6221 return build_function_call_expr (expfn, arglist);
6224 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6225 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6226 x is negative pow will error but cbrt won't. */
6227 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6229 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6231 if (powfn)
6233 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6234 tree tree_root;
6235 REAL_VALUE_TYPE dconstroot = dconstthird;
6237 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6238 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6239 tree_root = build_real (type, dconstroot);
6240 arglist = tree_cons (NULL_TREE, arg0,
6241 build_tree_list (NULL_TREE, tree_root));
6242 return build_function_call_expr (powfn, arglist);
6246 return NULL_TREE;
6249 /* Fold function call to builtin sin, sinf, or sinl. Return
6250 NULL_TREE if no simplification can be made. */
6251 static tree
6252 fold_builtin_sin (tree arglist)
6254 tree arg = TREE_VALUE (arglist);
6256 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6257 return NULL_TREE;
6259 /* Optimize sin (0.0) = 0.0. */
6260 if (real_zerop (arg))
6261 return arg;
6263 return NULL_TREE;
6266 /* Fold function call to builtin cos, cosf, or cosl. Return
6267 NULL_TREE if no simplification can be made. */
6268 static tree
6269 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6271 tree arg = TREE_VALUE (arglist);
6273 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6274 return NULL_TREE;
6276 /* Optimize cos (0.0) = 1.0. */
6277 if (real_zerop (arg))
6278 return build_real (type, dconst1);
6280 /* Optimize cos(-x) into cos (x). */
6281 if (TREE_CODE (arg) == NEGATE_EXPR)
6283 tree args = build_tree_list (NULL_TREE,
6284 TREE_OPERAND (arg, 0));
6285 return build_function_call_expr (fndecl, args);
6288 return NULL_TREE;
6291 /* Fold function call to builtin tan, tanf, or tanl. Return
6292 NULL_TREE if no simplification can be made. */
6293 static tree
6294 fold_builtin_tan (tree arglist)
6296 enum built_in_function fcode;
6297 tree arg = TREE_VALUE (arglist);
6299 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6300 return NULL_TREE;
6302 /* Optimize tan(0.0) = 0.0. */
6303 if (real_zerop (arg))
6304 return arg;
6306 /* Optimize tan(atan(x)) = x. */
6307 fcode = builtin_mathfn_code (arg);
6308 if (flag_unsafe_math_optimizations
6309 && (fcode == BUILT_IN_ATAN
6310 || fcode == BUILT_IN_ATANF
6311 || fcode == BUILT_IN_ATANL))
6312 return TREE_VALUE (TREE_OPERAND (arg, 1));
6314 return NULL_TREE;
6317 /* Fold function call to builtin atan, atanf, or atanl. Return
6318 NULL_TREE if no simplification can be made. */
6320 static tree
6321 fold_builtin_atan (tree arglist, tree type)
6324 tree arg = TREE_VALUE (arglist);
6326 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6327 return NULL_TREE;
6329 /* Optimize atan(0.0) = 0.0. */
6330 if (real_zerop (arg))
6331 return arg;
6333 /* Optimize atan(1.0) = pi/4. */
6334 if (real_onep (arg))
6336 REAL_VALUE_TYPE cst;
6338 real_convert (&cst, TYPE_MODE (type), &dconstpi);
6339 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6340 return build_real (type, cst);
6343 return NULL_TREE;
6346 /* Fold function call to builtin trunc, truncf or truncl. Return
6347 NULL_TREE if no simplification can be made. */
6349 static tree
6350 fold_builtin_trunc (tree exp)
6352 tree arglist = TREE_OPERAND (exp, 1);
6353 tree arg;
6355 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6356 return 0;
6358 /* Optimize trunc of constant value. */
6359 arg = TREE_VALUE (arglist);
6360 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6362 REAL_VALUE_TYPE r, x;
6363 tree type = TREE_TYPE (exp);
6365 x = TREE_REAL_CST (arg);
6366 real_trunc (&r, TYPE_MODE (type), &x);
6367 return build_real (type, r);
6370 return fold_trunc_transparent_mathfn (exp);
6373 /* Fold function call to builtin floor, floorf or floorl. Return
6374 NULL_TREE if no simplification can be made. */
6376 static tree
6377 fold_builtin_floor (tree exp)
6379 tree arglist = TREE_OPERAND (exp, 1);
6380 tree arg;
6382 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6383 return 0;
6385 /* Optimize floor of constant value. */
6386 arg = TREE_VALUE (arglist);
6387 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6389 REAL_VALUE_TYPE x;
6391 x = TREE_REAL_CST (arg);
6392 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6394 tree type = TREE_TYPE (exp);
6395 REAL_VALUE_TYPE r;
6397 real_floor (&r, TYPE_MODE (type), &x);
6398 return build_real (type, r);
6402 return fold_trunc_transparent_mathfn (exp);
6405 /* Fold function call to builtin ceil, ceilf or ceill. Return
6406 NULL_TREE if no simplification can be made. */
6408 static tree
6409 fold_builtin_ceil (tree exp)
6411 tree arglist = TREE_OPERAND (exp, 1);
6412 tree arg;
6414 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6415 return 0;
6417 /* Optimize ceil of constant value. */
6418 arg = TREE_VALUE (arglist);
6419 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6421 REAL_VALUE_TYPE x;
6423 x = TREE_REAL_CST (arg);
6424 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6426 tree type = TREE_TYPE (exp);
6427 REAL_VALUE_TYPE r;
6429 real_ceil (&r, TYPE_MODE (type), &x);
6430 return build_real (type, r);
6434 return fold_trunc_transparent_mathfn (exp);
6437 /* Fold function call to builtin round, roundf or roundl. Return
6438 NULL_TREE if no simplification can be made. */
6440 static tree
6441 fold_builtin_round (tree exp)
6443 tree arglist = TREE_OPERAND (exp, 1);
6444 tree arg;
6446 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6447 return 0;
6449 /* Optimize round of constant value. */
6450 arg = TREE_VALUE (arglist);
6451 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6453 REAL_VALUE_TYPE x;
6455 x = TREE_REAL_CST (arg);
6456 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6458 tree type = TREE_TYPE (exp);
6459 REAL_VALUE_TYPE r;
6461 real_round (&r, TYPE_MODE (type), &x);
6462 return build_real (type, r);
6466 return fold_trunc_transparent_mathfn (exp);
6469 /* Fold function call to builtin lround, lroundf or lroundl (or the
6470 corresponding long long versions). Return NULL_TREE if no
6471 simplification can be made. */
6473 static tree
6474 fold_builtin_lround (tree exp)
6476 tree arglist = TREE_OPERAND (exp, 1);
6477 tree arg;
6479 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6480 return 0;
6482 /* Optimize lround of constant value. */
6483 arg = TREE_VALUE (arglist);
6484 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6486 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6488 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6490 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6491 HOST_WIDE_INT hi, lo;
6492 REAL_VALUE_TYPE r;
6494 real_round (&r, TYPE_MODE (ftype), &x);
6495 REAL_VALUE_TO_INT (&lo, &hi, r);
6496 result = build_int_cst_wide (NULL_TREE, lo, hi);
6497 if (int_fits_type_p (result, itype))
6498 return fold_convert (itype, result);
6502 return fold_fixed_mathfn (exp);
6505 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6506 and their long and long long variants (i.e. ffsl and ffsll).
6507 Return NULL_TREE if no simplification can be made. */
6509 static tree
6510 fold_builtin_bitop (tree exp)
6512 tree fndecl = get_callee_fndecl (exp);
6513 tree arglist = TREE_OPERAND (exp, 1);
6514 tree arg;
6516 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6517 return NULL_TREE;
6519 /* Optimize for constant argument. */
6520 arg = TREE_VALUE (arglist);
6521 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6523 HOST_WIDE_INT hi, width, result;
6524 unsigned HOST_WIDE_INT lo;
6525 tree type;
6527 type = TREE_TYPE (arg);
6528 width = TYPE_PRECISION (type);
6529 lo = TREE_INT_CST_LOW (arg);
6531 /* Clear all the bits that are beyond the type's precision. */
6532 if (width > HOST_BITS_PER_WIDE_INT)
6534 hi = TREE_INT_CST_HIGH (arg);
6535 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6536 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6538 else
6540 hi = 0;
6541 if (width < HOST_BITS_PER_WIDE_INT)
6542 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6545 switch (DECL_FUNCTION_CODE (fndecl))
6547 case BUILT_IN_FFS:
6548 case BUILT_IN_FFSL:
6549 case BUILT_IN_FFSLL:
6550 if (lo != 0)
6551 result = exact_log2 (lo & -lo) + 1;
6552 else if (hi != 0)
6553 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6554 else
6555 result = 0;
6556 break;
6558 case BUILT_IN_CLZ:
6559 case BUILT_IN_CLZL:
6560 case BUILT_IN_CLZLL:
6561 if (hi != 0)
6562 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6563 else if (lo != 0)
6564 result = width - floor_log2 (lo) - 1;
6565 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6566 result = width;
6567 break;
6569 case BUILT_IN_CTZ:
6570 case BUILT_IN_CTZL:
6571 case BUILT_IN_CTZLL:
6572 if (lo != 0)
6573 result = exact_log2 (lo & -lo);
6574 else if (hi != 0)
6575 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6576 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6577 result = width;
6578 break;
6580 case BUILT_IN_POPCOUNT:
6581 case BUILT_IN_POPCOUNTL:
6582 case BUILT_IN_POPCOUNTLL:
6583 result = 0;
6584 while (lo)
6585 result++, lo &= lo - 1;
6586 while (hi)
6587 result++, hi &= hi - 1;
6588 break;
6590 case BUILT_IN_PARITY:
6591 case BUILT_IN_PARITYL:
6592 case BUILT_IN_PARITYLL:
6593 result = 0;
6594 while (lo)
6595 result++, lo &= lo - 1;
6596 while (hi)
6597 result++, hi &= hi - 1;
6598 result &= 1;
6599 break;
6601 default:
6602 gcc_unreachable ();
6605 return build_int_cst (TREE_TYPE (exp), result);
6608 return NULL_TREE;
6611 /* Return true if EXPR is the real constant contained in VALUE. */
6613 static bool
6614 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6616 STRIP_NOPS (expr);
6618 return ((TREE_CODE (expr) == REAL_CST
6619 && ! TREE_CONSTANT_OVERFLOW (expr)
6620 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6621 || (TREE_CODE (expr) == COMPLEX_CST
6622 && real_dconstp (TREE_REALPART (expr), value)
6623 && real_zerop (TREE_IMAGPART (expr))));
6626 /* A subroutine of fold_builtin to fold the various logarithmic
6627 functions. EXP is the CALL_EXPR of a call to a builtin logN
6628 function. VALUE is the base of the logN function. */
6630 static tree
6631 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6633 tree arglist = TREE_OPERAND (exp, 1);
6635 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6637 tree fndecl = get_callee_fndecl (exp);
6638 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6639 tree arg = TREE_VALUE (arglist);
6640 const enum built_in_function fcode = builtin_mathfn_code (arg);
6642 /* Optimize logN(1.0) = 0.0. */
6643 if (real_onep (arg))
6644 return build_real (type, dconst0);
6646 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6647 exactly, then only do this if flag_unsafe_math_optimizations. */
6648 if (exact_real_truncate (TYPE_MODE (type), value)
6649 || flag_unsafe_math_optimizations)
6651 const REAL_VALUE_TYPE value_truncate =
6652 real_value_truncate (TYPE_MODE (type), *value);
6653 if (real_dconstp (arg, &value_truncate))
6654 return build_real (type, dconst1);
6657 /* Special case, optimize logN(expN(x)) = x. */
6658 if (flag_unsafe_math_optimizations
6659 && ((value == &dconste
6660 && (fcode == BUILT_IN_EXP
6661 || fcode == BUILT_IN_EXPF
6662 || fcode == BUILT_IN_EXPL))
6663 || (value == &dconst2
6664 && (fcode == BUILT_IN_EXP2
6665 || fcode == BUILT_IN_EXP2F
6666 || fcode == BUILT_IN_EXP2L))
6667 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6668 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6670 /* Optimize logN(func()) for various exponential functions. We
6671 want to determine the value "x" and the power "exponent" in
6672 order to transform logN(x**exponent) into exponent*logN(x). */
6673 if (flag_unsafe_math_optimizations)
6675 tree exponent = 0, x = 0;
6677 switch (fcode)
6679 case BUILT_IN_EXP:
6680 case BUILT_IN_EXPF:
6681 case BUILT_IN_EXPL:
6682 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6683 x = build_real (type,
6684 real_value_truncate (TYPE_MODE (type), dconste));
6685 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6686 break;
6687 case BUILT_IN_EXP2:
6688 case BUILT_IN_EXP2F:
6689 case BUILT_IN_EXP2L:
6690 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6691 x = build_real (type, dconst2);
6692 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6693 break;
6694 case BUILT_IN_EXP10:
6695 case BUILT_IN_EXP10F:
6696 case BUILT_IN_EXP10L:
6697 case BUILT_IN_POW10:
6698 case BUILT_IN_POW10F:
6699 case BUILT_IN_POW10L:
6700 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6701 x = build_real (type, dconst10);
6702 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6703 break;
6704 case BUILT_IN_SQRT:
6705 case BUILT_IN_SQRTF:
6706 case BUILT_IN_SQRTL:
6707 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6708 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6709 exponent = build_real (type, dconsthalf);
6710 break;
6711 case BUILT_IN_CBRT:
6712 case BUILT_IN_CBRTF:
6713 case BUILT_IN_CBRTL:
6714 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6715 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6716 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6717 dconstthird));
6718 break;
6719 case BUILT_IN_POW:
6720 case BUILT_IN_POWF:
6721 case BUILT_IN_POWL:
6722 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6723 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6724 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6725 break;
6726 default:
6727 break;
6730 /* Now perform the optimization. */
6731 if (x && exponent)
6733 tree logfn;
6734 arglist = build_tree_list (NULL_TREE, x);
6735 logfn = build_function_call_expr (fndecl, arglist);
6736 return fold (build2 (MULT_EXPR, type, exponent, logfn));
6741 return 0;
6744 /* Fold a builtin function call to pow, powf, or powl. Return
6745 NULL_TREE if no simplification can be made. */
6746 static tree
6747 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6749 enum built_in_function fcode;
6750 tree arg0 = TREE_VALUE (arglist);
6751 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6753 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6754 return NULL_TREE;
6756 /* Optimize pow(1.0,y) = 1.0. */
6757 if (real_onep (arg0))
6758 return omit_one_operand (type, build_real (type, dconst1), arg1);
6760 if (TREE_CODE (arg1) == REAL_CST
6761 && ! TREE_CONSTANT_OVERFLOW (arg1))
6763 REAL_VALUE_TYPE c;
6764 c = TREE_REAL_CST (arg1);
6766 /* Optimize pow(x,0.0) = 1.0. */
6767 if (REAL_VALUES_EQUAL (c, dconst0))
6768 return omit_one_operand (type, build_real (type, dconst1),
6769 arg0);
6771 /* Optimize pow(x,1.0) = x. */
6772 if (REAL_VALUES_EQUAL (c, dconst1))
6773 return arg0;
6775 /* Optimize pow(x,-1.0) = 1.0/x. */
6776 if (REAL_VALUES_EQUAL (c, dconstm1))
6777 return fold (build2 (RDIV_EXPR, type,
6778 build_real (type, dconst1), arg0));
6780 /* Optimize pow(x,0.5) = sqrt(x). */
6781 if (flag_unsafe_math_optimizations
6782 && REAL_VALUES_EQUAL (c, dconsthalf))
6784 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6786 if (sqrtfn != NULL_TREE)
6788 tree arglist = build_tree_list (NULL_TREE, arg0);
6789 return build_function_call_expr (sqrtfn, arglist);
6793 /* Attempt to evaluate pow at compile-time. */
6794 if (TREE_CODE (arg0) == REAL_CST
6795 && ! TREE_CONSTANT_OVERFLOW (arg0))
6797 REAL_VALUE_TYPE cint;
6798 HOST_WIDE_INT n;
6800 n = real_to_integer (&c);
6801 real_from_integer (&cint, VOIDmode, n,
6802 n < 0 ? -1 : 0, 0);
6803 if (real_identical (&c, &cint))
6805 REAL_VALUE_TYPE x;
6806 bool inexact;
6808 x = TREE_REAL_CST (arg0);
6809 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6810 if (flag_unsafe_math_optimizations || !inexact)
6811 return build_real (type, x);
6816 /* Optimize pow(expN(x),y) = expN(x*y). */
6817 fcode = builtin_mathfn_code (arg0);
6818 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6820 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6821 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6822 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6823 arglist = build_tree_list (NULL_TREE, arg);
6824 return build_function_call_expr (expfn, arglist);
6827 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
6828 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6830 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6831 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6832 build_real (type, dconsthalf)));
6834 arglist = tree_cons (NULL_TREE, narg0,
6835 build_tree_list (NULL_TREE, narg1));
6836 return build_function_call_expr (fndecl, arglist);
6839 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
6840 if (flag_unsafe_math_optimizations
6841 && (fcode == BUILT_IN_POW
6842 || fcode == BUILT_IN_POWF
6843 || fcode == BUILT_IN_POWL))
6845 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6846 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6847 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
6848 arglist = tree_cons (NULL_TREE, arg00,
6849 build_tree_list (NULL_TREE, narg1));
6850 return build_function_call_expr (fndecl, arglist);
6852 return NULL_TREE;
6855 /* A subroutine of fold_builtin to fold the various exponent
6856 functions. EXP is the CALL_EXPR of a call to a builtin function.
6857 VALUE is the value which will be raised to a power. */
6859 static tree
6860 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6862 tree arglist = TREE_OPERAND (exp, 1);
6864 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6866 tree fndecl = get_callee_fndecl (exp);
6867 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6868 tree arg = TREE_VALUE (arglist);
6870 /* Optimize exp*(0.0) = 1.0. */
6871 if (real_zerop (arg))
6872 return build_real (type, dconst1);
6874 /* Optimize expN(1.0) = N. */
6875 if (real_onep (arg))
6877 REAL_VALUE_TYPE cst;
6879 real_convert (&cst, TYPE_MODE (type), value);
6880 return build_real (type, cst);
6883 /* Attempt to evaluate expN(integer) at compile-time. */
6884 if (flag_unsafe_math_optimizations
6885 && TREE_CODE (arg) == REAL_CST
6886 && ! TREE_CONSTANT_OVERFLOW (arg))
6888 REAL_VALUE_TYPE cint;
6889 REAL_VALUE_TYPE c;
6890 HOST_WIDE_INT n;
6892 c = TREE_REAL_CST (arg);
6893 n = real_to_integer (&c);
6894 real_from_integer (&cint, VOIDmode, n,
6895 n < 0 ? -1 : 0, 0);
6896 if (real_identical (&c, &cint))
6898 REAL_VALUE_TYPE x;
6900 real_powi (&x, TYPE_MODE (type), value, n);
6901 return build_real (type, x);
6905 /* Optimize expN(logN(x)) = x. */
6906 if (flag_unsafe_math_optimizations)
6908 const enum built_in_function fcode = builtin_mathfn_code (arg);
6910 if ((value == &dconste
6911 && (fcode == BUILT_IN_LOG
6912 || fcode == BUILT_IN_LOGF
6913 || fcode == BUILT_IN_LOGL))
6914 || (value == &dconst2
6915 && (fcode == BUILT_IN_LOG2
6916 || fcode == BUILT_IN_LOG2F
6917 || fcode == BUILT_IN_LOG2L))
6918 || (value == &dconst10
6919 && (fcode == BUILT_IN_LOG10
6920 || fcode == BUILT_IN_LOG10F
6921 || fcode == BUILT_IN_LOG10L)))
6922 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6926 return 0;
6929 /* Fold function call to builtin memcpy. Return
6930 NULL_TREE if no simplification can be made. */
6932 static tree
6933 fold_builtin_memcpy (tree exp)
6935 tree arglist = TREE_OPERAND (exp, 1);
6936 tree dest, src, len;
6938 if (!validate_arglist (arglist,
6939 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6940 return 0;
6942 dest = TREE_VALUE (arglist);
6943 src = TREE_VALUE (TREE_CHAIN (arglist));
6944 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6946 /* If the LEN parameter is zero, return DEST. */
6947 if (integer_zerop (len))
6948 return omit_one_operand (TREE_TYPE (exp), dest, src);
6950 /* If SRC and DEST are the same (and not volatile), return DEST. */
6951 if (operand_equal_p (src, dest, 0))
6952 return omit_one_operand (TREE_TYPE (exp), dest, len);
6954 return 0;
6957 /* Fold function call to builtin mempcpy. Return
6958 NULL_TREE if no simplification can be made. */
6960 static tree
6961 fold_builtin_mempcpy (tree arglist, tree type, int endp)
6963 if (validate_arglist (arglist,
6964 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6966 tree dest = TREE_VALUE (arglist);
6967 tree src = TREE_VALUE (TREE_CHAIN (arglist));
6968 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6970 /* If the LEN parameter is zero, return DEST. */
6971 if (integer_zerop (len))
6972 return omit_one_operand (type, dest, src);
6974 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6975 if (operand_equal_p (src, dest, 0))
6977 if (endp == 0)
6978 return omit_one_operand (type, dest, len);
6980 if (endp == 2)
6981 len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
6982 ssize_int (1)));
6984 len = fold_convert (TREE_TYPE (dest), len);
6985 len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6986 return fold_convert (type, len);
6989 return 0;
6992 /* Fold function call to builtin memmove. Return
6993 NULL_TREE if no simplification can be made. */
6995 static tree
6996 fold_builtin_memmove (tree arglist, tree type)
6998 tree dest, src, len;
7000 if (!validate_arglist (arglist,
7001 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7002 return 0;
7004 dest = TREE_VALUE (arglist);
7005 src = TREE_VALUE (TREE_CHAIN (arglist));
7006 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7008 /* If the LEN parameter is zero, return DEST. */
7009 if (integer_zerop (len))
7010 return omit_one_operand (type, dest, src);
7012 /* If SRC and DEST are the same (and not volatile), return DEST. */
7013 if (operand_equal_p (src, dest, 0))
7014 return omit_one_operand (type, dest, len);
7016 return 0;
7019 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7020 the length of the string to be copied. Return NULL_TREE if no
7021 simplification can be made. */
7023 tree
7024 fold_builtin_strcpy (tree exp, tree len)
7026 tree arglist = TREE_OPERAND (exp, 1);
7027 tree dest, src, fn;
7029 if (!validate_arglist (arglist,
7030 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7031 return 0;
7033 dest = TREE_VALUE (arglist);
7034 src = TREE_VALUE (TREE_CHAIN (arglist));
7036 /* If SRC and DEST are the same (and not volatile), return DEST. */
7037 if (operand_equal_p (src, dest, 0))
7038 return fold_convert (TREE_TYPE (exp), dest);
7040 if (optimize_size)
7041 return 0;
7043 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7044 if (!fn)
7045 return 0;
7047 if (!len)
7049 len = c_strlen (src, 1);
7050 if (! len || TREE_SIDE_EFFECTS (len))
7051 return 0;
7054 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7055 arglist = build_tree_list (NULL_TREE, len);
7056 arglist = tree_cons (NULL_TREE, src, arglist);
7057 arglist = tree_cons (NULL_TREE, dest, arglist);
7058 return fold_convert (TREE_TYPE (exp),
7059 build_function_call_expr (fn, arglist));
7062 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7063 the length of the source string. Return NULL_TREE if no simplification
7064 can be made. */
7066 tree
7067 fold_builtin_strncpy (tree exp, tree slen)
7069 tree arglist = TREE_OPERAND (exp, 1);
7070 tree dest, src, len, fn;
7072 if (!validate_arglist (arglist,
7073 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7074 return 0;
7076 dest = TREE_VALUE (arglist);
7077 src = TREE_VALUE (TREE_CHAIN (arglist));
7078 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7080 /* If the LEN parameter is zero, return DEST. */
7081 if (integer_zerop (len))
7082 return omit_one_operand (TREE_TYPE (exp), dest, src);
7084 /* We can't compare slen with len as constants below if len is not a
7085 constant. */
7086 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7087 return 0;
7089 if (!slen)
7090 slen = c_strlen (src, 1);
7092 /* Now, we must be passed a constant src ptr parameter. */
7093 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7094 return 0;
7096 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7098 /* We do not support simplification of this case, though we do
7099 support it when expanding trees into RTL. */
7100 /* FIXME: generate a call to __builtin_memset. */
7101 if (tree_int_cst_lt (slen, len))
7102 return 0;
7104 /* OK transform into builtin memcpy. */
7105 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7106 if (!fn)
7107 return 0;
7108 return fold_convert (TREE_TYPE (exp),
7109 build_function_call_expr (fn, arglist));
7112 /* Fold function call to builtin memcmp. Return
7113 NULL_TREE if no simplification can be made. */
7115 static tree
7116 fold_builtin_memcmp (tree arglist)
7118 tree arg1, arg2, len;
7119 const char *p1, *p2;
7121 if (!validate_arglist (arglist,
7122 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7123 return 0;
7125 arg1 = TREE_VALUE (arglist);
7126 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7127 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7129 /* If the LEN parameter is zero, return zero. */
7130 if (integer_zerop (len))
7131 return omit_two_operands (integer_type_node, integer_zero_node,
7132 arg1, arg2);
7134 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7135 if (operand_equal_p (arg1, arg2, 0))
7136 return omit_one_operand (integer_type_node, integer_zero_node, len);
7138 p1 = c_getstr (arg1);
7139 p2 = c_getstr (arg2);
7141 /* If all arguments are constant, and the value of len is not greater
7142 than the lengths of arg1 and arg2, evaluate at compile-time. */
7143 if (host_integerp (len, 1) && p1 && p2
7144 && compare_tree_int (len, strlen (p1) + 1) <= 0
7145 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7147 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7149 if (r > 0)
7150 return integer_one_node;
7151 else if (r < 0)
7152 return integer_minus_one_node;
7153 else
7154 return integer_zero_node;
7157 /* If len parameter is one, return an expression corresponding to
7158 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7159 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7161 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7162 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7163 tree ind1 = fold_convert (integer_type_node,
7164 build1 (INDIRECT_REF, cst_uchar_node,
7165 fold_convert (cst_uchar_ptr_node,
7166 arg1)));
7167 tree ind2 = fold_convert (integer_type_node,
7168 build1 (INDIRECT_REF, cst_uchar_node,
7169 fold_convert (cst_uchar_ptr_node,
7170 arg2)));
7171 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7174 return 0;
7177 /* Fold function call to builtin strcmp. Return
7178 NULL_TREE if no simplification can be made. */
7180 static tree
7181 fold_builtin_strcmp (tree arglist)
7183 tree arg1, arg2;
7184 const char *p1, *p2;
7186 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7187 return 0;
7189 arg1 = TREE_VALUE (arglist);
7190 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7192 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7193 if (operand_equal_p (arg1, arg2, 0))
7194 return integer_zero_node;
7196 p1 = c_getstr (arg1);
7197 p2 = c_getstr (arg2);
7199 if (p1 && p2)
7201 const int i = strcmp (p1, p2);
7202 if (i < 0)
7203 return integer_minus_one_node;
7204 else if (i > 0)
7205 return integer_one_node;
7206 else
7207 return integer_zero_node;
7210 /* If the second arg is "", return *(const unsigned char*)arg1. */
7211 if (p2 && *p2 == '\0')
7213 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7214 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7215 return fold_convert (integer_type_node,
7216 build1 (INDIRECT_REF, cst_uchar_node,
7217 fold_convert (cst_uchar_ptr_node,
7218 arg1)));
7221 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7222 if (p1 && *p1 == '\0')
7224 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7225 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7226 tree temp = fold_convert (integer_type_node,
7227 build1 (INDIRECT_REF, cst_uchar_node,
7228 fold_convert (cst_uchar_ptr_node,
7229 arg2)));
7230 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7233 return 0;
7236 /* Fold function call to builtin strncmp. Return
7237 NULL_TREE if no simplification can be made. */
7239 static tree
7240 fold_builtin_strncmp (tree arglist)
7242 tree arg1, arg2, len;
7243 const char *p1, *p2;
7245 if (!validate_arglist (arglist,
7246 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7247 return 0;
7249 arg1 = TREE_VALUE (arglist);
7250 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7251 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7253 /* If the LEN parameter is zero, return zero. */
7254 if (integer_zerop (len))
7255 return omit_two_operands (integer_type_node, integer_zero_node,
7256 arg1, arg2);
7258 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7259 if (operand_equal_p (arg1, arg2, 0))
7260 return omit_one_operand (integer_type_node, integer_zero_node, len);
7262 p1 = c_getstr (arg1);
7263 p2 = c_getstr (arg2);
7265 if (host_integerp (len, 1) && p1 && p2)
7267 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7268 if (i > 0)
7269 return integer_one_node;
7270 else if (i < 0)
7271 return integer_minus_one_node;
7272 else
7273 return integer_zero_node;
7276 /* If the second arg is "", and the length is greater than zero,
7277 return *(const unsigned char*)arg1. */
7278 if (p2 && *p2 == '\0'
7279 && TREE_CODE (len) == INTEGER_CST
7280 && tree_int_cst_sgn (len) == 1)
7282 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7283 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7284 return fold_convert (integer_type_node,
7285 build1 (INDIRECT_REF, cst_uchar_node,
7286 fold_convert (cst_uchar_ptr_node,
7287 arg1)));
7290 /* If the first arg is "", and the length is greater than zero,
7291 return -*(const unsigned char*)arg2. */
7292 if (p1 && *p1 == '\0'
7293 && TREE_CODE (len) == INTEGER_CST
7294 && tree_int_cst_sgn (len) == 1)
7296 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7297 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7298 tree temp = fold_convert (integer_type_node,
7299 build1 (INDIRECT_REF, cst_uchar_node,
7300 fold_convert (cst_uchar_ptr_node,
7301 arg2)));
7302 return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7305 /* If len parameter is one, return an expression corresponding to
7306 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7307 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7309 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7310 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7311 tree ind1 = fold_convert (integer_type_node,
7312 build1 (INDIRECT_REF, cst_uchar_node,
7313 fold_convert (cst_uchar_ptr_node,
7314 arg1)));
7315 tree ind2 = fold_convert (integer_type_node,
7316 build1 (INDIRECT_REF, cst_uchar_node,
7317 fold_convert (cst_uchar_ptr_node,
7318 arg2)));
7319 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7322 return 0;
7325 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7326 NULL_TREE if no simplification can be made. */
7328 static tree
7329 fold_builtin_signbit (tree exp)
7331 tree arglist = TREE_OPERAND (exp, 1);
7332 tree arg, temp;
7334 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7335 return NULL_TREE;
7337 arg = TREE_VALUE (arglist);
7339 /* If ARG is a compile-time constant, determine the result. */
7340 if (TREE_CODE (arg) == REAL_CST
7341 && !TREE_CONSTANT_OVERFLOW (arg))
7343 REAL_VALUE_TYPE c;
7345 c = TREE_REAL_CST (arg);
7346 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7347 return fold_convert (TREE_TYPE (exp), temp);
7350 /* If ARG is non-negative, the result is always zero. */
7351 if (tree_expr_nonnegative_p (arg))
7352 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7354 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7355 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7356 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7357 build_real (TREE_TYPE (arg), dconst0)));
7359 return NULL_TREE;
7362 /* Fold function call to builtin copysign, copysignf or copysignl.
7363 Return NULL_TREE if no simplification can be made. */
7365 static tree
7366 fold_builtin_copysign (tree arglist, tree type)
7368 tree arg1, arg2;
7370 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7371 return NULL_TREE;
7373 arg1 = TREE_VALUE (arglist);
7374 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7376 /* copysign(X,X) is X. */
7377 if (operand_equal_p (arg1, arg2, 0))
7378 return fold_convert (type, arg1);
7380 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7381 if (TREE_CODE (arg1) == REAL_CST
7382 && TREE_CODE (arg2) == REAL_CST
7383 && !TREE_CONSTANT_OVERFLOW (arg1)
7384 && !TREE_CONSTANT_OVERFLOW (arg2))
7386 REAL_VALUE_TYPE c1, c2;
7388 c1 = TREE_REAL_CST (arg1);
7389 c2 = TREE_REAL_CST (arg2);
7390 real_copysign (&c1, &c2);
7391 return build_real (type, c1);
7392 c1.sign = c2.sign;
7395 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7396 Remember to evaluate Y for side-effects. */
7397 if (tree_expr_nonnegative_p (arg2))
7398 return omit_one_operand (type,
7399 fold (build1 (ABS_EXPR, type, arg1)),
7400 arg2);
7402 return NULL_TREE;
7405 /* Fold a call to builtin isascii. */
7407 static tree
7408 fold_builtin_isascii (tree arglist)
7410 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7411 return 0;
7412 else
7414 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7415 tree arg = TREE_VALUE (arglist);
7417 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7418 build_int_cst (NULL_TREE,
7419 ~ (unsigned HOST_WIDE_INT) 0x7f));
7420 arg = fold (build2 (EQ_EXPR, integer_type_node,
7421 arg, integer_zero_node));
7423 if (in_gimple_form && !TREE_CONSTANT (arg))
7424 return NULL_TREE;
7425 else
7426 return arg;
7430 /* Fold a call to builtin toascii. */
7432 static tree
7433 fold_builtin_toascii (tree arglist)
7435 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7436 return 0;
7437 else
7439 /* Transform toascii(c) -> (c & 0x7f). */
7440 tree arg = TREE_VALUE (arglist);
7442 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7443 build_int_cst (NULL_TREE, 0x7f)));
7447 /* Fold a call to builtin isdigit. */
7449 static tree
7450 fold_builtin_isdigit (tree arglist)
7452 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7453 return 0;
7454 else
7456 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7457 /* According to the C standard, isdigit is unaffected by locale. */
7458 tree arg = TREE_VALUE (arglist);
7459 arg = fold_convert (unsigned_type_node, arg);
7460 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7461 build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7462 arg = build2 (LE_EXPR, integer_type_node, arg,
7463 build_int_cst (unsigned_type_node, 9));
7464 arg = fold (arg);
7465 if (in_gimple_form && !TREE_CONSTANT (arg))
7466 return NULL_TREE;
7467 else
7468 return arg;
7472 /* Fold a call to fabs, fabsf or fabsl. */
7474 static tree
7475 fold_builtin_fabs (tree arglist, tree type)
7477 tree arg;
7479 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7480 return 0;
7482 arg = TREE_VALUE (arglist);
7483 if (TREE_CODE (arg) == REAL_CST)
7484 return fold_abs_const (arg, type);
7485 return fold (build1 (ABS_EXPR, type, arg));
7488 /* Fold a call to abs, labs, llabs or imaxabs. */
7490 static tree
7491 fold_builtin_abs (tree arglist, tree type)
7493 tree arg;
7495 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7496 return 0;
7498 arg = TREE_VALUE (arglist);
7499 if (TREE_CODE (arg) == INTEGER_CST)
7500 return fold_abs_const (arg, type);
7501 return fold (build1 (ABS_EXPR, type, arg));
7504 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7505 EXP is the CALL_EXPR for the call. */
7507 static tree
7508 fold_builtin_classify (tree exp, int builtin_index)
7510 tree fndecl = get_callee_fndecl (exp);
7511 tree arglist = TREE_OPERAND (exp, 1);
7512 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7513 tree arg;
7514 REAL_VALUE_TYPE r;
7516 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7518 /* Check that we have exactly one argument. */
7519 if (arglist == 0)
7521 error ("too few arguments to function %qs",
7522 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7523 return error_mark_node;
7525 else if (TREE_CHAIN (arglist) != 0)
7527 error ("too many arguments to function %qs",
7528 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7529 return error_mark_node;
7531 else
7533 error ("non-floating-point argument to function %qs",
7534 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7535 return error_mark_node;
7539 arg = TREE_VALUE (arglist);
7540 switch (builtin_index)
7542 case BUILT_IN_ISINF:
7543 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7544 return omit_one_operand (type, integer_zero_node, arg);
7546 if (TREE_CODE (arg) == REAL_CST)
7548 r = TREE_REAL_CST (arg);
7549 if (real_isinf (&r))
7550 return real_compare (GT_EXPR, &r, &dconst0)
7551 ? integer_one_node : integer_minus_one_node;
7552 else
7553 return integer_zero_node;
7556 return NULL_TREE;
7558 case BUILT_IN_FINITE:
7559 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7560 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7561 return omit_one_operand (type, integer_zero_node, arg);
7563 if (TREE_CODE (arg) == REAL_CST)
7565 r = TREE_REAL_CST (arg);
7566 return real_isinf (&r) || real_isnan (&r)
7567 ? integer_zero_node : integer_one_node;
7570 return NULL_TREE;
7572 case BUILT_IN_ISNAN:
7573 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7574 return omit_one_operand (type, integer_zero_node, arg);
7576 if (TREE_CODE (arg) == REAL_CST)
7578 r = TREE_REAL_CST (arg);
7579 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7582 arg = builtin_save_expr (arg);
7583 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7585 default:
7586 gcc_unreachable ();
7590 /* Fold a call to an unordered comparison function such as
7591 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7592 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7593 the opposite of the desired result. UNORDERED_CODE is used
7594 for modes that can hold NaNs and ORDERED_CODE is used for
7595 the rest. */
7597 static tree
7598 fold_builtin_unordered_cmp (tree exp,
7599 enum tree_code unordered_code,
7600 enum tree_code ordered_code)
7602 tree fndecl = get_callee_fndecl (exp);
7603 tree arglist = TREE_OPERAND (exp, 1);
7604 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7605 enum tree_code code;
7606 tree arg0, arg1;
7607 tree type0, type1;
7608 enum tree_code code0, code1;
7609 tree cmp_type = NULL_TREE;
7611 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7613 /* Check that we have exactly two arguments. */
7614 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7616 error ("too few arguments to function %qs",
7617 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7618 return error_mark_node;
7620 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7622 error ("too many arguments to function %qs",
7623 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7624 return error_mark_node;
7628 arg0 = TREE_VALUE (arglist);
7629 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7631 type0 = TREE_TYPE (arg0);
7632 type1 = TREE_TYPE (arg1);
7634 code0 = TREE_CODE (type0);
7635 code1 = TREE_CODE (type1);
7637 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7638 /* Choose the wider of two real types. */
7639 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7640 ? type0 : type1;
7641 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7642 cmp_type = type0;
7643 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7644 cmp_type = type1;
7645 else
7647 error ("non-floating-point argument to function %qs",
7648 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7649 return error_mark_node;
7652 arg0 = fold_convert (cmp_type, arg0);
7653 arg1 = fold_convert (cmp_type, arg1);
7655 if (unordered_code == UNORDERED_EXPR)
7657 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7658 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7659 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7662 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7663 : ordered_code;
7664 return fold (build1 (TRUTH_NOT_EXPR, type,
7665 fold (build2 (code, type, arg0, arg1))));
7668 /* Used by constant folding to simplify calls to builtin functions. EXP is
7669 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7670 result of the function call is ignored. This function returns NULL_TREE
7671 if no simplification was possible. */
7673 static tree
7674 fold_builtin_1 (tree exp, bool ignore)
7676 tree fndecl = get_callee_fndecl (exp);
7677 tree arglist = TREE_OPERAND (exp, 1);
7678 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7680 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7681 return targetm.fold_builtin (exp, ignore);
7683 switch (DECL_FUNCTION_CODE (fndecl))
7685 case BUILT_IN_FPUTS:
7686 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7688 case BUILT_IN_FPUTS_UNLOCKED:
7689 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7691 case BUILT_IN_STRSTR:
7692 return fold_builtin_strstr (arglist);
7694 case BUILT_IN_STRCAT:
7695 return fold_builtin_strcat (arglist);
7697 case BUILT_IN_STRNCAT:
7698 return fold_builtin_strncat (arglist);
7700 case BUILT_IN_STRSPN:
7701 return fold_builtin_strspn (arglist);
7703 case BUILT_IN_STRCSPN:
7704 return fold_builtin_strcspn (arglist);
7706 case BUILT_IN_STRCHR:
7707 case BUILT_IN_INDEX:
7708 return fold_builtin_strchr (arglist);
7710 case BUILT_IN_STRRCHR:
7711 case BUILT_IN_RINDEX:
7712 return fold_builtin_strrchr (arglist);
7714 case BUILT_IN_STRCPY:
7715 return fold_builtin_strcpy (exp, NULL_TREE);
7717 case BUILT_IN_STRNCPY:
7718 return fold_builtin_strncpy (exp, NULL_TREE);
7720 case BUILT_IN_STRCMP:
7721 return fold_builtin_strcmp (arglist);
7723 case BUILT_IN_STRNCMP:
7724 return fold_builtin_strncmp (arglist);
7726 case BUILT_IN_STRPBRK:
7727 return fold_builtin_strpbrk (arglist);
7729 case BUILT_IN_BCMP:
7730 case BUILT_IN_MEMCMP:
7731 return fold_builtin_memcmp (arglist);
7733 case BUILT_IN_SPRINTF:
7734 return fold_builtin_sprintf (arglist, ignore);
7736 case BUILT_IN_CONSTANT_P:
7738 tree val;
7740 val = fold_builtin_constant_p (arglist);
7741 /* Gimplification will pull the CALL_EXPR for the builtin out of
7742 an if condition. When not optimizing, we'll not CSE it back.
7743 To avoid link error types of regressions, return false now. */
7744 if (!val && !optimize)
7745 val = integer_zero_node;
7747 return val;
7750 case BUILT_IN_EXPECT:
7751 return fold_builtin_expect (arglist);
7753 case BUILT_IN_CLASSIFY_TYPE:
7754 return fold_builtin_classify_type (arglist);
7756 case BUILT_IN_STRLEN:
7757 return fold_builtin_strlen (arglist);
7759 case BUILT_IN_FABS:
7760 case BUILT_IN_FABSF:
7761 case BUILT_IN_FABSL:
7762 return fold_builtin_fabs (arglist, type);
7764 case BUILT_IN_ABS:
7765 case BUILT_IN_LABS:
7766 case BUILT_IN_LLABS:
7767 case BUILT_IN_IMAXABS:
7768 return fold_builtin_abs (arglist, type);
7770 case BUILT_IN_CONJ:
7771 case BUILT_IN_CONJF:
7772 case BUILT_IN_CONJL:
7773 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7774 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7775 break;
7777 case BUILT_IN_CREAL:
7778 case BUILT_IN_CREALF:
7779 case BUILT_IN_CREALL:
7780 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7781 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7782 TREE_VALUE (arglist))));
7783 break;
7785 case BUILT_IN_CIMAG:
7786 case BUILT_IN_CIMAGF:
7787 case BUILT_IN_CIMAGL:
7788 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7789 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7790 TREE_VALUE (arglist))));
7791 break;
7793 case BUILT_IN_CABS:
7794 case BUILT_IN_CABSF:
7795 case BUILT_IN_CABSL:
7796 return fold_builtin_cabs (arglist, type);
7798 case BUILT_IN_SQRT:
7799 case BUILT_IN_SQRTF:
7800 case BUILT_IN_SQRTL:
7801 return fold_builtin_sqrt (arglist, type);
7803 case BUILT_IN_CBRT:
7804 case BUILT_IN_CBRTF:
7805 case BUILT_IN_CBRTL:
7806 return fold_builtin_cbrt (arglist, type);
7808 case BUILT_IN_SIN:
7809 case BUILT_IN_SINF:
7810 case BUILT_IN_SINL:
7811 return fold_builtin_sin (arglist);
7813 case BUILT_IN_COS:
7814 case BUILT_IN_COSF:
7815 case BUILT_IN_COSL:
7816 return fold_builtin_cos (arglist, type, fndecl);
7818 case BUILT_IN_EXP:
7819 case BUILT_IN_EXPF:
7820 case BUILT_IN_EXPL:
7821 return fold_builtin_exponent (exp, &dconste);
7823 case BUILT_IN_EXP2:
7824 case BUILT_IN_EXP2F:
7825 case BUILT_IN_EXP2L:
7826 return fold_builtin_exponent (exp, &dconst2);
7828 case BUILT_IN_EXP10:
7829 case BUILT_IN_EXP10F:
7830 case BUILT_IN_EXP10L:
7831 case BUILT_IN_POW10:
7832 case BUILT_IN_POW10F:
7833 case BUILT_IN_POW10L:
7834 return fold_builtin_exponent (exp, &dconst10);
7836 case BUILT_IN_LOG:
7837 case BUILT_IN_LOGF:
7838 case BUILT_IN_LOGL:
7839 return fold_builtin_logarithm (exp, &dconste);
7841 case BUILT_IN_LOG2:
7842 case BUILT_IN_LOG2F:
7843 case BUILT_IN_LOG2L:
7844 return fold_builtin_logarithm (exp, &dconst2);
7846 case BUILT_IN_LOG10:
7847 case BUILT_IN_LOG10F:
7848 case BUILT_IN_LOG10L:
7849 return fold_builtin_logarithm (exp, &dconst10);
7851 case BUILT_IN_TAN:
7852 case BUILT_IN_TANF:
7853 case BUILT_IN_TANL:
7854 return fold_builtin_tan (arglist);
7856 case BUILT_IN_ATAN:
7857 case BUILT_IN_ATANF:
7858 case BUILT_IN_ATANL:
7859 return fold_builtin_atan (arglist, type);
7861 case BUILT_IN_POW:
7862 case BUILT_IN_POWF:
7863 case BUILT_IN_POWL:
7864 return fold_builtin_pow (fndecl, arglist, type);
7866 case BUILT_IN_INF:
7867 case BUILT_IN_INFF:
7868 case BUILT_IN_INFL:
7869 return fold_builtin_inf (type, true);
7871 case BUILT_IN_HUGE_VAL:
7872 case BUILT_IN_HUGE_VALF:
7873 case BUILT_IN_HUGE_VALL:
7874 return fold_builtin_inf (type, false);
7876 case BUILT_IN_NAN:
7877 case BUILT_IN_NANF:
7878 case BUILT_IN_NANL:
7879 return fold_builtin_nan (arglist, type, true);
7881 case BUILT_IN_NANS:
7882 case BUILT_IN_NANSF:
7883 case BUILT_IN_NANSL:
7884 return fold_builtin_nan (arglist, type, false);
7886 case BUILT_IN_FLOOR:
7887 case BUILT_IN_FLOORF:
7888 case BUILT_IN_FLOORL:
7889 return fold_builtin_floor (exp);
7891 case BUILT_IN_CEIL:
7892 case BUILT_IN_CEILF:
7893 case BUILT_IN_CEILL:
7894 return fold_builtin_ceil (exp);
7896 case BUILT_IN_TRUNC:
7897 case BUILT_IN_TRUNCF:
7898 case BUILT_IN_TRUNCL:
7899 return fold_builtin_trunc (exp);
7901 case BUILT_IN_ROUND:
7902 case BUILT_IN_ROUNDF:
7903 case BUILT_IN_ROUNDL:
7904 return fold_builtin_round (exp);
7906 case BUILT_IN_NEARBYINT:
7907 case BUILT_IN_NEARBYINTF:
7908 case BUILT_IN_NEARBYINTL:
7909 case BUILT_IN_RINT:
7910 case BUILT_IN_RINTF:
7911 case BUILT_IN_RINTL:
7912 return fold_trunc_transparent_mathfn (exp);
7914 case BUILT_IN_LROUND:
7915 case BUILT_IN_LROUNDF:
7916 case BUILT_IN_LROUNDL:
7917 case BUILT_IN_LLROUND:
7918 case BUILT_IN_LLROUNDF:
7919 case BUILT_IN_LLROUNDL:
7920 return fold_builtin_lround (exp);
7922 case BUILT_IN_LRINT:
7923 case BUILT_IN_LRINTF:
7924 case BUILT_IN_LRINTL:
7925 case BUILT_IN_LLRINT:
7926 case BUILT_IN_LLRINTF:
7927 case BUILT_IN_LLRINTL:
7928 return fold_fixed_mathfn (exp);
7930 case BUILT_IN_FFS:
7931 case BUILT_IN_FFSL:
7932 case BUILT_IN_FFSLL:
7933 case BUILT_IN_CLZ:
7934 case BUILT_IN_CLZL:
7935 case BUILT_IN_CLZLL:
7936 case BUILT_IN_CTZ:
7937 case BUILT_IN_CTZL:
7938 case BUILT_IN_CTZLL:
7939 case BUILT_IN_POPCOUNT:
7940 case BUILT_IN_POPCOUNTL:
7941 case BUILT_IN_POPCOUNTLL:
7942 case BUILT_IN_PARITY:
7943 case BUILT_IN_PARITYL:
7944 case BUILT_IN_PARITYLL:
7945 return fold_builtin_bitop (exp);
7947 case BUILT_IN_MEMCPY:
7948 return fold_builtin_memcpy (exp);
7950 case BUILT_IN_MEMPCPY:
7951 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
7953 case BUILT_IN_MEMMOVE:
7954 return fold_builtin_memmove (arglist, type);
7956 case BUILT_IN_SIGNBIT:
7957 case BUILT_IN_SIGNBITF:
7958 case BUILT_IN_SIGNBITL:
7959 return fold_builtin_signbit (exp);
7961 case BUILT_IN_ISASCII:
7962 return fold_builtin_isascii (arglist);
7964 case BUILT_IN_TOASCII:
7965 return fold_builtin_toascii (arglist);
7967 case BUILT_IN_ISDIGIT:
7968 return fold_builtin_isdigit (arglist);
7970 case BUILT_IN_COPYSIGN:
7971 case BUILT_IN_COPYSIGNF:
7972 case BUILT_IN_COPYSIGNL:
7973 return fold_builtin_copysign (arglist, type);
7975 case BUILT_IN_FINITE:
7976 case BUILT_IN_FINITEF:
7977 case BUILT_IN_FINITEL:
7978 return fold_builtin_classify (exp, BUILT_IN_FINITE);
7980 case BUILT_IN_ISINF:
7981 case BUILT_IN_ISINFF:
7982 case BUILT_IN_ISINFL:
7983 return fold_builtin_classify (exp, BUILT_IN_ISINF);
7985 case BUILT_IN_ISNAN:
7986 case BUILT_IN_ISNANF:
7987 case BUILT_IN_ISNANL:
7988 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
7990 case BUILT_IN_ISGREATER:
7991 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
7992 case BUILT_IN_ISGREATEREQUAL:
7993 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
7994 case BUILT_IN_ISLESS:
7995 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
7996 case BUILT_IN_ISLESSEQUAL:
7997 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
7998 case BUILT_IN_ISLESSGREATER:
7999 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8000 case BUILT_IN_ISUNORDERED:
8001 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8003 /* We do the folding for va_start in the expander. */
8004 case BUILT_IN_VA_START:
8005 break;
8007 default:
8008 break;
8011 return 0;
8014 /* A wrapper function for builtin folding that prevents warnings for
8015 "statement without effect" and the like, caused by removing the
8016 call node earlier than the warning is generated. */
8018 tree
8019 fold_builtin (tree exp, bool ignore)
8021 exp = fold_builtin_1 (exp, ignore);
8022 if (exp)
8024 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8025 if (CONSTANT_CLASS_P (exp))
8026 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8027 TREE_NO_WARNING (exp) = 1;
8030 return exp;
8033 /* Conveniently construct a function call expression. */
8035 tree
8036 build_function_call_expr (tree fn, tree arglist)
8038 tree call_expr;
8040 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8041 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8042 call_expr, arglist, NULL_TREE);
8043 return fold (call_expr);
8046 /* This function validates the types of a function call argument list
8047 represented as a tree chain of parameters against a specified list
8048 of tree_codes. If the last specifier is a 0, that represents an
8049 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8051 static int
8052 validate_arglist (tree arglist, ...)
8054 enum tree_code code;
8055 int res = 0;
8056 va_list ap;
8058 va_start (ap, arglist);
8062 code = va_arg (ap, enum tree_code);
8063 switch (code)
8065 case 0:
8066 /* This signifies an ellipses, any further arguments are all ok. */
8067 res = 1;
8068 goto end;
8069 case VOID_TYPE:
8070 /* This signifies an endlink, if no arguments remain, return
8071 true, otherwise return false. */
8072 res = arglist == 0;
8073 goto end;
8074 default:
8075 /* If no parameters remain or the parameter's code does not
8076 match the specified code, return false. Otherwise continue
8077 checking any remaining arguments. */
8078 if (arglist == 0
8079 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8080 goto end;
8081 break;
8083 arglist = TREE_CHAIN (arglist);
8085 while (1);
8087 /* We need gotos here since we can only have one VA_CLOSE in a
8088 function. */
8089 end: ;
8090 va_end (ap);
8092 return res;
8095 /* Default target-specific builtin expander that does nothing. */
8098 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8099 rtx target ATTRIBUTE_UNUSED,
8100 rtx subtarget ATTRIBUTE_UNUSED,
8101 enum machine_mode mode ATTRIBUTE_UNUSED,
8102 int ignore ATTRIBUTE_UNUSED)
8104 return NULL_RTX;
8107 /* Returns true is EXP represents data that would potentially reside
8108 in a readonly section. */
8110 static bool
8111 readonly_data_expr (tree exp)
8113 STRIP_NOPS (exp);
8115 if (TREE_CODE (exp) != ADDR_EXPR)
8116 return false;
8118 exp = get_base_address (TREE_OPERAND (exp, 0));
8119 if (!exp)
8120 return false;
8122 /* Make sure we call decl_readonly_section only for trees it
8123 can handle (since it returns true for everything it doesn't
8124 understand). */
8125 if (TREE_CODE (exp) == STRING_CST
8126 || TREE_CODE (exp) == CONSTRUCTOR
8127 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8128 return decl_readonly_section (exp, 0);
8129 else
8130 return false;
8133 /* Simplify a call to the strstr builtin.
8135 Return 0 if no simplification was possible, otherwise return the
8136 simplified form of the call as a tree.
8138 The simplified form may be a constant or other expression which
8139 computes the same value, but in a more efficient manner (including
8140 calls to other builtin functions).
8142 The call may contain arguments which need to be evaluated, but
8143 which are not useful to determine the result of the call. In
8144 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8145 COMPOUND_EXPR will be an argument which must be evaluated.
8146 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8147 COMPOUND_EXPR in the chain will contain the tree for the simplified
8148 form of the builtin function call. */
8150 static tree
8151 fold_builtin_strstr (tree arglist)
8153 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8154 return 0;
8155 else
8157 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8158 tree fn;
8159 const char *p1, *p2;
8161 p2 = c_getstr (s2);
8162 if (p2 == NULL)
8163 return 0;
8165 p1 = c_getstr (s1);
8166 if (p1 != NULL)
8168 const char *r = strstr (p1, p2);
8170 if (r == NULL)
8171 return build_int_cst (TREE_TYPE (s1), 0);
8173 /* Return an offset into the constant string argument. */
8174 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8175 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8178 if (p2[0] == '\0')
8179 return s1;
8181 if (p2[1] != '\0')
8182 return 0;
8184 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8185 if (!fn)
8186 return 0;
8188 /* New argument list transforming strstr(s1, s2) to
8189 strchr(s1, s2[0]). */
8190 arglist = build_tree_list (NULL_TREE,
8191 build_int_cst (NULL_TREE, p2[0]));
8192 arglist = tree_cons (NULL_TREE, s1, arglist);
8193 return build_function_call_expr (fn, arglist);
8197 /* Simplify a call to the strchr builtin.
8199 Return 0 if no simplification was possible, otherwise return the
8200 simplified form of the call as a tree.
8202 The simplified form may be a constant or other expression which
8203 computes the same value, but in a more efficient manner (including
8204 calls to other builtin functions).
8206 The call may contain arguments which need to be evaluated, but
8207 which are not useful to determine the result of the call. In
8208 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8209 COMPOUND_EXPR will be an argument which must be evaluated.
8210 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8211 COMPOUND_EXPR in the chain will contain the tree for the simplified
8212 form of the builtin function call. */
8214 static tree
8215 fold_builtin_strchr (tree arglist)
8217 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8218 return 0;
8219 else
8221 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8222 const char *p1;
8224 if (TREE_CODE (s2) != INTEGER_CST)
8225 return 0;
8227 p1 = c_getstr (s1);
8228 if (p1 != NULL)
8230 char c;
8231 const char *r;
8233 if (target_char_cast (s2, &c))
8234 return 0;
8236 r = strchr (p1, c);
8238 if (r == NULL)
8239 return build_int_cst (TREE_TYPE (s1), 0);
8241 /* Return an offset into the constant string argument. */
8242 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8243 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8245 return 0;
8249 /* Simplify a call to the strrchr builtin.
8251 Return 0 if no simplification was possible, otherwise return the
8252 simplified form of the call as a tree.
8254 The simplified form may be a constant or other expression which
8255 computes the same value, but in a more efficient manner (including
8256 calls to other builtin functions).
8258 The call may contain arguments which need to be evaluated, but
8259 which are not useful to determine the result of the call. In
8260 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8261 COMPOUND_EXPR will be an argument which must be evaluated.
8262 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8263 COMPOUND_EXPR in the chain will contain the tree for the simplified
8264 form of the builtin function call. */
8266 static tree
8267 fold_builtin_strrchr (tree arglist)
8269 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8270 return 0;
8271 else
8273 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8274 tree fn;
8275 const char *p1;
8277 if (TREE_CODE (s2) != INTEGER_CST)
8278 return 0;
8280 p1 = c_getstr (s1);
8281 if (p1 != NULL)
8283 char c;
8284 const char *r;
8286 if (target_char_cast (s2, &c))
8287 return 0;
8289 r = strrchr (p1, c);
8291 if (r == NULL)
8292 return build_int_cst (TREE_TYPE (s1), 0);
8294 /* Return an offset into the constant string argument. */
8295 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8296 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8299 if (! integer_zerop (s2))
8300 return 0;
8302 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8303 if (!fn)
8304 return 0;
8306 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8307 return build_function_call_expr (fn, arglist);
8311 /* Simplify a call to the strpbrk builtin.
8313 Return 0 if no simplification was possible, otherwise return the
8314 simplified form of the call as a tree.
8316 The simplified form may be a constant or other expression which
8317 computes the same value, but in a more efficient manner (including
8318 calls to other builtin functions).
8320 The call may contain arguments which need to be evaluated, but
8321 which are not useful to determine the result of the call. In
8322 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8323 COMPOUND_EXPR will be an argument which must be evaluated.
8324 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8325 COMPOUND_EXPR in the chain will contain the tree for the simplified
8326 form of the builtin function call. */
8328 static tree
8329 fold_builtin_strpbrk (tree arglist)
8331 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8332 return 0;
8333 else
8335 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8336 tree fn;
8337 const char *p1, *p2;
8339 p2 = c_getstr (s2);
8340 if (p2 == NULL)
8341 return 0;
8343 p1 = c_getstr (s1);
8344 if (p1 != NULL)
8346 const char *r = strpbrk (p1, p2);
8348 if (r == NULL)
8349 return build_int_cst (TREE_TYPE (s1), 0);
8351 /* Return an offset into the constant string argument. */
8352 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8353 s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8356 if (p2[0] == '\0')
8357 /* strpbrk(x, "") == NULL.
8358 Evaluate and ignore s1 in case it had side-effects. */
8359 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8361 if (p2[1] != '\0')
8362 return 0; /* Really call strpbrk. */
8364 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8365 if (!fn)
8366 return 0;
8368 /* New argument list transforming strpbrk(s1, s2) to
8369 strchr(s1, s2[0]). */
8370 arglist = build_tree_list (NULL_TREE,
8371 build_int_cst (NULL_TREE, p2[0]));
8372 arglist = tree_cons (NULL_TREE, s1, arglist);
8373 return build_function_call_expr (fn, arglist);
8377 /* Simplify a call to the strcat builtin.
8379 Return 0 if no simplification was possible, otherwise return the
8380 simplified form of the call as a tree.
8382 The simplified form may be a constant or other expression which
8383 computes the same value, but in a more efficient manner (including
8384 calls to other builtin functions).
8386 The call may contain arguments which need to be evaluated, but
8387 which are not useful to determine the result of the call. In
8388 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8389 COMPOUND_EXPR will be an argument which must be evaluated.
8390 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8391 COMPOUND_EXPR in the chain will contain the tree for the simplified
8392 form of the builtin function call. */
8394 static tree
8395 fold_builtin_strcat (tree arglist)
8397 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8398 return 0;
8399 else
8401 tree dst = TREE_VALUE (arglist),
8402 src = TREE_VALUE (TREE_CHAIN (arglist));
8403 const char *p = c_getstr (src);
8405 /* If the string length is zero, return the dst parameter. */
8406 if (p && *p == '\0')
8407 return dst;
8409 return 0;
8413 /* Simplify a call to the strncat builtin.
8415 Return 0 if no simplification was possible, otherwise return the
8416 simplified form of the call as a tree.
8418 The simplified form may be a constant or other expression which
8419 computes the same value, but in a more efficient manner (including
8420 calls to other builtin functions).
8422 The call may contain arguments which need to be evaluated, but
8423 which are not useful to determine the result of the call. In
8424 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8425 COMPOUND_EXPR will be an argument which must be evaluated.
8426 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8427 COMPOUND_EXPR in the chain will contain the tree for the simplified
8428 form of the builtin function call. */
8430 static tree
8431 fold_builtin_strncat (tree arglist)
8433 if (!validate_arglist (arglist,
8434 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8435 return 0;
8436 else
8438 tree dst = TREE_VALUE (arglist);
8439 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8440 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8441 const char *p = c_getstr (src);
8443 /* If the requested length is zero, or the src parameter string
8444 length is zero, return the dst parameter. */
8445 if (integer_zerop (len) || (p && *p == '\0'))
8446 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8448 /* If the requested len is greater than or equal to the string
8449 length, call strcat. */
8450 if (TREE_CODE (len) == INTEGER_CST && p
8451 && compare_tree_int (len, strlen (p)) >= 0)
8453 tree newarglist
8454 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8455 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8457 /* If the replacement _DECL isn't initialized, don't do the
8458 transformation. */
8459 if (!fn)
8460 return 0;
8462 return build_function_call_expr (fn, newarglist);
8464 return 0;
8468 /* Simplify a call to the strspn builtin.
8470 Return 0 if no simplification was possible, otherwise return the
8471 simplified form of the call as a tree.
8473 The simplified form may be a constant or other expression which
8474 computes the same value, but in a more efficient manner (including
8475 calls to other builtin functions).
8477 The call may contain arguments which need to be evaluated, but
8478 which are not useful to determine the result of the call. In
8479 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8480 COMPOUND_EXPR will be an argument which must be evaluated.
8481 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8482 COMPOUND_EXPR in the chain will contain the tree for the simplified
8483 form of the builtin function call. */
8485 static tree
8486 fold_builtin_strspn (tree arglist)
8488 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8489 return 0;
8490 else
8492 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8493 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8495 /* If both arguments are constants, evaluate at compile-time. */
8496 if (p1 && p2)
8498 const size_t r = strspn (p1, p2);
8499 return size_int (r);
8502 /* If either argument is "", return 0. */
8503 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8504 /* Evaluate and ignore both arguments in case either one has
8505 side-effects. */
8506 return omit_two_operands (integer_type_node, integer_zero_node,
8507 s1, s2);
8508 return 0;
8512 /* Simplify a call to the strcspn builtin.
8514 Return 0 if no simplification was possible, otherwise return the
8515 simplified form of the call as a tree.
8517 The simplified form may be a constant or other expression which
8518 computes the same value, but in a more efficient manner (including
8519 calls to other builtin functions).
8521 The call may contain arguments which need to be evaluated, but
8522 which are not useful to determine the result of the call. In
8523 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8524 COMPOUND_EXPR will be an argument which must be evaluated.
8525 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8526 COMPOUND_EXPR in the chain will contain the tree for the simplified
8527 form of the builtin function call. */
8529 static tree
8530 fold_builtin_strcspn (tree arglist)
8532 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8533 return 0;
8534 else
8536 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8537 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8539 /* If both arguments are constants, evaluate at compile-time. */
8540 if (p1 && p2)
8542 const size_t r = strcspn (p1, p2);
8543 return size_int (r);
8546 /* If the first argument is "", return 0. */
8547 if (p1 && *p1 == '\0')
8549 /* Evaluate and ignore argument s2 in case it has
8550 side-effects. */
8551 return omit_one_operand (integer_type_node,
8552 integer_zero_node, s2);
8555 /* If the second argument is "", return __builtin_strlen(s1). */
8556 if (p2 && *p2 == '\0')
8558 tree newarglist = build_tree_list (NULL_TREE, s1),
8559 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8561 /* If the replacement _DECL isn't initialized, don't do the
8562 transformation. */
8563 if (!fn)
8564 return 0;
8566 return build_function_call_expr (fn, newarglist);
8568 return 0;
8572 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
8573 by the builtin will be ignored. UNLOCKED is true is true if this
8574 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
8575 the known length of the string. Return NULL_TREE if no simplification
8576 was possible. */
8578 tree
8579 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8581 tree fn;
8582 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8583 : implicit_built_in_decls[BUILT_IN_FPUTC];
8584 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8585 : implicit_built_in_decls[BUILT_IN_FWRITE];
8587 /* If the return value is used, or the replacement _DECL isn't
8588 initialized, don't do the transformation. */
8589 if (!ignore || !fn_fputc || !fn_fwrite)
8590 return 0;
8592 /* Verify the arguments in the original call. */
8593 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8594 return 0;
8596 if (! len)
8597 len = c_strlen (TREE_VALUE (arglist), 0);
8599 /* Get the length of the string passed to fputs. If the length
8600 can't be determined, punt. */
8601 if (!len
8602 || TREE_CODE (len) != INTEGER_CST)
8603 return 0;
8605 switch (compare_tree_int (len, 1))
8607 case -1: /* length is 0, delete the call entirely . */
8608 return omit_one_operand (integer_type_node, integer_zero_node,
8609 TREE_VALUE (TREE_CHAIN (arglist)));
8611 case 0: /* length is 1, call fputc. */
8613 const char *p = c_getstr (TREE_VALUE (arglist));
8615 if (p != NULL)
8617 /* New argument list transforming fputs(string, stream) to
8618 fputc(string[0], stream). */
8619 arglist = build_tree_list (NULL_TREE,
8620 TREE_VALUE (TREE_CHAIN (arglist)));
8621 arglist = tree_cons (NULL_TREE,
8622 build_int_cst (NULL_TREE, p[0]),
8623 arglist);
8624 fn = fn_fputc;
8625 break;
8628 /* FALLTHROUGH */
8629 case 1: /* length is greater than 1, call fwrite. */
8631 tree string_arg;
8633 /* If optimizing for size keep fputs. */
8634 if (optimize_size)
8635 return 0;
8636 string_arg = TREE_VALUE (arglist);
8637 /* New argument list transforming fputs(string, stream) to
8638 fwrite(string, 1, len, stream). */
8639 arglist = build_tree_list (NULL_TREE,
8640 TREE_VALUE (TREE_CHAIN (arglist)));
8641 arglist = tree_cons (NULL_TREE, len, arglist);
8642 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8643 arglist = tree_cons (NULL_TREE, string_arg, arglist);
8644 fn = fn_fwrite;
8645 break;
8647 default:
8648 gcc_unreachable ();
8651 /* These optimizations are only performed when the result is ignored,
8652 hence there's no need to cast the result to integer_type_node. */
8653 return build_function_call_expr (fn, arglist);
8656 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
8657 produced. False otherwise. This is done so that we don't output the error
8658 or warning twice or three times. */
8659 bool
8660 fold_builtin_next_arg (tree arglist)
8662 tree fntype = TREE_TYPE (current_function_decl);
8664 if (TYPE_ARG_TYPES (fntype) == 0
8665 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8666 == void_type_node))
8668 error ("%<va_start%> used in function with fixed args");
8669 return true;
8671 else if (arglist)
8673 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8674 tree arg = TREE_VALUE (arglist);
8676 /* Strip off all nops for the sake of the comparison. This
8677 is not quite the same as STRIP_NOPS. It does more.
8678 We must also strip off INDIRECT_EXPR for C++ reference
8679 parameters. */
8680 while (TREE_CODE (arg) == NOP_EXPR
8681 || TREE_CODE (arg) == CONVERT_EXPR
8682 || TREE_CODE (arg) == NON_LVALUE_EXPR
8683 || TREE_CODE (arg) == INDIRECT_REF)
8684 arg = TREE_OPERAND (arg, 0);
8685 if (arg != last_parm)
8687 /* FIXME: Sometimes with the tree optimizers we can get the
8688 not the last argument even though the user used the last
8689 argument. We just warn and set the arg to be the last
8690 argument so that we will get wrong-code because of
8691 it. */
8692 arg = last_parm;
8693 warning ("second parameter of %<va_start%> not last named argument");
8695 TREE_VALUE (arglist) = arg;
8697 else
8699 /* Evidently an out of date version of <stdarg.h>; can't validate
8700 va_start's second argument, but can still work as intended. */
8701 warning ("%<__builtin_next_arg%> called without an argument");
8702 return true;
8704 return false;
8708 /* Simplify a call to the sprintf builtin.
8710 Return 0 if no simplification was possible, otherwise return the
8711 simplified form of the call as a tree. If IGNORED is true, it means that
8712 the caller does not use the returned value of the function. */
8714 static tree
8715 fold_builtin_sprintf (tree arglist, int ignored)
8717 tree call, retval, dest, fmt;
8718 const char *fmt_str = NULL;
8720 /* Verify the required arguments in the original call. We deal with two
8721 types of sprintf() calls: 'sprintf (str, fmt)' and
8722 'sprintf (dest, "%s", orig)'. */
8723 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8724 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8725 VOID_TYPE))
8726 return NULL_TREE;
8728 /* Get the destination string and the format specifier. */
8729 dest = TREE_VALUE (arglist);
8730 fmt = TREE_VALUE (TREE_CHAIN (arglist));
8732 /* Check whether the format is a literal string constant. */
8733 fmt_str = c_getstr (fmt);
8734 if (fmt_str == NULL)
8735 return NULL_TREE;
8737 call = NULL_TREE;
8738 retval = NULL_TREE;
8740 /* If the format doesn't contain % args or %%, use strcpy. */
8741 if (strchr (fmt_str, '%') == NULL)
8743 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8745 if (!fn)
8746 return NULL_TREE;
8748 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8749 'format' is known to contain no % formats. */
8750 arglist = build_tree_list (NULL_TREE, fmt);
8751 arglist = tree_cons (NULL_TREE, dest, arglist);
8752 call = build_function_call_expr (fn, arglist);
8753 if (!ignored)
8754 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
8757 /* If the format is "%s", use strcpy if the result isn't used. */
8758 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
8760 tree fn, orig;
8761 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8763 if (!fn)
8764 return NULL_TREE;
8766 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
8767 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8768 arglist = build_tree_list (NULL_TREE, orig);
8769 arglist = tree_cons (NULL_TREE, dest, arglist);
8770 if (!ignored)
8772 retval = c_strlen (orig, 1);
8773 if (!retval || TREE_CODE (retval) != INTEGER_CST)
8774 return NULL_TREE;
8776 call = build_function_call_expr (fn, arglist);
8779 if (call && retval)
8781 retval = convert
8782 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
8783 retval);
8784 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
8786 else
8787 return call;