Imported GNU Classpath 0.90
[official-gcc.git] / gcc / builtins.c
blob1ce6083137ae782d20083f30adc62d93bc361804
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_sin (tree);
155 static tree fold_builtin_cos (tree, tree, tree);
156 static tree fold_builtin_tan (tree);
157 static tree fold_builtin_atan (tree, tree);
158 static tree fold_builtin_trunc (tree, tree);
159 static tree fold_builtin_floor (tree, tree);
160 static tree fold_builtin_ceil (tree, tree);
161 static tree fold_builtin_round (tree, tree);
162 static tree fold_builtin_int_roundingfn (tree, tree);
163 static tree fold_builtin_bitop (tree, tree);
164 static tree fold_builtin_memcpy (tree, tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree, tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree, tree);
172 static tree fold_builtin_copysign (tree, tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 enum tree_code);
180 static tree fold_builtin_1 (tree, tree, bool);
182 static tree fold_builtin_strpbrk (tree, tree);
183 static tree fold_builtin_strstr (tree, tree);
184 static tree fold_builtin_strrchr (tree, tree);
185 static tree fold_builtin_strcat (tree);
186 static tree fold_builtin_strncat (tree);
187 static tree fold_builtin_strspn (tree);
188 static tree fold_builtin_strcspn (tree);
189 static tree fold_builtin_sprintf (tree, int);
191 static rtx expand_builtin_object_size (tree);
192 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193 enum built_in_function);
194 static void maybe_emit_chk_warning (tree, enum built_in_function);
195 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196 static tree fold_builtin_object_size (tree);
197 static tree fold_builtin_strcat_chk (tree, tree);
198 static tree fold_builtin_strncat_chk (tree, tree);
199 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline;
205 static unsigned HOST_WIDE_INT target_percent;
206 static unsigned HOST_WIDE_INT target_c;
207 static unsigned HOST_WIDE_INT target_s;
208 static char target_percent_c[3];
209 static char target_percent_s[3];
210 static char target_percent_s_newline[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node)
218 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
219 if (strncmp (name, "__builtin_", 10) == 0)
220 return true;
221 if (strncmp (name, "__sync_", 7) == 0)
222 return true;
223 return false;
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
234 static int
235 get_pointer_alignment (tree exp, unsigned int max_align)
237 unsigned int align, inner;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
240 return 0;
242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243 align = MIN (align, max_align);
245 while (1)
247 switch (TREE_CODE (exp))
249 case NOP_EXPR:
250 case CONVERT_EXPR:
251 case NON_LVALUE_EXPR:
252 exp = TREE_OPERAND (exp, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254 return align;
256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257 align = MIN (inner, max_align);
258 break;
260 case PLUS_EXPR:
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
263 ALIGN. */
264 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265 return align;
267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268 & (max_align / BITS_PER_UNIT - 1))
269 != 0)
270 max_align >>= 1;
272 exp = TREE_OPERAND (exp, 0);
273 break;
275 case ADDR_EXPR:
276 /* See what we are pointing at and look at its alignment. */
277 exp = TREE_OPERAND (exp, 0);
278 while (handled_component_p (exp))
280 if (TREE_CODE (exp) == COMPONENT_REF)
281 align = MIN (align, DECL_ALIGN (TREE_OPERAND (exp, 1)));
282 exp = TREE_OPERAND (exp, 0);
284 if (TREE_CODE (exp) == FUNCTION_DECL)
285 align = MIN (align, FUNCTION_BOUNDARY);
286 else if (DECL_P (exp))
287 align = MIN (align, DECL_ALIGN (exp));
288 #ifdef CONSTANT_ALIGNMENT
289 else if (CONSTANT_CLASS_P (exp))
290 align = MIN (align, (unsigned)CONSTANT_ALIGNMENT (exp, align));
291 #endif
292 return align;
294 default:
295 return align;
300 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
301 way, because it could contain a zero byte in the middle.
302 TREE_STRING_LENGTH is the size of the character array, not the string.
304 ONLY_VALUE should be nonzero if the result is not going to be emitted
305 into the instruction stream and zero if it is going to be expanded.
306 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
307 is returned, otherwise NULL, since
308 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
309 evaluate the side-effects.
311 The value returned is of type `ssizetype'.
313 Unfortunately, string_constant can't access the values of const char
314 arrays with initializers, so neither can we do so here. */
316 tree
317 c_strlen (tree src, int only_value)
319 tree offset_node;
320 HOST_WIDE_INT offset;
321 int max;
322 const char *ptr;
324 STRIP_NOPS (src);
325 if (TREE_CODE (src) == COND_EXPR
326 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
328 tree len1, len2;
330 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
331 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
332 if (tree_int_cst_equal (len1, len2))
333 return len1;
336 if (TREE_CODE (src) == COMPOUND_EXPR
337 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
338 return c_strlen (TREE_OPERAND (src, 1), only_value);
340 src = string_constant (src, &offset_node);
341 if (src == 0)
342 return 0;
344 max = TREE_STRING_LENGTH (src) - 1;
345 ptr = TREE_STRING_POINTER (src);
347 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
349 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
350 compute the offset to the following null if we don't know where to
351 start searching for it. */
352 int i;
354 for (i = 0; i < max; i++)
355 if (ptr[i] == 0)
356 return 0;
358 /* We don't know the starting offset, but we do know that the string
359 has no internal zero bytes. We can assume that the offset falls
360 within the bounds of the string; otherwise, the programmer deserves
361 what he gets. Subtract the offset from the length of the string,
362 and return that. This would perhaps not be valid if we were dealing
363 with named arrays in addition to literal string constants. */
365 return size_diffop (size_int (max), offset_node);
368 /* We have a known offset into the string. Start searching there for
369 a null character if we can represent it as a single HOST_WIDE_INT. */
370 if (offset_node == 0)
371 offset = 0;
372 else if (! host_integerp (offset_node, 0))
373 offset = -1;
374 else
375 offset = tree_low_cst (offset_node, 0);
377 /* If the offset is known to be out of bounds, warn, and call strlen at
378 runtime. */
379 if (offset < 0 || offset > max)
381 warning (0, "offset outside bounds of constant string");
382 return 0;
385 /* Use strlen to search for the first zero byte. Since any strings
386 constructed with build_string will have nulls appended, we win even
387 if we get handed something like (char[4])"abcd".
389 Since OFFSET is our starting index into the string, no further
390 calculation is needed. */
391 return ssize_int (strlen (ptr + offset));
394 /* Return a char pointer for a C string if it is a string constant
395 or sum of string constant and integer constant. */
397 static const char *
398 c_getstr (tree src)
400 tree offset_node;
402 src = string_constant (src, &offset_node);
403 if (src == 0)
404 return 0;
406 if (offset_node == 0)
407 return TREE_STRING_POINTER (src);
408 else if (!host_integerp (offset_node, 1)
409 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
410 return 0;
412 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
415 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
416 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
418 static rtx
419 c_readstr (const char *str, enum machine_mode mode)
421 HOST_WIDE_INT c[2];
422 HOST_WIDE_INT ch;
423 unsigned int i, j;
425 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
427 c[0] = 0;
428 c[1] = 0;
429 ch = 1;
430 for (i = 0; i < GET_MODE_SIZE (mode); i++)
432 j = i;
433 if (WORDS_BIG_ENDIAN)
434 j = GET_MODE_SIZE (mode) - i - 1;
435 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
436 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
437 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
438 j *= BITS_PER_UNIT;
439 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
441 if (ch)
442 ch = (unsigned char) str[i];
443 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
445 return immed_double_const (c[0], c[1], mode);
448 /* Cast a target constant CST to target CHAR and if that value fits into
449 host char type, return zero and put that value into variable pointed to by
450 P. */
452 static int
453 target_char_cast (tree cst, char *p)
455 unsigned HOST_WIDE_INT val, hostval;
457 if (!host_integerp (cst, 1)
458 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
459 return 1;
461 val = tree_low_cst (cst, 1);
462 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
463 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
465 hostval = val;
466 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
467 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
469 if (val != hostval)
470 return 1;
472 *p = hostval;
473 return 0;
476 /* Similar to save_expr, but assumes that arbitrary code is not executed
477 in between the multiple evaluations. In particular, we assume that a
478 non-addressable local variable will not be modified. */
480 static tree
481 builtin_save_expr (tree exp)
483 if (TREE_ADDRESSABLE (exp) == 0
484 && (TREE_CODE (exp) == PARM_DECL
485 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
486 return exp;
488 return save_expr (exp);
491 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
492 times to get the address of either a higher stack frame, or a return
493 address located within it (depending on FNDECL_CODE). */
495 static rtx
496 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
498 int i;
500 #ifdef INITIAL_FRAME_ADDRESS_RTX
501 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
502 #else
503 rtx tem;
505 /* For a zero count, we don't care what frame address we return, so frame
506 pointer elimination is OK, and using the soft frame pointer is OK.
507 For a nonzero count, we require a stable offset from the current frame
508 pointer to the previous one, so we must use the hard frame pointer, and
509 we must disable frame pointer elimination. */
510 if (count == 0)
511 tem = frame_pointer_rtx;
512 else
514 tem = hard_frame_pointer_rtx;
516 /* Tell reload not to eliminate the frame pointer. */
517 current_function_accesses_prior_frames = 1;
519 #endif
521 /* Some machines need special handling before we can access
522 arbitrary frames. For example, on the sparc, we must first flush
523 all register windows to the stack. */
524 #ifdef SETUP_FRAME_ADDRESSES
525 if (count > 0)
526 SETUP_FRAME_ADDRESSES ();
527 #endif
529 /* On the sparc, the return address is not in the frame, it is in a
530 register. There is no way to access it off of the current frame
531 pointer, but it can be accessed off the previous frame pointer by
532 reading the value from the register window save area. */
533 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
534 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
535 count--;
536 #endif
538 /* Scan back COUNT frames to the specified frame. */
539 for (i = 0; i < count; i++)
541 /* Assume the dynamic chain pointer is in the word that the
542 frame address points to, unless otherwise specified. */
543 #ifdef DYNAMIC_CHAIN_ADDRESS
544 tem = DYNAMIC_CHAIN_ADDRESS (tem);
545 #endif
546 tem = memory_address (Pmode, tem);
547 tem = gen_frame_mem (Pmode, tem);
548 tem = copy_to_reg (tem);
551 /* For __builtin_frame_address, return what we've got. */
552 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
553 return tem;
555 /* For __builtin_return_address, Get the return address from that
556 frame. */
557 #ifdef RETURN_ADDR_RTX
558 tem = RETURN_ADDR_RTX (count, tem);
559 #else
560 tem = memory_address (Pmode,
561 plus_constant (tem, GET_MODE_SIZE (Pmode)));
562 tem = gen_frame_mem (Pmode, tem);
563 #endif
564 return tem;
567 /* Alias set used for setjmp buffer. */
568 static HOST_WIDE_INT setjmp_alias_set = -1;
570 /* Construct the leading half of a __builtin_setjmp call. Control will
571 return to RECEIVER_LABEL. This is used directly by sjlj exception
572 handling code. */
574 void
575 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
577 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
578 rtx stack_save;
579 rtx mem;
581 if (setjmp_alias_set == -1)
582 setjmp_alias_set = new_alias_set ();
584 buf_addr = convert_memory_address (Pmode, buf_addr);
586 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
588 /* We store the frame pointer and the address of receiver_label in
589 the buffer and use the rest of it for the stack save area, which
590 is machine-dependent. */
592 mem = gen_rtx_MEM (Pmode, buf_addr);
593 set_mem_alias_set (mem, setjmp_alias_set);
594 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
596 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
597 set_mem_alias_set (mem, setjmp_alias_set);
599 emit_move_insn (validize_mem (mem),
600 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
602 stack_save = gen_rtx_MEM (sa_mode,
603 plus_constant (buf_addr,
604 2 * GET_MODE_SIZE (Pmode)));
605 set_mem_alias_set (stack_save, setjmp_alias_set);
606 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
608 /* If there is further processing to do, do it. */
609 #ifdef HAVE_builtin_setjmp_setup
610 if (HAVE_builtin_setjmp_setup)
611 emit_insn (gen_builtin_setjmp_setup (buf_addr));
612 #endif
614 /* Tell optimize_save_area_alloca that extra work is going to
615 need to go on during alloca. */
616 current_function_calls_setjmp = 1;
618 /* Set this so all the registers get saved in our frame; we need to be
619 able to copy the saved values for any registers from frames we unwind. */
620 current_function_has_nonlocal_label = 1;
623 /* Construct the trailing part of a __builtin_setjmp call.
624 This is used directly by sjlj exception handling code. */
626 void
627 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
629 /* Clobber the FP when we get here, so we have to make sure it's
630 marked as used by this function. */
631 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
633 /* Mark the static chain as clobbered here so life information
634 doesn't get messed up for it. */
635 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
637 /* Now put in the code to restore the frame pointer, and argument
638 pointer, if needed. */
639 #ifdef HAVE_nonlocal_goto
640 if (! HAVE_nonlocal_goto)
641 #endif
642 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
644 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
645 if (fixed_regs[ARG_POINTER_REGNUM])
647 #ifdef ELIMINABLE_REGS
648 size_t i;
649 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
651 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
652 if (elim_regs[i].from == ARG_POINTER_REGNUM
653 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
654 break;
656 if (i == ARRAY_SIZE (elim_regs))
657 #endif
659 /* Now restore our arg pointer from the address at which it
660 was saved in our stack frame. */
661 emit_move_insn (virtual_incoming_args_rtx,
662 copy_to_reg (get_arg_pointer_save_area (cfun)));
665 #endif
667 #ifdef HAVE_builtin_setjmp_receiver
668 if (HAVE_builtin_setjmp_receiver)
669 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
670 else
671 #endif
672 #ifdef HAVE_nonlocal_goto_receiver
673 if (HAVE_nonlocal_goto_receiver)
674 emit_insn (gen_nonlocal_goto_receiver ());
675 else
676 #endif
677 { /* Nothing */ }
679 /* @@@ This is a kludge. Not all machine descriptions define a blockage
680 insn, but we must not allow the code we just generated to be reordered
681 by scheduling. Specifically, the update of the frame pointer must
682 happen immediately, not later. So emit an ASM_INPUT to act as blockage
683 insn. */
684 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
687 /* __builtin_setjmp is passed a pointer to an array of five words (not
688 all will be used on all machines). It operates similarly to the C
689 library function of the same name, but is more efficient. Much of
690 the code below (and for longjmp) is copied from the handling of
691 non-local gotos.
693 NOTE: This is intended for use by GNAT and the exception handling
694 scheme in the compiler and will only work in the method used by
695 them. */
697 static rtx
698 expand_builtin_setjmp (tree arglist, rtx target)
700 rtx buf_addr, next_lab, cont_lab;
702 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
703 return NULL_RTX;
705 if (target == 0 || !REG_P (target)
706 || REGNO (target) < FIRST_PSEUDO_REGISTER)
707 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
709 buf_addr = expand_normal (TREE_VALUE (arglist));
711 next_lab = gen_label_rtx ();
712 cont_lab = gen_label_rtx ();
714 expand_builtin_setjmp_setup (buf_addr, next_lab);
716 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
717 ensure that pending stack adjustments are flushed. */
718 emit_move_insn (target, const0_rtx);
719 emit_jump (cont_lab);
721 emit_label (next_lab);
723 expand_builtin_setjmp_receiver (next_lab);
725 /* Set TARGET to one. */
726 emit_move_insn (target, const1_rtx);
727 emit_label (cont_lab);
729 /* Tell flow about the strange goings on. Putting `next_lab' on
730 `nonlocal_goto_handler_labels' to indicates that function
731 calls may traverse the arc back to this label. */
733 current_function_has_nonlocal_label = 1;
734 nonlocal_goto_handler_labels
735 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
737 return target;
740 /* __builtin_longjmp is passed a pointer to an array of five words (not
741 all will be used on all machines). It operates similarly to the C
742 library function of the same name, but is more efficient. Much of
743 the code below is copied from the handling of non-local gotos.
745 NOTE: This is intended for use by GNAT and the exception handling
746 scheme in the compiler and will only work in the method used by
747 them. */
749 static void
750 expand_builtin_longjmp (rtx buf_addr, rtx value)
752 rtx fp, lab, stack, insn, last;
753 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
755 if (setjmp_alias_set == -1)
756 setjmp_alias_set = new_alias_set ();
758 buf_addr = convert_memory_address (Pmode, buf_addr);
760 buf_addr = force_reg (Pmode, buf_addr);
762 /* We used to store value in static_chain_rtx, but that fails if pointers
763 are smaller than integers. We instead require that the user must pass
764 a second argument of 1, because that is what builtin_setjmp will
765 return. This also makes EH slightly more efficient, since we are no
766 longer copying around a value that we don't care about. */
767 gcc_assert (value == const1_rtx);
769 last = get_last_insn ();
770 #ifdef HAVE_builtin_longjmp
771 if (HAVE_builtin_longjmp)
772 emit_insn (gen_builtin_longjmp (buf_addr));
773 else
774 #endif
776 fp = gen_rtx_MEM (Pmode, buf_addr);
777 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
778 GET_MODE_SIZE (Pmode)));
780 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
781 2 * GET_MODE_SIZE (Pmode)));
782 set_mem_alias_set (fp, setjmp_alias_set);
783 set_mem_alias_set (lab, setjmp_alias_set);
784 set_mem_alias_set (stack, setjmp_alias_set);
786 /* Pick up FP, label, and SP from the block and jump. This code is
787 from expand_goto in stmt.c; see there for detailed comments. */
788 #if HAVE_nonlocal_goto
789 if (HAVE_nonlocal_goto)
790 /* We have to pass a value to the nonlocal_goto pattern that will
791 get copied into the static_chain pointer, but it does not matter
792 what that value is, because builtin_setjmp does not use it. */
793 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
794 else
795 #endif
797 lab = copy_to_reg (lab);
799 emit_insn (gen_rtx_CLOBBER (VOIDmode,
800 gen_rtx_MEM (BLKmode,
801 gen_rtx_SCRATCH (VOIDmode))));
802 emit_insn (gen_rtx_CLOBBER (VOIDmode,
803 gen_rtx_MEM (BLKmode,
804 hard_frame_pointer_rtx)));
806 emit_move_insn (hard_frame_pointer_rtx, fp);
807 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
809 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
810 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
811 emit_indirect_jump (lab);
815 /* Search backwards and mark the jump insn as a non-local goto.
816 Note that this precludes the use of __builtin_longjmp to a
817 __builtin_setjmp target in the same function. However, we've
818 already cautioned the user that these functions are for
819 internal exception handling use only. */
820 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
822 gcc_assert (insn != last);
824 if (JUMP_P (insn))
826 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
827 REG_NOTES (insn));
828 break;
830 else if (CALL_P (insn))
831 break;
835 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
836 and the address of the save area. */
838 static rtx
839 expand_builtin_nonlocal_goto (tree arglist)
841 tree t_label, t_save_area;
842 rtx r_label, r_save_area, r_fp, r_sp, insn;
844 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
845 return NULL_RTX;
847 t_label = TREE_VALUE (arglist);
848 arglist = TREE_CHAIN (arglist);
849 t_save_area = TREE_VALUE (arglist);
851 r_label = expand_normal (t_label);
852 r_label = convert_memory_address (Pmode, r_label);
853 r_save_area = expand_normal (t_save_area);
854 r_save_area = convert_memory_address (Pmode, r_save_area);
855 r_fp = gen_rtx_MEM (Pmode, r_save_area);
856 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
857 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
859 current_function_has_nonlocal_goto = 1;
861 #if HAVE_nonlocal_goto
862 /* ??? We no longer need to pass the static chain value, afaik. */
863 if (HAVE_nonlocal_goto)
864 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
865 else
866 #endif
868 r_label = copy_to_reg (r_label);
870 emit_insn (gen_rtx_CLOBBER (VOIDmode,
871 gen_rtx_MEM (BLKmode,
872 gen_rtx_SCRATCH (VOIDmode))));
874 emit_insn (gen_rtx_CLOBBER (VOIDmode,
875 gen_rtx_MEM (BLKmode,
876 hard_frame_pointer_rtx)));
878 /* Restore frame pointer for containing function.
879 This sets the actual hard register used for the frame pointer
880 to the location of the function's incoming static chain info.
881 The non-local goto handler will then adjust it to contain the
882 proper value and reload the argument pointer, if needed. */
883 emit_move_insn (hard_frame_pointer_rtx, r_fp);
884 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
886 /* USE of hard_frame_pointer_rtx added for consistency;
887 not clear if really needed. */
888 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
889 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
890 emit_indirect_jump (r_label);
893 /* Search backwards to the jump insn and mark it as a
894 non-local goto. */
895 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
897 if (JUMP_P (insn))
899 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
900 const0_rtx, REG_NOTES (insn));
901 break;
903 else if (CALL_P (insn))
904 break;
907 return const0_rtx;
910 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
911 (not all will be used on all machines) that was passed to __builtin_setjmp.
912 It updates the stack pointer in that block to correspond to the current
913 stack pointer. */
915 static void
916 expand_builtin_update_setjmp_buf (rtx buf_addr)
918 enum machine_mode sa_mode = Pmode;
919 rtx stack_save;
922 #ifdef HAVE_save_stack_nonlocal
923 if (HAVE_save_stack_nonlocal)
924 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
925 #endif
926 #ifdef STACK_SAVEAREA_MODE
927 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
928 #endif
930 stack_save
931 = gen_rtx_MEM (sa_mode,
932 memory_address
933 (sa_mode,
934 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
936 #ifdef HAVE_setjmp
937 if (HAVE_setjmp)
938 emit_insn (gen_setjmp ());
939 #endif
941 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
944 /* Expand a call to __builtin_prefetch. For a target that does not support
945 data prefetch, evaluate the memory address argument in case it has side
946 effects. */
948 static void
949 expand_builtin_prefetch (tree arglist)
951 tree arg0, arg1, arg2;
952 rtx op0, op1, op2;
954 if (!validate_arglist (arglist, POINTER_TYPE, 0))
955 return;
957 arg0 = TREE_VALUE (arglist);
958 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
959 zero (read) and argument 2 (locality) defaults to 3 (high degree of
960 locality). */
961 if (TREE_CHAIN (arglist))
963 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
964 if (TREE_CHAIN (TREE_CHAIN (arglist)))
965 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
966 else
967 arg2 = build_int_cst (NULL_TREE, 3);
969 else
971 arg1 = integer_zero_node;
972 arg2 = build_int_cst (NULL_TREE, 3);
975 /* Argument 0 is an address. */
976 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
978 /* Argument 1 (read/write flag) must be a compile-time constant int. */
979 if (TREE_CODE (arg1) != INTEGER_CST)
981 error ("second argument to %<__builtin_prefetch%> must be a constant");
982 arg1 = integer_zero_node;
984 op1 = expand_normal (arg1);
985 /* Argument 1 must be either zero or one. */
986 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
988 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
989 " using zero");
990 op1 = const0_rtx;
993 /* Argument 2 (locality) must be a compile-time constant int. */
994 if (TREE_CODE (arg2) != INTEGER_CST)
996 error ("third argument to %<__builtin_prefetch%> must be a constant");
997 arg2 = integer_zero_node;
999 op2 = expand_normal (arg2);
1000 /* Argument 2 must be 0, 1, 2, or 3. */
1001 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1003 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1004 op2 = const0_rtx;
1007 #ifdef HAVE_prefetch
1008 if (HAVE_prefetch)
1010 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1011 (op0,
1012 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1013 || (GET_MODE (op0) != Pmode))
1015 op0 = convert_memory_address (Pmode, op0);
1016 op0 = force_reg (Pmode, op0);
1018 emit_insn (gen_prefetch (op0, op1, op2));
1020 #endif
1022 /* Don't do anything with direct references to volatile memory, but
1023 generate code to handle other side effects. */
1024 if (!MEM_P (op0) && side_effects_p (op0))
1025 emit_insn (op0);
1028 /* Get a MEM rtx for expression EXP which is the address of an operand
1029 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1030 the maximum length of the block of memory that might be accessed or
1031 NULL if unknown. */
1033 static rtx
1034 get_memory_rtx (tree exp, tree len)
1036 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1037 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1039 /* Get an expression we can use to find the attributes to assign to MEM.
1040 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1041 we can. First remove any nops. */
1042 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1043 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1044 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1045 exp = TREE_OPERAND (exp, 0);
1047 if (TREE_CODE (exp) == ADDR_EXPR)
1048 exp = TREE_OPERAND (exp, 0);
1049 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1050 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1051 else
1052 exp = NULL;
1054 /* Honor attributes derived from exp, except for the alias set
1055 (as builtin stringops may alias with anything) and the size
1056 (as stringops may access multiple array elements). */
1057 if (exp)
1059 set_mem_attributes (mem, exp, 0);
1061 /* Allow the string and memory builtins to overflow from one
1062 field into another, see http://gcc.gnu.org/PR23561.
1063 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1064 memory accessed by the string or memory builtin will fit
1065 within the field. */
1066 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1068 tree mem_expr = MEM_EXPR (mem);
1069 HOST_WIDE_INT offset = -1, length = -1;
1070 tree inner = exp;
1072 while (TREE_CODE (inner) == ARRAY_REF
1073 || TREE_CODE (inner) == NOP_EXPR
1074 || TREE_CODE (inner) == CONVERT_EXPR
1075 || TREE_CODE (inner) == NON_LVALUE_EXPR
1076 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1077 || TREE_CODE (inner) == SAVE_EXPR)
1078 inner = TREE_OPERAND (inner, 0);
1080 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1082 if (MEM_OFFSET (mem)
1083 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1084 offset = INTVAL (MEM_OFFSET (mem));
1086 if (offset >= 0 && len && host_integerp (len, 0))
1087 length = tree_low_cst (len, 0);
1089 while (TREE_CODE (inner) == COMPONENT_REF)
1091 tree field = TREE_OPERAND (inner, 1);
1092 gcc_assert (! DECL_BIT_FIELD (field));
1093 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1094 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1096 if (length >= 0
1097 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1098 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1100 HOST_WIDE_INT size
1101 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1102 /* If we can prove the memory starting at XEXP (mem, 0)
1103 and ending at XEXP (mem, 0) + LENGTH will fit into
1104 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1105 if (offset <= size
1106 && length <= size
1107 && offset + length <= size)
1108 break;
1111 if (offset >= 0
1112 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1113 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1114 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1115 / BITS_PER_UNIT;
1116 else
1118 offset = -1;
1119 length = -1;
1122 mem_expr = TREE_OPERAND (mem_expr, 0);
1123 inner = TREE_OPERAND (inner, 0);
1126 if (mem_expr == NULL)
1127 offset = -1;
1128 if (mem_expr != MEM_EXPR (mem))
1130 set_mem_expr (mem, mem_expr);
1131 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1134 set_mem_alias_set (mem, 0);
1135 set_mem_size (mem, NULL_RTX);
1138 return mem;
1141 /* Built-in functions to perform an untyped call and return. */
1143 /* For each register that may be used for calling a function, this
1144 gives a mode used to copy the register's value. VOIDmode indicates
1145 the register is not used for calling a function. If the machine
1146 has register windows, this gives only the outbound registers.
1147 INCOMING_REGNO gives the corresponding inbound register. */
1148 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1150 /* For each register that may be used for returning values, this gives
1151 a mode used to copy the register's value. VOIDmode indicates the
1152 register is not used for returning values. If the machine has
1153 register windows, this gives only the outbound registers.
1154 INCOMING_REGNO gives the corresponding inbound register. */
1155 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1157 /* For each register that may be used for calling a function, this
1158 gives the offset of that register into the block returned by
1159 __builtin_apply_args. 0 indicates that the register is not
1160 used for calling a function. */
1161 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1163 /* Return the size required for the block returned by __builtin_apply_args,
1164 and initialize apply_args_mode. */
1166 static int
1167 apply_args_size (void)
1169 static int size = -1;
1170 int align;
1171 unsigned int regno;
1172 enum machine_mode mode;
1174 /* The values computed by this function never change. */
1175 if (size < 0)
1177 /* The first value is the incoming arg-pointer. */
1178 size = GET_MODE_SIZE (Pmode);
1180 /* The second value is the structure value address unless this is
1181 passed as an "invisible" first argument. */
1182 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1183 size += GET_MODE_SIZE (Pmode);
1185 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1186 if (FUNCTION_ARG_REGNO_P (regno))
1188 mode = reg_raw_mode[regno];
1190 gcc_assert (mode != VOIDmode);
1192 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1193 if (size % align != 0)
1194 size = CEIL (size, align) * align;
1195 apply_args_reg_offset[regno] = size;
1196 size += GET_MODE_SIZE (mode);
1197 apply_args_mode[regno] = mode;
1199 else
1201 apply_args_mode[regno] = VOIDmode;
1202 apply_args_reg_offset[regno] = 0;
1205 return size;
1208 /* Return the size required for the block returned by __builtin_apply,
1209 and initialize apply_result_mode. */
1211 static int
1212 apply_result_size (void)
1214 static int size = -1;
1215 int align, regno;
1216 enum machine_mode mode;
1218 /* The values computed by this function never change. */
1219 if (size < 0)
1221 size = 0;
1223 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1224 if (FUNCTION_VALUE_REGNO_P (regno))
1226 mode = reg_raw_mode[regno];
1228 gcc_assert (mode != VOIDmode);
1230 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1231 if (size % align != 0)
1232 size = CEIL (size, align) * align;
1233 size += GET_MODE_SIZE (mode);
1234 apply_result_mode[regno] = mode;
1236 else
1237 apply_result_mode[regno] = VOIDmode;
1239 /* Allow targets that use untyped_call and untyped_return to override
1240 the size so that machine-specific information can be stored here. */
1241 #ifdef APPLY_RESULT_SIZE
1242 size = APPLY_RESULT_SIZE;
1243 #endif
1245 return size;
1248 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1249 /* Create a vector describing the result block RESULT. If SAVEP is true,
1250 the result block is used to save the values; otherwise it is used to
1251 restore the values. */
1253 static rtx
1254 result_vector (int savep, rtx result)
1256 int regno, size, align, nelts;
1257 enum machine_mode mode;
1258 rtx reg, mem;
1259 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1261 size = nelts = 0;
1262 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1263 if ((mode = apply_result_mode[regno]) != VOIDmode)
1265 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1266 if (size % align != 0)
1267 size = CEIL (size, align) * align;
1268 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1269 mem = adjust_address (result, mode, size);
1270 savevec[nelts++] = (savep
1271 ? gen_rtx_SET (VOIDmode, mem, reg)
1272 : gen_rtx_SET (VOIDmode, reg, mem));
1273 size += GET_MODE_SIZE (mode);
1275 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1277 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1279 /* Save the state required to perform an untyped call with the same
1280 arguments as were passed to the current function. */
1282 static rtx
1283 expand_builtin_apply_args_1 (void)
1285 rtx registers, tem;
1286 int size, align, regno;
1287 enum machine_mode mode;
1288 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1290 /* Create a block where the arg-pointer, structure value address,
1291 and argument registers can be saved. */
1292 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1294 /* Walk past the arg-pointer and structure value address. */
1295 size = GET_MODE_SIZE (Pmode);
1296 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1297 size += GET_MODE_SIZE (Pmode);
1299 /* Save each register used in calling a function to the block. */
1300 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1301 if ((mode = apply_args_mode[regno]) != VOIDmode)
1303 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1304 if (size % align != 0)
1305 size = CEIL (size, align) * align;
1307 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1309 emit_move_insn (adjust_address (registers, mode, size), tem);
1310 size += GET_MODE_SIZE (mode);
1313 /* Save the arg pointer to the block. */
1314 tem = copy_to_reg (virtual_incoming_args_rtx);
1315 #ifdef STACK_GROWS_DOWNWARD
1316 /* We need the pointer as the caller actually passed them to us, not
1317 as we might have pretended they were passed. Make sure it's a valid
1318 operand, as emit_move_insn isn't expected to handle a PLUS. */
1320 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1321 NULL_RTX);
1322 #endif
1323 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1325 size = GET_MODE_SIZE (Pmode);
1327 /* Save the structure value address unless this is passed as an
1328 "invisible" first argument. */
1329 if (struct_incoming_value)
1331 emit_move_insn (adjust_address (registers, Pmode, size),
1332 copy_to_reg (struct_incoming_value));
1333 size += GET_MODE_SIZE (Pmode);
1336 /* Return the address of the block. */
1337 return copy_addr_to_reg (XEXP (registers, 0));
1340 /* __builtin_apply_args returns block of memory allocated on
1341 the stack into which is stored the arg pointer, structure
1342 value address, static chain, and all the registers that might
1343 possibly be used in performing a function call. The code is
1344 moved to the start of the function so the incoming values are
1345 saved. */
1347 static rtx
1348 expand_builtin_apply_args (void)
1350 /* Don't do __builtin_apply_args more than once in a function.
1351 Save the result of the first call and reuse it. */
1352 if (apply_args_value != 0)
1353 return apply_args_value;
1355 /* When this function is called, it means that registers must be
1356 saved on entry to this function. So we migrate the
1357 call to the first insn of this function. */
1358 rtx temp;
1359 rtx seq;
1361 start_sequence ();
1362 temp = expand_builtin_apply_args_1 ();
1363 seq = get_insns ();
1364 end_sequence ();
1366 apply_args_value = temp;
1368 /* Put the insns after the NOTE that starts the function.
1369 If this is inside a start_sequence, make the outer-level insn
1370 chain current, so the code is placed at the start of the
1371 function. */
1372 push_topmost_sequence ();
1373 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1374 pop_topmost_sequence ();
1375 return temp;
1379 /* Perform an untyped call and save the state required to perform an
1380 untyped return of whatever value was returned by the given function. */
1382 static rtx
1383 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1385 int size, align, regno;
1386 enum machine_mode mode;
1387 rtx incoming_args, result, reg, dest, src, call_insn;
1388 rtx old_stack_level = 0;
1389 rtx call_fusage = 0;
1390 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1392 arguments = convert_memory_address (Pmode, arguments);
1394 /* Create a block where the return registers can be saved. */
1395 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1397 /* Fetch the arg pointer from the ARGUMENTS block. */
1398 incoming_args = gen_reg_rtx (Pmode);
1399 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1400 #ifndef STACK_GROWS_DOWNWARD
1401 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1402 incoming_args, 0, OPTAB_LIB_WIDEN);
1403 #endif
1405 /* Push a new argument block and copy the arguments. Do not allow
1406 the (potential) memcpy call below to interfere with our stack
1407 manipulations. */
1408 do_pending_stack_adjust ();
1409 NO_DEFER_POP;
1411 /* Save the stack with nonlocal if available. */
1412 #ifdef HAVE_save_stack_nonlocal
1413 if (HAVE_save_stack_nonlocal)
1414 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1415 else
1416 #endif
1417 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1419 /* Allocate a block of memory onto the stack and copy the memory
1420 arguments to the outgoing arguments address. */
1421 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1422 dest = virtual_outgoing_args_rtx;
1423 #ifndef STACK_GROWS_DOWNWARD
1424 if (GET_CODE (argsize) == CONST_INT)
1425 dest = plus_constant (dest, -INTVAL (argsize));
1426 else
1427 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1428 #endif
1429 dest = gen_rtx_MEM (BLKmode, dest);
1430 set_mem_align (dest, PARM_BOUNDARY);
1431 src = gen_rtx_MEM (BLKmode, incoming_args);
1432 set_mem_align (src, PARM_BOUNDARY);
1433 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1435 /* Refer to the argument block. */
1436 apply_args_size ();
1437 arguments = gen_rtx_MEM (BLKmode, arguments);
1438 set_mem_align (arguments, PARM_BOUNDARY);
1440 /* Walk past the arg-pointer and structure value address. */
1441 size = GET_MODE_SIZE (Pmode);
1442 if (struct_value)
1443 size += GET_MODE_SIZE (Pmode);
1445 /* Restore each of the registers previously saved. Make USE insns
1446 for each of these registers for use in making the call. */
1447 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1448 if ((mode = apply_args_mode[regno]) != VOIDmode)
1450 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1451 if (size % align != 0)
1452 size = CEIL (size, align) * align;
1453 reg = gen_rtx_REG (mode, regno);
1454 emit_move_insn (reg, adjust_address (arguments, mode, size));
1455 use_reg (&call_fusage, reg);
1456 size += GET_MODE_SIZE (mode);
1459 /* Restore the structure value address unless this is passed as an
1460 "invisible" first argument. */
1461 size = GET_MODE_SIZE (Pmode);
1462 if (struct_value)
1464 rtx value = gen_reg_rtx (Pmode);
1465 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1466 emit_move_insn (struct_value, value);
1467 if (REG_P (struct_value))
1468 use_reg (&call_fusage, struct_value);
1469 size += GET_MODE_SIZE (Pmode);
1472 /* All arguments and registers used for the call are set up by now! */
1473 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1475 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1476 and we don't want to load it into a register as an optimization,
1477 because prepare_call_address already did it if it should be done. */
1478 if (GET_CODE (function) != SYMBOL_REF)
1479 function = memory_address (FUNCTION_MODE, function);
1481 /* Generate the actual call instruction and save the return value. */
1482 #ifdef HAVE_untyped_call
1483 if (HAVE_untyped_call)
1484 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1485 result, result_vector (1, result)));
1486 else
1487 #endif
1488 #ifdef HAVE_call_value
1489 if (HAVE_call_value)
1491 rtx valreg = 0;
1493 /* Locate the unique return register. It is not possible to
1494 express a call that sets more than one return register using
1495 call_value; use untyped_call for that. In fact, untyped_call
1496 only needs to save the return registers in the given block. */
1497 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1498 if ((mode = apply_result_mode[regno]) != VOIDmode)
1500 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1502 valreg = gen_rtx_REG (mode, regno);
1505 emit_call_insn (GEN_CALL_VALUE (valreg,
1506 gen_rtx_MEM (FUNCTION_MODE, function),
1507 const0_rtx, NULL_RTX, const0_rtx));
1509 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1511 else
1512 #endif
1513 gcc_unreachable ();
1515 /* Find the CALL insn we just emitted, and attach the register usage
1516 information. */
1517 call_insn = last_call_insn ();
1518 add_function_usage_to (call_insn, call_fusage);
1520 /* Restore the stack. */
1521 #ifdef HAVE_save_stack_nonlocal
1522 if (HAVE_save_stack_nonlocal)
1523 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1524 else
1525 #endif
1526 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1528 OK_DEFER_POP;
1530 /* Return the address of the result block. */
1531 result = copy_addr_to_reg (XEXP (result, 0));
1532 return convert_memory_address (ptr_mode, result);
1535 /* Perform an untyped return. */
1537 static void
1538 expand_builtin_return (rtx result)
1540 int size, align, regno;
1541 enum machine_mode mode;
1542 rtx reg;
1543 rtx call_fusage = 0;
1545 result = convert_memory_address (Pmode, result);
1547 apply_result_size ();
1548 result = gen_rtx_MEM (BLKmode, result);
1550 #ifdef HAVE_untyped_return
1551 if (HAVE_untyped_return)
1553 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1554 emit_barrier ();
1555 return;
1557 #endif
1559 /* Restore the return value and note that each value is used. */
1560 size = 0;
1561 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1562 if ((mode = apply_result_mode[regno]) != VOIDmode)
1564 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1565 if (size % align != 0)
1566 size = CEIL (size, align) * align;
1567 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1568 emit_move_insn (reg, adjust_address (result, mode, size));
1570 push_to_sequence (call_fusage);
1571 emit_insn (gen_rtx_USE (VOIDmode, reg));
1572 call_fusage = get_insns ();
1573 end_sequence ();
1574 size += GET_MODE_SIZE (mode);
1577 /* Put the USE insns before the return. */
1578 emit_insn (call_fusage);
1580 /* Return whatever values was restored by jumping directly to the end
1581 of the function. */
1582 expand_naked_return ();
1585 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1587 static enum type_class
1588 type_to_class (tree type)
1590 switch (TREE_CODE (type))
1592 case VOID_TYPE: return void_type_class;
1593 case INTEGER_TYPE: return integer_type_class;
1594 case ENUMERAL_TYPE: return enumeral_type_class;
1595 case BOOLEAN_TYPE: return boolean_type_class;
1596 case POINTER_TYPE: return pointer_type_class;
1597 case REFERENCE_TYPE: return reference_type_class;
1598 case OFFSET_TYPE: return offset_type_class;
1599 case REAL_TYPE: return real_type_class;
1600 case COMPLEX_TYPE: return complex_type_class;
1601 case FUNCTION_TYPE: return function_type_class;
1602 case METHOD_TYPE: return method_type_class;
1603 case RECORD_TYPE: return record_type_class;
1604 case UNION_TYPE:
1605 case QUAL_UNION_TYPE: return union_type_class;
1606 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1607 ? string_type_class : array_type_class);
1608 case LANG_TYPE: return lang_type_class;
1609 default: return no_type_class;
1613 /* Expand a call to __builtin_classify_type with arguments found in
1614 ARGLIST. */
1616 static rtx
1617 expand_builtin_classify_type (tree arglist)
1619 if (arglist != 0)
1620 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1621 return GEN_INT (no_type_class);
1624 /* This helper macro, meant to be used in mathfn_built_in below,
1625 determines which among a set of three builtin math functions is
1626 appropriate for a given type mode. The `F' and `L' cases are
1627 automatically generated from the `double' case. */
1628 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1629 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1630 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1631 fcodel = BUILT_IN_MATHFN##L ; break;
1633 /* Return mathematic function equivalent to FN but operating directly
1634 on TYPE, if available. If we can't do the conversion, return zero. */
1635 tree
1636 mathfn_built_in (tree type, enum built_in_function fn)
1638 enum built_in_function fcode, fcodef, fcodel;
1640 switch (fn)
1642 CASE_MATHFN (BUILT_IN_ACOS)
1643 CASE_MATHFN (BUILT_IN_ACOSH)
1644 CASE_MATHFN (BUILT_IN_ASIN)
1645 CASE_MATHFN (BUILT_IN_ASINH)
1646 CASE_MATHFN (BUILT_IN_ATAN)
1647 CASE_MATHFN (BUILT_IN_ATAN2)
1648 CASE_MATHFN (BUILT_IN_ATANH)
1649 CASE_MATHFN (BUILT_IN_CBRT)
1650 CASE_MATHFN (BUILT_IN_CEIL)
1651 CASE_MATHFN (BUILT_IN_COPYSIGN)
1652 CASE_MATHFN (BUILT_IN_COS)
1653 CASE_MATHFN (BUILT_IN_COSH)
1654 CASE_MATHFN (BUILT_IN_DREM)
1655 CASE_MATHFN (BUILT_IN_ERF)
1656 CASE_MATHFN (BUILT_IN_ERFC)
1657 CASE_MATHFN (BUILT_IN_EXP)
1658 CASE_MATHFN (BUILT_IN_EXP10)
1659 CASE_MATHFN (BUILT_IN_EXP2)
1660 CASE_MATHFN (BUILT_IN_EXPM1)
1661 CASE_MATHFN (BUILT_IN_FABS)
1662 CASE_MATHFN (BUILT_IN_FDIM)
1663 CASE_MATHFN (BUILT_IN_FLOOR)
1664 CASE_MATHFN (BUILT_IN_FMA)
1665 CASE_MATHFN (BUILT_IN_FMAX)
1666 CASE_MATHFN (BUILT_IN_FMIN)
1667 CASE_MATHFN (BUILT_IN_FMOD)
1668 CASE_MATHFN (BUILT_IN_FREXP)
1669 CASE_MATHFN (BUILT_IN_GAMMA)
1670 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1671 CASE_MATHFN (BUILT_IN_HYPOT)
1672 CASE_MATHFN (BUILT_IN_ILOGB)
1673 CASE_MATHFN (BUILT_IN_INF)
1674 CASE_MATHFN (BUILT_IN_J0)
1675 CASE_MATHFN (BUILT_IN_J1)
1676 CASE_MATHFN (BUILT_IN_JN)
1677 CASE_MATHFN (BUILT_IN_LCEIL)
1678 CASE_MATHFN (BUILT_IN_LDEXP)
1679 CASE_MATHFN (BUILT_IN_LFLOOR)
1680 CASE_MATHFN (BUILT_IN_LGAMMA)
1681 CASE_MATHFN (BUILT_IN_LLCEIL)
1682 CASE_MATHFN (BUILT_IN_LLFLOOR)
1683 CASE_MATHFN (BUILT_IN_LLRINT)
1684 CASE_MATHFN (BUILT_IN_LLROUND)
1685 CASE_MATHFN (BUILT_IN_LOG)
1686 CASE_MATHFN (BUILT_IN_LOG10)
1687 CASE_MATHFN (BUILT_IN_LOG1P)
1688 CASE_MATHFN (BUILT_IN_LOG2)
1689 CASE_MATHFN (BUILT_IN_LOGB)
1690 CASE_MATHFN (BUILT_IN_LRINT)
1691 CASE_MATHFN (BUILT_IN_LROUND)
1692 CASE_MATHFN (BUILT_IN_MODF)
1693 CASE_MATHFN (BUILT_IN_NAN)
1694 CASE_MATHFN (BUILT_IN_NANS)
1695 CASE_MATHFN (BUILT_IN_NEARBYINT)
1696 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1697 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1698 CASE_MATHFN (BUILT_IN_POW)
1699 CASE_MATHFN (BUILT_IN_POWI)
1700 CASE_MATHFN (BUILT_IN_POW10)
1701 CASE_MATHFN (BUILT_IN_REMAINDER)
1702 CASE_MATHFN (BUILT_IN_REMQUO)
1703 CASE_MATHFN (BUILT_IN_RINT)
1704 CASE_MATHFN (BUILT_IN_ROUND)
1705 CASE_MATHFN (BUILT_IN_SCALB)
1706 CASE_MATHFN (BUILT_IN_SCALBLN)
1707 CASE_MATHFN (BUILT_IN_SCALBN)
1708 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1709 CASE_MATHFN (BUILT_IN_SIN)
1710 CASE_MATHFN (BUILT_IN_SINCOS)
1711 CASE_MATHFN (BUILT_IN_SINH)
1712 CASE_MATHFN (BUILT_IN_SQRT)
1713 CASE_MATHFN (BUILT_IN_TAN)
1714 CASE_MATHFN (BUILT_IN_TANH)
1715 CASE_MATHFN (BUILT_IN_TGAMMA)
1716 CASE_MATHFN (BUILT_IN_TRUNC)
1717 CASE_MATHFN (BUILT_IN_Y0)
1718 CASE_MATHFN (BUILT_IN_Y1)
1719 CASE_MATHFN (BUILT_IN_YN)
1721 default:
1722 return 0;
1725 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1726 return implicit_built_in_decls[fcode];
1727 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1728 return implicit_built_in_decls[fcodef];
1729 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1730 return implicit_built_in_decls[fcodel];
1731 else
1732 return 0;
1735 /* If errno must be maintained, expand the RTL to check if the result,
1736 TARGET, of a built-in function call, EXP, is NaN, and if so set
1737 errno to EDOM. */
1739 static void
1740 expand_errno_check (tree exp, rtx target)
1742 rtx lab = gen_label_rtx ();
1744 /* Test the result; if it is NaN, set errno=EDOM because
1745 the argument was not in the domain. */
1746 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1747 0, lab);
1749 #ifdef TARGET_EDOM
1750 /* If this built-in doesn't throw an exception, set errno directly. */
1751 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1753 #ifdef GEN_ERRNO_RTX
1754 rtx errno_rtx = GEN_ERRNO_RTX;
1755 #else
1756 rtx errno_rtx
1757 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1758 #endif
1759 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1760 emit_label (lab);
1761 return;
1763 #endif
1765 /* We can't set errno=EDOM directly; let the library call do it.
1766 Pop the arguments right away in case the call gets deleted. */
1767 NO_DEFER_POP;
1768 expand_call (exp, target, 0);
1769 OK_DEFER_POP;
1770 emit_label (lab);
1774 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1775 Return 0 if a normal call should be emitted rather than expanding the
1776 function in-line. EXP is the expression that is a call to the builtin
1777 function; if convenient, the result should be placed in TARGET.
1778 SUBTARGET may be used as the target for computing one of EXP's operands. */
1780 static rtx
1781 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1783 optab builtin_optab;
1784 rtx op0, insns, before_call;
1785 tree fndecl = get_callee_fndecl (exp);
1786 tree arglist = TREE_OPERAND (exp, 1);
1787 enum machine_mode mode;
1788 bool errno_set = false;
1789 tree arg, narg;
1791 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1792 return 0;
1794 arg = TREE_VALUE (arglist);
1796 switch (DECL_FUNCTION_CODE (fndecl))
1798 CASE_FLT_FN (BUILT_IN_SQRT):
1799 errno_set = ! tree_expr_nonnegative_p (arg);
1800 builtin_optab = sqrt_optab;
1801 break;
1802 CASE_FLT_FN (BUILT_IN_EXP):
1803 errno_set = true; builtin_optab = exp_optab; break;
1804 CASE_FLT_FN (BUILT_IN_EXP10):
1805 CASE_FLT_FN (BUILT_IN_POW10):
1806 errno_set = true; builtin_optab = exp10_optab; break;
1807 CASE_FLT_FN (BUILT_IN_EXP2):
1808 errno_set = true; builtin_optab = exp2_optab; break;
1809 CASE_FLT_FN (BUILT_IN_EXPM1):
1810 errno_set = true; builtin_optab = expm1_optab; break;
1811 CASE_FLT_FN (BUILT_IN_LOGB):
1812 errno_set = true; builtin_optab = logb_optab; break;
1813 CASE_FLT_FN (BUILT_IN_ILOGB):
1814 errno_set = true; builtin_optab = ilogb_optab; break;
1815 CASE_FLT_FN (BUILT_IN_LOG):
1816 errno_set = true; builtin_optab = log_optab; break;
1817 CASE_FLT_FN (BUILT_IN_LOG10):
1818 errno_set = true; builtin_optab = log10_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOG2):
1820 errno_set = true; builtin_optab = log2_optab; break;
1821 CASE_FLT_FN (BUILT_IN_LOG1P):
1822 errno_set = true; builtin_optab = log1p_optab; break;
1823 CASE_FLT_FN (BUILT_IN_ASIN):
1824 builtin_optab = asin_optab; break;
1825 CASE_FLT_FN (BUILT_IN_ACOS):
1826 builtin_optab = acos_optab; break;
1827 CASE_FLT_FN (BUILT_IN_TAN):
1828 builtin_optab = tan_optab; break;
1829 CASE_FLT_FN (BUILT_IN_ATAN):
1830 builtin_optab = atan_optab; break;
1831 CASE_FLT_FN (BUILT_IN_FLOOR):
1832 builtin_optab = floor_optab; break;
1833 CASE_FLT_FN (BUILT_IN_CEIL):
1834 builtin_optab = ceil_optab; break;
1835 CASE_FLT_FN (BUILT_IN_TRUNC):
1836 builtin_optab = btrunc_optab; break;
1837 CASE_FLT_FN (BUILT_IN_ROUND):
1838 builtin_optab = round_optab; break;
1839 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1840 builtin_optab = nearbyint_optab; break;
1841 CASE_FLT_FN (BUILT_IN_RINT):
1842 builtin_optab = rint_optab; break;
1843 CASE_FLT_FN (BUILT_IN_LRINT):
1844 CASE_FLT_FN (BUILT_IN_LLRINT):
1845 builtin_optab = lrint_optab; break;
1846 default:
1847 gcc_unreachable ();
1850 /* Make a suitable register to place result in. */
1851 mode = TYPE_MODE (TREE_TYPE (exp));
1853 if (! flag_errno_math || ! HONOR_NANS (mode))
1854 errno_set = false;
1856 /* Before working hard, check whether the instruction is available. */
1857 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1859 target = gen_reg_rtx (mode);
1861 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1862 need to expand the argument again. This way, we will not perform
1863 side-effects more the once. */
1864 narg = builtin_save_expr (arg);
1865 if (narg != arg)
1867 arg = narg;
1868 arglist = build_tree_list (NULL_TREE, arg);
1869 exp = build_function_call_expr (fndecl, arglist);
1872 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1874 start_sequence ();
1876 /* Compute into TARGET.
1877 Set TARGET to wherever the result comes back. */
1878 target = expand_unop (mode, builtin_optab, op0, target, 0);
1880 if (target != 0)
1882 if (errno_set)
1883 expand_errno_check (exp, target);
1885 /* Output the entire sequence. */
1886 insns = get_insns ();
1887 end_sequence ();
1888 emit_insn (insns);
1889 return target;
1892 /* If we were unable to expand via the builtin, stop the sequence
1893 (without outputting the insns) and call to the library function
1894 with the stabilized argument list. */
1895 end_sequence ();
1898 before_call = get_last_insn ();
1900 target = expand_call (exp, target, target == const0_rtx);
1902 /* If this is a sqrt operation and we don't care about errno, try to
1903 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1904 This allows the semantics of the libcall to be visible to the RTL
1905 optimizers. */
1906 if (builtin_optab == sqrt_optab && !errno_set)
1908 /* Search backwards through the insns emitted by expand_call looking
1909 for the instruction with the REG_RETVAL note. */
1910 rtx last = get_last_insn ();
1911 while (last != before_call)
1913 if (find_reg_note (last, REG_RETVAL, NULL))
1915 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1916 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1917 two elements, i.e. symbol_ref(sqrt) and the operand. */
1918 if (note
1919 && GET_CODE (note) == EXPR_LIST
1920 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1921 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1922 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1924 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1925 /* Check operand is a register with expected mode. */
1926 if (operand
1927 && REG_P (operand)
1928 && GET_MODE (operand) == mode)
1930 /* Replace the REG_EQUAL note with a SQRT rtx. */
1931 rtx equiv = gen_rtx_SQRT (mode, operand);
1932 set_unique_reg_note (last, REG_EQUAL, equiv);
1935 break;
1937 last = PREV_INSN (last);
1941 return target;
1944 /* Expand a call to the builtin binary math functions (pow and atan2).
1945 Return 0 if a normal call should be emitted rather than expanding the
1946 function in-line. EXP is the expression that is a call to the builtin
1947 function; if convenient, the result should be placed in TARGET.
1948 SUBTARGET may be used as the target for computing one of EXP's
1949 operands. */
1951 static rtx
1952 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1954 optab builtin_optab;
1955 rtx op0, op1, insns;
1956 int op1_type = REAL_TYPE;
1957 tree fndecl = get_callee_fndecl (exp);
1958 tree arglist = TREE_OPERAND (exp, 1);
1959 tree arg0, arg1, temp, narg;
1960 enum machine_mode mode;
1961 bool errno_set = true;
1962 bool stable = true;
1964 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1965 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1966 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1967 op1_type = INTEGER_TYPE;
1969 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1970 return 0;
1972 arg0 = TREE_VALUE (arglist);
1973 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1975 switch (DECL_FUNCTION_CODE (fndecl))
1977 CASE_FLT_FN (BUILT_IN_POW):
1978 builtin_optab = pow_optab; break;
1979 CASE_FLT_FN (BUILT_IN_ATAN2):
1980 builtin_optab = atan2_optab; break;
1981 CASE_FLT_FN (BUILT_IN_LDEXP):
1982 builtin_optab = ldexp_optab; break;
1983 CASE_FLT_FN (BUILT_IN_FMOD):
1984 builtin_optab = fmod_optab; break;
1985 CASE_FLT_FN (BUILT_IN_DREM):
1986 builtin_optab = drem_optab; break;
1987 default:
1988 gcc_unreachable ();
1991 /* Make a suitable register to place result in. */
1992 mode = TYPE_MODE (TREE_TYPE (exp));
1994 /* Before working hard, check whether the instruction is available. */
1995 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1996 return 0;
1998 target = gen_reg_rtx (mode);
2000 if (! flag_errno_math || ! HONOR_NANS (mode))
2001 errno_set = false;
2003 /* Always stabilize the argument list. */
2004 narg = builtin_save_expr (arg1);
2005 if (narg != arg1)
2007 arg1 = narg;
2008 temp = build_tree_list (NULL_TREE, narg);
2009 stable = false;
2011 else
2012 temp = TREE_CHAIN (arglist);
2014 narg = builtin_save_expr (arg0);
2015 if (narg != arg0)
2017 arg0 = narg;
2018 arglist = tree_cons (NULL_TREE, narg, temp);
2019 stable = false;
2021 else if (! stable)
2022 arglist = tree_cons (NULL_TREE, arg0, temp);
2024 if (! stable)
2025 exp = build_function_call_expr (fndecl, arglist);
2027 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2028 op1 = expand_normal (arg1);
2030 start_sequence ();
2032 /* Compute into TARGET.
2033 Set TARGET to wherever the result comes back. */
2034 target = expand_binop (mode, builtin_optab, op0, op1,
2035 target, 0, OPTAB_DIRECT);
2037 /* If we were unable to expand via the builtin, stop the sequence
2038 (without outputting the insns) and call to the library function
2039 with the stabilized argument list. */
2040 if (target == 0)
2042 end_sequence ();
2043 return expand_call (exp, target, target == const0_rtx);
2046 if (errno_set)
2047 expand_errno_check (exp, target);
2049 /* Output the entire sequence. */
2050 insns = get_insns ();
2051 end_sequence ();
2052 emit_insn (insns);
2054 return target;
2057 /* Expand a call to the builtin sin and cos math functions.
2058 Return 0 if a normal call should be emitted rather than expanding the
2059 function in-line. EXP is the expression that is a call to the builtin
2060 function; if convenient, the result should be placed in TARGET.
2061 SUBTARGET may be used as the target for computing one of EXP's
2062 operands. */
2064 static rtx
2065 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2067 optab builtin_optab;
2068 rtx op0, insns;
2069 tree fndecl = get_callee_fndecl (exp);
2070 tree arglist = TREE_OPERAND (exp, 1);
2071 enum machine_mode mode;
2072 tree arg, narg;
2074 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2075 return 0;
2077 arg = TREE_VALUE (arglist);
2079 switch (DECL_FUNCTION_CODE (fndecl))
2081 CASE_FLT_FN (BUILT_IN_SIN):
2082 CASE_FLT_FN (BUILT_IN_COS):
2083 builtin_optab = sincos_optab; break;
2084 default:
2085 gcc_unreachable ();
2088 /* Make a suitable register to place result in. */
2089 mode = TYPE_MODE (TREE_TYPE (exp));
2091 /* Check if sincos insn is available, otherwise fallback
2092 to sin or cos insn. */
2093 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2094 switch (DECL_FUNCTION_CODE (fndecl))
2096 CASE_FLT_FN (BUILT_IN_SIN):
2097 builtin_optab = sin_optab; break;
2098 CASE_FLT_FN (BUILT_IN_COS):
2099 builtin_optab = cos_optab; break;
2100 default:
2101 gcc_unreachable ();
2105 /* Before working hard, check whether the instruction is available. */
2106 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2108 target = gen_reg_rtx (mode);
2110 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2111 need to expand the argument again. This way, we will not perform
2112 side-effects more the once. */
2113 narg = save_expr (arg);
2114 if (narg != arg)
2116 arg = narg;
2117 arglist = build_tree_list (NULL_TREE, arg);
2118 exp = build_function_call_expr (fndecl, arglist);
2121 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2123 start_sequence ();
2125 /* Compute into TARGET.
2126 Set TARGET to wherever the result comes back. */
2127 if (builtin_optab == sincos_optab)
2129 int result;
2131 switch (DECL_FUNCTION_CODE (fndecl))
2133 CASE_FLT_FN (BUILT_IN_SIN):
2134 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2135 break;
2136 CASE_FLT_FN (BUILT_IN_COS):
2137 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2138 break;
2139 default:
2140 gcc_unreachable ();
2142 gcc_assert (result);
2144 else
2146 target = expand_unop (mode, builtin_optab, op0, target, 0);
2149 if (target != 0)
2151 /* Output the entire sequence. */
2152 insns = get_insns ();
2153 end_sequence ();
2154 emit_insn (insns);
2155 return target;
2158 /* If we were unable to expand via the builtin, stop the sequence
2159 (without outputting the insns) and call to the library function
2160 with the stabilized argument list. */
2161 end_sequence ();
2164 target = expand_call (exp, target, target == const0_rtx);
2166 return target;
2169 /* Expand a call to the builtin sincos math function.
2170 Return 0 if a normal call should be emitted rather than expanding the
2171 function in-line. EXP is the expression that is a call to the builtin
2172 function. */
2174 static rtx
2175 expand_builtin_sincos (tree exp)
2177 rtx op0, op1, op2, target1, target2;
2178 tree arglist = TREE_OPERAND (exp, 1);
2179 enum machine_mode mode;
2180 tree arg, sinp, cosp;
2181 int result;
2183 if (!validate_arglist (arglist, REAL_TYPE,
2184 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2185 return 0;
2187 arg = TREE_VALUE (arglist);
2188 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2189 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2191 /* Make a suitable register to place result in. */
2192 mode = TYPE_MODE (TREE_TYPE (arg));
2194 /* Check if sincos insn is available, otherwise emit the call. */
2195 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2196 return NULL_RTX;
2198 target1 = gen_reg_rtx (mode);
2199 target2 = gen_reg_rtx (mode);
2201 op0 = expand_normal (arg);
2202 op1 = expand_normal (build_fold_indirect_ref (sinp));
2203 op2 = expand_normal (build_fold_indirect_ref (cosp));
2205 /* Compute into target1 and target2.
2206 Set TARGET to wherever the result comes back. */
2207 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2208 gcc_assert (result);
2210 /* Move target1 and target2 to the memory locations indicated
2211 by op1 and op2. */
2212 emit_move_insn (op1, target1);
2213 emit_move_insn (op2, target2);
2215 return const0_rtx;
2218 /* Expand a call to one of the builtin rounding functions (lfloor).
2219 If expanding via optab fails, lower expression to (int)(floor(x)).
2220 EXP is the expression that is a call to the builtin function;
2221 if convenient, the result should be placed in TARGET. SUBTARGET may
2222 be used as the target for computing one of EXP's operands. */
2224 static rtx
2225 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2227 optab builtin_optab;
2228 rtx op0, insns, tmp;
2229 tree fndecl = get_callee_fndecl (exp);
2230 tree arglist = TREE_OPERAND (exp, 1);
2231 enum built_in_function fallback_fn;
2232 tree fallback_fndecl;
2233 enum machine_mode mode;
2234 tree arg, narg;
2236 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2237 gcc_unreachable ();
2239 arg = TREE_VALUE (arglist);
2241 switch (DECL_FUNCTION_CODE (fndecl))
2243 CASE_FLT_FN (BUILT_IN_LCEIL):
2244 CASE_FLT_FN (BUILT_IN_LLCEIL):
2245 builtin_optab = lceil_optab;
2246 fallback_fn = BUILT_IN_CEIL;
2247 break;
2249 CASE_FLT_FN (BUILT_IN_LFLOOR):
2250 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2251 builtin_optab = lfloor_optab;
2252 fallback_fn = BUILT_IN_FLOOR;
2253 break;
2255 default:
2256 gcc_unreachable ();
2259 /* Make a suitable register to place result in. */
2260 mode = TYPE_MODE (TREE_TYPE (exp));
2262 /* Before working hard, check whether the instruction is available. */
2263 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2265 target = gen_reg_rtx (mode);
2267 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2268 need to expand the argument again. This way, we will not perform
2269 side-effects more the once. */
2270 narg = builtin_save_expr (arg);
2271 if (narg != arg)
2273 arg = narg;
2274 arglist = build_tree_list (NULL_TREE, arg);
2275 exp = build_function_call_expr (fndecl, arglist);
2278 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2280 start_sequence ();
2282 /* Compute into TARGET.
2283 Set TARGET to wherever the result comes back. */
2284 target = expand_unop (mode, builtin_optab, op0, target, 0);
2286 if (target != 0)
2288 /* Output the entire sequence. */
2289 insns = get_insns ();
2290 end_sequence ();
2291 emit_insn (insns);
2292 return target;
2295 /* If we were unable to expand via the builtin, stop the sequence
2296 (without outputting the insns). */
2297 end_sequence ();
2300 /* Fall back to floating point rounding optab. */
2301 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2302 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2303 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2304 gcc_assert (fallback_fndecl != NULL_TREE);
2305 exp = build_function_call_expr (fallback_fndecl, arglist);
2307 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2309 /* Truncate the result of floating point optab to integer
2310 via expand_fix (). */
2311 target = gen_reg_rtx (mode);
2312 expand_fix (target, tmp, 0);
2314 return target;
2317 /* To evaluate powi(x,n), the floating point value x raised to the
2318 constant integer exponent n, we use a hybrid algorithm that
2319 combines the "window method" with look-up tables. For an
2320 introduction to exponentiation algorithms and "addition chains",
2321 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2322 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2323 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2324 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2326 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2327 multiplications to inline before calling the system library's pow
2328 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2329 so this default never requires calling pow, powf or powl. */
2331 #ifndef POWI_MAX_MULTS
2332 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2333 #endif
2335 /* The size of the "optimal power tree" lookup table. All
2336 exponents less than this value are simply looked up in the
2337 powi_table below. This threshold is also used to size the
2338 cache of pseudo registers that hold intermediate results. */
2339 #define POWI_TABLE_SIZE 256
2341 /* The size, in bits of the window, used in the "window method"
2342 exponentiation algorithm. This is equivalent to a radix of
2343 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2344 #define POWI_WINDOW_SIZE 3
2346 /* The following table is an efficient representation of an
2347 "optimal power tree". For each value, i, the corresponding
2348 value, j, in the table states than an optimal evaluation
2349 sequence for calculating pow(x,i) can be found by evaluating
2350 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2351 100 integers is given in Knuth's "Seminumerical algorithms". */
2353 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2355 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2356 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2357 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2358 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2359 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2360 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2361 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2362 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2363 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2364 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2365 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2366 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2367 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2368 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2369 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2370 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2371 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2372 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2373 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2374 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2375 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2376 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2377 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2378 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2379 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2380 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2381 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2382 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2383 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2384 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2385 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2386 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2390 /* Return the number of multiplications required to calculate
2391 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2392 subroutine of powi_cost. CACHE is an array indicating
2393 which exponents have already been calculated. */
2395 static int
2396 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2398 /* If we've already calculated this exponent, then this evaluation
2399 doesn't require any additional multiplications. */
2400 if (cache[n])
2401 return 0;
2403 cache[n] = true;
2404 return powi_lookup_cost (n - powi_table[n], cache)
2405 + powi_lookup_cost (powi_table[n], cache) + 1;
2408 /* Return the number of multiplications required to calculate
2409 powi(x,n) for an arbitrary x, given the exponent N. This
2410 function needs to be kept in sync with expand_powi below. */
2412 static int
2413 powi_cost (HOST_WIDE_INT n)
2415 bool cache[POWI_TABLE_SIZE];
2416 unsigned HOST_WIDE_INT digit;
2417 unsigned HOST_WIDE_INT val;
2418 int result;
2420 if (n == 0)
2421 return 0;
2423 /* Ignore the reciprocal when calculating the cost. */
2424 val = (n < 0) ? -n : n;
2426 /* Initialize the exponent cache. */
2427 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2428 cache[1] = true;
2430 result = 0;
2432 while (val >= POWI_TABLE_SIZE)
2434 if (val & 1)
2436 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2437 result += powi_lookup_cost (digit, cache)
2438 + POWI_WINDOW_SIZE + 1;
2439 val >>= POWI_WINDOW_SIZE;
2441 else
2443 val >>= 1;
2444 result++;
2448 return result + powi_lookup_cost (val, cache);
2451 /* Recursive subroutine of expand_powi. This function takes the array,
2452 CACHE, of already calculated exponents and an exponent N and returns
2453 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2455 static rtx
2456 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2458 unsigned HOST_WIDE_INT digit;
2459 rtx target, result;
2460 rtx op0, op1;
2462 if (n < POWI_TABLE_SIZE)
2464 if (cache[n])
2465 return cache[n];
2467 target = gen_reg_rtx (mode);
2468 cache[n] = target;
2470 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2471 op1 = expand_powi_1 (mode, powi_table[n], cache);
2473 else if (n & 1)
2475 target = gen_reg_rtx (mode);
2476 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2477 op0 = expand_powi_1 (mode, n - digit, cache);
2478 op1 = expand_powi_1 (mode, digit, cache);
2480 else
2482 target = gen_reg_rtx (mode);
2483 op0 = expand_powi_1 (mode, n >> 1, cache);
2484 op1 = op0;
2487 result = expand_mult (mode, op0, op1, target, 0);
2488 if (result != target)
2489 emit_move_insn (target, result);
2490 return target;
2493 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2494 floating point operand in mode MODE, and N is the exponent. This
2495 function needs to be kept in sync with powi_cost above. */
2497 static rtx
2498 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2500 unsigned HOST_WIDE_INT val;
2501 rtx cache[POWI_TABLE_SIZE];
2502 rtx result;
2504 if (n == 0)
2505 return CONST1_RTX (mode);
2507 val = (n < 0) ? -n : n;
2509 memset (cache, 0, sizeof (cache));
2510 cache[1] = x;
2512 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2514 /* If the original exponent was negative, reciprocate the result. */
2515 if (n < 0)
2516 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2517 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2519 return result;
2522 /* Expand a call to the pow built-in mathematical function. Return 0 if
2523 a normal call should be emitted rather than expanding the function
2524 in-line. EXP is the expression that is a call to the builtin
2525 function; if convenient, the result should be placed in TARGET. */
2527 static rtx
2528 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2530 tree arglist = TREE_OPERAND (exp, 1);
2531 tree arg0, arg1;
2533 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2534 return 0;
2536 arg0 = TREE_VALUE (arglist);
2537 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2539 if (TREE_CODE (arg1) == REAL_CST
2540 && ! TREE_CONSTANT_OVERFLOW (arg1))
2542 REAL_VALUE_TYPE cint;
2543 REAL_VALUE_TYPE c;
2544 HOST_WIDE_INT n;
2546 c = TREE_REAL_CST (arg1);
2547 n = real_to_integer (&c);
2548 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2549 if (real_identical (&c, &cint))
2551 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2552 Otherwise, check the number of multiplications required.
2553 Note that pow never sets errno for an integer exponent. */
2554 if ((n >= -1 && n <= 2)
2555 || (flag_unsafe_math_optimizations
2556 && ! optimize_size
2557 && powi_cost (n) <= POWI_MAX_MULTS))
2559 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2560 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2561 op = force_reg (mode, op);
2562 return expand_powi (op, mode, n);
2567 if (! flag_unsafe_math_optimizations)
2568 return NULL_RTX;
2569 return expand_builtin_mathfn_2 (exp, target, subtarget);
2572 /* Expand a call to the powi built-in mathematical function. Return 0 if
2573 a normal call should be emitted rather than expanding the function
2574 in-line. EXP is the expression that is a call to the builtin
2575 function; if convenient, the result should be placed in TARGET. */
2577 static rtx
2578 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2580 tree arglist = TREE_OPERAND (exp, 1);
2581 tree arg0, arg1;
2582 rtx op0, op1;
2583 enum machine_mode mode;
2584 enum machine_mode mode2;
2586 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2587 return 0;
2589 arg0 = TREE_VALUE (arglist);
2590 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2591 mode = TYPE_MODE (TREE_TYPE (exp));
2593 /* Handle constant power. */
2595 if (TREE_CODE (arg1) == INTEGER_CST
2596 && ! TREE_CONSTANT_OVERFLOW (arg1))
2598 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2600 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2601 Otherwise, check the number of multiplications required. */
2602 if ((TREE_INT_CST_HIGH (arg1) == 0
2603 || TREE_INT_CST_HIGH (arg1) == -1)
2604 && ((n >= -1 && n <= 2)
2605 || (! optimize_size
2606 && powi_cost (n) <= POWI_MAX_MULTS)))
2608 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2609 op0 = force_reg (mode, op0);
2610 return expand_powi (op0, mode, n);
2614 /* Emit a libcall to libgcc. */
2616 /* Mode of the 2nd argument must match that of an int. */
2617 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2619 if (target == NULL_RTX)
2620 target = gen_reg_rtx (mode);
2622 op0 = expand_expr (arg0, subtarget, mode, 0);
2623 if (GET_MODE (op0) != mode)
2624 op0 = convert_to_mode (mode, op0, 0);
2625 op1 = expand_expr (arg1, 0, mode2, 0);
2626 if (GET_MODE (op1) != mode2)
2627 op1 = convert_to_mode (mode2, op1, 0);
2629 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2630 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2631 op0, mode, op1, mode2);
2633 return target;
2636 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2637 if we failed the caller should emit a normal call, otherwise
2638 try to get the result in TARGET, if convenient. */
2640 static rtx
2641 expand_builtin_strlen (tree arglist, rtx target,
2642 enum machine_mode target_mode)
2644 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2645 return 0;
2646 else
2648 rtx pat;
2649 tree len, src = TREE_VALUE (arglist);
2650 rtx result, src_reg, char_rtx, before_strlen;
2651 enum machine_mode insn_mode = target_mode, char_mode;
2652 enum insn_code icode = CODE_FOR_nothing;
2653 int align;
2655 /* If the length can be computed at compile-time, return it. */
2656 len = c_strlen (src, 0);
2657 if (len)
2658 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2660 /* If the length can be computed at compile-time and is constant
2661 integer, but there are side-effects in src, evaluate
2662 src for side-effects, then return len.
2663 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2664 can be optimized into: i++; x = 3; */
2665 len = c_strlen (src, 1);
2666 if (len && TREE_CODE (len) == INTEGER_CST)
2668 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2669 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2672 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2674 /* If SRC is not a pointer type, don't do this operation inline. */
2675 if (align == 0)
2676 return 0;
2678 /* Bail out if we can't compute strlen in the right mode. */
2679 while (insn_mode != VOIDmode)
2681 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2682 if (icode != CODE_FOR_nothing)
2683 break;
2685 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2687 if (insn_mode == VOIDmode)
2688 return 0;
2690 /* Make a place to write the result of the instruction. */
2691 result = target;
2692 if (! (result != 0
2693 && REG_P (result)
2694 && GET_MODE (result) == insn_mode
2695 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2696 result = gen_reg_rtx (insn_mode);
2698 /* Make a place to hold the source address. We will not expand
2699 the actual source until we are sure that the expansion will
2700 not fail -- there are trees that cannot be expanded twice. */
2701 src_reg = gen_reg_rtx (Pmode);
2703 /* Mark the beginning of the strlen sequence so we can emit the
2704 source operand later. */
2705 before_strlen = get_last_insn ();
2707 char_rtx = const0_rtx;
2708 char_mode = insn_data[(int) icode].operand[2].mode;
2709 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2710 char_mode))
2711 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2713 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2714 char_rtx, GEN_INT (align));
2715 if (! pat)
2716 return 0;
2717 emit_insn (pat);
2719 /* Now that we are assured of success, expand the source. */
2720 start_sequence ();
2721 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2722 if (pat != src_reg)
2723 emit_move_insn (src_reg, pat);
2724 pat = get_insns ();
2725 end_sequence ();
2727 if (before_strlen)
2728 emit_insn_after (pat, before_strlen);
2729 else
2730 emit_insn_before (pat, get_insns ());
2732 /* Return the value in the proper mode for this function. */
2733 if (GET_MODE (result) == target_mode)
2734 target = result;
2735 else if (target != 0)
2736 convert_move (target, result, 0);
2737 else
2738 target = convert_to_mode (target_mode, result, 0);
2740 return target;
2744 /* Expand a call to the strstr builtin. Return 0 if we failed the
2745 caller should emit a normal call, otherwise try to get the result
2746 in TARGET, if convenient (and in mode MODE if that's convenient). */
2748 static rtx
2749 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2751 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2753 tree result = fold_builtin_strstr (arglist, type);
2754 if (result)
2755 return expand_expr (result, target, mode, EXPAND_NORMAL);
2757 return 0;
2760 /* Expand a call to the strchr builtin. Return 0 if we failed the
2761 caller should emit a normal call, otherwise try to get the result
2762 in TARGET, if convenient (and in mode MODE if that's convenient). */
2764 static rtx
2765 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2767 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2769 tree result = fold_builtin_strchr (arglist, type);
2770 if (result)
2771 return expand_expr (result, target, mode, EXPAND_NORMAL);
2773 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2775 return 0;
2778 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2779 caller should emit a normal call, otherwise try to get the result
2780 in TARGET, if convenient (and in mode MODE if that's convenient). */
2782 static rtx
2783 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2785 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2787 tree result = fold_builtin_strrchr (arglist, type);
2788 if (result)
2789 return expand_expr (result, target, mode, EXPAND_NORMAL);
2791 return 0;
2794 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2795 caller should emit a normal call, otherwise try to get the result
2796 in TARGET, if convenient (and in mode MODE if that's convenient). */
2798 static rtx
2799 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2801 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2803 tree result = fold_builtin_strpbrk (arglist, type);
2804 if (result)
2805 return expand_expr (result, target, mode, EXPAND_NORMAL);
2807 return 0;
2810 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2811 bytes from constant string DATA + OFFSET and return it as target
2812 constant. */
2814 static rtx
2815 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2816 enum machine_mode mode)
2818 const char *str = (const char *) data;
2820 gcc_assert (offset >= 0
2821 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2822 <= strlen (str) + 1));
2824 return c_readstr (str + offset, mode);
2827 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2828 Return 0 if we failed, the caller should emit a normal call,
2829 otherwise try to get the result in TARGET, if convenient (and in
2830 mode MODE if that's convenient). */
2831 static rtx
2832 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2834 tree fndecl = get_callee_fndecl (exp);
2835 tree arglist = TREE_OPERAND (exp, 1);
2836 if (!validate_arglist (arglist,
2837 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2838 return 0;
2839 else
2841 tree dest = TREE_VALUE (arglist);
2842 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2843 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2844 const char *src_str;
2845 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2846 unsigned int dest_align
2847 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2848 rtx dest_mem, src_mem, dest_addr, len_rtx;
2849 tree result = fold_builtin_memcpy (fndecl, arglist);
2851 if (result)
2852 return expand_expr (result, target, mode, EXPAND_NORMAL);
2854 /* If DEST is not a pointer type, call the normal function. */
2855 if (dest_align == 0)
2856 return 0;
2858 /* If either SRC is not a pointer type, don't do this
2859 operation in-line. */
2860 if (src_align == 0)
2861 return 0;
2863 dest_mem = get_memory_rtx (dest, len);
2864 set_mem_align (dest_mem, dest_align);
2865 len_rtx = expand_normal (len);
2866 src_str = c_getstr (src);
2868 /* If SRC is a string constant and block move would be done
2869 by pieces, we can avoid loading the string from memory
2870 and only stored the computed constants. */
2871 if (src_str
2872 && GET_CODE (len_rtx) == CONST_INT
2873 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2874 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2875 (void *) src_str, dest_align))
2877 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2878 builtin_memcpy_read_str,
2879 (void *) src_str, dest_align, 0);
2880 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2881 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2882 return dest_mem;
2885 src_mem = get_memory_rtx (src, len);
2886 set_mem_align (src_mem, src_align);
2888 /* Copy word part most expediently. */
2889 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2890 CALL_EXPR_TAILCALL (exp)
2891 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2893 if (dest_addr == 0)
2895 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2896 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2898 return dest_addr;
2902 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2903 Return 0 if we failed; the caller should emit a normal call,
2904 otherwise try to get the result in TARGET, if convenient (and in
2905 mode MODE if that's convenient). If ENDP is 0 return the
2906 destination pointer, if ENDP is 1 return the end pointer ala
2907 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2908 stpcpy. */
2910 static rtx
2911 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2912 int endp)
2914 if (!validate_arglist (arglist,
2915 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2916 return 0;
2917 /* If return value is ignored, transform mempcpy into memcpy. */
2918 else if (target == const0_rtx)
2920 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2922 if (!fn)
2923 return 0;
2925 return expand_expr (build_function_call_expr (fn, arglist),
2926 target, mode, EXPAND_NORMAL);
2928 else
2930 tree dest = TREE_VALUE (arglist);
2931 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2932 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2933 const char *src_str;
2934 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2935 unsigned int dest_align
2936 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2937 rtx dest_mem, src_mem, len_rtx;
2938 tree result = fold_builtin_mempcpy (arglist, type, endp);
2940 if (result)
2941 return expand_expr (result, target, mode, EXPAND_NORMAL);
2943 /* If either SRC or DEST is not a pointer type, don't do this
2944 operation in-line. */
2945 if (dest_align == 0 || src_align == 0)
2946 return 0;
2948 /* If LEN is not constant, call the normal function. */
2949 if (! host_integerp (len, 1))
2950 return 0;
2952 len_rtx = expand_normal (len);
2953 src_str = c_getstr (src);
2955 /* If SRC is a string constant and block move would be done
2956 by pieces, we can avoid loading the string from memory
2957 and only stored the computed constants. */
2958 if (src_str
2959 && GET_CODE (len_rtx) == CONST_INT
2960 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2961 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2962 (void *) src_str, dest_align))
2964 dest_mem = get_memory_rtx (dest, len);
2965 set_mem_align (dest_mem, dest_align);
2966 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2967 builtin_memcpy_read_str,
2968 (void *) src_str, dest_align, endp);
2969 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2970 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2971 return dest_mem;
2974 if (GET_CODE (len_rtx) == CONST_INT
2975 && can_move_by_pieces (INTVAL (len_rtx),
2976 MIN (dest_align, src_align)))
2978 dest_mem = get_memory_rtx (dest, len);
2979 set_mem_align (dest_mem, dest_align);
2980 src_mem = get_memory_rtx (src, len);
2981 set_mem_align (src_mem, src_align);
2982 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2983 MIN (dest_align, src_align), endp);
2984 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2985 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2986 return dest_mem;
2989 return 0;
2993 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2994 if we failed; the caller should emit a normal call. */
2996 static rtx
2997 expand_builtin_memmove (tree arglist, tree type, rtx target,
2998 enum machine_mode mode, tree orig_exp)
3000 if (!validate_arglist (arglist,
3001 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3002 return 0;
3003 else
3005 tree dest = TREE_VALUE (arglist);
3006 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3007 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3009 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3010 unsigned int dest_align
3011 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3012 tree result = fold_builtin_memmove (arglist, type);
3014 if (result)
3015 return expand_expr (result, target, mode, EXPAND_NORMAL);
3017 /* If DEST is not a pointer type, call the normal function. */
3018 if (dest_align == 0)
3019 return 0;
3021 /* If either SRC is not a pointer type, don't do this
3022 operation in-line. */
3023 if (src_align == 0)
3024 return 0;
3026 /* If src is categorized for a readonly section we can use
3027 normal memcpy. */
3028 if (readonly_data_expr (src))
3030 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3031 if (!fn)
3032 return 0;
3033 fn = build_function_call_expr (fn, arglist);
3034 if (TREE_CODE (fn) == CALL_EXPR)
3035 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3036 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3039 /* If length is 1 and we can expand memcpy call inline,
3040 it is ok to use memcpy as well. */
3041 if (integer_onep (len))
3043 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3044 /*endp=*/0);
3045 if (ret)
3046 return ret;
3049 /* Otherwise, call the normal function. */
3050 return 0;
3054 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3055 if we failed the caller should emit a normal call. */
3057 static rtx
3058 expand_builtin_bcopy (tree exp)
3060 tree arglist = TREE_OPERAND (exp, 1);
3061 tree type = TREE_TYPE (exp);
3062 tree src, dest, size, newarglist;
3064 if (!validate_arglist (arglist,
3065 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3066 return NULL_RTX;
3068 src = TREE_VALUE (arglist);
3069 dest = TREE_VALUE (TREE_CHAIN (arglist));
3070 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3072 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3073 memmove(ptr y, ptr x, size_t z). This is done this way
3074 so that if it isn't expanded inline, we fallback to
3075 calling bcopy instead of memmove. */
3077 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3078 newarglist = tree_cons (NULL_TREE, src, newarglist);
3079 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3081 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3084 #ifndef HAVE_movstr
3085 # define HAVE_movstr 0
3086 # define CODE_FOR_movstr CODE_FOR_nothing
3087 #endif
3089 /* Expand into a movstr instruction, if one is available. Return 0 if
3090 we failed, the caller should emit a normal call, otherwise try to
3091 get the result in TARGET, if convenient. If ENDP is 0 return the
3092 destination pointer, if ENDP is 1 return the end pointer ala
3093 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3094 stpcpy. */
3096 static rtx
3097 expand_movstr (tree dest, tree src, rtx target, int endp)
3099 rtx end;
3100 rtx dest_mem;
3101 rtx src_mem;
3102 rtx insn;
3103 const struct insn_data * data;
3105 if (!HAVE_movstr)
3106 return 0;
3108 dest_mem = get_memory_rtx (dest, NULL);
3109 src_mem = get_memory_rtx (src, NULL);
3110 if (!endp)
3112 target = force_reg (Pmode, XEXP (dest_mem, 0));
3113 dest_mem = replace_equiv_address (dest_mem, target);
3114 end = gen_reg_rtx (Pmode);
3116 else
3118 if (target == 0 || target == const0_rtx)
3120 end = gen_reg_rtx (Pmode);
3121 if (target == 0)
3122 target = end;
3124 else
3125 end = target;
3128 data = insn_data + CODE_FOR_movstr;
3130 if (data->operand[0].mode != VOIDmode)
3131 end = gen_lowpart (data->operand[0].mode, end);
3133 insn = data->genfun (end, dest_mem, src_mem);
3135 gcc_assert (insn);
3137 emit_insn (insn);
3139 /* movstr is supposed to set end to the address of the NUL
3140 terminator. If the caller requested a mempcpy-like return value,
3141 adjust it. */
3142 if (endp == 1 && target != const0_rtx)
3144 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3145 emit_move_insn (target, force_operand (tem, NULL_RTX));
3148 return target;
3151 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3152 if we failed the caller should emit a normal call, otherwise try to get
3153 the result in TARGET, if convenient (and in mode MODE if that's
3154 convenient). */
3156 static rtx
3157 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3159 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3161 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3162 if (result)
3163 return expand_expr (result, target, mode, EXPAND_NORMAL);
3165 return expand_movstr (TREE_VALUE (arglist),
3166 TREE_VALUE (TREE_CHAIN (arglist)),
3167 target, /*endp=*/0);
3169 return 0;
3172 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3173 Return 0 if we failed the caller should emit a normal call,
3174 otherwise try to get the result in TARGET, if convenient (and in
3175 mode MODE if that's convenient). */
3177 static rtx
3178 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3180 tree arglist = TREE_OPERAND (exp, 1);
3181 /* If return value is ignored, transform stpcpy into strcpy. */
3182 if (target == const0_rtx)
3184 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3185 if (!fn)
3186 return 0;
3188 return expand_expr (build_function_call_expr (fn, arglist),
3189 target, mode, EXPAND_NORMAL);
3192 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3193 return 0;
3194 else
3196 tree dst, src, len, lenp1;
3197 tree narglist;
3198 rtx ret;
3200 /* Ensure we get an actual string whose length can be evaluated at
3201 compile-time, not an expression containing a string. This is
3202 because the latter will potentially produce pessimized code
3203 when used to produce the return value. */
3204 src = TREE_VALUE (TREE_CHAIN (arglist));
3205 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3206 return expand_movstr (TREE_VALUE (arglist),
3207 TREE_VALUE (TREE_CHAIN (arglist)),
3208 target, /*endp=*/2);
3210 dst = TREE_VALUE (arglist);
3211 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3212 narglist = build_tree_list (NULL_TREE, lenp1);
3213 narglist = tree_cons (NULL_TREE, src, narglist);
3214 narglist = tree_cons (NULL_TREE, dst, narglist);
3215 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3216 target, mode, /*endp=*/2);
3218 if (ret)
3219 return ret;
3221 if (TREE_CODE (len) == INTEGER_CST)
3223 rtx len_rtx = expand_normal (len);
3225 if (GET_CODE (len_rtx) == CONST_INT)
3227 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3228 arglist, target, mode);
3230 if (ret)
3232 if (! target)
3234 if (mode != VOIDmode)
3235 target = gen_reg_rtx (mode);
3236 else
3237 target = gen_reg_rtx (GET_MODE (ret));
3239 if (GET_MODE (target) != GET_MODE (ret))
3240 ret = gen_lowpart (GET_MODE (target), ret);
3242 ret = plus_constant (ret, INTVAL (len_rtx));
3243 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3244 gcc_assert (ret);
3246 return target;
3251 return expand_movstr (TREE_VALUE (arglist),
3252 TREE_VALUE (TREE_CHAIN (arglist)),
3253 target, /*endp=*/2);
3257 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3258 bytes from constant string DATA + OFFSET and return it as target
3259 constant. */
3261 static rtx
3262 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3263 enum machine_mode mode)
3265 const char *str = (const char *) data;
3267 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3268 return const0_rtx;
3270 return c_readstr (str + offset, mode);
3273 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3274 if we failed the caller should emit a normal call. */
3276 static rtx
3277 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3279 tree fndecl = get_callee_fndecl (exp);
3280 tree arglist = TREE_OPERAND (exp, 1);
3281 if (validate_arglist (arglist,
3282 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3284 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3285 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3286 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3288 if (result)
3289 return expand_expr (result, target, mode, EXPAND_NORMAL);
3291 /* We must be passed a constant len and src parameter. */
3292 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3293 return 0;
3295 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3297 /* We're required to pad with trailing zeros if the requested
3298 len is greater than strlen(s2)+1. In that case try to
3299 use store_by_pieces, if it fails, punt. */
3300 if (tree_int_cst_lt (slen, len))
3302 tree dest = TREE_VALUE (arglist);
3303 unsigned int dest_align
3304 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3305 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3306 rtx dest_mem;
3308 if (!p || dest_align == 0 || !host_integerp (len, 1)
3309 || !can_store_by_pieces (tree_low_cst (len, 1),
3310 builtin_strncpy_read_str,
3311 (void *) p, dest_align))
3312 return 0;
3314 dest_mem = get_memory_rtx (dest, len);
3315 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3316 builtin_strncpy_read_str,
3317 (void *) p, dest_align, 0);
3318 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3319 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3320 return dest_mem;
3323 return 0;
3326 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3327 bytes from constant string DATA + OFFSET and return it as target
3328 constant. */
3330 static rtx
3331 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3332 enum machine_mode mode)
3334 const char *c = (const char *) data;
3335 char *p = alloca (GET_MODE_SIZE (mode));
3337 memset (p, *c, GET_MODE_SIZE (mode));
3339 return c_readstr (p, mode);
3342 /* Callback routine for store_by_pieces. Return the RTL of a register
3343 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3344 char value given in the RTL register data. For example, if mode is
3345 4 bytes wide, return the RTL for 0x01010101*data. */
3347 static rtx
3348 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3349 enum machine_mode mode)
3351 rtx target, coeff;
3352 size_t size;
3353 char *p;
3355 size = GET_MODE_SIZE (mode);
3356 if (size == 1)
3357 return (rtx) data;
3359 p = alloca (size);
3360 memset (p, 1, size);
3361 coeff = c_readstr (p, mode);
3363 target = convert_to_mode (mode, (rtx) data, 1);
3364 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3365 return force_reg (mode, target);
3368 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3369 if we failed the caller should emit a normal call, otherwise try to get
3370 the result in TARGET, if convenient (and in mode MODE if that's
3371 convenient). */
3373 static rtx
3374 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3375 tree orig_exp)
3377 if (!validate_arglist (arglist,
3378 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3379 return 0;
3380 else
3382 tree dest = TREE_VALUE (arglist);
3383 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3384 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3385 char c;
3387 unsigned int dest_align
3388 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3389 rtx dest_mem, dest_addr, len_rtx;
3391 /* If DEST is not a pointer type, don't do this
3392 operation in-line. */
3393 if (dest_align == 0)
3394 return 0;
3396 /* If the LEN parameter is zero, return DEST. */
3397 if (integer_zerop (len))
3399 /* Evaluate and ignore VAL in case it has side-effects. */
3400 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3401 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3404 len_rtx = expand_normal (len);
3405 dest_mem = get_memory_rtx (dest, len);
3407 if (TREE_CODE (val) != INTEGER_CST)
3409 rtx val_rtx;
3411 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3412 val_rtx = expand_normal (val);
3414 /* Assume that we can memset by pieces if we can store the
3415 * the coefficients by pieces (in the required modes).
3416 * We can't pass builtin_memset_gen_str as that emits RTL. */
3417 c = 1;
3418 if (host_integerp (len, 1)
3419 && !(optimize_size && tree_low_cst (len, 1) > 1)
3420 && can_store_by_pieces (tree_low_cst (len, 1),
3421 builtin_memset_read_str, &c, dest_align))
3423 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3424 val_rtx);
3425 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3426 builtin_memset_gen_str, val_rtx, dest_align, 0);
3428 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3429 dest_align))
3430 return 0;
3432 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3433 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3434 return dest_mem;
3437 if (target_char_cast (val, &c))
3438 return 0;
3440 if (c)
3442 if (host_integerp (len, 1)
3443 && !(optimize_size && tree_low_cst (len, 1) > 1)
3444 && can_store_by_pieces (tree_low_cst (len, 1),
3445 builtin_memset_read_str, &c, dest_align))
3446 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3447 builtin_memset_read_str, &c, dest_align, 0);
3448 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3449 dest_align))
3450 return 0;
3452 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3453 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3454 return dest_mem;
3457 set_mem_align (dest_mem, dest_align);
3458 dest_addr = clear_storage (dest_mem, len_rtx,
3459 CALL_EXPR_TAILCALL (orig_exp)
3460 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3462 if (dest_addr == 0)
3464 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3465 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3468 return dest_addr;
3472 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3473 if we failed the caller should emit a normal call. */
3475 static rtx
3476 expand_builtin_bzero (tree exp)
3478 tree arglist = TREE_OPERAND (exp, 1);
3479 tree dest, size, newarglist;
3481 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3482 return NULL_RTX;
3484 dest = TREE_VALUE (arglist);
3485 size = TREE_VALUE (TREE_CHAIN (arglist));
3487 /* New argument list transforming bzero(ptr x, int y) to
3488 memset(ptr x, int 0, size_t y). This is done this way
3489 so that if it isn't expanded inline, we fallback to
3490 calling bzero instead of memset. */
3492 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3493 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3494 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3496 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3499 /* Expand expression EXP, which is a call to the memcmp built-in function.
3500 ARGLIST is the argument list for this call. Return 0 if we failed and the
3501 caller should emit a normal call, otherwise try to get the result in
3502 TARGET, if convenient (and in mode MODE, if that's convenient). */
3504 static rtx
3505 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3506 enum machine_mode mode)
3508 if (!validate_arglist (arglist,
3509 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3510 return 0;
3511 else
3513 tree result = fold_builtin_memcmp (arglist);
3514 if (result)
3515 return expand_expr (result, target, mode, EXPAND_NORMAL);
3518 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3520 tree arg1 = TREE_VALUE (arglist);
3521 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3522 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3523 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3524 rtx result;
3525 rtx insn;
3527 int arg1_align
3528 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3529 int arg2_align
3530 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3531 enum machine_mode insn_mode;
3533 #ifdef HAVE_cmpmemsi
3534 if (HAVE_cmpmemsi)
3535 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3536 else
3537 #endif
3538 #ifdef HAVE_cmpstrnsi
3539 if (HAVE_cmpstrnsi)
3540 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3541 else
3542 #endif
3543 return 0;
3545 /* If we don't have POINTER_TYPE, call the function. */
3546 if (arg1_align == 0 || arg2_align == 0)
3547 return 0;
3549 /* Make a place to write the result of the instruction. */
3550 result = target;
3551 if (! (result != 0
3552 && REG_P (result) && GET_MODE (result) == insn_mode
3553 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3554 result = gen_reg_rtx (insn_mode);
3556 arg1_rtx = get_memory_rtx (arg1, len);
3557 arg2_rtx = get_memory_rtx (arg2, len);
3558 arg3_rtx = expand_normal (len);
3560 /* Set MEM_SIZE as appropriate. */
3561 if (GET_CODE (arg3_rtx) == CONST_INT)
3563 set_mem_size (arg1_rtx, arg3_rtx);
3564 set_mem_size (arg2_rtx, arg3_rtx);
3567 #ifdef HAVE_cmpmemsi
3568 if (HAVE_cmpmemsi)
3569 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3570 GEN_INT (MIN (arg1_align, arg2_align)));
3571 else
3572 #endif
3573 #ifdef HAVE_cmpstrnsi
3574 if (HAVE_cmpstrnsi)
3575 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3576 GEN_INT (MIN (arg1_align, arg2_align)));
3577 else
3578 #endif
3579 gcc_unreachable ();
3581 if (insn)
3582 emit_insn (insn);
3583 else
3584 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3585 TYPE_MODE (integer_type_node), 3,
3586 XEXP (arg1_rtx, 0), Pmode,
3587 XEXP (arg2_rtx, 0), Pmode,
3588 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3589 TYPE_UNSIGNED (sizetype)),
3590 TYPE_MODE (sizetype));
3592 /* Return the value in the proper mode for this function. */
3593 mode = TYPE_MODE (TREE_TYPE (exp));
3594 if (GET_MODE (result) == mode)
3595 return result;
3596 else if (target != 0)
3598 convert_move (target, result, 0);
3599 return target;
3601 else
3602 return convert_to_mode (mode, result, 0);
3604 #endif
3606 return 0;
3609 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3610 if we failed the caller should emit a normal call, otherwise try to get
3611 the result in TARGET, if convenient. */
3613 static rtx
3614 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3616 tree arglist = TREE_OPERAND (exp, 1);
3618 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3619 return 0;
3620 else
3622 tree result = fold_builtin_strcmp (arglist);
3623 if (result)
3624 return expand_expr (result, target, mode, EXPAND_NORMAL);
3627 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3628 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3629 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3631 rtx arg1_rtx, arg2_rtx;
3632 rtx result, insn = NULL_RTX;
3633 tree fndecl, fn;
3635 tree arg1 = TREE_VALUE (arglist);
3636 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3637 int arg1_align
3638 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3639 int arg2_align
3640 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3642 /* If we don't have POINTER_TYPE, call the function. */
3643 if (arg1_align == 0 || arg2_align == 0)
3644 return 0;
3646 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3647 arg1 = builtin_save_expr (arg1);
3648 arg2 = builtin_save_expr (arg2);
3650 arg1_rtx = get_memory_rtx (arg1, NULL);
3651 arg2_rtx = get_memory_rtx (arg2, NULL);
3653 #ifdef HAVE_cmpstrsi
3654 /* Try to call cmpstrsi. */
3655 if (HAVE_cmpstrsi)
3657 enum machine_mode insn_mode
3658 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3660 /* Make a place to write the result of the instruction. */
3661 result = target;
3662 if (! (result != 0
3663 && REG_P (result) && GET_MODE (result) == insn_mode
3664 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3665 result = gen_reg_rtx (insn_mode);
3667 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3668 GEN_INT (MIN (arg1_align, arg2_align)));
3670 #endif
3671 #if HAVE_cmpstrnsi
3672 /* Try to determine at least one length and call cmpstrnsi. */
3673 if (!insn && HAVE_cmpstrnsi)
3675 tree len;
3676 rtx arg3_rtx;
3678 enum machine_mode insn_mode
3679 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3680 tree len1 = c_strlen (arg1, 1);
3681 tree len2 = c_strlen (arg2, 1);
3683 if (len1)
3684 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3685 if (len2)
3686 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3688 /* If we don't have a constant length for the first, use the length
3689 of the second, if we know it. We don't require a constant for
3690 this case; some cost analysis could be done if both are available
3691 but neither is constant. For now, assume they're equally cheap,
3692 unless one has side effects. If both strings have constant lengths,
3693 use the smaller. */
3695 if (!len1)
3696 len = len2;
3697 else if (!len2)
3698 len = len1;
3699 else if (TREE_SIDE_EFFECTS (len1))
3700 len = len2;
3701 else if (TREE_SIDE_EFFECTS (len2))
3702 len = len1;
3703 else if (TREE_CODE (len1) != INTEGER_CST)
3704 len = len2;
3705 else if (TREE_CODE (len2) != INTEGER_CST)
3706 len = len1;
3707 else if (tree_int_cst_lt (len1, len2))
3708 len = len1;
3709 else
3710 len = len2;
3712 /* If both arguments have side effects, we cannot optimize. */
3713 if (!len || TREE_SIDE_EFFECTS (len))
3714 return 0;
3716 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3717 arg3_rtx = expand_normal (len);
3719 /* Make a place to write the result of the instruction. */
3720 result = target;
3721 if (! (result != 0
3722 && REG_P (result) && GET_MODE (result) == insn_mode
3723 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3724 result = gen_reg_rtx (insn_mode);
3726 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3727 GEN_INT (MIN (arg1_align, arg2_align)));
3729 #endif
3731 if (insn)
3733 emit_insn (insn);
3735 /* Return the value in the proper mode for this function. */
3736 mode = TYPE_MODE (TREE_TYPE (exp));
3737 if (GET_MODE (result) == mode)
3738 return result;
3739 if (target == 0)
3740 return convert_to_mode (mode, result, 0);
3741 convert_move (target, result, 0);
3742 return target;
3745 /* Expand the library call ourselves using a stabilized argument
3746 list to avoid re-evaluating the function's arguments twice. */
3747 arglist = build_tree_list (NULL_TREE, arg2);
3748 arglist = tree_cons (NULL_TREE, arg1, arglist);
3749 fndecl = get_callee_fndecl (exp);
3750 fn = build_function_call_expr (fndecl, arglist);
3751 if (TREE_CODE (fn) == CALL_EXPR)
3752 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3753 return expand_call (fn, target, target == const0_rtx);
3755 #endif
3756 return 0;
3759 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3760 if we failed the caller should emit a normal call, otherwise try to get
3761 the result in TARGET, if convenient. */
3763 static rtx
3764 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3766 tree arglist = TREE_OPERAND (exp, 1);
3768 if (!validate_arglist (arglist,
3769 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3770 return 0;
3771 else
3773 tree result = fold_builtin_strncmp (arglist);
3774 if (result)
3775 return expand_expr (result, target, mode, EXPAND_NORMAL);
3778 /* If c_strlen can determine an expression for one of the string
3779 lengths, and it doesn't have side effects, then emit cmpstrnsi
3780 using length MIN(strlen(string)+1, arg3). */
3781 #ifdef HAVE_cmpstrnsi
3782 if (HAVE_cmpstrnsi)
3784 tree arg1 = TREE_VALUE (arglist);
3785 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3786 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3787 tree len, len1, len2;
3788 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3789 rtx result, insn;
3790 tree fndecl, fn;
3792 int arg1_align
3793 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3794 int arg2_align
3795 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3796 enum machine_mode insn_mode
3797 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3799 len1 = c_strlen (arg1, 1);
3800 len2 = c_strlen (arg2, 1);
3802 if (len1)
3803 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3804 if (len2)
3805 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3807 /* If we don't have a constant length for the first, use the length
3808 of the second, if we know it. We don't require a constant for
3809 this case; some cost analysis could be done if both are available
3810 but neither is constant. For now, assume they're equally cheap,
3811 unless one has side effects. If both strings have constant lengths,
3812 use the smaller. */
3814 if (!len1)
3815 len = len2;
3816 else if (!len2)
3817 len = len1;
3818 else if (TREE_SIDE_EFFECTS (len1))
3819 len = len2;
3820 else if (TREE_SIDE_EFFECTS (len2))
3821 len = len1;
3822 else if (TREE_CODE (len1) != INTEGER_CST)
3823 len = len2;
3824 else if (TREE_CODE (len2) != INTEGER_CST)
3825 len = len1;
3826 else if (tree_int_cst_lt (len1, len2))
3827 len = len1;
3828 else
3829 len = len2;
3831 /* If both arguments have side effects, we cannot optimize. */
3832 if (!len || TREE_SIDE_EFFECTS (len))
3833 return 0;
3835 /* The actual new length parameter is MIN(len,arg3). */
3836 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3837 fold_convert (TREE_TYPE (len), arg3));
3839 /* If we don't have POINTER_TYPE, call the function. */
3840 if (arg1_align == 0 || arg2_align == 0)
3841 return 0;
3843 /* Make a place to write the result of the instruction. */
3844 result = target;
3845 if (! (result != 0
3846 && REG_P (result) && GET_MODE (result) == insn_mode
3847 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3848 result = gen_reg_rtx (insn_mode);
3850 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3851 arg1 = builtin_save_expr (arg1);
3852 arg2 = builtin_save_expr (arg2);
3853 len = builtin_save_expr (len);
3855 arg1_rtx = get_memory_rtx (arg1, len);
3856 arg2_rtx = get_memory_rtx (arg2, len);
3857 arg3_rtx = expand_normal (len);
3858 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3859 GEN_INT (MIN (arg1_align, arg2_align)));
3860 if (insn)
3862 emit_insn (insn);
3864 /* Return the value in the proper mode for this function. */
3865 mode = TYPE_MODE (TREE_TYPE (exp));
3866 if (GET_MODE (result) == mode)
3867 return result;
3868 if (target == 0)
3869 return convert_to_mode (mode, result, 0);
3870 convert_move (target, result, 0);
3871 return target;
3874 /* Expand the library call ourselves using a stabilized argument
3875 list to avoid re-evaluating the function's arguments twice. */
3876 arglist = build_tree_list (NULL_TREE, len);
3877 arglist = tree_cons (NULL_TREE, arg2, arglist);
3878 arglist = tree_cons (NULL_TREE, arg1, arglist);
3879 fndecl = get_callee_fndecl (exp);
3880 fn = build_function_call_expr (fndecl, arglist);
3881 if (TREE_CODE (fn) == CALL_EXPR)
3882 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3883 return expand_call (fn, target, target == const0_rtx);
3885 #endif
3886 return 0;
3889 /* Expand expression EXP, which is a call to the strcat builtin.
3890 Return 0 if we failed the caller should emit a normal call,
3891 otherwise try to get the result in TARGET, if convenient. */
3893 static rtx
3894 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3896 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3897 return 0;
3898 else
3900 tree dst = TREE_VALUE (arglist),
3901 src = TREE_VALUE (TREE_CHAIN (arglist));
3902 const char *p = c_getstr (src);
3904 /* If the string length is zero, return the dst parameter. */
3905 if (p && *p == '\0')
3906 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3908 if (!optimize_size)
3910 /* See if we can store by pieces into (dst + strlen(dst)). */
3911 tree newsrc, newdst,
3912 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3913 rtx insns;
3915 /* Stabilize the argument list. */
3916 newsrc = builtin_save_expr (src);
3917 if (newsrc != src)
3918 arglist = build_tree_list (NULL_TREE, newsrc);
3919 else
3920 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3922 dst = builtin_save_expr (dst);
3924 start_sequence ();
3926 /* Create strlen (dst). */
3927 newdst =
3928 build_function_call_expr (strlen_fn,
3929 build_tree_list (NULL_TREE, dst));
3930 /* Create (dst + (cast) strlen (dst)). */
3931 newdst = fold_convert (TREE_TYPE (dst), newdst);
3932 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3934 newdst = builtin_save_expr (newdst);
3935 arglist = tree_cons (NULL_TREE, newdst, arglist);
3937 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3939 end_sequence (); /* Stop sequence. */
3940 return 0;
3943 /* Output the entire sequence. */
3944 insns = get_insns ();
3945 end_sequence ();
3946 emit_insn (insns);
3948 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3951 return 0;
3955 /* Expand expression EXP, which is a call to the strncat builtin.
3956 Return 0 if we failed the caller should emit a normal call,
3957 otherwise try to get the result in TARGET, if convenient. */
3959 static rtx
3960 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3962 if (validate_arglist (arglist,
3963 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3965 tree result = fold_builtin_strncat (arglist);
3966 if (result)
3967 return expand_expr (result, target, mode, EXPAND_NORMAL);
3969 return 0;
3972 /* Expand expression EXP, which is a call to the strspn builtin.
3973 Return 0 if we failed the caller should emit a normal call,
3974 otherwise try to get the result in TARGET, if convenient. */
3976 static rtx
3977 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3979 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3981 tree result = fold_builtin_strspn (arglist);
3982 if (result)
3983 return expand_expr (result, target, mode, EXPAND_NORMAL);
3985 return 0;
3988 /* Expand expression EXP, which is a call to the strcspn builtin.
3989 Return 0 if we failed the caller should emit a normal call,
3990 otherwise try to get the result in TARGET, if convenient. */
3992 static rtx
3993 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3995 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3997 tree result = fold_builtin_strcspn (arglist);
3998 if (result)
3999 return expand_expr (result, target, mode, EXPAND_NORMAL);
4001 return 0;
4004 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4005 if that's convenient. */
4008 expand_builtin_saveregs (void)
4010 rtx val, seq;
4012 /* Don't do __builtin_saveregs more than once in a function.
4013 Save the result of the first call and reuse it. */
4014 if (saveregs_value != 0)
4015 return saveregs_value;
4017 /* When this function is called, it means that registers must be
4018 saved on entry to this function. So we migrate the call to the
4019 first insn of this function. */
4021 start_sequence ();
4023 /* Do whatever the machine needs done in this case. */
4024 val = targetm.calls.expand_builtin_saveregs ();
4026 seq = get_insns ();
4027 end_sequence ();
4029 saveregs_value = val;
4031 /* Put the insns after the NOTE that starts the function. If this
4032 is inside a start_sequence, make the outer-level insn chain current, so
4033 the code is placed at the start of the function. */
4034 push_topmost_sequence ();
4035 emit_insn_after (seq, entry_of_function ());
4036 pop_topmost_sequence ();
4038 return val;
4041 /* __builtin_args_info (N) returns word N of the arg space info
4042 for the current function. The number and meanings of words
4043 is controlled by the definition of CUMULATIVE_ARGS. */
4045 static rtx
4046 expand_builtin_args_info (tree arglist)
4048 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4049 int *word_ptr = (int *) &current_function_args_info;
4051 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4053 if (arglist != 0)
4055 if (!host_integerp (TREE_VALUE (arglist), 0))
4056 error ("argument of %<__builtin_args_info%> must be constant");
4057 else
4059 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4061 if (wordnum < 0 || wordnum >= nwords)
4062 error ("argument of %<__builtin_args_info%> out of range");
4063 else
4064 return GEN_INT (word_ptr[wordnum]);
4067 else
4068 error ("missing argument in %<__builtin_args_info%>");
4070 return const0_rtx;
4073 /* Expand a call to __builtin_next_arg. */
4075 static rtx
4076 expand_builtin_next_arg (void)
4078 /* Checking arguments is already done in fold_builtin_next_arg
4079 that must be called before this function. */
4080 return expand_binop (Pmode, add_optab,
4081 current_function_internal_arg_pointer,
4082 current_function_arg_offset_rtx,
4083 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4086 /* Make it easier for the backends by protecting the valist argument
4087 from multiple evaluations. */
4089 static tree
4090 stabilize_va_list (tree valist, int needs_lvalue)
4092 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4094 if (TREE_SIDE_EFFECTS (valist))
4095 valist = save_expr (valist);
4097 /* For this case, the backends will be expecting a pointer to
4098 TREE_TYPE (va_list_type_node), but it's possible we've
4099 actually been given an array (an actual va_list_type_node).
4100 So fix it. */
4101 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4103 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4104 valist = build_fold_addr_expr_with_type (valist, p1);
4107 else
4109 tree pt;
4111 if (! needs_lvalue)
4113 if (! TREE_SIDE_EFFECTS (valist))
4114 return valist;
4116 pt = build_pointer_type (va_list_type_node);
4117 valist = fold_build1 (ADDR_EXPR, pt, valist);
4118 TREE_SIDE_EFFECTS (valist) = 1;
4121 if (TREE_SIDE_EFFECTS (valist))
4122 valist = save_expr (valist);
4123 valist = build_fold_indirect_ref (valist);
4126 return valist;
4129 /* The "standard" definition of va_list is void*. */
4131 tree
4132 std_build_builtin_va_list (void)
4134 return ptr_type_node;
4137 /* The "standard" implementation of va_start: just assign `nextarg' to
4138 the variable. */
4140 void
4141 std_expand_builtin_va_start (tree valist, rtx nextarg)
4143 tree t;
4145 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4146 make_tree (ptr_type_node, nextarg));
4147 TREE_SIDE_EFFECTS (t) = 1;
4149 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4152 /* Expand ARGLIST, from a call to __builtin_va_start. */
4154 static rtx
4155 expand_builtin_va_start (tree arglist)
4157 rtx nextarg;
4158 tree chain, valist;
4160 chain = TREE_CHAIN (arglist);
4162 if (!chain)
4164 error ("too few arguments to function %<va_start%>");
4165 return const0_rtx;
4168 if (fold_builtin_next_arg (chain))
4169 return const0_rtx;
4171 nextarg = expand_builtin_next_arg ();
4172 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4174 #ifdef EXPAND_BUILTIN_VA_START
4175 EXPAND_BUILTIN_VA_START (valist, nextarg);
4176 #else
4177 std_expand_builtin_va_start (valist, nextarg);
4178 #endif
4180 return const0_rtx;
4183 /* The "standard" implementation of va_arg: read the value from the
4184 current (padded) address and increment by the (padded) size. */
4186 tree
4187 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4189 tree addr, t, type_size, rounded_size, valist_tmp;
4190 unsigned HOST_WIDE_INT align, boundary;
4191 bool indirect;
4193 #ifdef ARGS_GROW_DOWNWARD
4194 /* All of the alignment and movement below is for args-grow-up machines.
4195 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4196 implement their own specialized gimplify_va_arg_expr routines. */
4197 gcc_unreachable ();
4198 #endif
4200 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4201 if (indirect)
4202 type = build_pointer_type (type);
4204 align = PARM_BOUNDARY / BITS_PER_UNIT;
4205 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4207 /* Hoist the valist value into a temporary for the moment. */
4208 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4210 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4211 requires greater alignment, we must perform dynamic alignment. */
4212 if (boundary > align
4213 && !integer_zerop (TYPE_SIZE (type)))
4215 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4216 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4217 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4218 gimplify_and_add (t, pre_p);
4220 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4221 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4222 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4223 gimplify_and_add (t, pre_p);
4225 else
4226 boundary = align;
4228 /* If the actual alignment is less than the alignment of the type,
4229 adjust the type accordingly so that we don't assume strict alignment
4230 when deferencing the pointer. */
4231 boundary *= BITS_PER_UNIT;
4232 if (boundary < TYPE_ALIGN (type))
4234 type = build_variant_type_copy (type);
4235 TYPE_ALIGN (type) = boundary;
4238 /* Compute the rounded size of the type. */
4239 type_size = size_in_bytes (type);
4240 rounded_size = round_up (type_size, align);
4242 /* Reduce rounded_size so it's sharable with the postqueue. */
4243 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4245 /* Get AP. */
4246 addr = valist_tmp;
4247 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4249 /* Small args are padded downward. */
4250 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4251 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4252 size_binop (MINUS_EXPR, rounded_size, type_size));
4253 t = fold_convert (TREE_TYPE (addr), t);
4254 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4257 /* Compute new value for AP. */
4258 t = fold_convert (TREE_TYPE (valist), rounded_size);
4259 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4260 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4261 gimplify_and_add (t, pre_p);
4263 addr = fold_convert (build_pointer_type (type), addr);
4265 if (indirect)
4266 addr = build_va_arg_indirect_ref (addr);
4268 return build_va_arg_indirect_ref (addr);
4271 /* Build an indirect-ref expression over the given TREE, which represents a
4272 piece of a va_arg() expansion. */
4273 tree
4274 build_va_arg_indirect_ref (tree addr)
4276 addr = build_fold_indirect_ref (addr);
4278 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4279 mf_mark (addr);
4281 return addr;
4284 /* Return a dummy expression of type TYPE in order to keep going after an
4285 error. */
4287 static tree
4288 dummy_object (tree type)
4290 tree t = convert (build_pointer_type (type), null_pointer_node);
4291 return build1 (INDIRECT_REF, type, t);
4294 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4295 builtin function, but a very special sort of operator. */
4297 enum gimplify_status
4298 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4300 tree promoted_type, want_va_type, have_va_type;
4301 tree valist = TREE_OPERAND (*expr_p, 0);
4302 tree type = TREE_TYPE (*expr_p);
4303 tree t;
4305 /* Verify that valist is of the proper type. */
4306 want_va_type = va_list_type_node;
4307 have_va_type = TREE_TYPE (valist);
4309 if (have_va_type == error_mark_node)
4310 return GS_ERROR;
4312 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4314 /* If va_list is an array type, the argument may have decayed
4315 to a pointer type, e.g. by being passed to another function.
4316 In that case, unwrap both types so that we can compare the
4317 underlying records. */
4318 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4319 || POINTER_TYPE_P (have_va_type))
4321 want_va_type = TREE_TYPE (want_va_type);
4322 have_va_type = TREE_TYPE (have_va_type);
4326 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4328 error ("first argument to %<va_arg%> not of type %<va_list%>");
4329 return GS_ERROR;
4332 /* Generate a diagnostic for requesting data of a type that cannot
4333 be passed through `...' due to type promotion at the call site. */
4334 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4335 != type)
4337 static bool gave_help;
4339 /* Unfortunately, this is merely undefined, rather than a constraint
4340 violation, so we cannot make this an error. If this call is never
4341 executed, the program is still strictly conforming. */
4342 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4343 type, promoted_type);
4344 if (! gave_help)
4346 gave_help = true;
4347 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4348 promoted_type, type);
4351 /* We can, however, treat "undefined" any way we please.
4352 Call abort to encourage the user to fix the program. */
4353 inform ("if this code is reached, the program will abort");
4354 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4355 NULL);
4356 append_to_statement_list (t, pre_p);
4358 /* This is dead code, but go ahead and finish so that the
4359 mode of the result comes out right. */
4360 *expr_p = dummy_object (type);
4361 return GS_ALL_DONE;
4363 else
4365 /* Make it easier for the backends by protecting the valist argument
4366 from multiple evaluations. */
4367 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4369 /* For this case, the backends will be expecting a pointer to
4370 TREE_TYPE (va_list_type_node), but it's possible we've
4371 actually been given an array (an actual va_list_type_node).
4372 So fix it. */
4373 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4375 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4376 valist = build_fold_addr_expr_with_type (valist, p1);
4378 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4380 else
4381 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4383 if (!targetm.gimplify_va_arg_expr)
4384 /* FIXME:Once most targets are converted we should merely
4385 assert this is non-null. */
4386 return GS_ALL_DONE;
4388 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4389 return GS_OK;
4393 /* Expand ARGLIST, from a call to __builtin_va_end. */
4395 static rtx
4396 expand_builtin_va_end (tree arglist)
4398 tree valist = TREE_VALUE (arglist);
4400 /* Evaluate for side effects, if needed. I hate macros that don't
4401 do that. */
4402 if (TREE_SIDE_EFFECTS (valist))
4403 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4405 return const0_rtx;
4408 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4409 builtin rather than just as an assignment in stdarg.h because of the
4410 nastiness of array-type va_list types. */
4412 static rtx
4413 expand_builtin_va_copy (tree arglist)
4415 tree dst, src, t;
4417 dst = TREE_VALUE (arglist);
4418 src = TREE_VALUE (TREE_CHAIN (arglist));
4420 dst = stabilize_va_list (dst, 1);
4421 src = stabilize_va_list (src, 0);
4423 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4425 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4426 TREE_SIDE_EFFECTS (t) = 1;
4427 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4429 else
4431 rtx dstb, srcb, size;
4433 /* Evaluate to pointers. */
4434 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4435 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4436 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4437 VOIDmode, EXPAND_NORMAL);
4439 dstb = convert_memory_address (Pmode, dstb);
4440 srcb = convert_memory_address (Pmode, srcb);
4442 /* "Dereference" to BLKmode memories. */
4443 dstb = gen_rtx_MEM (BLKmode, dstb);
4444 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4445 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4446 srcb = gen_rtx_MEM (BLKmode, srcb);
4447 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4448 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4450 /* Copy. */
4451 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4454 return const0_rtx;
4457 /* Expand a call to one of the builtin functions __builtin_frame_address or
4458 __builtin_return_address. */
4460 static rtx
4461 expand_builtin_frame_address (tree fndecl, tree arglist)
4463 /* The argument must be a nonnegative integer constant.
4464 It counts the number of frames to scan up the stack.
4465 The value is the return address saved in that frame. */
4466 if (arglist == 0)
4467 /* Warning about missing arg was already issued. */
4468 return const0_rtx;
4469 else if (! host_integerp (TREE_VALUE (arglist), 1))
4471 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4472 error ("invalid argument to %<__builtin_frame_address%>");
4473 else
4474 error ("invalid argument to %<__builtin_return_address%>");
4475 return const0_rtx;
4477 else
4479 rtx tem
4480 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4481 tree_low_cst (TREE_VALUE (arglist), 1));
4483 /* Some ports cannot access arbitrary stack frames. */
4484 if (tem == NULL)
4486 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4487 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4488 else
4489 warning (0, "unsupported argument to %<__builtin_return_address%>");
4490 return const0_rtx;
4493 /* For __builtin_frame_address, return what we've got. */
4494 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4495 return tem;
4497 if (!REG_P (tem)
4498 && ! CONSTANT_P (tem))
4499 tem = copy_to_mode_reg (Pmode, tem);
4500 return tem;
4504 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4505 we failed and the caller should emit a normal call, otherwise try to get
4506 the result in TARGET, if convenient. */
4508 static rtx
4509 expand_builtin_alloca (tree arglist, rtx target)
4511 rtx op0;
4512 rtx result;
4514 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4515 should always expand to function calls. These can be intercepted
4516 in libmudflap. */
4517 if (flag_mudflap)
4518 return 0;
4520 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4521 return 0;
4523 /* Compute the argument. */
4524 op0 = expand_normal (TREE_VALUE (arglist));
4526 /* Allocate the desired space. */
4527 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4528 result = convert_memory_address (ptr_mode, result);
4530 return result;
4533 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4534 Return 0 if a normal call should be emitted rather than expanding the
4535 function in-line. If convenient, the result should be placed in TARGET.
4536 SUBTARGET may be used as the target for computing one of EXP's operands. */
4538 static rtx
4539 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4540 rtx subtarget, optab op_optab)
4542 rtx op0;
4543 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4544 return 0;
4546 /* Compute the argument. */
4547 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4548 /* Compute op, into TARGET if possible.
4549 Set TARGET to wherever the result comes back. */
4550 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4551 op_optab, op0, target, 1);
4552 gcc_assert (target);
4554 return convert_to_mode (target_mode, target, 0);
4557 /* If the string passed to fputs is a constant and is one character
4558 long, we attempt to transform this call into __builtin_fputc(). */
4560 static rtx
4561 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4563 /* Verify the arguments in the original call. */
4564 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4566 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4567 unlocked, NULL_TREE);
4568 if (result)
4569 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4571 return 0;
4574 /* Expand a call to __builtin_expect. We return our argument and emit a
4575 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4576 a non-jump context. */
4578 static rtx
4579 expand_builtin_expect (tree arglist, rtx target)
4581 tree exp, c;
4582 rtx note, rtx_c;
4584 if (arglist == NULL_TREE
4585 || TREE_CHAIN (arglist) == NULL_TREE)
4586 return const0_rtx;
4587 exp = TREE_VALUE (arglist);
4588 c = TREE_VALUE (TREE_CHAIN (arglist));
4590 if (TREE_CODE (c) != INTEGER_CST)
4592 error ("second argument to %<__builtin_expect%> must be a constant");
4593 c = integer_zero_node;
4596 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4598 /* Don't bother with expected value notes for integral constants. */
4599 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4601 /* We do need to force this into a register so that we can be
4602 moderately sure to be able to correctly interpret the branch
4603 condition later. */
4604 target = force_reg (GET_MODE (target), target);
4606 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4608 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4609 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4612 return target;
4615 /* Like expand_builtin_expect, except do this in a jump context. This is
4616 called from do_jump if the conditional is a __builtin_expect. Return either
4617 a list of insns to emit the jump or NULL if we cannot optimize
4618 __builtin_expect. We need to optimize this at jump time so that machines
4619 like the PowerPC don't turn the test into a SCC operation, and then jump
4620 based on the test being 0/1. */
4623 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4625 tree arglist = TREE_OPERAND (exp, 1);
4626 tree arg0 = TREE_VALUE (arglist);
4627 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4628 rtx ret = NULL_RTX;
4630 /* Only handle __builtin_expect (test, 0) and
4631 __builtin_expect (test, 1). */
4632 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4633 && (integer_zerop (arg1) || integer_onep (arg1)))
4635 rtx insn, drop_through_label, temp;
4637 /* Expand the jump insns. */
4638 start_sequence ();
4639 do_jump (arg0, if_false_label, if_true_label);
4640 ret = get_insns ();
4642 drop_through_label = get_last_insn ();
4643 if (drop_through_label && NOTE_P (drop_through_label))
4644 drop_through_label = prev_nonnote_insn (drop_through_label);
4645 if (drop_through_label && !LABEL_P (drop_through_label))
4646 drop_through_label = NULL_RTX;
4647 end_sequence ();
4649 if (! if_true_label)
4650 if_true_label = drop_through_label;
4651 if (! if_false_label)
4652 if_false_label = drop_through_label;
4654 /* Go through and add the expect's to each of the conditional jumps. */
4655 insn = ret;
4656 while (insn != NULL_RTX)
4658 rtx next = NEXT_INSN (insn);
4660 if (JUMP_P (insn) && any_condjump_p (insn))
4662 rtx ifelse = SET_SRC (pc_set (insn));
4663 rtx then_dest = XEXP (ifelse, 1);
4664 rtx else_dest = XEXP (ifelse, 2);
4665 int taken = -1;
4667 /* First check if we recognize any of the labels. */
4668 if (GET_CODE (then_dest) == LABEL_REF
4669 && XEXP (then_dest, 0) == if_true_label)
4670 taken = 1;
4671 else if (GET_CODE (then_dest) == LABEL_REF
4672 && XEXP (then_dest, 0) == if_false_label)
4673 taken = 0;
4674 else if (GET_CODE (else_dest) == LABEL_REF
4675 && XEXP (else_dest, 0) == if_false_label)
4676 taken = 1;
4677 else if (GET_CODE (else_dest) == LABEL_REF
4678 && XEXP (else_dest, 0) == if_true_label)
4679 taken = 0;
4680 /* Otherwise check where we drop through. */
4681 else if (else_dest == pc_rtx)
4683 if (next && NOTE_P (next))
4684 next = next_nonnote_insn (next);
4686 if (next && JUMP_P (next)
4687 && any_uncondjump_p (next))
4688 temp = XEXP (SET_SRC (pc_set (next)), 0);
4689 else
4690 temp = next;
4692 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4693 else that can't possibly match either target label. */
4694 if (temp == if_false_label)
4695 taken = 1;
4696 else if (temp == if_true_label)
4697 taken = 0;
4699 else if (then_dest == pc_rtx)
4701 if (next && NOTE_P (next))
4702 next = next_nonnote_insn (next);
4704 if (next && JUMP_P (next)
4705 && any_uncondjump_p (next))
4706 temp = XEXP (SET_SRC (pc_set (next)), 0);
4707 else
4708 temp = next;
4710 if (temp == if_false_label)
4711 taken = 0;
4712 else if (temp == if_true_label)
4713 taken = 1;
4716 if (taken != -1)
4718 /* If the test is expected to fail, reverse the
4719 probabilities. */
4720 if (integer_zerop (arg1))
4721 taken = 1 - taken;
4722 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4726 insn = next;
4730 return ret;
4733 void
4734 expand_builtin_trap (void)
4736 #ifdef HAVE_trap
4737 if (HAVE_trap)
4738 emit_insn (gen_trap ());
4739 else
4740 #endif
4741 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4742 emit_barrier ();
4745 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4746 Return 0 if a normal call should be emitted rather than expanding
4747 the function inline. If convenient, the result should be placed
4748 in TARGET. SUBTARGET may be used as the target for computing
4749 the operand. */
4751 static rtx
4752 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4754 enum machine_mode mode;
4755 tree arg;
4756 rtx op0;
4758 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4759 return 0;
4761 arg = TREE_VALUE (arglist);
4762 mode = TYPE_MODE (TREE_TYPE (arg));
4763 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4764 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4767 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4768 Return NULL is a normal call should be emitted rather than expanding the
4769 function inline. If convenient, the result should be placed in TARGET.
4770 SUBTARGET may be used as the target for computing the operand. */
4772 static rtx
4773 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4775 rtx op0, op1;
4776 tree arg;
4778 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4779 return 0;
4781 arg = TREE_VALUE (arglist);
4782 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4784 arg = TREE_VALUE (TREE_CHAIN (arglist));
4785 op1 = expand_normal (arg);
4787 return expand_copysign (op0, op1, target);
4790 /* Create a new constant string literal and return a char* pointer to it.
4791 The STRING_CST value is the LEN characters at STR. */
4792 tree
4793 build_string_literal (int len, const char *str)
4795 tree t, elem, index, type;
4797 t = build_string (len, str);
4798 elem = build_type_variant (char_type_node, 1, 0);
4799 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4800 type = build_array_type (elem, index);
4801 TREE_TYPE (t) = type;
4802 TREE_CONSTANT (t) = 1;
4803 TREE_INVARIANT (t) = 1;
4804 TREE_READONLY (t) = 1;
4805 TREE_STATIC (t) = 1;
4807 type = build_pointer_type (type);
4808 t = build1 (ADDR_EXPR, type, t);
4810 type = build_pointer_type (elem);
4811 t = build1 (NOP_EXPR, type, t);
4812 return t;
4815 /* Expand EXP, a call to printf or printf_unlocked.
4816 Return 0 if a normal call should be emitted rather than transforming
4817 the function inline. If convenient, the result should be placed in
4818 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4819 call. */
4820 static rtx
4821 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4822 bool unlocked)
4824 tree arglist = TREE_OPERAND (exp, 1);
4825 /* If we're using an unlocked function, assume the other unlocked
4826 functions exist explicitly. */
4827 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4828 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4829 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4830 : implicit_built_in_decls[BUILT_IN_PUTS];
4831 const char *fmt_str;
4832 tree fn, fmt, arg;
4834 /* If the return value is used, don't do the transformation. */
4835 if (target != const0_rtx)
4836 return 0;
4838 /* Verify the required arguments in the original call. */
4839 if (! arglist)
4840 return 0;
4841 fmt = TREE_VALUE (arglist);
4842 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4843 return 0;
4844 arglist = TREE_CHAIN (arglist);
4846 /* Check whether the format is a literal string constant. */
4847 fmt_str = c_getstr (fmt);
4848 if (fmt_str == NULL)
4849 return 0;
4851 if (!init_target_chars())
4852 return 0;
4854 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4855 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4857 if (! arglist
4858 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4859 || TREE_CHAIN (arglist))
4860 return 0;
4861 fn = fn_puts;
4863 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4864 else if (strcmp (fmt_str, target_percent_c) == 0)
4866 if (! arglist
4867 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4868 || TREE_CHAIN (arglist))
4869 return 0;
4870 fn = fn_putchar;
4872 else
4874 /* We can't handle anything else with % args or %% ... yet. */
4875 if (strchr (fmt_str, target_percent))
4876 return 0;
4878 if (arglist)
4879 return 0;
4881 /* If the format specifier was "", printf does nothing. */
4882 if (fmt_str[0] == '\0')
4883 return const0_rtx;
4884 /* If the format specifier has length of 1, call putchar. */
4885 if (fmt_str[1] == '\0')
4887 /* Given printf("c"), (where c is any one character,)
4888 convert "c"[0] to an int and pass that to the replacement
4889 function. */
4890 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4891 arglist = build_tree_list (NULL_TREE, arg);
4892 fn = fn_putchar;
4894 else
4896 /* If the format specifier was "string\n", call puts("string"). */
4897 size_t len = strlen (fmt_str);
4898 if ((unsigned char)fmt_str[len - 1] == target_newline)
4900 /* Create a NUL-terminated string that's one char shorter
4901 than the original, stripping off the trailing '\n'. */
4902 char *newstr = alloca (len);
4903 memcpy (newstr, fmt_str, len - 1);
4904 newstr[len - 1] = 0;
4906 arg = build_string_literal (len, newstr);
4907 arglist = build_tree_list (NULL_TREE, arg);
4908 fn = fn_puts;
4910 else
4911 /* We'd like to arrange to call fputs(string,stdout) here,
4912 but we need stdout and don't have a way to get it yet. */
4913 return 0;
4917 if (!fn)
4918 return 0;
4919 fn = build_function_call_expr (fn, arglist);
4920 if (TREE_CODE (fn) == CALL_EXPR)
4921 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4922 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4925 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4926 Return 0 if a normal call should be emitted rather than transforming
4927 the function inline. If convenient, the result should be placed in
4928 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4929 call. */
4930 static rtx
4931 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4932 bool unlocked)
4934 tree arglist = TREE_OPERAND (exp, 1);
4935 /* If we're using an unlocked function, assume the other unlocked
4936 functions exist explicitly. */
4937 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4938 : implicit_built_in_decls[BUILT_IN_FPUTC];
4939 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4940 : implicit_built_in_decls[BUILT_IN_FPUTS];
4941 const char *fmt_str;
4942 tree fn, fmt, fp, arg;
4944 /* If the return value is used, don't do the transformation. */
4945 if (target != const0_rtx)
4946 return 0;
4948 /* Verify the required arguments in the original call. */
4949 if (! arglist)
4950 return 0;
4951 fp = TREE_VALUE (arglist);
4952 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4953 return 0;
4954 arglist = TREE_CHAIN (arglist);
4955 if (! arglist)
4956 return 0;
4957 fmt = TREE_VALUE (arglist);
4958 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4959 return 0;
4960 arglist = TREE_CHAIN (arglist);
4962 /* Check whether the format is a literal string constant. */
4963 fmt_str = c_getstr (fmt);
4964 if (fmt_str == NULL)
4965 return 0;
4967 if (!init_target_chars())
4968 return 0;
4970 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4971 if (strcmp (fmt_str, target_percent_s) == 0)
4973 if (! arglist
4974 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4975 || TREE_CHAIN (arglist))
4976 return 0;
4977 arg = TREE_VALUE (arglist);
4978 arglist = build_tree_list (NULL_TREE, fp);
4979 arglist = tree_cons (NULL_TREE, arg, arglist);
4980 fn = fn_fputs;
4982 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4983 else if (strcmp (fmt_str, target_percent_c) == 0)
4985 if (! arglist
4986 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4987 || TREE_CHAIN (arglist))
4988 return 0;
4989 arg = TREE_VALUE (arglist);
4990 arglist = build_tree_list (NULL_TREE, fp);
4991 arglist = tree_cons (NULL_TREE, arg, arglist);
4992 fn = fn_fputc;
4994 else
4996 /* We can't handle anything else with % args or %% ... yet. */
4997 if (strchr (fmt_str, target_percent))
4998 return 0;
5000 if (arglist)
5001 return 0;
5003 /* If the format specifier was "", fprintf does nothing. */
5004 if (fmt_str[0] == '\0')
5006 /* Evaluate and ignore FILE* argument for side-effects. */
5007 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5008 return const0_rtx;
5011 /* When "string" doesn't contain %, replace all cases of
5012 fprintf(stream,string) with fputs(string,stream). The fputs
5013 builtin will take care of special cases like length == 1. */
5014 arglist = build_tree_list (NULL_TREE, fp);
5015 arglist = tree_cons (NULL_TREE, fmt, arglist);
5016 fn = fn_fputs;
5019 if (!fn)
5020 return 0;
5021 fn = build_function_call_expr (fn, arglist);
5022 if (TREE_CODE (fn) == CALL_EXPR)
5023 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5024 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5027 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5028 a normal call should be emitted rather than expanding the function
5029 inline. If convenient, the result should be placed in TARGET with
5030 mode MODE. */
5032 static rtx
5033 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5035 tree orig_arglist, dest, fmt;
5036 const char *fmt_str;
5038 orig_arglist = arglist;
5040 /* Verify the required arguments in the original call. */
5041 if (! arglist)
5042 return 0;
5043 dest = TREE_VALUE (arglist);
5044 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5045 return 0;
5046 arglist = TREE_CHAIN (arglist);
5047 if (! arglist)
5048 return 0;
5049 fmt = TREE_VALUE (arglist);
5050 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5051 return 0;
5052 arglist = TREE_CHAIN (arglist);
5054 /* Check whether the format is a literal string constant. */
5055 fmt_str = c_getstr (fmt);
5056 if (fmt_str == NULL)
5057 return 0;
5059 if (!init_target_chars())
5060 return 0;
5062 /* If the format doesn't contain % args or %%, use strcpy. */
5063 if (strchr (fmt_str, target_percent) == 0)
5065 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5066 tree exp;
5068 if (arglist || ! fn)
5069 return 0;
5070 expand_expr (build_function_call_expr (fn, orig_arglist),
5071 const0_rtx, VOIDmode, EXPAND_NORMAL);
5072 if (target == const0_rtx)
5073 return const0_rtx;
5074 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5075 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5077 /* If the format is "%s", use strcpy if the result isn't used. */
5078 else if (strcmp (fmt_str, target_percent_s) == 0)
5080 tree fn, arg, len;
5081 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5083 if (! fn)
5084 return 0;
5086 if (! arglist || TREE_CHAIN (arglist))
5087 return 0;
5088 arg = TREE_VALUE (arglist);
5089 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5090 return 0;
5092 if (target != const0_rtx)
5094 len = c_strlen (arg, 1);
5095 if (! len || TREE_CODE (len) != INTEGER_CST)
5096 return 0;
5098 else
5099 len = NULL_TREE;
5101 arglist = build_tree_list (NULL_TREE, arg);
5102 arglist = tree_cons (NULL_TREE, dest, arglist);
5103 expand_expr (build_function_call_expr (fn, arglist),
5104 const0_rtx, VOIDmode, EXPAND_NORMAL);
5106 if (target == const0_rtx)
5107 return const0_rtx;
5108 return expand_expr (len, target, mode, EXPAND_NORMAL);
5111 return 0;
5114 /* Expand a call to either the entry or exit function profiler. */
5116 static rtx
5117 expand_builtin_profile_func (bool exitp)
5119 rtx this, which;
5121 this = DECL_RTL (current_function_decl);
5122 gcc_assert (MEM_P (this));
5123 this = XEXP (this, 0);
5125 if (exitp)
5126 which = profile_function_exit_libfunc;
5127 else
5128 which = profile_function_entry_libfunc;
5130 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5131 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5133 Pmode);
5135 return const0_rtx;
5138 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5140 static rtx
5141 round_trampoline_addr (rtx tramp)
5143 rtx temp, addend, mask;
5145 /* If we don't need too much alignment, we'll have been guaranteed
5146 proper alignment by get_trampoline_type. */
5147 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5148 return tramp;
5150 /* Round address up to desired boundary. */
5151 temp = gen_reg_rtx (Pmode);
5152 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5153 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5155 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5156 temp, 0, OPTAB_LIB_WIDEN);
5157 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5158 temp, 0, OPTAB_LIB_WIDEN);
5160 return tramp;
5163 static rtx
5164 expand_builtin_init_trampoline (tree arglist)
5166 tree t_tramp, t_func, t_chain;
5167 rtx r_tramp, r_func, r_chain;
5168 #ifdef TRAMPOLINE_TEMPLATE
5169 rtx blktramp;
5170 #endif
5172 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5173 POINTER_TYPE, VOID_TYPE))
5174 return NULL_RTX;
5176 t_tramp = TREE_VALUE (arglist);
5177 arglist = TREE_CHAIN (arglist);
5178 t_func = TREE_VALUE (arglist);
5179 arglist = TREE_CHAIN (arglist);
5180 t_chain = TREE_VALUE (arglist);
5182 r_tramp = expand_normal (t_tramp);
5183 r_func = expand_normal (t_func);
5184 r_chain = expand_normal (t_chain);
5186 /* Generate insns to initialize the trampoline. */
5187 r_tramp = round_trampoline_addr (r_tramp);
5188 #ifdef TRAMPOLINE_TEMPLATE
5189 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5190 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5191 emit_block_move (blktramp, assemble_trampoline_template (),
5192 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5193 #endif
5194 trampolines_created = 1;
5195 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5197 return const0_rtx;
5200 static rtx
5201 expand_builtin_adjust_trampoline (tree arglist)
5203 rtx tramp;
5205 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5206 return NULL_RTX;
5208 tramp = expand_normal (TREE_VALUE (arglist));
5209 tramp = round_trampoline_addr (tramp);
5210 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5211 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5212 #endif
5214 return tramp;
5217 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5218 Return NULL_RTX if a normal call should be emitted rather than expanding
5219 the function in-line. EXP is the expression that is a call to the builtin
5220 function; if convenient, the result should be placed in TARGET. */
5222 static rtx
5223 expand_builtin_signbit (tree exp, rtx target)
5225 const struct real_format *fmt;
5226 enum machine_mode fmode, imode, rmode;
5227 HOST_WIDE_INT hi, lo;
5228 tree arg, arglist;
5229 int word, bitpos;
5230 rtx temp;
5232 arglist = TREE_OPERAND (exp, 1);
5233 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5234 return 0;
5236 arg = TREE_VALUE (arglist);
5237 fmode = TYPE_MODE (TREE_TYPE (arg));
5238 rmode = TYPE_MODE (TREE_TYPE (exp));
5239 fmt = REAL_MODE_FORMAT (fmode);
5241 /* For floating point formats without a sign bit, implement signbit
5242 as "ARG < 0.0". */
5243 bitpos = fmt->signbit_ro;
5244 if (bitpos < 0)
5246 /* But we can't do this if the format supports signed zero. */
5247 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5248 return 0;
5250 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5251 build_real (TREE_TYPE (arg), dconst0));
5252 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5255 temp = expand_normal (arg);
5256 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5258 imode = int_mode_for_mode (fmode);
5259 if (imode == BLKmode)
5260 return 0;
5261 temp = gen_lowpart (imode, temp);
5263 else
5265 imode = word_mode;
5266 /* Handle targets with different FP word orders. */
5267 if (FLOAT_WORDS_BIG_ENDIAN)
5268 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5269 else
5270 word = bitpos / BITS_PER_WORD;
5271 temp = operand_subword_force (temp, word, fmode);
5272 bitpos = bitpos % BITS_PER_WORD;
5275 /* Force the intermediate word_mode (or narrower) result into a
5276 register. This avoids attempting to create paradoxical SUBREGs
5277 of floating point modes below. */
5278 temp = force_reg (imode, temp);
5280 /* If the bitpos is within the "result mode" lowpart, the operation
5281 can be implement with a single bitwise AND. Otherwise, we need
5282 a right shift and an AND. */
5284 if (bitpos < GET_MODE_BITSIZE (rmode))
5286 if (bitpos < HOST_BITS_PER_WIDE_INT)
5288 hi = 0;
5289 lo = (HOST_WIDE_INT) 1 << bitpos;
5291 else
5293 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5294 lo = 0;
5297 if (imode != rmode)
5298 temp = gen_lowpart (rmode, temp);
5299 temp = expand_binop (rmode, and_optab, temp,
5300 immed_double_const (lo, hi, rmode),
5301 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5303 else
5305 /* Perform a logical right shift to place the signbit in the least
5306 significant bit, then truncate the result to the desired mode
5307 and mask just this bit. */
5308 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5309 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5310 temp = gen_lowpart (rmode, temp);
5311 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5312 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5315 return temp;
5318 /* Expand fork or exec calls. TARGET is the desired target of the
5319 call. ARGLIST is the list of arguments of the call. FN is the
5320 identificator of the actual function. IGNORE is nonzero if the
5321 value is to be ignored. */
5323 static rtx
5324 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5326 tree id, decl;
5327 tree call;
5329 /* If we are not profiling, just call the function. */
5330 if (!profile_arc_flag)
5331 return NULL_RTX;
5333 /* Otherwise call the wrapper. This should be equivalent for the rest of
5334 compiler, so the code does not diverge, and the wrapper may run the
5335 code necessary for keeping the profiling sane. */
5337 switch (DECL_FUNCTION_CODE (fn))
5339 case BUILT_IN_FORK:
5340 id = get_identifier ("__gcov_fork");
5341 break;
5343 case BUILT_IN_EXECL:
5344 id = get_identifier ("__gcov_execl");
5345 break;
5347 case BUILT_IN_EXECV:
5348 id = get_identifier ("__gcov_execv");
5349 break;
5351 case BUILT_IN_EXECLP:
5352 id = get_identifier ("__gcov_execlp");
5353 break;
5355 case BUILT_IN_EXECLE:
5356 id = get_identifier ("__gcov_execle");
5357 break;
5359 case BUILT_IN_EXECVP:
5360 id = get_identifier ("__gcov_execvp");
5361 break;
5363 case BUILT_IN_EXECVE:
5364 id = get_identifier ("__gcov_execve");
5365 break;
5367 default:
5368 gcc_unreachable ();
5371 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5372 DECL_EXTERNAL (decl) = 1;
5373 TREE_PUBLIC (decl) = 1;
5374 DECL_ARTIFICIAL (decl) = 1;
5375 TREE_NOTHROW (decl) = 1;
5376 call = build_function_call_expr (decl, arglist);
5378 return expand_call (call, target, ignore);
5382 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5383 the pointer in these functions is void*, the tree optimizers may remove
5384 casts. The mode computed in expand_builtin isn't reliable either, due
5385 to __sync_bool_compare_and_swap.
5387 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5388 group of builtins. This gives us log2 of the mode size. */
5390 static inline enum machine_mode
5391 get_builtin_sync_mode (int fcode_diff)
5393 /* The size is not negotiable, so ask not to get BLKmode in return
5394 if the target indicates that a smaller size would be better. */
5395 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5398 /* Expand the memory expression LOC and return the appropriate memory operand
5399 for the builtin_sync operations. */
5401 static rtx
5402 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5404 rtx addr, mem;
5406 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5408 /* Note that we explicitly do not want any alias information for this
5409 memory, so that we kill all other live memories. Otherwise we don't
5410 satisfy the full barrier semantics of the intrinsic. */
5411 mem = validize_mem (gen_rtx_MEM (mode, addr));
5413 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5414 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5415 MEM_VOLATILE_P (mem) = 1;
5417 return mem;
5420 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5421 ARGLIST is the operands list to the function. CODE is the rtx code
5422 that corresponds to the arithmetic or logical operation from the name;
5423 an exception here is that NOT actually means NAND. TARGET is an optional
5424 place for us to store the results; AFTER is true if this is the
5425 fetch_and_xxx form. IGNORE is true if we don't actually care about
5426 the result of the operation at all. */
5428 static rtx
5429 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5430 enum rtx_code code, bool after,
5431 rtx target, bool ignore)
5433 rtx val, mem;
5435 /* Expand the operands. */
5436 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5438 arglist = TREE_CHAIN (arglist);
5439 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5441 if (ignore)
5442 return expand_sync_operation (mem, val, code);
5443 else
5444 return expand_sync_fetch_operation (mem, val, code, after, target);
5447 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5448 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5449 true if this is the boolean form. TARGET is a place for us to store the
5450 results; this is NOT optional if IS_BOOL is true. */
5452 static rtx
5453 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5454 bool is_bool, rtx target)
5456 rtx old_val, new_val, mem;
5458 /* Expand the operands. */
5459 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5461 arglist = TREE_CHAIN (arglist);
5462 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5464 arglist = TREE_CHAIN (arglist);
5465 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5467 if (is_bool)
5468 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5469 else
5470 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5473 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5474 general form is actually an atomic exchange, and some targets only
5475 support a reduced form with the second argument being a constant 1.
5476 ARGLIST is the operands list to the function; TARGET is an optional
5477 place for us to store the results. */
5479 static rtx
5480 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5481 rtx target)
5483 rtx val, mem;
5485 /* Expand the operands. */
5486 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5488 arglist = TREE_CHAIN (arglist);
5489 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5491 return expand_sync_lock_test_and_set (mem, val, target);
5494 /* Expand the __sync_synchronize intrinsic. */
5496 static void
5497 expand_builtin_synchronize (void)
5499 tree x;
5501 #ifdef HAVE_memory_barrier
5502 if (HAVE_memory_barrier)
5504 emit_insn (gen_memory_barrier ());
5505 return;
5507 #endif
5509 /* If no explicit memory barrier instruction is available, create an
5510 empty asm stmt with a memory clobber. */
5511 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5512 tree_cons (NULL, build_string (6, "memory"), NULL));
5513 ASM_VOLATILE_P (x) = 1;
5514 expand_asm_expr (x);
5517 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5518 to the function. */
5520 static void
5521 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5523 enum insn_code icode;
5524 rtx mem, insn;
5525 rtx val = const0_rtx;
5527 /* Expand the operands. */
5528 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5530 /* If there is an explicit operation in the md file, use it. */
5531 icode = sync_lock_release[mode];
5532 if (icode != CODE_FOR_nothing)
5534 if (!insn_data[icode].operand[1].predicate (val, mode))
5535 val = force_reg (mode, val);
5537 insn = GEN_FCN (icode) (mem, val);
5538 if (insn)
5540 emit_insn (insn);
5541 return;
5545 /* Otherwise we can implement this operation by emitting a barrier
5546 followed by a store of zero. */
5547 expand_builtin_synchronize ();
5548 emit_move_insn (mem, val);
5551 /* Expand an expression EXP that calls a built-in function,
5552 with result going to TARGET if that's convenient
5553 (and in mode MODE if that's convenient).
5554 SUBTARGET may be used as the target for computing one of EXP's operands.
5555 IGNORE is nonzero if the value is to be ignored. */
5558 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5559 int ignore)
5561 tree fndecl = get_callee_fndecl (exp);
5562 tree arglist = TREE_OPERAND (exp, 1);
5563 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5564 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5566 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5567 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5568 else
5570 /* Try expanding the builtin via the generic target hook. */
5571 rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
5572 mode, ignore);
5573 if (tmp != NULL_RTX)
5574 return tmp;
5577 /* When not optimizing, generate calls to library functions for a certain
5578 set of builtins. */
5579 if (!optimize
5580 && !called_as_built_in (fndecl)
5581 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5582 && fcode != BUILT_IN_ALLOCA)
5583 return expand_call (exp, target, ignore);
5585 /* The built-in function expanders test for target == const0_rtx
5586 to determine whether the function's result will be ignored. */
5587 if (ignore)
5588 target = const0_rtx;
5590 /* If the result of a pure or const built-in function is ignored, and
5591 none of its arguments are volatile, we can avoid expanding the
5592 built-in call and just evaluate the arguments for side-effects. */
5593 if (target == const0_rtx
5594 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5596 bool volatilep = false;
5597 tree arg;
5599 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5600 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5602 volatilep = true;
5603 break;
5606 if (! volatilep)
5608 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5609 expand_expr (TREE_VALUE (arg), const0_rtx,
5610 VOIDmode, EXPAND_NORMAL);
5611 return const0_rtx;
5615 switch (fcode)
5617 CASE_FLT_FN (BUILT_IN_FABS):
5618 target = expand_builtin_fabs (arglist, target, subtarget);
5619 if (target)
5620 return target;
5621 break;
5623 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5624 target = expand_builtin_copysign (arglist, target, subtarget);
5625 if (target)
5626 return target;
5627 break;
5629 /* Just do a normal library call if we were unable to fold
5630 the values. */
5631 CASE_FLT_FN (BUILT_IN_CABS):
5632 break;
5634 CASE_FLT_FN (BUILT_IN_EXP):
5635 CASE_FLT_FN (BUILT_IN_EXP10):
5636 CASE_FLT_FN (BUILT_IN_POW10):
5637 CASE_FLT_FN (BUILT_IN_EXP2):
5638 CASE_FLT_FN (BUILT_IN_EXPM1):
5639 CASE_FLT_FN (BUILT_IN_LOGB):
5640 CASE_FLT_FN (BUILT_IN_ILOGB):
5641 CASE_FLT_FN (BUILT_IN_LOG):
5642 CASE_FLT_FN (BUILT_IN_LOG10):
5643 CASE_FLT_FN (BUILT_IN_LOG2):
5644 CASE_FLT_FN (BUILT_IN_LOG1P):
5645 CASE_FLT_FN (BUILT_IN_TAN):
5646 CASE_FLT_FN (BUILT_IN_ASIN):
5647 CASE_FLT_FN (BUILT_IN_ACOS):
5648 CASE_FLT_FN (BUILT_IN_ATAN):
5649 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5650 because of possible accuracy problems. */
5651 if (! flag_unsafe_math_optimizations)
5652 break;
5653 CASE_FLT_FN (BUILT_IN_SQRT):
5654 CASE_FLT_FN (BUILT_IN_FLOOR):
5655 CASE_FLT_FN (BUILT_IN_CEIL):
5656 CASE_FLT_FN (BUILT_IN_TRUNC):
5657 CASE_FLT_FN (BUILT_IN_ROUND):
5658 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5659 CASE_FLT_FN (BUILT_IN_RINT):
5660 CASE_FLT_FN (BUILT_IN_LRINT):
5661 CASE_FLT_FN (BUILT_IN_LLRINT):
5662 target = expand_builtin_mathfn (exp, target, subtarget);
5663 if (target)
5664 return target;
5665 break;
5667 CASE_FLT_FN (BUILT_IN_LCEIL):
5668 CASE_FLT_FN (BUILT_IN_LLCEIL):
5669 CASE_FLT_FN (BUILT_IN_LFLOOR):
5670 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5671 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5672 if (target)
5673 return target;
5674 break;
5676 CASE_FLT_FN (BUILT_IN_POW):
5677 target = expand_builtin_pow (exp, target, subtarget);
5678 if (target)
5679 return target;
5680 break;
5682 CASE_FLT_FN (BUILT_IN_POWI):
5683 target = expand_builtin_powi (exp, target, subtarget);
5684 if (target)
5685 return target;
5686 break;
5688 CASE_FLT_FN (BUILT_IN_ATAN2):
5689 CASE_FLT_FN (BUILT_IN_LDEXP):
5690 CASE_FLT_FN (BUILT_IN_FMOD):
5691 CASE_FLT_FN (BUILT_IN_DREM):
5692 if (! flag_unsafe_math_optimizations)
5693 break;
5694 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5695 if (target)
5696 return target;
5697 break;
5699 CASE_FLT_FN (BUILT_IN_SIN):
5700 CASE_FLT_FN (BUILT_IN_COS):
5701 if (! flag_unsafe_math_optimizations)
5702 break;
5703 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5704 if (target)
5705 return target;
5706 break;
5708 CASE_FLT_FN (BUILT_IN_SINCOS):
5709 if (! flag_unsafe_math_optimizations)
5710 break;
5711 target = expand_builtin_sincos (exp);
5712 if (target)
5713 return target;
5714 break;
5716 case BUILT_IN_APPLY_ARGS:
5717 return expand_builtin_apply_args ();
5719 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5720 FUNCTION with a copy of the parameters described by
5721 ARGUMENTS, and ARGSIZE. It returns a block of memory
5722 allocated on the stack into which is stored all the registers
5723 that might possibly be used for returning the result of a
5724 function. ARGUMENTS is the value returned by
5725 __builtin_apply_args. ARGSIZE is the number of bytes of
5726 arguments that must be copied. ??? How should this value be
5727 computed? We'll also need a safe worst case value for varargs
5728 functions. */
5729 case BUILT_IN_APPLY:
5730 if (!validate_arglist (arglist, POINTER_TYPE,
5731 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5732 && !validate_arglist (arglist, REFERENCE_TYPE,
5733 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5734 return const0_rtx;
5735 else
5737 int i;
5738 tree t;
5739 rtx ops[3];
5741 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5742 ops[i] = expand_normal (TREE_VALUE (t));
5744 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5747 /* __builtin_return (RESULT) causes the function to return the
5748 value described by RESULT. RESULT is address of the block of
5749 memory returned by __builtin_apply. */
5750 case BUILT_IN_RETURN:
5751 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5752 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5753 return const0_rtx;
5755 case BUILT_IN_SAVEREGS:
5756 return expand_builtin_saveregs ();
5758 case BUILT_IN_ARGS_INFO:
5759 return expand_builtin_args_info (arglist);
5761 /* Return the address of the first anonymous stack arg. */
5762 case BUILT_IN_NEXT_ARG:
5763 if (fold_builtin_next_arg (arglist))
5764 return const0_rtx;
5765 return expand_builtin_next_arg ();
5767 case BUILT_IN_CLASSIFY_TYPE:
5768 return expand_builtin_classify_type (arglist);
5770 case BUILT_IN_CONSTANT_P:
5771 return const0_rtx;
5773 case BUILT_IN_FRAME_ADDRESS:
5774 case BUILT_IN_RETURN_ADDRESS:
5775 return expand_builtin_frame_address (fndecl, arglist);
5777 /* Returns the address of the area where the structure is returned.
5778 0 otherwise. */
5779 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5780 if (arglist != 0
5781 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5782 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5783 return const0_rtx;
5784 else
5785 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5787 case BUILT_IN_ALLOCA:
5788 target = expand_builtin_alloca (arglist, target);
5789 if (target)
5790 return target;
5791 break;
5793 case BUILT_IN_STACK_SAVE:
5794 return expand_stack_save ();
5796 case BUILT_IN_STACK_RESTORE:
5797 expand_stack_restore (TREE_VALUE (arglist));
5798 return const0_rtx;
5800 CASE_INT_FN (BUILT_IN_FFS):
5801 case BUILT_IN_FFSIMAX:
5802 target = expand_builtin_unop (target_mode, arglist, target,
5803 subtarget, ffs_optab);
5804 if (target)
5805 return target;
5806 break;
5808 CASE_INT_FN (BUILT_IN_CLZ):
5809 case BUILT_IN_CLZIMAX:
5810 target = expand_builtin_unop (target_mode, arglist, target,
5811 subtarget, clz_optab);
5812 if (target)
5813 return target;
5814 break;
5816 CASE_INT_FN (BUILT_IN_CTZ):
5817 case BUILT_IN_CTZIMAX:
5818 target = expand_builtin_unop (target_mode, arglist, target,
5819 subtarget, ctz_optab);
5820 if (target)
5821 return target;
5822 break;
5824 CASE_INT_FN (BUILT_IN_POPCOUNT):
5825 case BUILT_IN_POPCOUNTIMAX:
5826 target = expand_builtin_unop (target_mode, arglist, target,
5827 subtarget, popcount_optab);
5828 if (target)
5829 return target;
5830 break;
5832 CASE_INT_FN (BUILT_IN_PARITY):
5833 case BUILT_IN_PARITYIMAX:
5834 target = expand_builtin_unop (target_mode, arglist, target,
5835 subtarget, parity_optab);
5836 if (target)
5837 return target;
5838 break;
5840 case BUILT_IN_STRLEN:
5841 target = expand_builtin_strlen (arglist, target, target_mode);
5842 if (target)
5843 return target;
5844 break;
5846 case BUILT_IN_STRCPY:
5847 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5848 if (target)
5849 return target;
5850 break;
5852 case BUILT_IN_STRNCPY:
5853 target = expand_builtin_strncpy (exp, target, mode);
5854 if (target)
5855 return target;
5856 break;
5858 case BUILT_IN_STPCPY:
5859 target = expand_builtin_stpcpy (exp, target, mode);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_STRCAT:
5865 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5866 if (target)
5867 return target;
5868 break;
5870 case BUILT_IN_STRNCAT:
5871 target = expand_builtin_strncat (arglist, target, mode);
5872 if (target)
5873 return target;
5874 break;
5876 case BUILT_IN_STRSPN:
5877 target = expand_builtin_strspn (arglist, target, mode);
5878 if (target)
5879 return target;
5880 break;
5882 case BUILT_IN_STRCSPN:
5883 target = expand_builtin_strcspn (arglist, target, mode);
5884 if (target)
5885 return target;
5886 break;
5888 case BUILT_IN_STRSTR:
5889 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5890 if (target)
5891 return target;
5892 break;
5894 case BUILT_IN_STRPBRK:
5895 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5896 if (target)
5897 return target;
5898 break;
5900 case BUILT_IN_INDEX:
5901 case BUILT_IN_STRCHR:
5902 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5903 if (target)
5904 return target;
5905 break;
5907 case BUILT_IN_RINDEX:
5908 case BUILT_IN_STRRCHR:
5909 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5910 if (target)
5911 return target;
5912 break;
5914 case BUILT_IN_MEMCPY:
5915 target = expand_builtin_memcpy (exp, target, mode);
5916 if (target)
5917 return target;
5918 break;
5920 case BUILT_IN_MEMPCPY:
5921 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5922 if (target)
5923 return target;
5924 break;
5926 case BUILT_IN_MEMMOVE:
5927 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5928 mode, exp);
5929 if (target)
5930 return target;
5931 break;
5933 case BUILT_IN_BCOPY:
5934 target = expand_builtin_bcopy (exp);
5935 if (target)
5936 return target;
5937 break;
5939 case BUILT_IN_MEMSET:
5940 target = expand_builtin_memset (arglist, target, mode, exp);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_BZERO:
5946 target = expand_builtin_bzero (exp);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_STRCMP:
5952 target = expand_builtin_strcmp (exp, target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_STRNCMP:
5958 target = expand_builtin_strncmp (exp, target, mode);
5959 if (target)
5960 return target;
5961 break;
5963 case BUILT_IN_BCMP:
5964 case BUILT_IN_MEMCMP:
5965 target = expand_builtin_memcmp (exp, arglist, target, mode);
5966 if (target)
5967 return target;
5968 break;
5970 case BUILT_IN_SETJMP:
5971 target = expand_builtin_setjmp (arglist, target);
5972 if (target)
5973 return target;
5974 break;
5976 /* __builtin_longjmp is passed a pointer to an array of five words.
5977 It's similar to the C library longjmp function but works with
5978 __builtin_setjmp above. */
5979 case BUILT_IN_LONGJMP:
5980 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5981 break;
5982 else
5984 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5985 VOIDmode, EXPAND_NORMAL);
5986 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
5988 if (value != const1_rtx)
5990 error ("%<__builtin_longjmp%> second argument must be 1");
5991 return const0_rtx;
5994 expand_builtin_longjmp (buf_addr, value);
5995 return const0_rtx;
5998 case BUILT_IN_NONLOCAL_GOTO:
5999 target = expand_builtin_nonlocal_goto (arglist);
6000 if (target)
6001 return target;
6002 break;
6004 /* This updates the setjmp buffer that is its argument with the value
6005 of the current stack pointer. */
6006 case BUILT_IN_UPDATE_SETJMP_BUF:
6007 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6009 rtx buf_addr
6010 = expand_normal (TREE_VALUE (arglist));
6012 expand_builtin_update_setjmp_buf (buf_addr);
6013 return const0_rtx;
6015 break;
6017 case BUILT_IN_TRAP:
6018 expand_builtin_trap ();
6019 return const0_rtx;
6021 case BUILT_IN_PRINTF:
6022 target = expand_builtin_printf (exp, target, mode, false);
6023 if (target)
6024 return target;
6025 break;
6027 case BUILT_IN_PRINTF_UNLOCKED:
6028 target = expand_builtin_printf (exp, target, mode, true);
6029 if (target)
6030 return target;
6031 break;
6033 case BUILT_IN_FPUTS:
6034 target = expand_builtin_fputs (arglist, target, false);
6035 if (target)
6036 return target;
6037 break;
6038 case BUILT_IN_FPUTS_UNLOCKED:
6039 target = expand_builtin_fputs (arglist, target, true);
6040 if (target)
6041 return target;
6042 break;
6044 case BUILT_IN_FPRINTF:
6045 target = expand_builtin_fprintf (exp, target, mode, false);
6046 if (target)
6047 return target;
6048 break;
6050 case BUILT_IN_FPRINTF_UNLOCKED:
6051 target = expand_builtin_fprintf (exp, target, mode, true);
6052 if (target)
6053 return target;
6054 break;
6056 case BUILT_IN_SPRINTF:
6057 target = expand_builtin_sprintf (arglist, target, mode);
6058 if (target)
6059 return target;
6060 break;
6062 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6063 target = expand_builtin_signbit (exp, target);
6064 if (target)
6065 return target;
6066 break;
6068 /* Various hooks for the DWARF 2 __throw routine. */
6069 case BUILT_IN_UNWIND_INIT:
6070 expand_builtin_unwind_init ();
6071 return const0_rtx;
6072 case BUILT_IN_DWARF_CFA:
6073 return virtual_cfa_rtx;
6074 #ifdef DWARF2_UNWIND_INFO
6075 case BUILT_IN_DWARF_SP_COLUMN:
6076 return expand_builtin_dwarf_sp_column ();
6077 case BUILT_IN_INIT_DWARF_REG_SIZES:
6078 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6079 return const0_rtx;
6080 #endif
6081 case BUILT_IN_FROB_RETURN_ADDR:
6082 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6083 case BUILT_IN_EXTRACT_RETURN_ADDR:
6084 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6085 case BUILT_IN_EH_RETURN:
6086 expand_builtin_eh_return (TREE_VALUE (arglist),
6087 TREE_VALUE (TREE_CHAIN (arglist)));
6088 return const0_rtx;
6089 #ifdef EH_RETURN_DATA_REGNO
6090 case BUILT_IN_EH_RETURN_DATA_REGNO:
6091 return expand_builtin_eh_return_data_regno (arglist);
6092 #endif
6093 case BUILT_IN_EXTEND_POINTER:
6094 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6096 case BUILT_IN_VA_START:
6097 case BUILT_IN_STDARG_START:
6098 return expand_builtin_va_start (arglist);
6099 case BUILT_IN_VA_END:
6100 return expand_builtin_va_end (arglist);
6101 case BUILT_IN_VA_COPY:
6102 return expand_builtin_va_copy (arglist);
6103 case BUILT_IN_EXPECT:
6104 return expand_builtin_expect (arglist, target);
6105 case BUILT_IN_PREFETCH:
6106 expand_builtin_prefetch (arglist);
6107 return const0_rtx;
6109 case BUILT_IN_PROFILE_FUNC_ENTER:
6110 return expand_builtin_profile_func (false);
6111 case BUILT_IN_PROFILE_FUNC_EXIT:
6112 return expand_builtin_profile_func (true);
6114 case BUILT_IN_INIT_TRAMPOLINE:
6115 return expand_builtin_init_trampoline (arglist);
6116 case BUILT_IN_ADJUST_TRAMPOLINE:
6117 return expand_builtin_adjust_trampoline (arglist);
6119 case BUILT_IN_FORK:
6120 case BUILT_IN_EXECL:
6121 case BUILT_IN_EXECV:
6122 case BUILT_IN_EXECLP:
6123 case BUILT_IN_EXECLE:
6124 case BUILT_IN_EXECVP:
6125 case BUILT_IN_EXECVE:
6126 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6127 if (target)
6128 return target;
6129 break;
6131 case BUILT_IN_FETCH_AND_ADD_1:
6132 case BUILT_IN_FETCH_AND_ADD_2:
6133 case BUILT_IN_FETCH_AND_ADD_4:
6134 case BUILT_IN_FETCH_AND_ADD_8:
6135 case BUILT_IN_FETCH_AND_ADD_16:
6136 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6137 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6138 false, target, ignore);
6139 if (target)
6140 return target;
6141 break;
6143 case BUILT_IN_FETCH_AND_SUB_1:
6144 case BUILT_IN_FETCH_AND_SUB_2:
6145 case BUILT_IN_FETCH_AND_SUB_4:
6146 case BUILT_IN_FETCH_AND_SUB_8:
6147 case BUILT_IN_FETCH_AND_SUB_16:
6148 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6149 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6150 false, target, ignore);
6151 if (target)
6152 return target;
6153 break;
6155 case BUILT_IN_FETCH_AND_OR_1:
6156 case BUILT_IN_FETCH_AND_OR_2:
6157 case BUILT_IN_FETCH_AND_OR_4:
6158 case BUILT_IN_FETCH_AND_OR_8:
6159 case BUILT_IN_FETCH_AND_OR_16:
6160 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6161 target = expand_builtin_sync_operation (mode, arglist, IOR,
6162 false, target, ignore);
6163 if (target)
6164 return target;
6165 break;
6167 case BUILT_IN_FETCH_AND_AND_1:
6168 case BUILT_IN_FETCH_AND_AND_2:
6169 case BUILT_IN_FETCH_AND_AND_4:
6170 case BUILT_IN_FETCH_AND_AND_8:
6171 case BUILT_IN_FETCH_AND_AND_16:
6172 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6173 target = expand_builtin_sync_operation (mode, arglist, AND,
6174 false, target, ignore);
6175 if (target)
6176 return target;
6177 break;
6179 case BUILT_IN_FETCH_AND_XOR_1:
6180 case BUILT_IN_FETCH_AND_XOR_2:
6181 case BUILT_IN_FETCH_AND_XOR_4:
6182 case BUILT_IN_FETCH_AND_XOR_8:
6183 case BUILT_IN_FETCH_AND_XOR_16:
6184 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6185 target = expand_builtin_sync_operation (mode, arglist, XOR,
6186 false, target, ignore);
6187 if (target)
6188 return target;
6189 break;
6191 case BUILT_IN_FETCH_AND_NAND_1:
6192 case BUILT_IN_FETCH_AND_NAND_2:
6193 case BUILT_IN_FETCH_AND_NAND_4:
6194 case BUILT_IN_FETCH_AND_NAND_8:
6195 case BUILT_IN_FETCH_AND_NAND_16:
6196 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6197 target = expand_builtin_sync_operation (mode, arglist, NOT,
6198 false, target, ignore);
6199 if (target)
6200 return target;
6201 break;
6203 case BUILT_IN_ADD_AND_FETCH_1:
6204 case BUILT_IN_ADD_AND_FETCH_2:
6205 case BUILT_IN_ADD_AND_FETCH_4:
6206 case BUILT_IN_ADD_AND_FETCH_8:
6207 case BUILT_IN_ADD_AND_FETCH_16:
6208 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6209 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6210 true, target, ignore);
6211 if (target)
6212 return target;
6213 break;
6215 case BUILT_IN_SUB_AND_FETCH_1:
6216 case BUILT_IN_SUB_AND_FETCH_2:
6217 case BUILT_IN_SUB_AND_FETCH_4:
6218 case BUILT_IN_SUB_AND_FETCH_8:
6219 case BUILT_IN_SUB_AND_FETCH_16:
6220 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6221 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6222 true, target, ignore);
6223 if (target)
6224 return target;
6225 break;
6227 case BUILT_IN_OR_AND_FETCH_1:
6228 case BUILT_IN_OR_AND_FETCH_2:
6229 case BUILT_IN_OR_AND_FETCH_4:
6230 case BUILT_IN_OR_AND_FETCH_8:
6231 case BUILT_IN_OR_AND_FETCH_16:
6232 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6233 target = expand_builtin_sync_operation (mode, arglist, IOR,
6234 true, target, ignore);
6235 if (target)
6236 return target;
6237 break;
6239 case BUILT_IN_AND_AND_FETCH_1:
6240 case BUILT_IN_AND_AND_FETCH_2:
6241 case BUILT_IN_AND_AND_FETCH_4:
6242 case BUILT_IN_AND_AND_FETCH_8:
6243 case BUILT_IN_AND_AND_FETCH_16:
6244 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6245 target = expand_builtin_sync_operation (mode, arglist, AND,
6246 true, target, ignore);
6247 if (target)
6248 return target;
6249 break;
6251 case BUILT_IN_XOR_AND_FETCH_1:
6252 case BUILT_IN_XOR_AND_FETCH_2:
6253 case BUILT_IN_XOR_AND_FETCH_4:
6254 case BUILT_IN_XOR_AND_FETCH_8:
6255 case BUILT_IN_XOR_AND_FETCH_16:
6256 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6257 target = expand_builtin_sync_operation (mode, arglist, XOR,
6258 true, target, ignore);
6259 if (target)
6260 return target;
6261 break;
6263 case BUILT_IN_NAND_AND_FETCH_1:
6264 case BUILT_IN_NAND_AND_FETCH_2:
6265 case BUILT_IN_NAND_AND_FETCH_4:
6266 case BUILT_IN_NAND_AND_FETCH_8:
6267 case BUILT_IN_NAND_AND_FETCH_16:
6268 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6269 target = expand_builtin_sync_operation (mode, arglist, NOT,
6270 true, target, ignore);
6271 if (target)
6272 return target;
6273 break;
6275 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6276 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6277 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6278 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6279 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6280 if (mode == VOIDmode)
6281 mode = TYPE_MODE (boolean_type_node);
6282 if (!target || !register_operand (target, mode))
6283 target = gen_reg_rtx (mode);
6285 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6286 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6287 if (target)
6288 return target;
6289 break;
6291 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6292 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6293 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6294 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6295 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6296 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6297 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6298 if (target)
6299 return target;
6300 break;
6302 case BUILT_IN_LOCK_TEST_AND_SET_1:
6303 case BUILT_IN_LOCK_TEST_AND_SET_2:
6304 case BUILT_IN_LOCK_TEST_AND_SET_4:
6305 case BUILT_IN_LOCK_TEST_AND_SET_8:
6306 case BUILT_IN_LOCK_TEST_AND_SET_16:
6307 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6308 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6309 if (target)
6310 return target;
6311 break;
6313 case BUILT_IN_LOCK_RELEASE_1:
6314 case BUILT_IN_LOCK_RELEASE_2:
6315 case BUILT_IN_LOCK_RELEASE_4:
6316 case BUILT_IN_LOCK_RELEASE_8:
6317 case BUILT_IN_LOCK_RELEASE_16:
6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6319 expand_builtin_lock_release (mode, arglist);
6320 return const0_rtx;
6322 case BUILT_IN_SYNCHRONIZE:
6323 expand_builtin_synchronize ();
6324 return const0_rtx;
6326 case BUILT_IN_OBJECT_SIZE:
6327 return expand_builtin_object_size (exp);
6329 case BUILT_IN_MEMCPY_CHK:
6330 case BUILT_IN_MEMPCPY_CHK:
6331 case BUILT_IN_MEMMOVE_CHK:
6332 case BUILT_IN_MEMSET_CHK:
6333 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6334 if (target)
6335 return target;
6336 break;
6338 case BUILT_IN_STRCPY_CHK:
6339 case BUILT_IN_STPCPY_CHK:
6340 case BUILT_IN_STRNCPY_CHK:
6341 case BUILT_IN_STRCAT_CHK:
6342 case BUILT_IN_SNPRINTF_CHK:
6343 case BUILT_IN_VSNPRINTF_CHK:
6344 maybe_emit_chk_warning (exp, fcode);
6345 break;
6347 case BUILT_IN_SPRINTF_CHK:
6348 case BUILT_IN_VSPRINTF_CHK:
6349 maybe_emit_sprintf_chk_warning (exp, fcode);
6350 break;
6352 default: /* just do library call, if unknown builtin */
6353 break;
6356 /* The switch statement above can drop through to cause the function
6357 to be called normally. */
6358 return expand_call (exp, target, ignore);
6361 /* Determine whether a tree node represents a call to a built-in
6362 function. If the tree T is a call to a built-in function with
6363 the right number of arguments of the appropriate types, return
6364 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6365 Otherwise the return value is END_BUILTINS. */
6367 enum built_in_function
6368 builtin_mathfn_code (tree t)
6370 tree fndecl, arglist, parmlist;
6371 tree argtype, parmtype;
6373 if (TREE_CODE (t) != CALL_EXPR
6374 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6375 return END_BUILTINS;
6377 fndecl = get_callee_fndecl (t);
6378 if (fndecl == NULL_TREE
6379 || TREE_CODE (fndecl) != FUNCTION_DECL
6380 || ! DECL_BUILT_IN (fndecl)
6381 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6382 return END_BUILTINS;
6384 arglist = TREE_OPERAND (t, 1);
6385 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6386 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6388 /* If a function doesn't take a variable number of arguments,
6389 the last element in the list will have type `void'. */
6390 parmtype = TREE_VALUE (parmlist);
6391 if (VOID_TYPE_P (parmtype))
6393 if (arglist)
6394 return END_BUILTINS;
6395 return DECL_FUNCTION_CODE (fndecl);
6398 if (! arglist)
6399 return END_BUILTINS;
6401 argtype = TREE_TYPE (TREE_VALUE (arglist));
6403 if (SCALAR_FLOAT_TYPE_P (parmtype))
6405 if (! SCALAR_FLOAT_TYPE_P (argtype))
6406 return END_BUILTINS;
6408 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6410 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6411 return END_BUILTINS;
6413 else if (POINTER_TYPE_P (parmtype))
6415 if (! POINTER_TYPE_P (argtype))
6416 return END_BUILTINS;
6418 else if (INTEGRAL_TYPE_P (parmtype))
6420 if (! INTEGRAL_TYPE_P (argtype))
6421 return END_BUILTINS;
6423 else
6424 return END_BUILTINS;
6426 arglist = TREE_CHAIN (arglist);
6429 /* Variable-length argument list. */
6430 return DECL_FUNCTION_CODE (fndecl);
6433 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6434 constant. ARGLIST is the argument list of the call. */
6436 static tree
6437 fold_builtin_constant_p (tree arglist)
6439 if (arglist == 0)
6440 return 0;
6442 arglist = TREE_VALUE (arglist);
6444 /* We return 1 for a numeric type that's known to be a constant
6445 value at compile-time or for an aggregate type that's a
6446 literal constant. */
6447 STRIP_NOPS (arglist);
6449 /* If we know this is a constant, emit the constant of one. */
6450 if (CONSTANT_CLASS_P (arglist)
6451 || (TREE_CODE (arglist) == CONSTRUCTOR
6452 && TREE_CONSTANT (arglist)))
6453 return integer_one_node;
6454 if (TREE_CODE (arglist) == ADDR_EXPR)
6456 tree op = TREE_OPERAND (arglist, 0);
6457 if (TREE_CODE (op) == STRING_CST
6458 || (TREE_CODE (op) == ARRAY_REF
6459 && integer_zerop (TREE_OPERAND (op, 1))
6460 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6461 return integer_one_node;
6464 /* If this expression has side effects, show we don't know it to be a
6465 constant. Likewise if it's a pointer or aggregate type since in
6466 those case we only want literals, since those are only optimized
6467 when generating RTL, not later.
6468 And finally, if we are compiling an initializer, not code, we
6469 need to return a definite result now; there's not going to be any
6470 more optimization done. */
6471 if (TREE_SIDE_EFFECTS (arglist)
6472 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6473 || POINTER_TYPE_P (TREE_TYPE (arglist))
6474 || cfun == 0)
6475 return integer_zero_node;
6477 return 0;
6480 /* Fold a call to __builtin_expect, if we expect that a comparison against
6481 the argument will fold to a constant. In practice, this means a true
6482 constant or the address of a non-weak symbol. ARGLIST is the argument
6483 list of the call. */
6485 static tree
6486 fold_builtin_expect (tree arglist)
6488 tree arg, inner;
6490 if (arglist == 0)
6491 return 0;
6493 arg = TREE_VALUE (arglist);
6495 /* If the argument isn't invariant, then there's nothing we can do. */
6496 if (!TREE_INVARIANT (arg))
6497 return 0;
6499 /* If we're looking at an address of a weak decl, then do not fold. */
6500 inner = arg;
6501 STRIP_NOPS (inner);
6502 if (TREE_CODE (inner) == ADDR_EXPR)
6506 inner = TREE_OPERAND (inner, 0);
6508 while (TREE_CODE (inner) == COMPONENT_REF
6509 || TREE_CODE (inner) == ARRAY_REF);
6510 if (DECL_P (inner) && DECL_WEAK (inner))
6511 return 0;
6514 /* Otherwise, ARG already has the proper type for the return value. */
6515 return arg;
6518 /* Fold a call to __builtin_classify_type. */
6520 static tree
6521 fold_builtin_classify_type (tree arglist)
6523 if (arglist == 0)
6524 return build_int_cst (NULL_TREE, no_type_class);
6526 return build_int_cst (NULL_TREE,
6527 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6530 /* Fold a call to __builtin_strlen. */
6532 static tree
6533 fold_builtin_strlen (tree arglist)
6535 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6536 return NULL_TREE;
6537 else
6539 tree len = c_strlen (TREE_VALUE (arglist), 0);
6541 if (len)
6543 /* Convert from the internal "sizetype" type to "size_t". */
6544 if (size_type_node)
6545 len = fold_convert (size_type_node, len);
6546 return len;
6549 return NULL_TREE;
6553 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6555 static tree
6556 fold_builtin_inf (tree type, int warn)
6558 REAL_VALUE_TYPE real;
6560 /* __builtin_inff is intended to be usable to define INFINITY on all
6561 targets. If an infinity is not available, INFINITY expands "to a
6562 positive constant of type float that overflows at translation
6563 time", footnote "In this case, using INFINITY will violate the
6564 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6565 Thus we pedwarn to ensure this constraint violation is
6566 diagnosed. */
6567 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6568 pedwarn ("target format does not support infinity");
6570 real_inf (&real);
6571 return build_real (type, real);
6574 /* Fold a call to __builtin_nan or __builtin_nans. */
6576 static tree
6577 fold_builtin_nan (tree arglist, tree type, int quiet)
6579 REAL_VALUE_TYPE real;
6580 const char *str;
6582 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6583 return 0;
6584 str = c_getstr (TREE_VALUE (arglist));
6585 if (!str)
6586 return 0;
6588 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6589 return 0;
6591 return build_real (type, real);
6594 /* Return true if the floating point expression T has an integer value.
6595 We also allow +Inf, -Inf and NaN to be considered integer values. */
6597 static bool
6598 integer_valued_real_p (tree t)
6600 switch (TREE_CODE (t))
6602 case FLOAT_EXPR:
6603 return true;
6605 case ABS_EXPR:
6606 case SAVE_EXPR:
6607 case NON_LVALUE_EXPR:
6608 return integer_valued_real_p (TREE_OPERAND (t, 0));
6610 case COMPOUND_EXPR:
6611 case MODIFY_EXPR:
6612 case BIND_EXPR:
6613 return integer_valued_real_p (TREE_OPERAND (t, 1));
6615 case PLUS_EXPR:
6616 case MINUS_EXPR:
6617 case MULT_EXPR:
6618 case MIN_EXPR:
6619 case MAX_EXPR:
6620 return integer_valued_real_p (TREE_OPERAND (t, 0))
6621 && integer_valued_real_p (TREE_OPERAND (t, 1));
6623 case COND_EXPR:
6624 return integer_valued_real_p (TREE_OPERAND (t, 1))
6625 && integer_valued_real_p (TREE_OPERAND (t, 2));
6627 case REAL_CST:
6628 if (! TREE_CONSTANT_OVERFLOW (t))
6630 REAL_VALUE_TYPE c, cint;
6632 c = TREE_REAL_CST (t);
6633 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6634 return real_identical (&c, &cint);
6636 break;
6638 case NOP_EXPR:
6640 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6641 if (TREE_CODE (type) == INTEGER_TYPE)
6642 return true;
6643 if (TREE_CODE (type) == REAL_TYPE)
6644 return integer_valued_real_p (TREE_OPERAND (t, 0));
6645 break;
6648 case CALL_EXPR:
6649 switch (builtin_mathfn_code (t))
6651 CASE_FLT_FN (BUILT_IN_CEIL):
6652 CASE_FLT_FN (BUILT_IN_FLOOR):
6653 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6654 CASE_FLT_FN (BUILT_IN_RINT):
6655 CASE_FLT_FN (BUILT_IN_ROUND):
6656 CASE_FLT_FN (BUILT_IN_TRUNC):
6657 return true;
6659 default:
6660 break;
6662 break;
6664 default:
6665 break;
6667 return false;
6670 /* EXP is assumed to be builtin call where truncation can be propagated
6671 across (for instance floor((double)f) == (double)floorf (f).
6672 Do the transformation. */
6674 static tree
6675 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6677 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6678 tree arg;
6680 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6681 return 0;
6683 arg = TREE_VALUE (arglist);
6684 /* Integer rounding functions are idempotent. */
6685 if (fcode == builtin_mathfn_code (arg))
6686 return arg;
6688 /* If argument is already integer valued, and we don't need to worry
6689 about setting errno, there's no need to perform rounding. */
6690 if (! flag_errno_math && integer_valued_real_p (arg))
6691 return arg;
6693 if (optimize)
6695 tree arg0 = strip_float_extensions (arg);
6696 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6697 tree newtype = TREE_TYPE (arg0);
6698 tree decl;
6700 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6701 && (decl = mathfn_built_in (newtype, fcode)))
6703 arglist =
6704 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6705 return fold_convert (ftype,
6706 build_function_call_expr (decl, arglist));
6709 return 0;
6712 /* EXP is assumed to be builtin call which can narrow the FP type of
6713 the argument, for instance lround((double)f) -> lroundf (f). */
6715 static tree
6716 fold_fixed_mathfn (tree fndecl, tree arglist)
6718 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6719 tree arg;
6721 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6722 return 0;
6724 arg = TREE_VALUE (arglist);
6726 /* If argument is already integer valued, and we don't need to worry
6727 about setting errno, there's no need to perform rounding. */
6728 if (! flag_errno_math && integer_valued_real_p (arg))
6729 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6731 if (optimize)
6733 tree ftype = TREE_TYPE (arg);
6734 tree arg0 = strip_float_extensions (arg);
6735 tree newtype = TREE_TYPE (arg0);
6736 tree decl;
6738 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6739 && (decl = mathfn_built_in (newtype, fcode)))
6741 arglist =
6742 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6743 return build_function_call_expr (decl, arglist);
6746 return 0;
6749 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6750 is the argument list and TYPE is the return type. Return
6751 NULL_TREE if no if no simplification can be made. */
6753 static tree
6754 fold_builtin_cabs (tree arglist, tree type)
6756 tree arg;
6758 if (!arglist || TREE_CHAIN (arglist))
6759 return NULL_TREE;
6761 arg = TREE_VALUE (arglist);
6762 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6763 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6764 return NULL_TREE;
6766 /* Evaluate cabs of a constant at compile-time. */
6767 if (flag_unsafe_math_optimizations
6768 && TREE_CODE (arg) == COMPLEX_CST
6769 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6770 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6771 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6772 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6774 REAL_VALUE_TYPE r, i;
6776 r = TREE_REAL_CST (TREE_REALPART (arg));
6777 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6779 real_arithmetic (&r, MULT_EXPR, &r, &r);
6780 real_arithmetic (&i, MULT_EXPR, &i, &i);
6781 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6782 if (real_sqrt (&r, TYPE_MODE (type), &r)
6783 || ! flag_trapping_math)
6784 return build_real (type, r);
6787 /* If either part is zero, cabs is fabs of the other. */
6788 if (TREE_CODE (arg) == COMPLEX_EXPR
6789 && real_zerop (TREE_OPERAND (arg, 0)))
6790 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6791 if (TREE_CODE (arg) == COMPLEX_EXPR
6792 && real_zerop (TREE_OPERAND (arg, 1)))
6793 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6795 /* Don't do this when optimizing for size. */
6796 if (flag_unsafe_math_optimizations
6797 && optimize && !optimize_size)
6799 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6801 if (sqrtfn != NULL_TREE)
6803 tree rpart, ipart, result, arglist;
6805 arg = builtin_save_expr (arg);
6807 rpart = fold_build1 (REALPART_EXPR, type, arg);
6808 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6810 rpart = builtin_save_expr (rpart);
6811 ipart = builtin_save_expr (ipart);
6813 result = fold_build2 (PLUS_EXPR, type,
6814 fold_build2 (MULT_EXPR, type,
6815 rpart, rpart),
6816 fold_build2 (MULT_EXPR, type,
6817 ipart, ipart));
6819 arglist = build_tree_list (NULL_TREE, result);
6820 return build_function_call_expr (sqrtfn, arglist);
6824 return NULL_TREE;
6827 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6828 NULL_TREE if no simplification can be made. */
6830 static tree
6831 fold_builtin_sqrt (tree arglist, tree type)
6834 enum built_in_function fcode;
6835 tree arg = TREE_VALUE (arglist);
6837 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6838 return NULL_TREE;
6840 /* Optimize sqrt of constant value. */
6841 if (TREE_CODE (arg) == REAL_CST
6842 && ! TREE_CONSTANT_OVERFLOW (arg))
6844 REAL_VALUE_TYPE r, x;
6846 x = TREE_REAL_CST (arg);
6847 if (real_sqrt (&r, TYPE_MODE (type), &x)
6848 || (!flag_trapping_math && !flag_errno_math))
6849 return build_real (type, r);
6852 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6853 fcode = builtin_mathfn_code (arg);
6854 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6856 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6857 arg = fold_build2 (MULT_EXPR, type,
6858 TREE_VALUE (TREE_OPERAND (arg, 1)),
6859 build_real (type, dconsthalf));
6860 arglist = build_tree_list (NULL_TREE, arg);
6861 return build_function_call_expr (expfn, arglist);
6864 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6865 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6867 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6869 if (powfn)
6871 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6872 tree tree_root;
6873 /* The inner root was either sqrt or cbrt. */
6874 REAL_VALUE_TYPE dconstroot =
6875 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6877 /* Adjust for the outer root. */
6878 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6879 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6880 tree_root = build_real (type, dconstroot);
6881 arglist = tree_cons (NULL_TREE, arg0,
6882 build_tree_list (NULL_TREE, tree_root));
6883 return build_function_call_expr (powfn, arglist);
6887 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6888 if (flag_unsafe_math_optimizations
6889 && (fcode == BUILT_IN_POW
6890 || fcode == BUILT_IN_POWF
6891 || fcode == BUILT_IN_POWL))
6893 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6894 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6895 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6896 tree narg1;
6897 if (!tree_expr_nonnegative_p (arg0))
6898 arg0 = build1 (ABS_EXPR, type, arg0);
6899 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6900 build_real (type, dconsthalf));
6901 arglist = tree_cons (NULL_TREE, arg0,
6902 build_tree_list (NULL_TREE, narg1));
6903 return build_function_call_expr (powfn, arglist);
6906 return NULL_TREE;
6909 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6910 NULL_TREE if no simplification can be made. */
6911 static tree
6912 fold_builtin_cbrt (tree arglist, tree type)
6914 tree arg = TREE_VALUE (arglist);
6915 const enum built_in_function fcode = builtin_mathfn_code (arg);
6917 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6918 return NULL_TREE;
6920 /* Optimize cbrt of constant value. */
6921 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6922 return arg;
6924 if (flag_unsafe_math_optimizations)
6926 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6927 if (BUILTIN_EXPONENT_P (fcode))
6929 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6930 const REAL_VALUE_TYPE third_trunc =
6931 real_value_truncate (TYPE_MODE (type), dconstthird);
6932 arg = fold_build2 (MULT_EXPR, type,
6933 TREE_VALUE (TREE_OPERAND (arg, 1)),
6934 build_real (type, third_trunc));
6935 arglist = build_tree_list (NULL_TREE, arg);
6936 return build_function_call_expr (expfn, arglist);
6939 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6940 if (BUILTIN_SQRT_P (fcode))
6942 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6944 if (powfn)
6946 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6947 tree tree_root;
6948 REAL_VALUE_TYPE dconstroot = dconstthird;
6950 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6951 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6952 tree_root = build_real (type, dconstroot);
6953 arglist = tree_cons (NULL_TREE, arg0,
6954 build_tree_list (NULL_TREE, tree_root));
6955 return build_function_call_expr (powfn, arglist);
6959 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6960 if (BUILTIN_CBRT_P (fcode))
6962 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6963 if (tree_expr_nonnegative_p (arg0))
6965 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6967 if (powfn)
6969 tree tree_root;
6970 REAL_VALUE_TYPE dconstroot;
6972 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6973 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6974 tree_root = build_real (type, dconstroot);
6975 arglist = tree_cons (NULL_TREE, arg0,
6976 build_tree_list (NULL_TREE, tree_root));
6977 return build_function_call_expr (powfn, arglist);
6982 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6983 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6984 || fcode == BUILT_IN_POWL)
6986 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6987 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6988 if (tree_expr_nonnegative_p (arg00))
6990 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6991 const REAL_VALUE_TYPE dconstroot
6992 = real_value_truncate (TYPE_MODE (type), dconstthird);
6993 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6994 build_real (type, dconstroot));
6995 arglist = tree_cons (NULL_TREE, arg00,
6996 build_tree_list (NULL_TREE, narg01));
6997 return build_function_call_expr (powfn, arglist);
7001 return NULL_TREE;
7004 /* Fold function call to builtin sin, sinf, or sinl. Return
7005 NULL_TREE if no simplification can be made. */
7006 static tree
7007 fold_builtin_sin (tree arglist)
7009 tree arg = TREE_VALUE (arglist);
7011 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7012 return NULL_TREE;
7014 /* Optimize sin (0.0) = 0.0. */
7015 if (real_zerop (arg))
7016 return arg;
7018 return NULL_TREE;
7021 /* Fold function call to builtin cos, cosf, or cosl. Return
7022 NULL_TREE if no simplification can be made. */
7023 static tree
7024 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7026 tree arg = TREE_VALUE (arglist);
7028 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7029 return NULL_TREE;
7031 /* Optimize cos (0.0) = 1.0. */
7032 if (real_zerop (arg))
7033 return build_real (type, dconst1);
7035 /* Optimize cos(-x) into cos (x). */
7036 if (TREE_CODE (arg) == NEGATE_EXPR)
7038 tree args = build_tree_list (NULL_TREE,
7039 TREE_OPERAND (arg, 0));
7040 return build_function_call_expr (fndecl, args);
7043 return NULL_TREE;
7046 /* Fold function call to builtin tan, tanf, or tanl. Return
7047 NULL_TREE if no simplification can be made. */
7048 static tree
7049 fold_builtin_tan (tree arglist)
7051 enum built_in_function fcode;
7052 tree arg = TREE_VALUE (arglist);
7054 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7055 return NULL_TREE;
7057 /* Optimize tan(0.0) = 0.0. */
7058 if (real_zerop (arg))
7059 return arg;
7061 /* Optimize tan(atan(x)) = x. */
7062 fcode = builtin_mathfn_code (arg);
7063 if (flag_unsafe_math_optimizations
7064 && (fcode == BUILT_IN_ATAN
7065 || fcode == BUILT_IN_ATANF
7066 || fcode == BUILT_IN_ATANL))
7067 return TREE_VALUE (TREE_OPERAND (arg, 1));
7069 return NULL_TREE;
7072 /* Fold function call to builtin atan, atanf, or atanl. Return
7073 NULL_TREE if no simplification can be made. */
7075 static tree
7076 fold_builtin_atan (tree arglist, tree type)
7079 tree arg = TREE_VALUE (arglist);
7081 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7082 return NULL_TREE;
7084 /* Optimize atan(0.0) = 0.0. */
7085 if (real_zerop (arg))
7086 return arg;
7088 /* Optimize atan(1.0) = pi/4. */
7089 if (real_onep (arg))
7091 REAL_VALUE_TYPE cst;
7093 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7094 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7095 return build_real (type, cst);
7098 return NULL_TREE;
7101 /* Fold function call to builtin trunc, truncf or truncl. Return
7102 NULL_TREE if no simplification can be made. */
7104 static tree
7105 fold_builtin_trunc (tree fndecl, tree arglist)
7107 tree arg;
7109 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7110 return 0;
7112 /* Optimize trunc of constant value. */
7113 arg = TREE_VALUE (arglist);
7114 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7116 REAL_VALUE_TYPE r, x;
7117 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7119 x = TREE_REAL_CST (arg);
7120 real_trunc (&r, TYPE_MODE (type), &x);
7121 return build_real (type, r);
7124 return fold_trunc_transparent_mathfn (fndecl, arglist);
7127 /* Fold function call to builtin floor, floorf or floorl. Return
7128 NULL_TREE if no simplification can be made. */
7130 static tree
7131 fold_builtin_floor (tree fndecl, tree arglist)
7133 tree arg;
7135 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7136 return 0;
7138 /* Optimize floor of constant value. */
7139 arg = TREE_VALUE (arglist);
7140 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7142 REAL_VALUE_TYPE x;
7144 x = TREE_REAL_CST (arg);
7145 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7147 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7148 REAL_VALUE_TYPE r;
7150 real_floor (&r, TYPE_MODE (type), &x);
7151 return build_real (type, r);
7155 return fold_trunc_transparent_mathfn (fndecl, arglist);
7158 /* Fold function call to builtin ceil, ceilf or ceill. Return
7159 NULL_TREE if no simplification can be made. */
7161 static tree
7162 fold_builtin_ceil (tree fndecl, tree arglist)
7164 tree arg;
7166 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7167 return 0;
7169 /* Optimize ceil of constant value. */
7170 arg = TREE_VALUE (arglist);
7171 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7173 REAL_VALUE_TYPE x;
7175 x = TREE_REAL_CST (arg);
7176 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7178 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7179 REAL_VALUE_TYPE r;
7181 real_ceil (&r, TYPE_MODE (type), &x);
7182 return build_real (type, r);
7186 return fold_trunc_transparent_mathfn (fndecl, arglist);
7189 /* Fold function call to builtin round, roundf or roundl. Return
7190 NULL_TREE if no simplification can be made. */
7192 static tree
7193 fold_builtin_round (tree fndecl, tree arglist)
7195 tree arg;
7197 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7198 return 0;
7200 /* Optimize round of constant value. */
7201 arg = TREE_VALUE (arglist);
7202 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7204 REAL_VALUE_TYPE x;
7206 x = TREE_REAL_CST (arg);
7207 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7209 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7210 REAL_VALUE_TYPE r;
7212 real_round (&r, TYPE_MODE (type), &x);
7213 return build_real (type, r);
7217 return fold_trunc_transparent_mathfn (fndecl, arglist);
7220 /* Fold function call to builtin lround, lroundf or lroundl (or the
7221 corresponding long long versions) and other rounding functions.
7222 Return NULL_TREE if no simplification can be made. */
7224 static tree
7225 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7227 tree arg;
7229 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7230 return 0;
7232 /* Optimize lround of constant value. */
7233 arg = TREE_VALUE (arglist);
7234 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7236 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7238 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7240 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7241 tree ftype = TREE_TYPE (arg), result;
7242 HOST_WIDE_INT hi, lo;
7243 REAL_VALUE_TYPE r;
7245 switch (DECL_FUNCTION_CODE (fndecl))
7247 CASE_FLT_FN (BUILT_IN_LFLOOR):
7248 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7249 real_floor (&r, TYPE_MODE (ftype), &x);
7250 break;
7252 CASE_FLT_FN (BUILT_IN_LCEIL):
7253 CASE_FLT_FN (BUILT_IN_LLCEIL):
7254 real_ceil (&r, TYPE_MODE (ftype), &x);
7255 break;
7257 CASE_FLT_FN (BUILT_IN_LROUND):
7258 CASE_FLT_FN (BUILT_IN_LLROUND):
7259 real_round (&r, TYPE_MODE (ftype), &x);
7260 break;
7262 default:
7263 gcc_unreachable ();
7266 REAL_VALUE_TO_INT (&lo, &hi, r);
7267 result = build_int_cst_wide (NULL_TREE, lo, hi);
7268 if (int_fits_type_p (result, itype))
7269 return fold_convert (itype, result);
7273 return fold_fixed_mathfn (fndecl, arglist);
7276 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7277 and their long and long long variants (i.e. ffsl and ffsll).
7278 Return NULL_TREE if no simplification can be made. */
7280 static tree
7281 fold_builtin_bitop (tree fndecl, tree arglist)
7283 tree arg;
7285 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7286 return NULL_TREE;
7288 /* Optimize for constant argument. */
7289 arg = TREE_VALUE (arglist);
7290 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7292 HOST_WIDE_INT hi, width, result;
7293 unsigned HOST_WIDE_INT lo;
7294 tree type;
7296 type = TREE_TYPE (arg);
7297 width = TYPE_PRECISION (type);
7298 lo = TREE_INT_CST_LOW (arg);
7300 /* Clear all the bits that are beyond the type's precision. */
7301 if (width > HOST_BITS_PER_WIDE_INT)
7303 hi = TREE_INT_CST_HIGH (arg);
7304 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7305 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7307 else
7309 hi = 0;
7310 if (width < HOST_BITS_PER_WIDE_INT)
7311 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7314 switch (DECL_FUNCTION_CODE (fndecl))
7316 CASE_INT_FN (BUILT_IN_FFS):
7317 if (lo != 0)
7318 result = exact_log2 (lo & -lo) + 1;
7319 else if (hi != 0)
7320 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7321 else
7322 result = 0;
7323 break;
7325 CASE_INT_FN (BUILT_IN_CLZ):
7326 if (hi != 0)
7327 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7328 else if (lo != 0)
7329 result = width - floor_log2 (lo) - 1;
7330 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7331 result = width;
7332 break;
7334 CASE_INT_FN (BUILT_IN_CTZ):
7335 if (lo != 0)
7336 result = exact_log2 (lo & -lo);
7337 else if (hi != 0)
7338 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7339 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7340 result = width;
7341 break;
7343 CASE_INT_FN (BUILT_IN_POPCOUNT):
7344 result = 0;
7345 while (lo)
7346 result++, lo &= lo - 1;
7347 while (hi)
7348 result++, hi &= hi - 1;
7349 break;
7351 CASE_INT_FN (BUILT_IN_PARITY):
7352 result = 0;
7353 while (lo)
7354 result++, lo &= lo - 1;
7355 while (hi)
7356 result++, hi &= hi - 1;
7357 result &= 1;
7358 break;
7360 default:
7361 gcc_unreachable ();
7364 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7367 return NULL_TREE;
7370 /* Return true if EXPR is the real constant contained in VALUE. */
7372 static bool
7373 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7375 STRIP_NOPS (expr);
7377 return ((TREE_CODE (expr) == REAL_CST
7378 && ! TREE_CONSTANT_OVERFLOW (expr)
7379 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7380 || (TREE_CODE (expr) == COMPLEX_CST
7381 && real_dconstp (TREE_REALPART (expr), value)
7382 && real_zerop (TREE_IMAGPART (expr))));
7385 /* A subroutine of fold_builtin to fold the various logarithmic
7386 functions. EXP is the CALL_EXPR of a call to a builtin logN
7387 function. VALUE is the base of the logN function. */
7389 static tree
7390 fold_builtin_logarithm (tree fndecl, tree arglist,
7391 const REAL_VALUE_TYPE *value)
7393 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7395 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7396 tree arg = TREE_VALUE (arglist);
7397 const enum built_in_function fcode = builtin_mathfn_code (arg);
7399 /* Optimize logN(1.0) = 0.0. */
7400 if (real_onep (arg))
7401 return build_real (type, dconst0);
7403 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7404 exactly, then only do this if flag_unsafe_math_optimizations. */
7405 if (exact_real_truncate (TYPE_MODE (type), value)
7406 || flag_unsafe_math_optimizations)
7408 const REAL_VALUE_TYPE value_truncate =
7409 real_value_truncate (TYPE_MODE (type), *value);
7410 if (real_dconstp (arg, &value_truncate))
7411 return build_real (type, dconst1);
7414 /* Special case, optimize logN(expN(x)) = x. */
7415 if (flag_unsafe_math_optimizations
7416 && ((value == &dconste
7417 && (fcode == BUILT_IN_EXP
7418 || fcode == BUILT_IN_EXPF
7419 || fcode == BUILT_IN_EXPL))
7420 || (value == &dconst2
7421 && (fcode == BUILT_IN_EXP2
7422 || fcode == BUILT_IN_EXP2F
7423 || fcode == BUILT_IN_EXP2L))
7424 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7425 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7427 /* Optimize logN(func()) for various exponential functions. We
7428 want to determine the value "x" and the power "exponent" in
7429 order to transform logN(x**exponent) into exponent*logN(x). */
7430 if (flag_unsafe_math_optimizations)
7432 tree exponent = 0, x = 0;
7434 switch (fcode)
7436 CASE_FLT_FN (BUILT_IN_EXP):
7437 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7438 x = build_real (type,
7439 real_value_truncate (TYPE_MODE (type), dconste));
7440 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7441 break;
7442 CASE_FLT_FN (BUILT_IN_EXP2):
7443 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7444 x = build_real (type, dconst2);
7445 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7446 break;
7447 CASE_FLT_FN (BUILT_IN_EXP10):
7448 CASE_FLT_FN (BUILT_IN_POW10):
7449 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7450 x = build_real (type, dconst10);
7451 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7452 break;
7453 CASE_FLT_FN (BUILT_IN_SQRT):
7454 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7455 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7456 exponent = build_real (type, dconsthalf);
7457 break;
7458 CASE_FLT_FN (BUILT_IN_CBRT):
7459 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7460 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7461 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7462 dconstthird));
7463 break;
7464 CASE_FLT_FN (BUILT_IN_POW):
7465 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7466 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7467 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7468 break;
7469 default:
7470 break;
7473 /* Now perform the optimization. */
7474 if (x && exponent)
7476 tree logfn;
7477 arglist = build_tree_list (NULL_TREE, x);
7478 logfn = build_function_call_expr (fndecl, arglist);
7479 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7484 return 0;
7487 /* Fold a builtin function call to pow, powf, or powl. Return
7488 NULL_TREE if no simplification can be made. */
7489 static tree
7490 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7492 tree arg0 = TREE_VALUE (arglist);
7493 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7495 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7496 return NULL_TREE;
7498 /* Optimize pow(1.0,y) = 1.0. */
7499 if (real_onep (arg0))
7500 return omit_one_operand (type, build_real (type, dconst1), arg1);
7502 if (TREE_CODE (arg1) == REAL_CST
7503 && ! TREE_CONSTANT_OVERFLOW (arg1))
7505 REAL_VALUE_TYPE cint;
7506 REAL_VALUE_TYPE c;
7507 HOST_WIDE_INT n;
7509 c = TREE_REAL_CST (arg1);
7511 /* Optimize pow(x,0.0) = 1.0. */
7512 if (REAL_VALUES_EQUAL (c, dconst0))
7513 return omit_one_operand (type, build_real (type, dconst1),
7514 arg0);
7516 /* Optimize pow(x,1.0) = x. */
7517 if (REAL_VALUES_EQUAL (c, dconst1))
7518 return arg0;
7520 /* Optimize pow(x,-1.0) = 1.0/x. */
7521 if (REAL_VALUES_EQUAL (c, dconstm1))
7522 return fold_build2 (RDIV_EXPR, type,
7523 build_real (type, dconst1), arg0);
7525 /* Optimize pow(x,0.5) = sqrt(x). */
7526 if (flag_unsafe_math_optimizations
7527 && REAL_VALUES_EQUAL (c, dconsthalf))
7529 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7531 if (sqrtfn != NULL_TREE)
7533 tree arglist = build_tree_list (NULL_TREE, arg0);
7534 return build_function_call_expr (sqrtfn, arglist);
7538 /* Check for an integer exponent. */
7539 n = real_to_integer (&c);
7540 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7541 if (real_identical (&c, &cint))
7543 /* Attempt to evaluate pow at compile-time. */
7544 if (TREE_CODE (arg0) == REAL_CST
7545 && ! TREE_CONSTANT_OVERFLOW (arg0))
7547 REAL_VALUE_TYPE x;
7548 bool inexact;
7550 x = TREE_REAL_CST (arg0);
7551 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7552 if (flag_unsafe_math_optimizations || !inexact)
7553 return build_real (type, x);
7556 /* Strip sign ops from even integer powers. */
7557 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7559 tree narg0 = fold_strip_sign_ops (arg0);
7560 if (narg0)
7562 arglist = build_tree_list (NULL_TREE, arg1);
7563 arglist = tree_cons (NULL_TREE, narg0, arglist);
7564 return build_function_call_expr (fndecl, arglist);
7570 if (flag_unsafe_math_optimizations)
7572 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7574 /* Optimize pow(expN(x),y) = expN(x*y). */
7575 if (BUILTIN_EXPONENT_P (fcode))
7577 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7578 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7579 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7580 arglist = build_tree_list (NULL_TREE, arg);
7581 return build_function_call_expr (expfn, arglist);
7584 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7585 if (BUILTIN_SQRT_P (fcode))
7587 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7588 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7589 build_real (type, dconsthalf));
7591 arglist = tree_cons (NULL_TREE, narg0,
7592 build_tree_list (NULL_TREE, narg1));
7593 return build_function_call_expr (fndecl, arglist);
7596 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7597 if (BUILTIN_CBRT_P (fcode))
7599 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7600 if (tree_expr_nonnegative_p (arg))
7602 const REAL_VALUE_TYPE dconstroot
7603 = real_value_truncate (TYPE_MODE (type), dconstthird);
7604 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7605 build_real (type, dconstroot));
7606 arglist = tree_cons (NULL_TREE, arg,
7607 build_tree_list (NULL_TREE, narg1));
7608 return build_function_call_expr (fndecl, arglist);
7612 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7613 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7614 || fcode == BUILT_IN_POWL)
7616 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7617 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7618 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7619 arglist = tree_cons (NULL_TREE, arg00,
7620 build_tree_list (NULL_TREE, narg1));
7621 return build_function_call_expr (fndecl, arglist);
7625 return NULL_TREE;
7628 /* Fold a builtin function call to powi, powif, or powil. Return
7629 NULL_TREE if no simplification can be made. */
7630 static tree
7631 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7633 tree arg0 = TREE_VALUE (arglist);
7634 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7636 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7637 return NULL_TREE;
7639 /* Optimize pow(1.0,y) = 1.0. */
7640 if (real_onep (arg0))
7641 return omit_one_operand (type, build_real (type, dconst1), arg1);
7643 if (host_integerp (arg1, 0))
7645 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7647 /* Evaluate powi at compile-time. */
7648 if (TREE_CODE (arg0) == REAL_CST
7649 && ! TREE_CONSTANT_OVERFLOW (arg0))
7651 REAL_VALUE_TYPE x;
7652 x = TREE_REAL_CST (arg0);
7653 real_powi (&x, TYPE_MODE (type), &x, c);
7654 return build_real (type, x);
7657 /* Optimize pow(x,0) = 1.0. */
7658 if (c == 0)
7659 return omit_one_operand (type, build_real (type, dconst1),
7660 arg0);
7662 /* Optimize pow(x,1) = x. */
7663 if (c == 1)
7664 return arg0;
7666 /* Optimize pow(x,-1) = 1.0/x. */
7667 if (c == -1)
7668 return fold_build2 (RDIV_EXPR, type,
7669 build_real (type, dconst1), arg0);
7672 return NULL_TREE;
7675 /* A subroutine of fold_builtin to fold the various exponent
7676 functions. EXP is the CALL_EXPR of a call to a builtin function.
7677 VALUE is the value which will be raised to a power. */
7679 static tree
7680 fold_builtin_exponent (tree fndecl, tree arglist,
7681 const REAL_VALUE_TYPE *value)
7683 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7685 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7686 tree arg = TREE_VALUE (arglist);
7688 /* Optimize exp*(0.0) = 1.0. */
7689 if (real_zerop (arg))
7690 return build_real (type, dconst1);
7692 /* Optimize expN(1.0) = N. */
7693 if (real_onep (arg))
7695 REAL_VALUE_TYPE cst;
7697 real_convert (&cst, TYPE_MODE (type), value);
7698 return build_real (type, cst);
7701 /* Attempt to evaluate expN(integer) at compile-time. */
7702 if (flag_unsafe_math_optimizations
7703 && TREE_CODE (arg) == REAL_CST
7704 && ! TREE_CONSTANT_OVERFLOW (arg))
7706 REAL_VALUE_TYPE cint;
7707 REAL_VALUE_TYPE c;
7708 HOST_WIDE_INT n;
7710 c = TREE_REAL_CST (arg);
7711 n = real_to_integer (&c);
7712 real_from_integer (&cint, VOIDmode, n,
7713 n < 0 ? -1 : 0, 0);
7714 if (real_identical (&c, &cint))
7716 REAL_VALUE_TYPE x;
7718 real_powi (&x, TYPE_MODE (type), value, n);
7719 return build_real (type, x);
7723 /* Optimize expN(logN(x)) = x. */
7724 if (flag_unsafe_math_optimizations)
7726 const enum built_in_function fcode = builtin_mathfn_code (arg);
7728 if ((value == &dconste
7729 && (fcode == BUILT_IN_LOG
7730 || fcode == BUILT_IN_LOGF
7731 || fcode == BUILT_IN_LOGL))
7732 || (value == &dconst2
7733 && (fcode == BUILT_IN_LOG2
7734 || fcode == BUILT_IN_LOG2F
7735 || fcode == BUILT_IN_LOG2L))
7736 || (value == &dconst10
7737 && (fcode == BUILT_IN_LOG10
7738 || fcode == BUILT_IN_LOG10F
7739 || fcode == BUILT_IN_LOG10L)))
7740 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7744 return 0;
7747 /* Fold function call to builtin memcpy. Return
7748 NULL_TREE if no simplification can be made. */
7750 static tree
7751 fold_builtin_memcpy (tree fndecl, tree arglist)
7753 tree dest, src, len;
7755 if (!validate_arglist (arglist,
7756 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7757 return 0;
7759 dest = TREE_VALUE (arglist);
7760 src = TREE_VALUE (TREE_CHAIN (arglist));
7761 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7763 /* If the LEN parameter is zero, return DEST. */
7764 if (integer_zerop (len))
7765 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7767 /* If SRC and DEST are the same (and not volatile), return DEST. */
7768 if (operand_equal_p (src, dest, 0))
7769 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7771 return 0;
7774 /* Fold function call to builtin mempcpy. Return
7775 NULL_TREE if no simplification can be made. */
7777 static tree
7778 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7780 if (validate_arglist (arglist,
7781 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7783 tree dest = TREE_VALUE (arglist);
7784 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7785 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7787 /* If the LEN parameter is zero, return DEST. */
7788 if (integer_zerop (len))
7789 return omit_one_operand (type, dest, src);
7791 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7792 if (operand_equal_p (src, dest, 0))
7794 if (endp == 0)
7795 return omit_one_operand (type, dest, len);
7797 if (endp == 2)
7798 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7799 ssize_int (1));
7801 len = fold_convert (TREE_TYPE (dest), len);
7802 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7803 return fold_convert (type, len);
7806 return 0;
7809 /* Fold function call to builtin memmove. Return
7810 NULL_TREE if no simplification can be made. */
7812 static tree
7813 fold_builtin_memmove (tree arglist, tree type)
7815 tree dest, src, len;
7817 if (!validate_arglist (arglist,
7818 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7819 return 0;
7821 dest = TREE_VALUE (arglist);
7822 src = TREE_VALUE (TREE_CHAIN (arglist));
7823 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7825 /* If the LEN parameter is zero, return DEST. */
7826 if (integer_zerop (len))
7827 return omit_one_operand (type, dest, src);
7829 /* If SRC and DEST are the same (and not volatile), return DEST. */
7830 if (operand_equal_p (src, dest, 0))
7831 return omit_one_operand (type, dest, len);
7833 return 0;
7836 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7837 the length of the string to be copied. Return NULL_TREE if no
7838 simplification can be made. */
7840 tree
7841 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7843 tree dest, src, fn;
7845 if (!validate_arglist (arglist,
7846 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7847 return 0;
7849 dest = TREE_VALUE (arglist);
7850 src = TREE_VALUE (TREE_CHAIN (arglist));
7852 /* If SRC and DEST are the same (and not volatile), return DEST. */
7853 if (operand_equal_p (src, dest, 0))
7854 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7856 if (optimize_size)
7857 return 0;
7859 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7860 if (!fn)
7861 return 0;
7863 if (!len)
7865 len = c_strlen (src, 1);
7866 if (! len || TREE_SIDE_EFFECTS (len))
7867 return 0;
7870 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7871 arglist = build_tree_list (NULL_TREE, len);
7872 arglist = tree_cons (NULL_TREE, src, arglist);
7873 arglist = tree_cons (NULL_TREE, dest, arglist);
7874 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7875 build_function_call_expr (fn, arglist));
7878 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7879 the length of the source string. Return NULL_TREE if no simplification
7880 can be made. */
7882 tree
7883 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7885 tree dest, src, len, fn;
7887 if (!validate_arglist (arglist,
7888 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7889 return 0;
7891 dest = TREE_VALUE (arglist);
7892 src = TREE_VALUE (TREE_CHAIN (arglist));
7893 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7895 /* If the LEN parameter is zero, return DEST. */
7896 if (integer_zerop (len))
7897 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7899 /* We can't compare slen with len as constants below if len is not a
7900 constant. */
7901 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7902 return 0;
7904 if (!slen)
7905 slen = c_strlen (src, 1);
7907 /* Now, we must be passed a constant src ptr parameter. */
7908 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7909 return 0;
7911 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7913 /* We do not support simplification of this case, though we do
7914 support it when expanding trees into RTL. */
7915 /* FIXME: generate a call to __builtin_memset. */
7916 if (tree_int_cst_lt (slen, len))
7917 return 0;
7919 /* OK transform into builtin memcpy. */
7920 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7921 if (!fn)
7922 return 0;
7923 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7924 build_function_call_expr (fn, arglist));
7927 /* Fold function call to builtin memcmp. Return
7928 NULL_TREE if no simplification can be made. */
7930 static tree
7931 fold_builtin_memcmp (tree arglist)
7933 tree arg1, arg2, len;
7934 const char *p1, *p2;
7936 if (!validate_arglist (arglist,
7937 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7938 return 0;
7940 arg1 = TREE_VALUE (arglist);
7941 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7942 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7944 /* If the LEN parameter is zero, return zero. */
7945 if (integer_zerop (len))
7946 return omit_two_operands (integer_type_node, integer_zero_node,
7947 arg1, arg2);
7949 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7950 if (operand_equal_p (arg1, arg2, 0))
7951 return omit_one_operand (integer_type_node, integer_zero_node, len);
7953 p1 = c_getstr (arg1);
7954 p2 = c_getstr (arg2);
7956 /* If all arguments are constant, and the value of len is not greater
7957 than the lengths of arg1 and arg2, evaluate at compile-time. */
7958 if (host_integerp (len, 1) && p1 && p2
7959 && compare_tree_int (len, strlen (p1) + 1) <= 0
7960 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7962 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7964 if (r > 0)
7965 return integer_one_node;
7966 else if (r < 0)
7967 return integer_minus_one_node;
7968 else
7969 return integer_zero_node;
7972 /* If len parameter is one, return an expression corresponding to
7973 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7974 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7976 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7977 tree cst_uchar_ptr_node
7978 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7980 tree ind1 = fold_convert (integer_type_node,
7981 build1 (INDIRECT_REF, cst_uchar_node,
7982 fold_convert (cst_uchar_ptr_node,
7983 arg1)));
7984 tree ind2 = fold_convert (integer_type_node,
7985 build1 (INDIRECT_REF, cst_uchar_node,
7986 fold_convert (cst_uchar_ptr_node,
7987 arg2)));
7988 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7991 return 0;
7994 /* Fold function call to builtin strcmp. Return
7995 NULL_TREE if no simplification can be made. */
7997 static tree
7998 fold_builtin_strcmp (tree arglist)
8000 tree arg1, arg2;
8001 const char *p1, *p2;
8003 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8004 return 0;
8006 arg1 = TREE_VALUE (arglist);
8007 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8009 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8010 if (operand_equal_p (arg1, arg2, 0))
8011 return integer_zero_node;
8013 p1 = c_getstr (arg1);
8014 p2 = c_getstr (arg2);
8016 if (p1 && p2)
8018 const int i = strcmp (p1, p2);
8019 if (i < 0)
8020 return integer_minus_one_node;
8021 else if (i > 0)
8022 return integer_one_node;
8023 else
8024 return integer_zero_node;
8027 /* If the second arg is "", return *(const unsigned char*)arg1. */
8028 if (p2 && *p2 == '\0')
8030 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8031 tree cst_uchar_ptr_node
8032 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8034 return fold_convert (integer_type_node,
8035 build1 (INDIRECT_REF, cst_uchar_node,
8036 fold_convert (cst_uchar_ptr_node,
8037 arg1)));
8040 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8041 if (p1 && *p1 == '\0')
8043 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8044 tree cst_uchar_ptr_node
8045 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8047 tree temp = fold_convert (integer_type_node,
8048 build1 (INDIRECT_REF, cst_uchar_node,
8049 fold_convert (cst_uchar_ptr_node,
8050 arg2)));
8051 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8054 return 0;
8057 /* Fold function call to builtin strncmp. Return
8058 NULL_TREE if no simplification can be made. */
8060 static tree
8061 fold_builtin_strncmp (tree arglist)
8063 tree arg1, arg2, len;
8064 const char *p1, *p2;
8066 if (!validate_arglist (arglist,
8067 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8068 return 0;
8070 arg1 = TREE_VALUE (arglist);
8071 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8072 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8074 /* If the LEN parameter is zero, return zero. */
8075 if (integer_zerop (len))
8076 return omit_two_operands (integer_type_node, integer_zero_node,
8077 arg1, arg2);
8079 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8080 if (operand_equal_p (arg1, arg2, 0))
8081 return omit_one_operand (integer_type_node, integer_zero_node, len);
8083 p1 = c_getstr (arg1);
8084 p2 = c_getstr (arg2);
8086 if (host_integerp (len, 1) && p1 && p2)
8088 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8089 if (i > 0)
8090 return integer_one_node;
8091 else if (i < 0)
8092 return integer_minus_one_node;
8093 else
8094 return integer_zero_node;
8097 /* If the second arg is "", and the length is greater than zero,
8098 return *(const unsigned char*)arg1. */
8099 if (p2 && *p2 == '\0'
8100 && TREE_CODE (len) == INTEGER_CST
8101 && tree_int_cst_sgn (len) == 1)
8103 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8104 tree cst_uchar_ptr_node
8105 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8107 return fold_convert (integer_type_node,
8108 build1 (INDIRECT_REF, cst_uchar_node,
8109 fold_convert (cst_uchar_ptr_node,
8110 arg1)));
8113 /* If the first arg is "", and the length is greater than zero,
8114 return -*(const unsigned char*)arg2. */
8115 if (p1 && *p1 == '\0'
8116 && TREE_CODE (len) == INTEGER_CST
8117 && tree_int_cst_sgn (len) == 1)
8119 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8120 tree cst_uchar_ptr_node
8121 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8123 tree temp = fold_convert (integer_type_node,
8124 build1 (INDIRECT_REF, cst_uchar_node,
8125 fold_convert (cst_uchar_ptr_node,
8126 arg2)));
8127 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8130 /* If len parameter is one, return an expression corresponding to
8131 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8132 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8134 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8135 tree cst_uchar_ptr_node
8136 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8138 tree ind1 = fold_convert (integer_type_node,
8139 build1 (INDIRECT_REF, cst_uchar_node,
8140 fold_convert (cst_uchar_ptr_node,
8141 arg1)));
8142 tree ind2 = fold_convert (integer_type_node,
8143 build1 (INDIRECT_REF, cst_uchar_node,
8144 fold_convert (cst_uchar_ptr_node,
8145 arg2)));
8146 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8149 return 0;
8152 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8153 NULL_TREE if no simplification can be made. */
8155 static tree
8156 fold_builtin_signbit (tree fndecl, tree arglist)
8158 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8159 tree arg, temp;
8161 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8162 return NULL_TREE;
8164 arg = TREE_VALUE (arglist);
8166 /* If ARG is a compile-time constant, determine the result. */
8167 if (TREE_CODE (arg) == REAL_CST
8168 && !TREE_CONSTANT_OVERFLOW (arg))
8170 REAL_VALUE_TYPE c;
8172 c = TREE_REAL_CST (arg);
8173 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8174 return fold_convert (type, temp);
8177 /* If ARG is non-negative, the result is always zero. */
8178 if (tree_expr_nonnegative_p (arg))
8179 return omit_one_operand (type, integer_zero_node, arg);
8181 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8182 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8183 return fold_build2 (LT_EXPR, type, arg,
8184 build_real (TREE_TYPE (arg), dconst0));
8186 return NULL_TREE;
8189 /* Fold function call to builtin copysign, copysignf or copysignl.
8190 Return NULL_TREE if no simplification can be made. */
8192 static tree
8193 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8195 tree arg1, arg2, tem;
8197 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8198 return NULL_TREE;
8200 arg1 = TREE_VALUE (arglist);
8201 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8203 /* copysign(X,X) is X. */
8204 if (operand_equal_p (arg1, arg2, 0))
8205 return fold_convert (type, arg1);
8207 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8208 if (TREE_CODE (arg1) == REAL_CST
8209 && TREE_CODE (arg2) == REAL_CST
8210 && !TREE_CONSTANT_OVERFLOW (arg1)
8211 && !TREE_CONSTANT_OVERFLOW (arg2))
8213 REAL_VALUE_TYPE c1, c2;
8215 c1 = TREE_REAL_CST (arg1);
8216 c2 = TREE_REAL_CST (arg2);
8217 /* c1.sign := c2.sign. */
8218 real_copysign (&c1, &c2);
8219 return build_real (type, c1);
8222 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8223 Remember to evaluate Y for side-effects. */
8224 if (tree_expr_nonnegative_p (arg2))
8225 return omit_one_operand (type,
8226 fold_build1 (ABS_EXPR, type, arg1),
8227 arg2);
8229 /* Strip sign changing operations for the first argument. */
8230 tem = fold_strip_sign_ops (arg1);
8231 if (tem)
8233 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8234 return build_function_call_expr (fndecl, arglist);
8237 return NULL_TREE;
8240 /* Fold a call to builtin isascii. */
8242 static tree
8243 fold_builtin_isascii (tree arglist)
8245 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8246 return 0;
8247 else
8249 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8250 tree arg = TREE_VALUE (arglist);
8252 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8253 build_int_cst (NULL_TREE,
8254 ~ (unsigned HOST_WIDE_INT) 0x7f));
8255 arg = fold_build2 (EQ_EXPR, integer_type_node,
8256 arg, integer_zero_node);
8258 if (in_gimple_form && !TREE_CONSTANT (arg))
8259 return NULL_TREE;
8260 else
8261 return arg;
8265 /* Fold a call to builtin toascii. */
8267 static tree
8268 fold_builtin_toascii (tree arglist)
8270 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8271 return 0;
8272 else
8274 /* Transform toascii(c) -> (c & 0x7f). */
8275 tree arg = TREE_VALUE (arglist);
8277 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8278 build_int_cst (NULL_TREE, 0x7f));
8282 /* Fold a call to builtin isdigit. */
8284 static tree
8285 fold_builtin_isdigit (tree arglist)
8287 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8288 return 0;
8289 else
8291 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8292 /* According to the C standard, isdigit is unaffected by locale.
8293 However, it definitely is affected by the target character set. */
8294 tree arg;
8295 unsigned HOST_WIDE_INT target_digit0
8296 = lang_hooks.to_target_charset ('0');
8298 if (target_digit0 == 0)
8299 return NULL_TREE;
8301 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8302 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8303 build_int_cst (unsigned_type_node, target_digit0));
8304 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8305 build_int_cst (unsigned_type_node, 9));
8306 if (in_gimple_form && !TREE_CONSTANT (arg))
8307 return NULL_TREE;
8308 else
8309 return arg;
8313 /* Fold a call to fabs, fabsf or fabsl. */
8315 static tree
8316 fold_builtin_fabs (tree arglist, tree type)
8318 tree arg;
8320 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8321 return 0;
8323 arg = TREE_VALUE (arglist);
8324 arg = fold_convert (type, arg);
8325 if (TREE_CODE (arg) == REAL_CST)
8326 return fold_abs_const (arg, type);
8327 return fold_build1 (ABS_EXPR, type, arg);
8330 /* Fold a call to abs, labs, llabs or imaxabs. */
8332 static tree
8333 fold_builtin_abs (tree arglist, tree type)
8335 tree arg;
8337 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8338 return 0;
8340 arg = TREE_VALUE (arglist);
8341 arg = fold_convert (type, arg);
8342 if (TREE_CODE (arg) == INTEGER_CST)
8343 return fold_abs_const (arg, type);
8344 return fold_build1 (ABS_EXPR, type, arg);
8347 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8348 EXP is the CALL_EXPR for the call. */
8350 static tree
8351 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8353 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8354 tree arg;
8355 REAL_VALUE_TYPE r;
8357 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8359 /* Check that we have exactly one argument. */
8360 if (arglist == 0)
8362 error ("too few arguments to function %qs",
8363 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8364 return error_mark_node;
8366 else if (TREE_CHAIN (arglist) != 0)
8368 error ("too many arguments to function %qs",
8369 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8370 return error_mark_node;
8372 else
8374 error ("non-floating-point argument to function %qs",
8375 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8376 return error_mark_node;
8380 arg = TREE_VALUE (arglist);
8381 switch (builtin_index)
8383 case BUILT_IN_ISINF:
8384 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8385 return omit_one_operand (type, integer_zero_node, arg);
8387 if (TREE_CODE (arg) == REAL_CST)
8389 r = TREE_REAL_CST (arg);
8390 if (real_isinf (&r))
8391 return real_compare (GT_EXPR, &r, &dconst0)
8392 ? integer_one_node : integer_minus_one_node;
8393 else
8394 return integer_zero_node;
8397 return NULL_TREE;
8399 case BUILT_IN_FINITE:
8400 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8401 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8402 return omit_one_operand (type, integer_zero_node, arg);
8404 if (TREE_CODE (arg) == REAL_CST)
8406 r = TREE_REAL_CST (arg);
8407 return real_isinf (&r) || real_isnan (&r)
8408 ? integer_zero_node : integer_one_node;
8411 return NULL_TREE;
8413 case BUILT_IN_ISNAN:
8414 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8415 return omit_one_operand (type, integer_zero_node, arg);
8417 if (TREE_CODE (arg) == REAL_CST)
8419 r = TREE_REAL_CST (arg);
8420 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8423 arg = builtin_save_expr (arg);
8424 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8426 default:
8427 gcc_unreachable ();
8431 /* Fold a call to an unordered comparison function such as
8432 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8433 being called and ARGLIST is the argument list for the call.
8434 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8435 the opposite of the desired result. UNORDERED_CODE is used
8436 for modes that can hold NaNs and ORDERED_CODE is used for
8437 the rest. */
8439 static tree
8440 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8441 enum tree_code unordered_code,
8442 enum tree_code ordered_code)
8444 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8445 enum tree_code code;
8446 tree arg0, arg1;
8447 tree type0, type1;
8448 enum tree_code code0, code1;
8449 tree cmp_type = NULL_TREE;
8451 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8453 /* Check that we have exactly two arguments. */
8454 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8456 error ("too few arguments to function %qs",
8457 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8458 return error_mark_node;
8460 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8462 error ("too many arguments to function %qs",
8463 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8464 return error_mark_node;
8468 arg0 = TREE_VALUE (arglist);
8469 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8471 type0 = TREE_TYPE (arg0);
8472 type1 = TREE_TYPE (arg1);
8474 code0 = TREE_CODE (type0);
8475 code1 = TREE_CODE (type1);
8477 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8478 /* Choose the wider of two real types. */
8479 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8480 ? type0 : type1;
8481 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8482 cmp_type = type0;
8483 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8484 cmp_type = type1;
8485 else
8487 error ("non-floating-point argument to function %qs",
8488 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8489 return error_mark_node;
8492 arg0 = fold_convert (cmp_type, arg0);
8493 arg1 = fold_convert (cmp_type, arg1);
8495 if (unordered_code == UNORDERED_EXPR)
8497 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8498 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8499 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8502 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8503 : ordered_code;
8504 return fold_build1 (TRUTH_NOT_EXPR, type,
8505 fold_build2 (code, type, arg0, arg1));
8508 /* Used by constant folding to simplify calls to builtin functions. EXP is
8509 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8510 result of the function call is ignored. This function returns NULL_TREE
8511 if no simplification was possible. */
8513 static tree
8514 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8516 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8517 enum built_in_function fcode;
8519 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8520 return targetm.fold_builtin (fndecl, arglist, ignore);
8522 fcode = DECL_FUNCTION_CODE (fndecl);
8523 switch (fcode)
8525 case BUILT_IN_FPUTS:
8526 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8528 case BUILT_IN_FPUTS_UNLOCKED:
8529 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8531 case BUILT_IN_STRSTR:
8532 return fold_builtin_strstr (arglist, type);
8534 case BUILT_IN_STRCAT:
8535 return fold_builtin_strcat (arglist);
8537 case BUILT_IN_STRNCAT:
8538 return fold_builtin_strncat (arglist);
8540 case BUILT_IN_STRSPN:
8541 return fold_builtin_strspn (arglist);
8543 case BUILT_IN_STRCSPN:
8544 return fold_builtin_strcspn (arglist);
8546 case BUILT_IN_STRCHR:
8547 case BUILT_IN_INDEX:
8548 return fold_builtin_strchr (arglist, type);
8550 case BUILT_IN_STRRCHR:
8551 case BUILT_IN_RINDEX:
8552 return fold_builtin_strrchr (arglist, type);
8554 case BUILT_IN_STRCPY:
8555 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8557 case BUILT_IN_STRNCPY:
8558 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8560 case BUILT_IN_STRCMP:
8561 return fold_builtin_strcmp (arglist);
8563 case BUILT_IN_STRNCMP:
8564 return fold_builtin_strncmp (arglist);
8566 case BUILT_IN_STRPBRK:
8567 return fold_builtin_strpbrk (arglist, type);
8569 case BUILT_IN_BCMP:
8570 case BUILT_IN_MEMCMP:
8571 return fold_builtin_memcmp (arglist);
8573 case BUILT_IN_SPRINTF:
8574 return fold_builtin_sprintf (arglist, ignore);
8576 case BUILT_IN_CONSTANT_P:
8578 tree val;
8580 val = fold_builtin_constant_p (arglist);
8581 /* Gimplification will pull the CALL_EXPR for the builtin out of
8582 an if condition. When not optimizing, we'll not CSE it back.
8583 To avoid link error types of regressions, return false now. */
8584 if (!val && !optimize)
8585 val = integer_zero_node;
8587 return val;
8590 case BUILT_IN_EXPECT:
8591 return fold_builtin_expect (arglist);
8593 case BUILT_IN_CLASSIFY_TYPE:
8594 return fold_builtin_classify_type (arglist);
8596 case BUILT_IN_STRLEN:
8597 return fold_builtin_strlen (arglist);
8599 CASE_FLT_FN (BUILT_IN_FABS):
8600 return fold_builtin_fabs (arglist, type);
8602 case BUILT_IN_ABS:
8603 case BUILT_IN_LABS:
8604 case BUILT_IN_LLABS:
8605 case BUILT_IN_IMAXABS:
8606 return fold_builtin_abs (arglist, type);
8608 CASE_FLT_FN (BUILT_IN_CONJ):
8609 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8610 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8611 break;
8613 CASE_FLT_FN (BUILT_IN_CREAL):
8614 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8615 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8616 TREE_VALUE (arglist)));
8617 break;
8619 CASE_FLT_FN (BUILT_IN_CIMAG):
8620 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8621 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8622 TREE_VALUE (arglist)));
8623 break;
8625 CASE_FLT_FN (BUILT_IN_CABS):
8626 return fold_builtin_cabs (arglist, type);
8628 CASE_FLT_FN (BUILT_IN_SQRT):
8629 return fold_builtin_sqrt (arglist, type);
8631 CASE_FLT_FN (BUILT_IN_CBRT):
8632 return fold_builtin_cbrt (arglist, type);
8634 CASE_FLT_FN (BUILT_IN_SIN):
8635 return fold_builtin_sin (arglist);
8637 CASE_FLT_FN (BUILT_IN_COS):
8638 return fold_builtin_cos (arglist, type, fndecl);
8640 CASE_FLT_FN (BUILT_IN_EXP):
8641 return fold_builtin_exponent (fndecl, arglist, &dconste);
8643 CASE_FLT_FN (BUILT_IN_EXP2):
8644 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8646 CASE_FLT_FN (BUILT_IN_EXP10):
8647 CASE_FLT_FN (BUILT_IN_POW10):
8648 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8650 CASE_FLT_FN (BUILT_IN_LOG):
8651 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8653 CASE_FLT_FN (BUILT_IN_LOG2):
8654 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8656 CASE_FLT_FN (BUILT_IN_LOG10):
8657 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8659 CASE_FLT_FN (BUILT_IN_TAN):
8660 return fold_builtin_tan (arglist);
8662 CASE_FLT_FN (BUILT_IN_ATAN):
8663 return fold_builtin_atan (arglist, type);
8665 CASE_FLT_FN (BUILT_IN_POW):
8666 return fold_builtin_pow (fndecl, arglist, type);
8668 CASE_FLT_FN (BUILT_IN_POWI):
8669 return fold_builtin_powi (fndecl, arglist, type);
8671 CASE_FLT_FN (BUILT_IN_INF):
8672 case BUILT_IN_INFD32:
8673 case BUILT_IN_INFD64:
8674 case BUILT_IN_INFD128:
8675 return fold_builtin_inf (type, true);
8677 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8678 return fold_builtin_inf (type, false);
8680 CASE_FLT_FN (BUILT_IN_NAN):
8681 case BUILT_IN_NAND32:
8682 case BUILT_IN_NAND64:
8683 case BUILT_IN_NAND128:
8684 return fold_builtin_nan (arglist, type, true);
8686 CASE_FLT_FN (BUILT_IN_NANS):
8687 return fold_builtin_nan (arglist, type, false);
8689 CASE_FLT_FN (BUILT_IN_FLOOR):
8690 return fold_builtin_floor (fndecl, arglist);
8692 CASE_FLT_FN (BUILT_IN_CEIL):
8693 return fold_builtin_ceil (fndecl, arglist);
8695 CASE_FLT_FN (BUILT_IN_TRUNC):
8696 return fold_builtin_trunc (fndecl, arglist);
8698 CASE_FLT_FN (BUILT_IN_ROUND):
8699 return fold_builtin_round (fndecl, arglist);
8701 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8702 CASE_FLT_FN (BUILT_IN_RINT):
8703 return fold_trunc_transparent_mathfn (fndecl, arglist);
8705 CASE_FLT_FN (BUILT_IN_LCEIL):
8706 CASE_FLT_FN (BUILT_IN_LLCEIL):
8707 CASE_FLT_FN (BUILT_IN_LFLOOR):
8708 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8709 CASE_FLT_FN (BUILT_IN_LROUND):
8710 CASE_FLT_FN (BUILT_IN_LLROUND):
8711 return fold_builtin_int_roundingfn (fndecl, arglist);
8713 CASE_FLT_FN (BUILT_IN_LRINT):
8714 CASE_FLT_FN (BUILT_IN_LLRINT):
8715 return fold_fixed_mathfn (fndecl, arglist);
8717 CASE_INT_FN (BUILT_IN_FFS):
8718 CASE_INT_FN (BUILT_IN_CLZ):
8719 CASE_INT_FN (BUILT_IN_CTZ):
8720 CASE_INT_FN (BUILT_IN_POPCOUNT):
8721 CASE_INT_FN (BUILT_IN_PARITY):
8722 return fold_builtin_bitop (fndecl, arglist);
8724 case BUILT_IN_MEMCPY:
8725 return fold_builtin_memcpy (fndecl, arglist);
8727 case BUILT_IN_MEMPCPY:
8728 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8730 case BUILT_IN_MEMMOVE:
8731 return fold_builtin_memmove (arglist, type);
8733 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8734 return fold_builtin_signbit (fndecl, arglist);
8736 case BUILT_IN_ISASCII:
8737 return fold_builtin_isascii (arglist);
8739 case BUILT_IN_TOASCII:
8740 return fold_builtin_toascii (arglist);
8742 case BUILT_IN_ISDIGIT:
8743 return fold_builtin_isdigit (arglist);
8745 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8746 return fold_builtin_copysign (fndecl, arglist, type);
8748 CASE_FLT_FN (BUILT_IN_FINITE):
8749 case BUILT_IN_FINITED32:
8750 case BUILT_IN_FINITED64:
8751 case BUILT_IN_FINITED128:
8752 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8754 CASE_FLT_FN (BUILT_IN_ISINF):
8755 case BUILT_IN_ISINFD32:
8756 case BUILT_IN_ISINFD64:
8757 case BUILT_IN_ISINFD128:
8758 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8760 CASE_FLT_FN (BUILT_IN_ISNAN):
8761 case BUILT_IN_ISNAND32:
8762 case BUILT_IN_ISNAND64:
8763 case BUILT_IN_ISNAND128:
8764 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8766 case BUILT_IN_ISGREATER:
8767 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8768 case BUILT_IN_ISGREATEREQUAL:
8769 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8770 case BUILT_IN_ISLESS:
8771 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8772 case BUILT_IN_ISLESSEQUAL:
8773 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8774 case BUILT_IN_ISLESSGREATER:
8775 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8776 case BUILT_IN_ISUNORDERED:
8777 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8778 NOP_EXPR);
8780 /* We do the folding for va_start in the expander. */
8781 case BUILT_IN_VA_START:
8782 break;
8784 case BUILT_IN_OBJECT_SIZE:
8785 return fold_builtin_object_size (arglist);
8786 case BUILT_IN_MEMCPY_CHK:
8787 case BUILT_IN_MEMPCPY_CHK:
8788 case BUILT_IN_MEMMOVE_CHK:
8789 case BUILT_IN_MEMSET_CHK:
8790 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8791 DECL_FUNCTION_CODE (fndecl));
8792 case BUILT_IN_STRCPY_CHK:
8793 case BUILT_IN_STPCPY_CHK:
8794 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8795 DECL_FUNCTION_CODE (fndecl));
8796 case BUILT_IN_STRNCPY_CHK:
8797 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8798 case BUILT_IN_STRCAT_CHK:
8799 return fold_builtin_strcat_chk (fndecl, arglist);
8800 case BUILT_IN_STRNCAT_CHK:
8801 return fold_builtin_strncat_chk (fndecl, arglist);
8802 case BUILT_IN_SPRINTF_CHK:
8803 case BUILT_IN_VSPRINTF_CHK:
8804 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8805 case BUILT_IN_SNPRINTF_CHK:
8806 case BUILT_IN_VSNPRINTF_CHK:
8807 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8808 DECL_FUNCTION_CODE (fndecl));
8810 case BUILT_IN_PRINTF:
8811 case BUILT_IN_PRINTF_UNLOCKED:
8812 case BUILT_IN_VPRINTF:
8813 case BUILT_IN_PRINTF_CHK:
8814 case BUILT_IN_VPRINTF_CHK:
8815 return fold_builtin_printf (fndecl, arglist, ignore,
8816 DECL_FUNCTION_CODE (fndecl));
8818 case BUILT_IN_FPRINTF:
8819 case BUILT_IN_FPRINTF_UNLOCKED:
8820 case BUILT_IN_VFPRINTF:
8821 case BUILT_IN_FPRINTF_CHK:
8822 case BUILT_IN_VFPRINTF_CHK:
8823 return fold_builtin_fprintf (fndecl, arglist, ignore,
8824 DECL_FUNCTION_CODE (fndecl));
8826 default:
8827 break;
8830 return 0;
8833 /* A wrapper function for builtin folding that prevents warnings for
8834 "statement without effect" and the like, caused by removing the
8835 call node earlier than the warning is generated. */
8837 tree
8838 fold_builtin (tree fndecl, tree arglist, bool ignore)
8840 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8841 if (exp)
8843 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8844 TREE_NO_WARNING (exp) = 1;
8847 return exp;
8850 /* Conveniently construct a function call expression. */
8852 tree
8853 build_function_call_expr (tree fn, tree arglist)
8855 tree call_expr;
8857 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8858 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8859 call_expr, arglist, NULL_TREE);
8862 /* This function validates the types of a function call argument list
8863 represented as a tree chain of parameters against a specified list
8864 of tree_codes. If the last specifier is a 0, that represents an
8865 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8867 static int
8868 validate_arglist (tree arglist, ...)
8870 enum tree_code code;
8871 int res = 0;
8872 va_list ap;
8874 va_start (ap, arglist);
8878 code = va_arg (ap, enum tree_code);
8879 switch (code)
8881 case 0:
8882 /* This signifies an ellipses, any further arguments are all ok. */
8883 res = 1;
8884 goto end;
8885 case VOID_TYPE:
8886 /* This signifies an endlink, if no arguments remain, return
8887 true, otherwise return false. */
8888 res = arglist == 0;
8889 goto end;
8890 default:
8891 /* If no parameters remain or the parameter's code does not
8892 match the specified code, return false. Otherwise continue
8893 checking any remaining arguments. */
8894 if (arglist == 0)
8895 goto end;
8896 if (code == POINTER_TYPE)
8898 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8899 goto end;
8901 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8902 goto end;
8903 break;
8905 arglist = TREE_CHAIN (arglist);
8907 while (1);
8909 /* We need gotos here since we can only have one VA_CLOSE in a
8910 function. */
8911 end: ;
8912 va_end (ap);
8914 return res;
8917 /* Default target-specific builtin expander that does nothing. */
8920 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8921 rtx target ATTRIBUTE_UNUSED,
8922 rtx subtarget ATTRIBUTE_UNUSED,
8923 enum machine_mode mode ATTRIBUTE_UNUSED,
8924 int ignore ATTRIBUTE_UNUSED)
8926 return NULL_RTX;
8929 /* Default target-specific library builtin expander that does nothing. */
8932 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
8933 rtx target ATTRIBUTE_UNUSED,
8934 rtx subtarget ATTRIBUTE_UNUSED,
8935 enum machine_mode mode ATTRIBUTE_UNUSED,
8936 int ignore ATTRIBUTE_UNUSED)
8938 return NULL_RTX;
8941 /* Returns true is EXP represents data that would potentially reside
8942 in a readonly section. */
8944 static bool
8945 readonly_data_expr (tree exp)
8947 STRIP_NOPS (exp);
8949 if (TREE_CODE (exp) != ADDR_EXPR)
8950 return false;
8952 exp = get_base_address (TREE_OPERAND (exp, 0));
8953 if (!exp)
8954 return false;
8956 /* Make sure we call decl_readonly_section only for trees it
8957 can handle (since it returns true for everything it doesn't
8958 understand). */
8959 if (TREE_CODE (exp) == STRING_CST
8960 || TREE_CODE (exp) == CONSTRUCTOR
8961 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8962 return decl_readonly_section (exp, 0);
8963 else
8964 return false;
8967 /* Simplify a call to the strstr builtin.
8969 Return 0 if no simplification was possible, otherwise return the
8970 simplified form of the call as a tree.
8972 The simplified form may be a constant or other expression which
8973 computes the same value, but in a more efficient manner (including
8974 calls to other builtin functions).
8976 The call may contain arguments which need to be evaluated, but
8977 which are not useful to determine the result of the call. In
8978 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8979 COMPOUND_EXPR will be an argument which must be evaluated.
8980 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8981 COMPOUND_EXPR in the chain will contain the tree for the simplified
8982 form of the builtin function call. */
8984 static tree
8985 fold_builtin_strstr (tree arglist, tree type)
8987 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8988 return 0;
8989 else
8991 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8992 tree fn;
8993 const char *p1, *p2;
8995 p2 = c_getstr (s2);
8996 if (p2 == NULL)
8997 return 0;
8999 p1 = c_getstr (s1);
9000 if (p1 != NULL)
9002 const char *r = strstr (p1, p2);
9003 tree tem;
9005 if (r == NULL)
9006 return build_int_cst (TREE_TYPE (s1), 0);
9008 /* Return an offset into the constant string argument. */
9009 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9010 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9011 return fold_convert (type, tem);
9014 /* The argument is const char *, and the result is char *, so we need
9015 a type conversion here to avoid a warning. */
9016 if (p2[0] == '\0')
9017 return fold_convert (type, s1);
9019 if (p2[1] != '\0')
9020 return 0;
9022 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9023 if (!fn)
9024 return 0;
9026 /* New argument list transforming strstr(s1, s2) to
9027 strchr(s1, s2[0]). */
9028 arglist = build_tree_list (NULL_TREE,
9029 build_int_cst (NULL_TREE, p2[0]));
9030 arglist = tree_cons (NULL_TREE, s1, arglist);
9031 return build_function_call_expr (fn, arglist);
9035 /* Simplify a call to the strchr builtin.
9037 Return 0 if no simplification was possible, otherwise return the
9038 simplified form of the call as a tree.
9040 The simplified form may be a constant or other expression which
9041 computes the same value, but in a more efficient manner (including
9042 calls to other builtin functions).
9044 The call may contain arguments which need to be evaluated, but
9045 which are not useful to determine the result of the call. In
9046 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9047 COMPOUND_EXPR will be an argument which must be evaluated.
9048 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9049 COMPOUND_EXPR in the chain will contain the tree for the simplified
9050 form of the builtin function call. */
9052 static tree
9053 fold_builtin_strchr (tree arglist, tree type)
9055 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9056 return 0;
9057 else
9059 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9060 const char *p1;
9062 if (TREE_CODE (s2) != INTEGER_CST)
9063 return 0;
9065 p1 = c_getstr (s1);
9066 if (p1 != NULL)
9068 char c;
9069 const char *r;
9070 tree tem;
9072 if (target_char_cast (s2, &c))
9073 return 0;
9075 r = strchr (p1, c);
9077 if (r == NULL)
9078 return build_int_cst (TREE_TYPE (s1), 0);
9080 /* Return an offset into the constant string argument. */
9081 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9082 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9083 return fold_convert (type, tem);
9085 return 0;
9089 /* Simplify a call to the strrchr builtin.
9091 Return 0 if no simplification was possible, otherwise return the
9092 simplified form of the call as a tree.
9094 The simplified form may be a constant or other expression which
9095 computes the same value, but in a more efficient manner (including
9096 calls to other builtin functions).
9098 The call may contain arguments which need to be evaluated, but
9099 which are not useful to determine the result of the call. In
9100 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9101 COMPOUND_EXPR will be an argument which must be evaluated.
9102 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9103 COMPOUND_EXPR in the chain will contain the tree for the simplified
9104 form of the builtin function call. */
9106 static tree
9107 fold_builtin_strrchr (tree arglist, tree type)
9109 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9110 return 0;
9111 else
9113 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9114 tree fn;
9115 const char *p1;
9117 if (TREE_CODE (s2) != INTEGER_CST)
9118 return 0;
9120 p1 = c_getstr (s1);
9121 if (p1 != NULL)
9123 char c;
9124 const char *r;
9125 tree tem;
9127 if (target_char_cast (s2, &c))
9128 return 0;
9130 r = strrchr (p1, c);
9132 if (r == NULL)
9133 return build_int_cst (TREE_TYPE (s1), 0);
9135 /* Return an offset into the constant string argument. */
9136 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9137 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9138 return fold_convert (type, tem);
9141 if (! integer_zerop (s2))
9142 return 0;
9144 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9145 if (!fn)
9146 return 0;
9148 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9149 return build_function_call_expr (fn, arglist);
9153 /* Simplify a call to the strpbrk builtin.
9155 Return 0 if no simplification was possible, otherwise return the
9156 simplified form of the call as a tree.
9158 The simplified form may be a constant or other expression which
9159 computes the same value, but in a more efficient manner (including
9160 calls to other builtin functions).
9162 The call may contain arguments which need to be evaluated, but
9163 which are not useful to determine the result of the call. In
9164 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9165 COMPOUND_EXPR will be an argument which must be evaluated.
9166 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9167 COMPOUND_EXPR in the chain will contain the tree for the simplified
9168 form of the builtin function call. */
9170 static tree
9171 fold_builtin_strpbrk (tree arglist, tree type)
9173 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9174 return 0;
9175 else
9177 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9178 tree fn;
9179 const char *p1, *p2;
9181 p2 = c_getstr (s2);
9182 if (p2 == NULL)
9183 return 0;
9185 p1 = c_getstr (s1);
9186 if (p1 != NULL)
9188 const char *r = strpbrk (p1, p2);
9189 tree tem;
9191 if (r == NULL)
9192 return build_int_cst (TREE_TYPE (s1), 0);
9194 /* Return an offset into the constant string argument. */
9195 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9196 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9197 return fold_convert (type, tem);
9200 if (p2[0] == '\0')
9201 /* strpbrk(x, "") == NULL.
9202 Evaluate and ignore s1 in case it had side-effects. */
9203 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9205 if (p2[1] != '\0')
9206 return 0; /* Really call strpbrk. */
9208 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9209 if (!fn)
9210 return 0;
9212 /* New argument list transforming strpbrk(s1, s2) to
9213 strchr(s1, s2[0]). */
9214 arglist = build_tree_list (NULL_TREE,
9215 build_int_cst (NULL_TREE, p2[0]));
9216 arglist = tree_cons (NULL_TREE, s1, arglist);
9217 return build_function_call_expr (fn, arglist);
9221 /* Simplify a call to the strcat builtin.
9223 Return 0 if no simplification was possible, otherwise return the
9224 simplified form of the call as a tree.
9226 The simplified form may be a constant or other expression which
9227 computes the same value, but in a more efficient manner (including
9228 calls to other builtin functions).
9230 The call may contain arguments which need to be evaluated, but
9231 which are not useful to determine the result of the call. In
9232 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9233 COMPOUND_EXPR will be an argument which must be evaluated.
9234 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9235 COMPOUND_EXPR in the chain will contain the tree for the simplified
9236 form of the builtin function call. */
9238 static tree
9239 fold_builtin_strcat (tree arglist)
9241 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9242 return 0;
9243 else
9245 tree dst = TREE_VALUE (arglist),
9246 src = TREE_VALUE (TREE_CHAIN (arglist));
9247 const char *p = c_getstr (src);
9249 /* If the string length is zero, return the dst parameter. */
9250 if (p && *p == '\0')
9251 return dst;
9253 return 0;
9257 /* Simplify a call to the strncat builtin.
9259 Return 0 if no simplification was possible, otherwise return the
9260 simplified form of the call as a tree.
9262 The simplified form may be a constant or other expression which
9263 computes the same value, but in a more efficient manner (including
9264 calls to other builtin functions).
9266 The call may contain arguments which need to be evaluated, but
9267 which are not useful to determine the result of the call. In
9268 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9269 COMPOUND_EXPR will be an argument which must be evaluated.
9270 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9271 COMPOUND_EXPR in the chain will contain the tree for the simplified
9272 form of the builtin function call. */
9274 static tree
9275 fold_builtin_strncat (tree arglist)
9277 if (!validate_arglist (arglist,
9278 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9279 return 0;
9280 else
9282 tree dst = TREE_VALUE (arglist);
9283 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9284 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9285 const char *p = c_getstr (src);
9287 /* If the requested length is zero, or the src parameter string
9288 length is zero, return the dst parameter. */
9289 if (integer_zerop (len) || (p && *p == '\0'))
9290 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9292 /* If the requested len is greater than or equal to the string
9293 length, call strcat. */
9294 if (TREE_CODE (len) == INTEGER_CST && p
9295 && compare_tree_int (len, strlen (p)) >= 0)
9297 tree newarglist
9298 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9299 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9301 /* If the replacement _DECL isn't initialized, don't do the
9302 transformation. */
9303 if (!fn)
9304 return 0;
9306 return build_function_call_expr (fn, newarglist);
9308 return 0;
9312 /* Simplify a call to the strspn builtin.
9314 Return 0 if no simplification was possible, otherwise return the
9315 simplified form of the call as a tree.
9317 The simplified form may be a constant or other expression which
9318 computes the same value, but in a more efficient manner (including
9319 calls to other builtin functions).
9321 The call may contain arguments which need to be evaluated, but
9322 which are not useful to determine the result of the call. In
9323 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9324 COMPOUND_EXPR will be an argument which must be evaluated.
9325 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9326 COMPOUND_EXPR in the chain will contain the tree for the simplified
9327 form of the builtin function call. */
9329 static tree
9330 fold_builtin_strspn (tree arglist)
9332 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9333 return 0;
9334 else
9336 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9337 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9339 /* If both arguments are constants, evaluate at compile-time. */
9340 if (p1 && p2)
9342 const size_t r = strspn (p1, p2);
9343 return size_int (r);
9346 /* If either argument is "", return 0. */
9347 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9348 /* Evaluate and ignore both arguments in case either one has
9349 side-effects. */
9350 return omit_two_operands (integer_type_node, integer_zero_node,
9351 s1, s2);
9352 return 0;
9356 /* Simplify a call to the strcspn builtin.
9358 Return 0 if no simplification was possible, otherwise return the
9359 simplified form of the call as a tree.
9361 The simplified form may be a constant or other expression which
9362 computes the same value, but in a more efficient manner (including
9363 calls to other builtin functions).
9365 The call may contain arguments which need to be evaluated, but
9366 which are not useful to determine the result of the call. In
9367 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9368 COMPOUND_EXPR will be an argument which must be evaluated.
9369 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9370 COMPOUND_EXPR in the chain will contain the tree for the simplified
9371 form of the builtin function call. */
9373 static tree
9374 fold_builtin_strcspn (tree arglist)
9376 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9377 return 0;
9378 else
9380 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9381 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9383 /* If both arguments are constants, evaluate at compile-time. */
9384 if (p1 && p2)
9386 const size_t r = strcspn (p1, p2);
9387 return size_int (r);
9390 /* If the first argument is "", return 0. */
9391 if (p1 && *p1 == '\0')
9393 /* Evaluate and ignore argument s2 in case it has
9394 side-effects. */
9395 return omit_one_operand (integer_type_node,
9396 integer_zero_node, s2);
9399 /* If the second argument is "", return __builtin_strlen(s1). */
9400 if (p2 && *p2 == '\0')
9402 tree newarglist = build_tree_list (NULL_TREE, s1),
9403 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9405 /* If the replacement _DECL isn't initialized, don't do the
9406 transformation. */
9407 if (!fn)
9408 return 0;
9410 return build_function_call_expr (fn, newarglist);
9412 return 0;
9416 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9417 by the builtin will be ignored. UNLOCKED is true is true if this
9418 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9419 the known length of the string. Return NULL_TREE if no simplification
9420 was possible. */
9422 tree
9423 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9425 tree fn;
9426 /* If we're using an unlocked function, assume the other unlocked
9427 functions exist explicitly. */
9428 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9429 : implicit_built_in_decls[BUILT_IN_FPUTC];
9430 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9431 : implicit_built_in_decls[BUILT_IN_FWRITE];
9433 /* If the return value is used, don't do the transformation. */
9434 if (!ignore)
9435 return 0;
9437 /* Verify the arguments in the original call. */
9438 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9439 return 0;
9441 if (! len)
9442 len = c_strlen (TREE_VALUE (arglist), 0);
9444 /* Get the length of the string passed to fputs. If the length
9445 can't be determined, punt. */
9446 if (!len
9447 || TREE_CODE (len) != INTEGER_CST)
9448 return 0;
9450 switch (compare_tree_int (len, 1))
9452 case -1: /* length is 0, delete the call entirely . */
9453 return omit_one_operand (integer_type_node, integer_zero_node,
9454 TREE_VALUE (TREE_CHAIN (arglist)));
9456 case 0: /* length is 1, call fputc. */
9458 const char *p = c_getstr (TREE_VALUE (arglist));
9460 if (p != NULL)
9462 /* New argument list transforming fputs(string, stream) to
9463 fputc(string[0], stream). */
9464 arglist = build_tree_list (NULL_TREE,
9465 TREE_VALUE (TREE_CHAIN (arglist)));
9466 arglist = tree_cons (NULL_TREE,
9467 build_int_cst (NULL_TREE, p[0]),
9468 arglist);
9469 fn = fn_fputc;
9470 break;
9473 /* FALLTHROUGH */
9474 case 1: /* length is greater than 1, call fwrite. */
9476 tree string_arg;
9478 /* If optimizing for size keep fputs. */
9479 if (optimize_size)
9480 return 0;
9481 string_arg = TREE_VALUE (arglist);
9482 /* New argument list transforming fputs(string, stream) to
9483 fwrite(string, 1, len, stream). */
9484 arglist = build_tree_list (NULL_TREE,
9485 TREE_VALUE (TREE_CHAIN (arglist)));
9486 arglist = tree_cons (NULL_TREE, len, arglist);
9487 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9488 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9489 fn = fn_fwrite;
9490 break;
9492 default:
9493 gcc_unreachable ();
9496 /* If the replacement _DECL isn't initialized, don't do the
9497 transformation. */
9498 if (!fn)
9499 return 0;
9501 /* These optimizations are only performed when the result is ignored,
9502 hence there's no need to cast the result to integer_type_node. */
9503 return build_function_call_expr (fn, arglist);
9506 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9507 produced. False otherwise. This is done so that we don't output the error
9508 or warning twice or three times. */
9509 bool
9510 fold_builtin_next_arg (tree arglist)
9512 tree fntype = TREE_TYPE (current_function_decl);
9514 if (TYPE_ARG_TYPES (fntype) == 0
9515 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9516 == void_type_node))
9518 error ("%<va_start%> used in function with fixed args");
9519 return true;
9521 else if (!arglist)
9523 /* Evidently an out of date version of <stdarg.h>; can't validate
9524 va_start's second argument, but can still work as intended. */
9525 warning (0, "%<__builtin_next_arg%> called without an argument");
9526 return true;
9528 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9529 when we checked the arguments and if needed issued a warning. */
9530 else if (!TREE_CHAIN (arglist)
9531 || !integer_zerop (TREE_VALUE (arglist))
9532 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9533 || TREE_CHAIN (TREE_CHAIN (arglist)))
9535 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9536 tree arg = TREE_VALUE (arglist);
9538 if (TREE_CHAIN (arglist))
9540 error ("%<va_start%> used with too many arguments");
9541 return true;
9544 /* Strip off all nops for the sake of the comparison. This
9545 is not quite the same as STRIP_NOPS. It does more.
9546 We must also strip off INDIRECT_EXPR for C++ reference
9547 parameters. */
9548 while (TREE_CODE (arg) == NOP_EXPR
9549 || TREE_CODE (arg) == CONVERT_EXPR
9550 || TREE_CODE (arg) == NON_LVALUE_EXPR
9551 || TREE_CODE (arg) == INDIRECT_REF)
9552 arg = TREE_OPERAND (arg, 0);
9553 if (arg != last_parm)
9555 /* FIXME: Sometimes with the tree optimizers we can get the
9556 not the last argument even though the user used the last
9557 argument. We just warn and set the arg to be the last
9558 argument so that we will get wrong-code because of
9559 it. */
9560 warning (0, "second parameter of %<va_start%> not last named argument");
9562 /* We want to verify the second parameter just once before the tree
9563 optimizers are run and then avoid keeping it in the tree,
9564 as otherwise we could warn even for correct code like:
9565 void foo (int i, ...)
9566 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9567 TREE_VALUE (arglist) = integer_zero_node;
9568 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9570 return false;
9574 /* Simplify a call to the sprintf builtin.
9576 Return 0 if no simplification was possible, otherwise return the
9577 simplified form of the call as a tree. If IGNORED is true, it means that
9578 the caller does not use the returned value of the function. */
9580 static tree
9581 fold_builtin_sprintf (tree arglist, int ignored)
9583 tree call, retval, dest, fmt;
9584 const char *fmt_str = NULL;
9586 /* Verify the required arguments in the original call. We deal with two
9587 types of sprintf() calls: 'sprintf (str, fmt)' and
9588 'sprintf (dest, "%s", orig)'. */
9589 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9590 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9591 VOID_TYPE))
9592 return NULL_TREE;
9594 /* Get the destination string and the format specifier. */
9595 dest = TREE_VALUE (arglist);
9596 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9598 /* Check whether the format is a literal string constant. */
9599 fmt_str = c_getstr (fmt);
9600 if (fmt_str == NULL)
9601 return NULL_TREE;
9603 call = NULL_TREE;
9604 retval = NULL_TREE;
9606 if (!init_target_chars())
9607 return 0;
9609 /* If the format doesn't contain % args or %%, use strcpy. */
9610 if (strchr (fmt_str, target_percent) == NULL)
9612 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9614 if (!fn)
9615 return NULL_TREE;
9617 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9618 'format' is known to contain no % formats. */
9619 arglist = build_tree_list (NULL_TREE, fmt);
9620 arglist = tree_cons (NULL_TREE, dest, arglist);
9621 call = build_function_call_expr (fn, arglist);
9622 if (!ignored)
9623 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9626 /* If the format is "%s", use strcpy if the result isn't used. */
9627 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9629 tree fn, orig;
9630 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9632 if (!fn)
9633 return NULL_TREE;
9635 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9636 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9637 arglist = build_tree_list (NULL_TREE, orig);
9638 arglist = tree_cons (NULL_TREE, dest, arglist);
9639 if (!ignored)
9641 retval = c_strlen (orig, 1);
9642 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9643 return NULL_TREE;
9645 call = build_function_call_expr (fn, arglist);
9648 if (call && retval)
9650 retval = convert
9651 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9652 retval);
9653 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9655 else
9656 return call;
9659 /* Expand a call to __builtin_object_size. */
9662 expand_builtin_object_size (tree exp)
9664 tree ost;
9665 int object_size_type;
9666 tree fndecl = get_callee_fndecl (exp);
9667 tree arglist = TREE_OPERAND (exp, 1);
9668 location_t locus = EXPR_LOCATION (exp);
9670 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9672 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9673 &locus, fndecl);
9674 expand_builtin_trap ();
9675 return const0_rtx;
9678 ost = TREE_VALUE (TREE_CHAIN (arglist));
9679 STRIP_NOPS (ost);
9681 if (TREE_CODE (ost) != INTEGER_CST
9682 || tree_int_cst_sgn (ost) < 0
9683 || compare_tree_int (ost, 3) > 0)
9685 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9686 &locus, fndecl);
9687 expand_builtin_trap ();
9688 return const0_rtx;
9691 object_size_type = tree_low_cst (ost, 0);
9693 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9696 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9697 FCODE is the BUILT_IN_* to use.
9698 Return 0 if we failed; the caller should emit a normal call,
9699 otherwise try to get the result in TARGET, if convenient (and in
9700 mode MODE if that's convenient). */
9702 static rtx
9703 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9704 enum built_in_function fcode)
9706 tree arglist = TREE_OPERAND (exp, 1);
9707 tree dest, src, len, size;
9709 if (!validate_arglist (arglist,
9710 POINTER_TYPE,
9711 fcode == BUILT_IN_MEMSET_CHK
9712 ? INTEGER_TYPE : POINTER_TYPE,
9713 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9714 return 0;
9716 dest = TREE_VALUE (arglist);
9717 src = TREE_VALUE (TREE_CHAIN (arglist));
9718 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9719 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9721 if (! host_integerp (size, 1))
9722 return 0;
9724 if (host_integerp (len, 1) || integer_all_onesp (size))
9726 tree fn;
9728 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9730 location_t locus = EXPR_LOCATION (exp);
9731 warning (0, "%Hcall to %D will always overflow destination buffer",
9732 &locus, get_callee_fndecl (exp));
9733 return 0;
9736 arglist = build_tree_list (NULL_TREE, len);
9737 arglist = tree_cons (NULL_TREE, src, arglist);
9738 arglist = tree_cons (NULL_TREE, dest, arglist);
9740 fn = NULL_TREE;
9741 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9742 mem{cpy,pcpy,move,set} is available. */
9743 switch (fcode)
9745 case BUILT_IN_MEMCPY_CHK:
9746 fn = built_in_decls[BUILT_IN_MEMCPY];
9747 break;
9748 case BUILT_IN_MEMPCPY_CHK:
9749 fn = built_in_decls[BUILT_IN_MEMPCPY];
9750 break;
9751 case BUILT_IN_MEMMOVE_CHK:
9752 fn = built_in_decls[BUILT_IN_MEMMOVE];
9753 break;
9754 case BUILT_IN_MEMSET_CHK:
9755 fn = built_in_decls[BUILT_IN_MEMSET];
9756 break;
9757 default:
9758 break;
9761 if (! fn)
9762 return 0;
9764 fn = build_function_call_expr (fn, arglist);
9765 if (TREE_CODE (fn) == CALL_EXPR)
9766 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9767 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9769 else if (fcode == BUILT_IN_MEMSET_CHK)
9770 return 0;
9771 else
9773 unsigned int dest_align
9774 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9776 /* If DEST is not a pointer type, call the normal function. */
9777 if (dest_align == 0)
9778 return 0;
9780 /* If SRC and DEST are the same (and not volatile), do nothing. */
9781 if (operand_equal_p (src, dest, 0))
9783 tree expr;
9785 if (fcode != BUILT_IN_MEMPCPY_CHK)
9787 /* Evaluate and ignore LEN in case it has side-effects. */
9788 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9789 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9792 len = fold_convert (TREE_TYPE (dest), len);
9793 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9794 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9797 /* __memmove_chk special case. */
9798 if (fcode == BUILT_IN_MEMMOVE_CHK)
9800 unsigned int src_align
9801 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9803 if (src_align == 0)
9804 return 0;
9806 /* If src is categorized for a readonly section we can use
9807 normal __memcpy_chk. */
9808 if (readonly_data_expr (src))
9810 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9811 if (!fn)
9812 return 0;
9813 fn = build_function_call_expr (fn, arglist);
9814 if (TREE_CODE (fn) == CALL_EXPR)
9815 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9816 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9819 return 0;
9823 /* Emit warning if a buffer overflow is detected at compile time. */
9825 static void
9826 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9828 int arg_mask, is_strlen = 0;
9829 tree arglist = TREE_OPERAND (exp, 1), a;
9830 tree len, size;
9831 location_t locus;
9833 switch (fcode)
9835 case BUILT_IN_STRCPY_CHK:
9836 case BUILT_IN_STPCPY_CHK:
9837 /* For __strcat_chk the warning will be emitted only if overflowing
9838 by at least strlen (dest) + 1 bytes. */
9839 case BUILT_IN_STRCAT_CHK:
9840 arg_mask = 6;
9841 is_strlen = 1;
9842 break;
9843 case BUILT_IN_STRNCPY_CHK:
9844 arg_mask = 12;
9845 break;
9846 case BUILT_IN_SNPRINTF_CHK:
9847 case BUILT_IN_VSNPRINTF_CHK:
9848 arg_mask = 10;
9849 break;
9850 default:
9851 gcc_unreachable ();
9854 len = NULL_TREE;
9855 size = NULL_TREE;
9856 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9857 if (arg_mask & 1)
9859 if (len)
9860 size = a;
9861 else
9862 len = a;
9865 if (!len || !size)
9866 return;
9868 len = TREE_VALUE (len);
9869 size = TREE_VALUE (size);
9871 if (! host_integerp (size, 1) || integer_all_onesp (size))
9872 return;
9874 if (is_strlen)
9876 len = c_strlen (len, 1);
9877 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9878 return;
9880 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9881 return;
9883 locus = EXPR_LOCATION (exp);
9884 warning (0, "%Hcall to %D will always overflow destination buffer",
9885 &locus, get_callee_fndecl (exp));
9888 /* Emit warning if a buffer overflow is detected at compile time
9889 in __sprintf_chk/__vsprintf_chk calls. */
9891 static void
9892 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9894 tree arglist = TREE_OPERAND (exp, 1);
9895 tree dest, size, len, fmt, flag;
9896 const char *fmt_str;
9898 /* Verify the required arguments in the original call. */
9899 if (! arglist)
9900 return;
9901 dest = TREE_VALUE (arglist);
9902 arglist = TREE_CHAIN (arglist);
9903 if (! arglist)
9904 return;
9905 flag = TREE_VALUE (arglist);
9906 arglist = TREE_CHAIN (arglist);
9907 if (! arglist)
9908 return;
9909 size = TREE_VALUE (arglist);
9910 arglist = TREE_CHAIN (arglist);
9911 if (! arglist)
9912 return;
9913 fmt = TREE_VALUE (arglist);
9914 arglist = TREE_CHAIN (arglist);
9916 if (! host_integerp (size, 1) || integer_all_onesp (size))
9917 return;
9919 /* Check whether the format is a literal string constant. */
9920 fmt_str = c_getstr (fmt);
9921 if (fmt_str == NULL)
9922 return;
9924 if (!init_target_chars())
9925 return;
9927 /* If the format doesn't contain % args or %%, we know its size. */
9928 if (strchr (fmt_str, target_percent) == 0)
9929 len = build_int_cstu (size_type_node, strlen (fmt_str));
9930 /* If the format is "%s" and first ... argument is a string literal,
9931 we know it too. */
9932 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9934 tree arg;
9936 if (! arglist)
9937 return;
9938 arg = TREE_VALUE (arglist);
9939 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9940 return;
9942 len = c_strlen (arg, 1);
9943 if (!len || ! host_integerp (len, 1))
9944 return;
9946 else
9947 return;
9949 if (! tree_int_cst_lt (len, size))
9951 location_t locus = EXPR_LOCATION (exp);
9952 warning (0, "%Hcall to %D will always overflow destination buffer",
9953 &locus, get_callee_fndecl (exp));
9957 /* Fold a call to __builtin_object_size, if possible. */
9959 tree
9960 fold_builtin_object_size (tree arglist)
9962 tree ptr, ost, ret = 0;
9963 int object_size_type;
9965 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9966 return 0;
9968 ptr = TREE_VALUE (arglist);
9969 ost = TREE_VALUE (TREE_CHAIN (arglist));
9970 STRIP_NOPS (ost);
9972 if (TREE_CODE (ost) != INTEGER_CST
9973 || tree_int_cst_sgn (ost) < 0
9974 || compare_tree_int (ost, 3) > 0)
9975 return 0;
9977 object_size_type = tree_low_cst (ost, 0);
9979 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9980 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9981 and (size_t) 0 for types 2 and 3. */
9982 if (TREE_SIDE_EFFECTS (ptr))
9983 return fold_convert (size_type_node,
9984 object_size_type < 2
9985 ? integer_minus_one_node : integer_zero_node);
9987 if (TREE_CODE (ptr) == ADDR_EXPR)
9988 ret = build_int_cstu (size_type_node,
9989 compute_builtin_object_size (ptr, object_size_type));
9991 else if (TREE_CODE (ptr) == SSA_NAME)
9993 unsigned HOST_WIDE_INT bytes;
9995 /* If object size is not known yet, delay folding until
9996 later. Maybe subsequent passes will help determining
9997 it. */
9998 bytes = compute_builtin_object_size (ptr, object_size_type);
9999 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10000 ? -1 : 0))
10001 ret = build_int_cstu (size_type_node, bytes);
10004 if (ret)
10006 ret = force_fit_type (ret, -1, false, false);
10007 if (TREE_CONSTANT_OVERFLOW (ret))
10008 ret = 0;
10011 return ret;
10014 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10015 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10016 code of the builtin. If MAXLEN is not NULL, it is maximum length
10017 passed as third argument. */
10019 tree
10020 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10021 enum built_in_function fcode)
10023 tree dest, src, len, size, fn;
10025 if (!validate_arglist (arglist,
10026 POINTER_TYPE,
10027 fcode == BUILT_IN_MEMSET_CHK
10028 ? INTEGER_TYPE : POINTER_TYPE,
10029 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10030 return 0;
10032 dest = TREE_VALUE (arglist);
10033 /* Actually val for __memset_chk, but it doesn't matter. */
10034 src = TREE_VALUE (TREE_CHAIN (arglist));
10035 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10036 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10038 /* If SRC and DEST are the same (and not volatile), return DEST
10039 (resp. DEST+LEN for __mempcpy_chk). */
10040 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10042 if (fcode != BUILT_IN_MEMPCPY_CHK)
10043 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10044 else
10046 tree temp = fold_convert (TREE_TYPE (dest), len);
10047 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10048 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10052 if (! host_integerp (size, 1))
10053 return 0;
10055 if (! integer_all_onesp (size))
10057 if (! host_integerp (len, 1))
10059 /* If LEN is not constant, try MAXLEN too.
10060 For MAXLEN only allow optimizing into non-_ocs function
10061 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10062 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10064 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10066 /* (void) __mempcpy_chk () can be optimized into
10067 (void) __memcpy_chk (). */
10068 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10069 if (!fn)
10070 return 0;
10072 return build_function_call_expr (fn, arglist);
10074 return 0;
10077 else
10078 maxlen = len;
10080 if (tree_int_cst_lt (size, maxlen))
10081 return 0;
10084 arglist = build_tree_list (NULL_TREE, len);
10085 arglist = tree_cons (NULL_TREE, src, arglist);
10086 arglist = tree_cons (NULL_TREE, dest, arglist);
10088 fn = NULL_TREE;
10089 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10090 mem{cpy,pcpy,move,set} is available. */
10091 switch (fcode)
10093 case BUILT_IN_MEMCPY_CHK:
10094 fn = built_in_decls[BUILT_IN_MEMCPY];
10095 break;
10096 case BUILT_IN_MEMPCPY_CHK:
10097 fn = built_in_decls[BUILT_IN_MEMPCPY];
10098 break;
10099 case BUILT_IN_MEMMOVE_CHK:
10100 fn = built_in_decls[BUILT_IN_MEMMOVE];
10101 break;
10102 case BUILT_IN_MEMSET_CHK:
10103 fn = built_in_decls[BUILT_IN_MEMSET];
10104 break;
10105 default:
10106 break;
10109 if (!fn)
10110 return 0;
10112 return build_function_call_expr (fn, arglist);
10115 /* Fold a call to the __st[rp]cpy_chk builtin.
10116 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10117 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10118 strings passed as second argument. */
10120 tree
10121 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10122 enum built_in_function fcode)
10124 tree dest, src, size, len, fn;
10126 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10127 VOID_TYPE))
10128 return 0;
10130 dest = TREE_VALUE (arglist);
10131 src = TREE_VALUE (TREE_CHAIN (arglist));
10132 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10134 /* If SRC and DEST are the same (and not volatile), return DEST. */
10135 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10136 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10138 if (! host_integerp (size, 1))
10139 return 0;
10141 if (! integer_all_onesp (size))
10143 len = c_strlen (src, 1);
10144 if (! len || ! host_integerp (len, 1))
10146 /* If LEN is not constant, try MAXLEN too.
10147 For MAXLEN only allow optimizing into non-_ocs function
10148 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10149 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10151 if (fcode == BUILT_IN_STPCPY_CHK)
10153 if (! ignore)
10154 return 0;
10156 /* If return value of __stpcpy_chk is ignored,
10157 optimize into __strcpy_chk. */
10158 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10159 if (!fn)
10160 return 0;
10162 return build_function_call_expr (fn, arglist);
10165 if (! len || TREE_SIDE_EFFECTS (len))
10166 return 0;
10168 /* If c_strlen returned something, but not a constant,
10169 transform __strcpy_chk into __memcpy_chk. */
10170 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10171 if (!fn)
10172 return 0;
10174 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10175 arglist = build_tree_list (NULL_TREE, size);
10176 arglist = tree_cons (NULL_TREE, len, arglist);
10177 arglist = tree_cons (NULL_TREE, src, arglist);
10178 arglist = tree_cons (NULL_TREE, dest, arglist);
10179 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10180 build_function_call_expr (fn, arglist));
10183 else
10184 maxlen = len;
10186 if (! tree_int_cst_lt (maxlen, size))
10187 return 0;
10190 arglist = build_tree_list (NULL_TREE, src);
10191 arglist = tree_cons (NULL_TREE, dest, arglist);
10193 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10194 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10195 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10196 if (!fn)
10197 return 0;
10199 return build_function_call_expr (fn, arglist);
10202 /* Fold a call to the __strncpy_chk builtin.
10203 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10205 tree
10206 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10208 tree dest, src, size, len, fn;
10210 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10211 INTEGER_TYPE, VOID_TYPE))
10212 return 0;
10214 dest = TREE_VALUE (arglist);
10215 src = TREE_VALUE (TREE_CHAIN (arglist));
10216 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10217 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10219 if (! host_integerp (size, 1))
10220 return 0;
10222 if (! integer_all_onesp (size))
10224 if (! host_integerp (len, 1))
10226 /* If LEN is not constant, try MAXLEN too.
10227 For MAXLEN only allow optimizing into non-_ocs function
10228 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10229 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10230 return 0;
10232 else
10233 maxlen = len;
10235 if (tree_int_cst_lt (size, maxlen))
10236 return 0;
10239 arglist = build_tree_list (NULL_TREE, len);
10240 arglist = tree_cons (NULL_TREE, src, arglist);
10241 arglist = tree_cons (NULL_TREE, dest, arglist);
10243 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10244 fn = built_in_decls[BUILT_IN_STRNCPY];
10245 if (!fn)
10246 return 0;
10248 return build_function_call_expr (fn, arglist);
10251 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10253 static tree
10254 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10256 tree dest, src, size, fn;
10257 const char *p;
10259 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10260 VOID_TYPE))
10261 return 0;
10263 dest = TREE_VALUE (arglist);
10264 src = TREE_VALUE (TREE_CHAIN (arglist));
10265 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10267 p = c_getstr (src);
10268 /* If the SRC parameter is "", return DEST. */
10269 if (p && *p == '\0')
10270 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10272 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10273 return 0;
10275 arglist = build_tree_list (NULL_TREE, src);
10276 arglist = tree_cons (NULL_TREE, dest, arglist);
10278 /* If __builtin_strcat_chk is used, assume strcat is available. */
10279 fn = built_in_decls[BUILT_IN_STRCAT];
10280 if (!fn)
10281 return 0;
10283 return build_function_call_expr (fn, arglist);
10286 /* Fold a call to the __strncat_chk builtin EXP. */
10288 static tree
10289 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10291 tree dest, src, size, len, fn;
10292 const char *p;
10294 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10295 INTEGER_TYPE, VOID_TYPE))
10296 return 0;
10298 dest = TREE_VALUE (arglist);
10299 src = TREE_VALUE (TREE_CHAIN (arglist));
10300 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10301 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10303 p = c_getstr (src);
10304 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10305 if (p && *p == '\0')
10306 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10307 else if (integer_zerop (len))
10308 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10310 if (! host_integerp (size, 1))
10311 return 0;
10313 if (! integer_all_onesp (size))
10315 tree src_len = c_strlen (src, 1);
10316 if (src_len
10317 && host_integerp (src_len, 1)
10318 && host_integerp (len, 1)
10319 && ! tree_int_cst_lt (len, src_len))
10321 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10322 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10323 if (!fn)
10324 return 0;
10326 arglist = build_tree_list (NULL_TREE, size);
10327 arglist = tree_cons (NULL_TREE, src, arglist);
10328 arglist = tree_cons (NULL_TREE, dest, arglist);
10329 return build_function_call_expr (fn, arglist);
10331 return 0;
10334 arglist = build_tree_list (NULL_TREE, len);
10335 arglist = tree_cons (NULL_TREE, src, arglist);
10336 arglist = tree_cons (NULL_TREE, dest, arglist);
10338 /* If __builtin_strncat_chk is used, assume strncat is available. */
10339 fn = built_in_decls[BUILT_IN_STRNCAT];
10340 if (!fn)
10341 return 0;
10343 return build_function_call_expr (fn, arglist);
10346 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10347 a normal call should be emitted rather than expanding the function
10348 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10350 static tree
10351 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10353 tree dest, size, len, fn, fmt, flag;
10354 const char *fmt_str;
10356 /* Verify the required arguments in the original call. */
10357 if (! arglist)
10358 return 0;
10359 dest = TREE_VALUE (arglist);
10360 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10361 return 0;
10362 arglist = TREE_CHAIN (arglist);
10363 if (! arglist)
10364 return 0;
10365 flag = TREE_VALUE (arglist);
10366 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10367 return 0;
10368 arglist = TREE_CHAIN (arglist);
10369 if (! arglist)
10370 return 0;
10371 size = TREE_VALUE (arglist);
10372 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10373 return 0;
10374 arglist = TREE_CHAIN (arglist);
10375 if (! arglist)
10376 return 0;
10377 fmt = TREE_VALUE (arglist);
10378 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10379 return 0;
10380 arglist = TREE_CHAIN (arglist);
10382 if (! host_integerp (size, 1))
10383 return 0;
10385 len = NULL_TREE;
10387 if (!init_target_chars())
10388 return 0;
10390 /* Check whether the format is a literal string constant. */
10391 fmt_str = c_getstr (fmt);
10392 if (fmt_str != NULL)
10394 /* If the format doesn't contain % args or %%, we know the size. */
10395 if (strchr (fmt_str, target_percent) == 0)
10397 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10398 len = build_int_cstu (size_type_node, strlen (fmt_str));
10400 /* If the format is "%s" and first ... argument is a string literal,
10401 we know the size too. */
10402 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10404 tree arg;
10406 if (arglist && !TREE_CHAIN (arglist))
10408 arg = TREE_VALUE (arglist);
10409 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10411 len = c_strlen (arg, 1);
10412 if (! len || ! host_integerp (len, 1))
10413 len = NULL_TREE;
10419 if (! integer_all_onesp (size))
10421 if (! len || ! tree_int_cst_lt (len, size))
10422 return 0;
10425 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10426 or if format doesn't contain % chars or is "%s". */
10427 if (! integer_zerop (flag))
10429 if (fmt_str == NULL)
10430 return 0;
10431 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10432 return 0;
10435 arglist = tree_cons (NULL_TREE, fmt, arglist);
10436 arglist = tree_cons (NULL_TREE, dest, arglist);
10438 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10439 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10440 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10441 if (!fn)
10442 return 0;
10444 return build_function_call_expr (fn, arglist);
10447 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10448 a normal call should be emitted rather than expanding the function
10449 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10450 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10451 passed as second argument. */
10453 tree
10454 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10455 enum built_in_function fcode)
10457 tree dest, size, len, fn, fmt, flag;
10458 const char *fmt_str;
10460 /* Verify the required arguments in the original call. */
10461 if (! arglist)
10462 return 0;
10463 dest = TREE_VALUE (arglist);
10464 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10465 return 0;
10466 arglist = TREE_CHAIN (arglist);
10467 if (! arglist)
10468 return 0;
10469 len = TREE_VALUE (arglist);
10470 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10471 return 0;
10472 arglist = TREE_CHAIN (arglist);
10473 if (! arglist)
10474 return 0;
10475 flag = TREE_VALUE (arglist);
10476 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10477 return 0;
10478 arglist = TREE_CHAIN (arglist);
10479 if (! arglist)
10480 return 0;
10481 size = TREE_VALUE (arglist);
10482 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10483 return 0;
10484 arglist = TREE_CHAIN (arglist);
10485 if (! arglist)
10486 return 0;
10487 fmt = TREE_VALUE (arglist);
10488 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10489 return 0;
10490 arglist = TREE_CHAIN (arglist);
10492 if (! host_integerp (size, 1))
10493 return 0;
10495 if (! integer_all_onesp (size))
10497 if (! host_integerp (len, 1))
10499 /* If LEN is not constant, try MAXLEN too.
10500 For MAXLEN only allow optimizing into non-_ocs function
10501 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10502 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10503 return 0;
10505 else
10506 maxlen = len;
10508 if (tree_int_cst_lt (size, maxlen))
10509 return 0;
10512 if (!init_target_chars())
10513 return 0;
10515 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10516 or if format doesn't contain % chars or is "%s". */
10517 if (! integer_zerop (flag))
10519 fmt_str = c_getstr (fmt);
10520 if (fmt_str == NULL)
10521 return 0;
10522 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10523 return 0;
10526 arglist = tree_cons (NULL_TREE, fmt, arglist);
10527 arglist = tree_cons (NULL_TREE, len, arglist);
10528 arglist = tree_cons (NULL_TREE, dest, arglist);
10530 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10531 available. */
10532 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10533 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10534 if (!fn)
10535 return 0;
10537 return build_function_call_expr (fn, arglist);
10540 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10542 Return 0 if no simplification was possible, otherwise return the
10543 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10544 code of the function to be simplified. */
10546 static tree
10547 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10548 enum built_in_function fcode)
10550 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10551 const char *fmt_str = NULL;
10553 /* If the return value is used, don't do the transformation. */
10554 if (! ignore)
10555 return 0;
10557 /* Verify the required arguments in the original call. */
10558 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10560 tree flag;
10562 if (! arglist)
10563 return 0;
10564 flag = TREE_VALUE (arglist);
10565 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10566 || TREE_SIDE_EFFECTS (flag))
10567 return 0;
10568 arglist = TREE_CHAIN (arglist);
10571 if (! arglist)
10572 return 0;
10573 fmt = TREE_VALUE (arglist);
10574 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10575 return 0;
10576 arglist = TREE_CHAIN (arglist);
10578 /* Check whether the format is a literal string constant. */
10579 fmt_str = c_getstr (fmt);
10580 if (fmt_str == NULL)
10581 return NULL_TREE;
10583 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10585 /* If we're using an unlocked function, assume the other
10586 unlocked functions exist explicitly. */
10587 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10588 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10590 else
10592 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10593 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10596 if (!init_target_chars())
10597 return 0;
10599 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10601 const char *str;
10603 if (strcmp (fmt_str, target_percent_s) == 0)
10605 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10606 return 0;
10608 if (! arglist
10609 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10610 || TREE_CHAIN (arglist))
10611 return 0;
10613 str = c_getstr (TREE_VALUE (arglist));
10614 if (str == NULL)
10615 return 0;
10617 else
10619 /* The format specifier doesn't contain any '%' characters. */
10620 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10621 && arglist)
10622 return 0;
10623 str = fmt_str;
10626 /* If the string was "", printf does nothing. */
10627 if (str[0] == '\0')
10628 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10630 /* If the string has length of 1, call putchar. */
10631 if (str[1] == '\0')
10633 /* Given printf("c"), (where c is any one character,)
10634 convert "c"[0] to an int and pass that to the replacement
10635 function. */
10636 arg = build_int_cst (NULL_TREE, str[0]);
10637 arglist = build_tree_list (NULL_TREE, arg);
10638 fn = fn_putchar;
10640 else
10642 /* If the string was "string\n", call puts("string"). */
10643 size_t len = strlen (str);
10644 if ((unsigned char)str[len - 1] == target_newline)
10646 /* Create a NUL-terminated string that's one char shorter
10647 than the original, stripping off the trailing '\n'. */
10648 char *newstr = alloca (len);
10649 memcpy (newstr, str, len - 1);
10650 newstr[len - 1] = 0;
10652 arg = build_string_literal (len, newstr);
10653 arglist = build_tree_list (NULL_TREE, arg);
10654 fn = fn_puts;
10656 else
10657 /* We'd like to arrange to call fputs(string,stdout) here,
10658 but we need stdout and don't have a way to get it yet. */
10659 return 0;
10663 /* The other optimizations can be done only on the non-va_list variants. */
10664 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10665 return 0;
10667 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10668 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10670 if (! arglist
10671 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10672 || TREE_CHAIN (arglist))
10673 return 0;
10674 fn = fn_puts;
10677 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10678 else if (strcmp (fmt_str, target_percent_c) == 0)
10680 if (! arglist
10681 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10682 || TREE_CHAIN (arglist))
10683 return 0;
10684 fn = fn_putchar;
10687 if (!fn)
10688 return 0;
10690 call = build_function_call_expr (fn, arglist);
10691 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10694 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10696 Return 0 if no simplification was possible, otherwise return the
10697 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10698 code of the function to be simplified. */
10700 static tree
10701 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10702 enum built_in_function fcode)
10704 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10705 const char *fmt_str = NULL;
10707 /* If the return value is used, don't do the transformation. */
10708 if (! ignore)
10709 return 0;
10711 /* Verify the required arguments in the original call. */
10712 if (! arglist)
10713 return 0;
10714 fp = TREE_VALUE (arglist);
10715 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10716 return 0;
10717 arglist = TREE_CHAIN (arglist);
10719 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10721 tree flag;
10723 if (! arglist)
10724 return 0;
10725 flag = TREE_VALUE (arglist);
10726 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10727 || TREE_SIDE_EFFECTS (flag))
10728 return 0;
10729 arglist = TREE_CHAIN (arglist);
10732 if (! arglist)
10733 return 0;
10734 fmt = TREE_VALUE (arglist);
10735 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10736 return 0;
10737 arglist = TREE_CHAIN (arglist);
10739 /* Check whether the format is a literal string constant. */
10740 fmt_str = c_getstr (fmt);
10741 if (fmt_str == NULL)
10742 return NULL_TREE;
10744 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10746 /* If we're using an unlocked function, assume the other
10747 unlocked functions exist explicitly. */
10748 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10749 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10751 else
10753 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10754 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10757 if (!init_target_chars())
10758 return 0;
10760 /* If the format doesn't contain % args or %%, use strcpy. */
10761 if (strchr (fmt_str, target_percent) == NULL)
10763 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10764 && arglist)
10765 return 0;
10767 /* If the format specifier was "", fprintf does nothing. */
10768 if (fmt_str[0] == '\0')
10770 /* If FP has side-effects, just wait until gimplification is
10771 done. */
10772 if (TREE_SIDE_EFFECTS (fp))
10773 return 0;
10775 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10778 /* When "string" doesn't contain %, replace all cases of
10779 fprintf (fp, string) with fputs (string, fp). The fputs
10780 builtin will take care of special cases like length == 1. */
10781 arglist = build_tree_list (NULL_TREE, fp);
10782 arglist = tree_cons (NULL_TREE, fmt, arglist);
10783 fn = fn_fputs;
10786 /* The other optimizations can be done only on the non-va_list variants. */
10787 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10788 return 0;
10790 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10791 else if (strcmp (fmt_str, target_percent_s) == 0)
10793 if (! arglist
10794 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10795 || TREE_CHAIN (arglist))
10796 return 0;
10797 arg = TREE_VALUE (arglist);
10798 arglist = build_tree_list (NULL_TREE, fp);
10799 arglist = tree_cons (NULL_TREE, arg, arglist);
10800 fn = fn_fputs;
10803 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10804 else if (strcmp (fmt_str, target_percent_c) == 0)
10806 if (! arglist
10807 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10808 || TREE_CHAIN (arglist))
10809 return 0;
10810 arg = TREE_VALUE (arglist);
10811 arglist = build_tree_list (NULL_TREE, fp);
10812 arglist = tree_cons (NULL_TREE, arg, arglist);
10813 fn = fn_fputc;
10816 if (!fn)
10817 return 0;
10819 call = build_function_call_expr (fn, arglist);
10820 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10823 /* Initialize format string characters in the target charset. */
10825 static bool
10826 init_target_chars (void)
10828 static bool init;
10829 if (!init)
10831 target_newline = lang_hooks.to_target_charset ('\n');
10832 target_percent = lang_hooks.to_target_charset ('%');
10833 target_c = lang_hooks.to_target_charset ('c');
10834 target_s = lang_hooks.to_target_charset ('s');
10835 if (target_newline == 0 || target_percent == 0 || target_c == 0
10836 || target_s == 0)
10837 return false;
10839 target_percent_c[0] = target_percent;
10840 target_percent_c[1] = target_c;
10841 target_percent_c[2] = '\0';
10843 target_percent_s[0] = target_percent;
10844 target_percent_s[1] = target_s;
10845 target_percent_s[2] = '\0';
10847 target_percent_s_newline[0] = target_percent;
10848 target_percent_s_newline[1] = target_s;
10849 target_percent_s_newline[2] = target_newline;
10850 target_percent_s_newline[3] = '\0';
10852 init = true;
10854 return true;