2006-01-30 Marcin Dalecki <martin@dalecki.de>
[official-gcc.git] / gcc / builtins.c
blobbb113dc7f7b996318c90b83cde46441ab1294b9d
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 if (TREE_CODE (exp) == FUNCTION_DECL)
279 align = FUNCTION_BOUNDARY;
280 else if (DECL_P (exp))
281 align = DECL_ALIGN (exp);
282 #ifdef CONSTANT_ALIGNMENT
283 else if (CONSTANT_CLASS_P (exp))
284 align = CONSTANT_ALIGNMENT (exp, align);
285 #endif
286 return MIN (align, max_align);
288 default:
289 return align;
294 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
295 way, because it could contain a zero byte in the middle.
296 TREE_STRING_LENGTH is the size of the character array, not the string.
298 ONLY_VALUE should be nonzero if the result is not going to be emitted
299 into the instruction stream and zero if it is going to be expanded.
300 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
301 is returned, otherwise NULL, since
302 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
303 evaluate the side-effects.
305 The value returned is of type `ssizetype'.
307 Unfortunately, string_constant can't access the values of const char
308 arrays with initializers, so neither can we do so here. */
310 tree
311 c_strlen (tree src, int only_value)
313 tree offset_node;
314 HOST_WIDE_INT offset;
315 int max;
316 const char *ptr;
318 STRIP_NOPS (src);
319 if (TREE_CODE (src) == COND_EXPR
320 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
322 tree len1, len2;
324 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
325 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
326 if (tree_int_cst_equal (len1, len2))
327 return len1;
330 if (TREE_CODE (src) == COMPOUND_EXPR
331 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
332 return c_strlen (TREE_OPERAND (src, 1), only_value);
334 src = string_constant (src, &offset_node);
335 if (src == 0)
336 return 0;
338 max = TREE_STRING_LENGTH (src) - 1;
339 ptr = TREE_STRING_POINTER (src);
341 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
343 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
344 compute the offset to the following null if we don't know where to
345 start searching for it. */
346 int i;
348 for (i = 0; i < max; i++)
349 if (ptr[i] == 0)
350 return 0;
352 /* We don't know the starting offset, but we do know that the string
353 has no internal zero bytes. We can assume that the offset falls
354 within the bounds of the string; otherwise, the programmer deserves
355 what he gets. Subtract the offset from the length of the string,
356 and return that. This would perhaps not be valid if we were dealing
357 with named arrays in addition to literal string constants. */
359 return size_diffop (size_int (max), offset_node);
362 /* We have a known offset into the string. Start searching there for
363 a null character if we can represent it as a single HOST_WIDE_INT. */
364 if (offset_node == 0)
365 offset = 0;
366 else if (! host_integerp (offset_node, 0))
367 offset = -1;
368 else
369 offset = tree_low_cst (offset_node, 0);
371 /* If the offset is known to be out of bounds, warn, and call strlen at
372 runtime. */
373 if (offset < 0 || offset > max)
375 warning (0, "offset outside bounds of constant string");
376 return 0;
379 /* Use strlen to search for the first zero byte. Since any strings
380 constructed with build_string will have nulls appended, we win even
381 if we get handed something like (char[4])"abcd".
383 Since OFFSET is our starting index into the string, no further
384 calculation is needed. */
385 return ssize_int (strlen (ptr + offset));
388 /* Return a char pointer for a C string if it is a string constant
389 or sum of string constant and integer constant. */
391 static const char *
392 c_getstr (tree src)
394 tree offset_node;
396 src = string_constant (src, &offset_node);
397 if (src == 0)
398 return 0;
400 if (offset_node == 0)
401 return TREE_STRING_POINTER (src);
402 else if (!host_integerp (offset_node, 1)
403 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
404 return 0;
406 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
409 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
410 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
412 static rtx
413 c_readstr (const char *str, enum machine_mode mode)
415 HOST_WIDE_INT c[2];
416 HOST_WIDE_INT ch;
417 unsigned int i, j;
419 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
421 c[0] = 0;
422 c[1] = 0;
423 ch = 1;
424 for (i = 0; i < GET_MODE_SIZE (mode); i++)
426 j = i;
427 if (WORDS_BIG_ENDIAN)
428 j = GET_MODE_SIZE (mode) - i - 1;
429 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
430 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
431 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
432 j *= BITS_PER_UNIT;
433 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
435 if (ch)
436 ch = (unsigned char) str[i];
437 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
439 return immed_double_const (c[0], c[1], mode);
442 /* Cast a target constant CST to target CHAR and if that value fits into
443 host char type, return zero and put that value into variable pointed to by
444 P. */
446 static int
447 target_char_cast (tree cst, char *p)
449 unsigned HOST_WIDE_INT val, hostval;
451 if (!host_integerp (cst, 1)
452 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
453 return 1;
455 val = tree_low_cst (cst, 1);
456 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
457 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
459 hostval = val;
460 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
461 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
463 if (val != hostval)
464 return 1;
466 *p = hostval;
467 return 0;
470 /* Similar to save_expr, but assumes that arbitrary code is not executed
471 in between the multiple evaluations. In particular, we assume that a
472 non-addressable local variable will not be modified. */
474 static tree
475 builtin_save_expr (tree exp)
477 if (TREE_ADDRESSABLE (exp) == 0
478 && (TREE_CODE (exp) == PARM_DECL
479 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
480 return exp;
482 return save_expr (exp);
485 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
486 times to get the address of either a higher stack frame, or a return
487 address located within it (depending on FNDECL_CODE). */
489 static rtx
490 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
492 int i;
494 #ifdef INITIAL_FRAME_ADDRESS_RTX
495 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
496 #else
497 rtx tem;
499 /* For a zero count, we don't care what frame address we return, so frame
500 pointer elimination is OK, and using the soft frame pointer is OK.
501 For a non-zero count, we require a stable offset from the current frame
502 pointer to the previous one, so we must use the hard frame pointer, and
503 we must disable frame pointer elimination. */
504 if (count == 0)
505 tem = frame_pointer_rtx;
506 else
508 tem = hard_frame_pointer_rtx;
510 /* Tell reload not to eliminate the frame pointer. */
511 current_function_accesses_prior_frames = 1;
513 #endif
515 /* Some machines need special handling before we can access
516 arbitrary frames. For example, on the sparc, we must first flush
517 all register windows to the stack. */
518 #ifdef SETUP_FRAME_ADDRESSES
519 if (count > 0)
520 SETUP_FRAME_ADDRESSES ();
521 #endif
523 /* On the sparc, the return address is not in the frame, it is in a
524 register. There is no way to access it off of the current frame
525 pointer, but it can be accessed off the previous frame pointer by
526 reading the value from the register window save area. */
527 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
528 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
529 count--;
530 #endif
532 /* Scan back COUNT frames to the specified frame. */
533 for (i = 0; i < count; i++)
535 /* Assume the dynamic chain pointer is in the word that the
536 frame address points to, unless otherwise specified. */
537 #ifdef DYNAMIC_CHAIN_ADDRESS
538 tem = DYNAMIC_CHAIN_ADDRESS (tem);
539 #endif
540 tem = memory_address (Pmode, tem);
541 tem = gen_frame_mem (Pmode, tem);
542 tem = copy_to_reg (tem);
545 /* For __builtin_frame_address, return what we've got. */
546 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
547 return tem;
549 /* For __builtin_return_address, Get the return address from that
550 frame. */
551 #ifdef RETURN_ADDR_RTX
552 tem = RETURN_ADDR_RTX (count, tem);
553 #else
554 tem = memory_address (Pmode,
555 plus_constant (tem, GET_MODE_SIZE (Pmode)));
556 tem = gen_frame_mem (Pmode, tem);
557 #endif
558 return tem;
561 /* Alias set used for setjmp buffer. */
562 static HOST_WIDE_INT setjmp_alias_set = -1;
564 /* Construct the leading half of a __builtin_setjmp call. Control will
565 return to RECEIVER_LABEL. This is used directly by sjlj exception
566 handling code. */
568 void
569 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
571 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
572 rtx stack_save;
573 rtx mem;
575 if (setjmp_alias_set == -1)
576 setjmp_alias_set = new_alias_set ();
578 buf_addr = convert_memory_address (Pmode, buf_addr);
580 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
582 /* We store the frame pointer and the address of receiver_label in
583 the buffer and use the rest of it for the stack save area, which
584 is machine-dependent. */
586 mem = gen_rtx_MEM (Pmode, buf_addr);
587 set_mem_alias_set (mem, setjmp_alias_set);
588 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
590 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
591 set_mem_alias_set (mem, setjmp_alias_set);
593 emit_move_insn (validize_mem (mem),
594 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
596 stack_save = gen_rtx_MEM (sa_mode,
597 plus_constant (buf_addr,
598 2 * GET_MODE_SIZE (Pmode)));
599 set_mem_alias_set (stack_save, setjmp_alias_set);
600 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
602 /* If there is further processing to do, do it. */
603 #ifdef HAVE_builtin_setjmp_setup
604 if (HAVE_builtin_setjmp_setup)
605 emit_insn (gen_builtin_setjmp_setup (buf_addr));
606 #endif
608 /* Tell optimize_save_area_alloca that extra work is going to
609 need to go on during alloca. */
610 current_function_calls_setjmp = 1;
612 /* Set this so all the registers get saved in our frame; we need to be
613 able to copy the saved values for any registers from frames we unwind. */
614 current_function_has_nonlocal_label = 1;
617 /* Construct the trailing part of a __builtin_setjmp call.
618 This is used directly by sjlj exception handling code. */
620 void
621 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
623 /* Clobber the FP when we get here, so we have to make sure it's
624 marked as used by this function. */
625 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
627 /* Mark the static chain as clobbered here so life information
628 doesn't get messed up for it. */
629 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
631 /* Now put in the code to restore the frame pointer, and argument
632 pointer, if needed. */
633 #ifdef HAVE_nonlocal_goto
634 if (! HAVE_nonlocal_goto)
635 #endif
636 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
638 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
639 if (fixed_regs[ARG_POINTER_REGNUM])
641 #ifdef ELIMINABLE_REGS
642 size_t i;
643 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
645 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
646 if (elim_regs[i].from == ARG_POINTER_REGNUM
647 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
648 break;
650 if (i == ARRAY_SIZE (elim_regs))
651 #endif
653 /* Now restore our arg pointer from the address at which it
654 was saved in our stack frame. */
655 emit_move_insn (virtual_incoming_args_rtx,
656 copy_to_reg (get_arg_pointer_save_area (cfun)));
659 #endif
661 #ifdef HAVE_builtin_setjmp_receiver
662 if (HAVE_builtin_setjmp_receiver)
663 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
664 else
665 #endif
666 #ifdef HAVE_nonlocal_goto_receiver
667 if (HAVE_nonlocal_goto_receiver)
668 emit_insn (gen_nonlocal_goto_receiver ());
669 else
670 #endif
671 { /* Nothing */ }
673 /* @@@ This is a kludge. Not all machine descriptions define a blockage
674 insn, but we must not allow the code we just generated to be reordered
675 by scheduling. Specifically, the update of the frame pointer must
676 happen immediately, not later. So emit an ASM_INPUT to act as blockage
677 insn. */
678 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
681 /* __builtin_setjmp is passed a pointer to an array of five words (not
682 all will be used on all machines). It operates similarly to the C
683 library function of the same name, but is more efficient. Much of
684 the code below (and for longjmp) is copied from the handling of
685 non-local gotos.
687 NOTE: This is intended for use by GNAT and the exception handling
688 scheme in the compiler and will only work in the method used by
689 them. */
691 static rtx
692 expand_builtin_setjmp (tree arglist, rtx target)
694 rtx buf_addr, next_lab, cont_lab;
696 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
697 return NULL_RTX;
699 if (target == 0 || !REG_P (target)
700 || REGNO (target) < FIRST_PSEUDO_REGISTER)
701 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
703 buf_addr = expand_normal (TREE_VALUE (arglist));
705 next_lab = gen_label_rtx ();
706 cont_lab = gen_label_rtx ();
708 expand_builtin_setjmp_setup (buf_addr, next_lab);
710 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
711 ensure that pending stack adjustments are flushed. */
712 emit_move_insn (target, const0_rtx);
713 emit_jump (cont_lab);
715 emit_label (next_lab);
717 expand_builtin_setjmp_receiver (next_lab);
719 /* Set TARGET to one. */
720 emit_move_insn (target, const1_rtx);
721 emit_label (cont_lab);
723 /* Tell flow about the strange goings on. Putting `next_lab' on
724 `nonlocal_goto_handler_labels' to indicates that function
725 calls may traverse the arc back to this label. */
727 current_function_has_nonlocal_label = 1;
728 nonlocal_goto_handler_labels
729 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
731 return target;
734 /* __builtin_longjmp is passed a pointer to an array of five words (not
735 all will be used on all machines). It operates similarly to the C
736 library function of the same name, but is more efficient. Much of
737 the code below is copied from the handling of non-local gotos.
739 NOTE: This is intended for use by GNAT and the exception handling
740 scheme in the compiler and will only work in the method used by
741 them. */
743 static void
744 expand_builtin_longjmp (rtx buf_addr, rtx value)
746 rtx fp, lab, stack, insn, last;
747 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
749 if (setjmp_alias_set == -1)
750 setjmp_alias_set = new_alias_set ();
752 buf_addr = convert_memory_address (Pmode, buf_addr);
754 buf_addr = force_reg (Pmode, buf_addr);
756 /* We used to store value in static_chain_rtx, but that fails if pointers
757 are smaller than integers. We instead require that the user must pass
758 a second argument of 1, because that is what builtin_setjmp will
759 return. This also makes EH slightly more efficient, since we are no
760 longer copying around a value that we don't care about. */
761 gcc_assert (value == const1_rtx);
763 last = get_last_insn ();
764 #ifdef HAVE_builtin_longjmp
765 if (HAVE_builtin_longjmp)
766 emit_insn (gen_builtin_longjmp (buf_addr));
767 else
768 #endif
770 fp = gen_rtx_MEM (Pmode, buf_addr);
771 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
772 GET_MODE_SIZE (Pmode)));
774 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
775 2 * GET_MODE_SIZE (Pmode)));
776 set_mem_alias_set (fp, setjmp_alias_set);
777 set_mem_alias_set (lab, setjmp_alias_set);
778 set_mem_alias_set (stack, setjmp_alias_set);
780 /* Pick up FP, label, and SP from the block and jump. This code is
781 from expand_goto in stmt.c; see there for detailed comments. */
782 #if HAVE_nonlocal_goto
783 if (HAVE_nonlocal_goto)
784 /* We have to pass a value to the nonlocal_goto pattern that will
785 get copied into the static_chain pointer, but it does not matter
786 what that value is, because builtin_setjmp does not use it. */
787 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
788 else
789 #endif
791 lab = copy_to_reg (lab);
793 emit_insn (gen_rtx_CLOBBER (VOIDmode,
794 gen_rtx_MEM (BLKmode,
795 gen_rtx_SCRATCH (VOIDmode))));
796 emit_insn (gen_rtx_CLOBBER (VOIDmode,
797 gen_rtx_MEM (BLKmode,
798 hard_frame_pointer_rtx)));
800 emit_move_insn (hard_frame_pointer_rtx, fp);
801 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
803 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
804 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
805 emit_indirect_jump (lab);
809 /* Search backwards and mark the jump insn as a non-local goto.
810 Note that this precludes the use of __builtin_longjmp to a
811 __builtin_setjmp target in the same function. However, we've
812 already cautioned the user that these functions are for
813 internal exception handling use only. */
814 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
816 gcc_assert (insn != last);
818 if (JUMP_P (insn))
820 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
821 REG_NOTES (insn));
822 break;
824 else if (CALL_P (insn))
825 break;
829 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
830 and the address of the save area. */
832 static rtx
833 expand_builtin_nonlocal_goto (tree arglist)
835 tree t_label, t_save_area;
836 rtx r_label, r_save_area, r_fp, r_sp, insn;
838 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
839 return NULL_RTX;
841 t_label = TREE_VALUE (arglist);
842 arglist = TREE_CHAIN (arglist);
843 t_save_area = TREE_VALUE (arglist);
845 r_label = expand_normal (t_label);
846 r_label = convert_memory_address (Pmode, r_label);
847 r_save_area = expand_normal (t_save_area);
848 r_save_area = convert_memory_address (Pmode, r_save_area);
849 r_fp = gen_rtx_MEM (Pmode, r_save_area);
850 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
851 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
853 current_function_has_nonlocal_goto = 1;
855 #if HAVE_nonlocal_goto
856 /* ??? We no longer need to pass the static chain value, afaik. */
857 if (HAVE_nonlocal_goto)
858 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
859 else
860 #endif
862 r_label = copy_to_reg (r_label);
864 emit_insn (gen_rtx_CLOBBER (VOIDmode,
865 gen_rtx_MEM (BLKmode,
866 gen_rtx_SCRATCH (VOIDmode))));
868 emit_insn (gen_rtx_CLOBBER (VOIDmode,
869 gen_rtx_MEM (BLKmode,
870 hard_frame_pointer_rtx)));
872 /* Restore frame pointer for containing function.
873 This sets the actual hard register used for the frame pointer
874 to the location of the function's incoming static chain info.
875 The non-local goto handler will then adjust it to contain the
876 proper value and reload the argument pointer, if needed. */
877 emit_move_insn (hard_frame_pointer_rtx, r_fp);
878 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
880 /* USE of hard_frame_pointer_rtx added for consistency;
881 not clear if really needed. */
882 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
883 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
884 emit_indirect_jump (r_label);
887 /* Search backwards to the jump insn and mark it as a
888 non-local goto. */
889 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
891 if (JUMP_P (insn))
893 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
894 const0_rtx, REG_NOTES (insn));
895 break;
897 else if (CALL_P (insn))
898 break;
901 return const0_rtx;
904 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
905 (not all will be used on all machines) that was passed to __builtin_setjmp.
906 It updates the stack pointer in that block to correspond to the current
907 stack pointer. */
909 static void
910 expand_builtin_update_setjmp_buf (rtx buf_addr)
912 enum machine_mode sa_mode = Pmode;
913 rtx stack_save;
916 #ifdef HAVE_save_stack_nonlocal
917 if (HAVE_save_stack_nonlocal)
918 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
919 #endif
920 #ifdef STACK_SAVEAREA_MODE
921 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
922 #endif
924 stack_save
925 = gen_rtx_MEM (sa_mode,
926 memory_address
927 (sa_mode,
928 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
930 #ifdef HAVE_setjmp
931 if (HAVE_setjmp)
932 emit_insn (gen_setjmp ());
933 #endif
935 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
938 /* Expand a call to __builtin_prefetch. For a target that does not support
939 data prefetch, evaluate the memory address argument in case it has side
940 effects. */
942 static void
943 expand_builtin_prefetch (tree arglist)
945 tree arg0, arg1, arg2;
946 rtx op0, op1, op2;
948 if (!validate_arglist (arglist, POINTER_TYPE, 0))
949 return;
951 arg0 = TREE_VALUE (arglist);
952 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
953 zero (read) and argument 2 (locality) defaults to 3 (high degree of
954 locality). */
955 if (TREE_CHAIN (arglist))
957 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
958 if (TREE_CHAIN (TREE_CHAIN (arglist)))
959 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
960 else
961 arg2 = build_int_cst (NULL_TREE, 3);
963 else
965 arg1 = integer_zero_node;
966 arg2 = build_int_cst (NULL_TREE, 3);
969 /* Argument 0 is an address. */
970 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
972 /* Argument 1 (read/write flag) must be a compile-time constant int. */
973 if (TREE_CODE (arg1) != INTEGER_CST)
975 error ("second argument to %<__builtin_prefetch%> must be a constant");
976 arg1 = integer_zero_node;
978 op1 = expand_normal (arg1);
979 /* Argument 1 must be either zero or one. */
980 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
982 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
983 " using zero");
984 op1 = const0_rtx;
987 /* Argument 2 (locality) must be a compile-time constant int. */
988 if (TREE_CODE (arg2) != INTEGER_CST)
990 error ("third argument to %<__builtin_prefetch%> must be a constant");
991 arg2 = integer_zero_node;
993 op2 = expand_normal (arg2);
994 /* Argument 2 must be 0, 1, 2, or 3. */
995 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
997 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
998 op2 = const0_rtx;
1001 #ifdef HAVE_prefetch
1002 if (HAVE_prefetch)
1004 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1005 (op0,
1006 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1007 || (GET_MODE (op0) != Pmode))
1009 op0 = convert_memory_address (Pmode, op0);
1010 op0 = force_reg (Pmode, op0);
1012 emit_insn (gen_prefetch (op0, op1, op2));
1014 #endif
1016 /* Don't do anything with direct references to volatile memory, but
1017 generate code to handle other side effects. */
1018 if (!MEM_P (op0) && side_effects_p (op0))
1019 emit_insn (op0);
1022 /* Get a MEM rtx for expression EXP which is the address of an operand
1023 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1024 the maximum length of the block of memory that might be accessed or
1025 NULL if unknown. */
1027 static rtx
1028 get_memory_rtx (tree exp, tree len)
1030 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1031 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1033 /* Get an expression we can use to find the attributes to assign to MEM.
1034 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1035 we can. First remove any nops. */
1036 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1037 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1038 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1039 exp = TREE_OPERAND (exp, 0);
1041 if (TREE_CODE (exp) == ADDR_EXPR)
1042 exp = TREE_OPERAND (exp, 0);
1043 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1044 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1045 else
1046 exp = NULL;
1048 /* Honor attributes derived from exp, except for the alias set
1049 (as builtin stringops may alias with anything) and the size
1050 (as stringops may access multiple array elements). */
1051 if (exp)
1053 set_mem_attributes (mem, exp, 0);
1055 /* Allow the string and memory builtins to overflow from one
1056 field into another, see http://gcc.gnu.org/PR23561.
1057 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1058 memory accessed by the string or memory builtin will fit
1059 within the field. */
1060 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1062 tree mem_expr = MEM_EXPR (mem);
1063 HOST_WIDE_INT offset = -1, length = -1;
1064 tree inner = exp;
1066 while (TREE_CODE (inner) == ARRAY_REF
1067 || TREE_CODE (inner) == NOP_EXPR
1068 || TREE_CODE (inner) == CONVERT_EXPR
1069 || TREE_CODE (inner) == NON_LVALUE_EXPR
1070 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1071 || TREE_CODE (inner) == SAVE_EXPR)
1072 inner = TREE_OPERAND (inner, 0);
1074 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1076 if (MEM_OFFSET (mem)
1077 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1078 offset = INTVAL (MEM_OFFSET (mem));
1080 if (offset >= 0 && len && host_integerp (len, 0))
1081 length = tree_low_cst (len, 0);
1083 while (TREE_CODE (inner) == COMPONENT_REF)
1085 tree field = TREE_OPERAND (inner, 1);
1086 gcc_assert (! DECL_BIT_FIELD (field));
1087 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1088 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1090 if (length >= 0
1091 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1092 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1094 HOST_WIDE_INT size
1095 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1096 /* If we can prove the memory starting at XEXP (mem, 0)
1097 and ending at XEXP (mem, 0) + LENGTH will fit into
1098 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1099 if (offset <= size
1100 && length <= size
1101 && offset + length <= size)
1102 break;
1105 if (offset >= 0
1106 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1107 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1108 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1109 / BITS_PER_UNIT;
1110 else
1112 offset = -1;
1113 length = -1;
1116 mem_expr = TREE_OPERAND (mem_expr, 0);
1117 inner = TREE_OPERAND (inner, 0);
1120 if (mem_expr == NULL)
1121 offset = -1;
1122 if (mem_expr != MEM_EXPR (mem))
1124 set_mem_expr (mem, mem_expr);
1125 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1128 set_mem_alias_set (mem, 0);
1129 set_mem_size (mem, NULL_RTX);
1132 return mem;
1135 /* Built-in functions to perform an untyped call and return. */
1137 /* For each register that may be used for calling a function, this
1138 gives a mode used to copy the register's value. VOIDmode indicates
1139 the register is not used for calling a function. If the machine
1140 has register windows, this gives only the outbound registers.
1141 INCOMING_REGNO gives the corresponding inbound register. */
1142 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1144 /* For each register that may be used for returning values, this gives
1145 a mode used to copy the register's value. VOIDmode indicates the
1146 register is not used for returning values. If the machine has
1147 register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1151 /* For each register that may be used for calling a function, this
1152 gives the offset of that register into the block returned by
1153 __builtin_apply_args. 0 indicates that the register is not
1154 used for calling a function. */
1155 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1157 /* Return the size required for the block returned by __builtin_apply_args,
1158 and initialize apply_args_mode. */
1160 static int
1161 apply_args_size (void)
1163 static int size = -1;
1164 int align;
1165 unsigned int regno;
1166 enum machine_mode mode;
1168 /* The values computed by this function never change. */
1169 if (size < 0)
1171 /* The first value is the incoming arg-pointer. */
1172 size = GET_MODE_SIZE (Pmode);
1174 /* The second value is the structure value address unless this is
1175 passed as an "invisible" first argument. */
1176 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1177 size += GET_MODE_SIZE (Pmode);
1179 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1180 if (FUNCTION_ARG_REGNO_P (regno))
1182 mode = reg_raw_mode[regno];
1184 gcc_assert (mode != VOIDmode);
1186 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1187 if (size % align != 0)
1188 size = CEIL (size, align) * align;
1189 apply_args_reg_offset[regno] = size;
1190 size += GET_MODE_SIZE (mode);
1191 apply_args_mode[regno] = mode;
1193 else
1195 apply_args_mode[regno] = VOIDmode;
1196 apply_args_reg_offset[regno] = 0;
1199 return size;
1202 /* Return the size required for the block returned by __builtin_apply,
1203 and initialize apply_result_mode. */
1205 static int
1206 apply_result_size (void)
1208 static int size = -1;
1209 int align, regno;
1210 enum machine_mode mode;
1212 /* The values computed by this function never change. */
1213 if (size < 0)
1215 size = 0;
1217 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1218 if (FUNCTION_VALUE_REGNO_P (regno))
1220 mode = reg_raw_mode[regno];
1222 gcc_assert (mode != VOIDmode);
1224 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1225 if (size % align != 0)
1226 size = CEIL (size, align) * align;
1227 size += GET_MODE_SIZE (mode);
1228 apply_result_mode[regno] = mode;
1230 else
1231 apply_result_mode[regno] = VOIDmode;
1233 /* Allow targets that use untyped_call and untyped_return to override
1234 the size so that machine-specific information can be stored here. */
1235 #ifdef APPLY_RESULT_SIZE
1236 size = APPLY_RESULT_SIZE;
1237 #endif
1239 return size;
1242 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1243 /* Create a vector describing the result block RESULT. If SAVEP is true,
1244 the result block is used to save the values; otherwise it is used to
1245 restore the values. */
1247 static rtx
1248 result_vector (int savep, rtx result)
1250 int regno, size, align, nelts;
1251 enum machine_mode mode;
1252 rtx reg, mem;
1253 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1255 size = nelts = 0;
1256 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1257 if ((mode = apply_result_mode[regno]) != VOIDmode)
1259 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1260 if (size % align != 0)
1261 size = CEIL (size, align) * align;
1262 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1263 mem = adjust_address (result, mode, size);
1264 savevec[nelts++] = (savep
1265 ? gen_rtx_SET (VOIDmode, mem, reg)
1266 : gen_rtx_SET (VOIDmode, reg, mem));
1267 size += GET_MODE_SIZE (mode);
1269 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1271 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1273 /* Save the state required to perform an untyped call with the same
1274 arguments as were passed to the current function. */
1276 static rtx
1277 expand_builtin_apply_args_1 (void)
1279 rtx registers, tem;
1280 int size, align, regno;
1281 enum machine_mode mode;
1282 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1284 /* Create a block where the arg-pointer, structure value address,
1285 and argument registers can be saved. */
1286 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1288 /* Walk past the arg-pointer and structure value address. */
1289 size = GET_MODE_SIZE (Pmode);
1290 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1291 size += GET_MODE_SIZE (Pmode);
1293 /* Save each register used in calling a function to the block. */
1294 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1295 if ((mode = apply_args_mode[regno]) != VOIDmode)
1297 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1298 if (size % align != 0)
1299 size = CEIL (size, align) * align;
1301 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1303 emit_move_insn (adjust_address (registers, mode, size), tem);
1304 size += GET_MODE_SIZE (mode);
1307 /* Save the arg pointer to the block. */
1308 tem = copy_to_reg (virtual_incoming_args_rtx);
1309 #ifdef STACK_GROWS_DOWNWARD
1310 /* We need the pointer as the caller actually passed them to us, not
1311 as we might have pretended they were passed. Make sure it's a valid
1312 operand, as emit_move_insn isn't expected to handle a PLUS. */
1314 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1315 NULL_RTX);
1316 #endif
1317 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1319 size = GET_MODE_SIZE (Pmode);
1321 /* Save the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 if (struct_incoming_value)
1325 emit_move_insn (adjust_address (registers, Pmode, size),
1326 copy_to_reg (struct_incoming_value));
1327 size += GET_MODE_SIZE (Pmode);
1330 /* Return the address of the block. */
1331 return copy_addr_to_reg (XEXP (registers, 0));
1334 /* __builtin_apply_args returns block of memory allocated on
1335 the stack into which is stored the arg pointer, structure
1336 value address, static chain, and all the registers that might
1337 possibly be used in performing a function call. The code is
1338 moved to the start of the function so the incoming values are
1339 saved. */
1341 static rtx
1342 expand_builtin_apply_args (void)
1344 /* Don't do __builtin_apply_args more than once in a function.
1345 Save the result of the first call and reuse it. */
1346 if (apply_args_value != 0)
1347 return apply_args_value;
1349 /* When this function is called, it means that registers must be
1350 saved on entry to this function. So we migrate the
1351 call to the first insn of this function. */
1352 rtx temp;
1353 rtx seq;
1355 start_sequence ();
1356 temp = expand_builtin_apply_args_1 ();
1357 seq = get_insns ();
1358 end_sequence ();
1360 apply_args_value = temp;
1362 /* Put the insns after the NOTE that starts the function.
1363 If this is inside a start_sequence, make the outer-level insn
1364 chain current, so the code is placed at the start of the
1365 function. */
1366 push_topmost_sequence ();
1367 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1368 pop_topmost_sequence ();
1369 return temp;
1373 /* Perform an untyped call and save the state required to perform an
1374 untyped return of whatever value was returned by the given function. */
1376 static rtx
1377 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1379 int size, align, regno;
1380 enum machine_mode mode;
1381 rtx incoming_args, result, reg, dest, src, call_insn;
1382 rtx old_stack_level = 0;
1383 rtx call_fusage = 0;
1384 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1386 arguments = convert_memory_address (Pmode, arguments);
1388 /* Create a block where the return registers can be saved. */
1389 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1391 /* Fetch the arg pointer from the ARGUMENTS block. */
1392 incoming_args = gen_reg_rtx (Pmode);
1393 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1394 #ifndef STACK_GROWS_DOWNWARD
1395 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1396 incoming_args, 0, OPTAB_LIB_WIDEN);
1397 #endif
1399 /* Push a new argument block and copy the arguments. Do not allow
1400 the (potential) memcpy call below to interfere with our stack
1401 manipulations. */
1402 do_pending_stack_adjust ();
1403 NO_DEFER_POP;
1405 /* Save the stack with nonlocal if available. */
1406 #ifdef HAVE_save_stack_nonlocal
1407 if (HAVE_save_stack_nonlocal)
1408 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1409 else
1410 #endif
1411 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1413 /* Allocate a block of memory onto the stack and copy the memory
1414 arguments to the outgoing arguments address. */
1415 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1416 dest = virtual_outgoing_args_rtx;
1417 #ifndef STACK_GROWS_DOWNWARD
1418 if (GET_CODE (argsize) == CONST_INT)
1419 dest = plus_constant (dest, -INTVAL (argsize));
1420 else
1421 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1422 #endif
1423 dest = gen_rtx_MEM (BLKmode, dest);
1424 set_mem_align (dest, PARM_BOUNDARY);
1425 src = gen_rtx_MEM (BLKmode, incoming_args);
1426 set_mem_align (src, PARM_BOUNDARY);
1427 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1429 /* Refer to the argument block. */
1430 apply_args_size ();
1431 arguments = gen_rtx_MEM (BLKmode, arguments);
1432 set_mem_align (arguments, PARM_BOUNDARY);
1434 /* Walk past the arg-pointer and structure value address. */
1435 size = GET_MODE_SIZE (Pmode);
1436 if (struct_value)
1437 size += GET_MODE_SIZE (Pmode);
1439 /* Restore each of the registers previously saved. Make USE insns
1440 for each of these registers for use in making the call. */
1441 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1442 if ((mode = apply_args_mode[regno]) != VOIDmode)
1444 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1445 if (size % align != 0)
1446 size = CEIL (size, align) * align;
1447 reg = gen_rtx_REG (mode, regno);
1448 emit_move_insn (reg, adjust_address (arguments, mode, size));
1449 use_reg (&call_fusage, reg);
1450 size += GET_MODE_SIZE (mode);
1453 /* Restore the structure value address unless this is passed as an
1454 "invisible" first argument. */
1455 size = GET_MODE_SIZE (Pmode);
1456 if (struct_value)
1458 rtx value = gen_reg_rtx (Pmode);
1459 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1460 emit_move_insn (struct_value, value);
1461 if (REG_P (struct_value))
1462 use_reg (&call_fusage, struct_value);
1463 size += GET_MODE_SIZE (Pmode);
1466 /* All arguments and registers used for the call are set up by now! */
1467 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1469 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1470 and we don't want to load it into a register as an optimization,
1471 because prepare_call_address already did it if it should be done. */
1472 if (GET_CODE (function) != SYMBOL_REF)
1473 function = memory_address (FUNCTION_MODE, function);
1475 /* Generate the actual call instruction and save the return value. */
1476 #ifdef HAVE_untyped_call
1477 if (HAVE_untyped_call)
1478 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1479 result, result_vector (1, result)));
1480 else
1481 #endif
1482 #ifdef HAVE_call_value
1483 if (HAVE_call_value)
1485 rtx valreg = 0;
1487 /* Locate the unique return register. It is not possible to
1488 express a call that sets more than one return register using
1489 call_value; use untyped_call for that. In fact, untyped_call
1490 only needs to save the return registers in the given block. */
1491 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1492 if ((mode = apply_result_mode[regno]) != VOIDmode)
1494 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1496 valreg = gen_rtx_REG (mode, regno);
1499 emit_call_insn (GEN_CALL_VALUE (valreg,
1500 gen_rtx_MEM (FUNCTION_MODE, function),
1501 const0_rtx, NULL_RTX, const0_rtx));
1503 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1505 else
1506 #endif
1507 gcc_unreachable ();
1509 /* Find the CALL insn we just emitted, and attach the register usage
1510 information. */
1511 call_insn = last_call_insn ();
1512 add_function_usage_to (call_insn, call_fusage);
1514 /* Restore the stack. */
1515 #ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal)
1517 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1518 else
1519 #endif
1520 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1522 OK_DEFER_POP;
1524 /* Return the address of the result block. */
1525 result = copy_addr_to_reg (XEXP (result, 0));
1526 return convert_memory_address (ptr_mode, result);
1529 /* Perform an untyped return. */
1531 static void
1532 expand_builtin_return (rtx result)
1534 int size, align, regno;
1535 enum machine_mode mode;
1536 rtx reg;
1537 rtx call_fusage = 0;
1539 result = convert_memory_address (Pmode, result);
1541 apply_result_size ();
1542 result = gen_rtx_MEM (BLKmode, result);
1544 #ifdef HAVE_untyped_return
1545 if (HAVE_untyped_return)
1547 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1548 emit_barrier ();
1549 return;
1551 #endif
1553 /* Restore the return value and note that each value is used. */
1554 size = 0;
1555 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1556 if ((mode = apply_result_mode[regno]) != VOIDmode)
1558 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1559 if (size % align != 0)
1560 size = CEIL (size, align) * align;
1561 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1562 emit_move_insn (reg, adjust_address (result, mode, size));
1564 push_to_sequence (call_fusage);
1565 emit_insn (gen_rtx_USE (VOIDmode, reg));
1566 call_fusage = get_insns ();
1567 end_sequence ();
1568 size += GET_MODE_SIZE (mode);
1571 /* Put the USE insns before the return. */
1572 emit_insn (call_fusage);
1574 /* Return whatever values was restored by jumping directly to the end
1575 of the function. */
1576 expand_naked_return ();
1579 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1581 static enum type_class
1582 type_to_class (tree type)
1584 switch (TREE_CODE (type))
1586 case VOID_TYPE: return void_type_class;
1587 case INTEGER_TYPE: return integer_type_class;
1588 case CHAR_TYPE: return char_type_class;
1589 case ENUMERAL_TYPE: return enumeral_type_class;
1590 case BOOLEAN_TYPE: return boolean_type_class;
1591 case POINTER_TYPE: return pointer_type_class;
1592 case REFERENCE_TYPE: return reference_type_class;
1593 case OFFSET_TYPE: return offset_type_class;
1594 case REAL_TYPE: return real_type_class;
1595 case COMPLEX_TYPE: return complex_type_class;
1596 case FUNCTION_TYPE: return function_type_class;
1597 case METHOD_TYPE: return method_type_class;
1598 case RECORD_TYPE: return record_type_class;
1599 case UNION_TYPE:
1600 case QUAL_UNION_TYPE: return union_type_class;
1601 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1602 ? string_type_class : array_type_class);
1603 case LANG_TYPE: return lang_type_class;
1604 default: return no_type_class;
1608 /* Expand a call to __builtin_classify_type with arguments found in
1609 ARGLIST. */
1611 static rtx
1612 expand_builtin_classify_type (tree arglist)
1614 if (arglist != 0)
1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1616 return GEN_INT (no_type_class);
1619 /* This helper macro, meant to be used in mathfn_built_in below,
1620 determines which among a set of three builtin math functions is
1621 appropriate for a given type mode. The `F' and `L' cases are
1622 automatically generated from the `double' case. */
1623 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626 fcodel = BUILT_IN_MATHFN##L ; break;
1628 /* Return mathematic function equivalent to FN but operating directly
1629 on TYPE, if available. If we can't do the conversion, return zero. */
1630 tree
1631 mathfn_built_in (tree type, enum built_in_function fn)
1633 enum built_in_function fcode, fcodef, fcodel;
1635 switch (fn)
1637 CASE_MATHFN (BUILT_IN_ACOS)
1638 CASE_MATHFN (BUILT_IN_ACOSH)
1639 CASE_MATHFN (BUILT_IN_ASIN)
1640 CASE_MATHFN (BUILT_IN_ASINH)
1641 CASE_MATHFN (BUILT_IN_ATAN)
1642 CASE_MATHFN (BUILT_IN_ATAN2)
1643 CASE_MATHFN (BUILT_IN_ATANH)
1644 CASE_MATHFN (BUILT_IN_CBRT)
1645 CASE_MATHFN (BUILT_IN_CEIL)
1646 CASE_MATHFN (BUILT_IN_COPYSIGN)
1647 CASE_MATHFN (BUILT_IN_COS)
1648 CASE_MATHFN (BUILT_IN_COSH)
1649 CASE_MATHFN (BUILT_IN_DREM)
1650 CASE_MATHFN (BUILT_IN_ERF)
1651 CASE_MATHFN (BUILT_IN_ERFC)
1652 CASE_MATHFN (BUILT_IN_EXP)
1653 CASE_MATHFN (BUILT_IN_EXP10)
1654 CASE_MATHFN (BUILT_IN_EXP2)
1655 CASE_MATHFN (BUILT_IN_EXPM1)
1656 CASE_MATHFN (BUILT_IN_FABS)
1657 CASE_MATHFN (BUILT_IN_FDIM)
1658 CASE_MATHFN (BUILT_IN_FLOOR)
1659 CASE_MATHFN (BUILT_IN_FMA)
1660 CASE_MATHFN (BUILT_IN_FMAX)
1661 CASE_MATHFN (BUILT_IN_FMIN)
1662 CASE_MATHFN (BUILT_IN_FMOD)
1663 CASE_MATHFN (BUILT_IN_FREXP)
1664 CASE_MATHFN (BUILT_IN_GAMMA)
1665 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1666 CASE_MATHFN (BUILT_IN_HYPOT)
1667 CASE_MATHFN (BUILT_IN_ILOGB)
1668 CASE_MATHFN (BUILT_IN_INF)
1669 CASE_MATHFN (BUILT_IN_J0)
1670 CASE_MATHFN (BUILT_IN_J1)
1671 CASE_MATHFN (BUILT_IN_JN)
1672 CASE_MATHFN (BUILT_IN_LCEIL)
1673 CASE_MATHFN (BUILT_IN_LDEXP)
1674 CASE_MATHFN (BUILT_IN_LFLOOR)
1675 CASE_MATHFN (BUILT_IN_LGAMMA)
1676 CASE_MATHFN (BUILT_IN_LLCEIL)
1677 CASE_MATHFN (BUILT_IN_LLFLOOR)
1678 CASE_MATHFN (BUILT_IN_LLRINT)
1679 CASE_MATHFN (BUILT_IN_LLROUND)
1680 CASE_MATHFN (BUILT_IN_LOG)
1681 CASE_MATHFN (BUILT_IN_LOG10)
1682 CASE_MATHFN (BUILT_IN_LOG1P)
1683 CASE_MATHFN (BUILT_IN_LOG2)
1684 CASE_MATHFN (BUILT_IN_LOGB)
1685 CASE_MATHFN (BUILT_IN_LRINT)
1686 CASE_MATHFN (BUILT_IN_LROUND)
1687 CASE_MATHFN (BUILT_IN_MODF)
1688 CASE_MATHFN (BUILT_IN_NAN)
1689 CASE_MATHFN (BUILT_IN_NANS)
1690 CASE_MATHFN (BUILT_IN_NEARBYINT)
1691 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1693 CASE_MATHFN (BUILT_IN_POW)
1694 CASE_MATHFN (BUILT_IN_POWI)
1695 CASE_MATHFN (BUILT_IN_POW10)
1696 CASE_MATHFN (BUILT_IN_REMAINDER)
1697 CASE_MATHFN (BUILT_IN_REMQUO)
1698 CASE_MATHFN (BUILT_IN_RINT)
1699 CASE_MATHFN (BUILT_IN_ROUND)
1700 CASE_MATHFN (BUILT_IN_SCALB)
1701 CASE_MATHFN (BUILT_IN_SCALBLN)
1702 CASE_MATHFN (BUILT_IN_SCALBN)
1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1704 CASE_MATHFN (BUILT_IN_SIN)
1705 CASE_MATHFN (BUILT_IN_SINCOS)
1706 CASE_MATHFN (BUILT_IN_SINH)
1707 CASE_MATHFN (BUILT_IN_SQRT)
1708 CASE_MATHFN (BUILT_IN_TAN)
1709 CASE_MATHFN (BUILT_IN_TANH)
1710 CASE_MATHFN (BUILT_IN_TGAMMA)
1711 CASE_MATHFN (BUILT_IN_TRUNC)
1712 CASE_MATHFN (BUILT_IN_Y0)
1713 CASE_MATHFN (BUILT_IN_Y1)
1714 CASE_MATHFN (BUILT_IN_YN)
1716 default:
1717 return 0;
1720 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1721 return implicit_built_in_decls[fcode];
1722 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1723 return implicit_built_in_decls[fcodef];
1724 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1725 return implicit_built_in_decls[fcodel];
1726 else
1727 return 0;
1730 /* If errno must be maintained, expand the RTL to check if the result,
1731 TARGET, of a built-in function call, EXP, is NaN, and if so set
1732 errno to EDOM. */
1734 static void
1735 expand_errno_check (tree exp, rtx target)
1737 rtx lab = gen_label_rtx ();
1739 /* Test the result; if it is NaN, set errno=EDOM because
1740 the argument was not in the domain. */
1741 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1742 0, lab);
1744 #ifdef TARGET_EDOM
1745 /* If this built-in doesn't throw an exception, set errno directly. */
1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1748 #ifdef GEN_ERRNO_RTX
1749 rtx errno_rtx = GEN_ERRNO_RTX;
1750 #else
1751 rtx errno_rtx
1752 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1753 #endif
1754 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1755 emit_label (lab);
1756 return;
1758 #endif
1760 /* We can't set errno=EDOM directly; let the library call do it.
1761 Pop the arguments right away in case the call gets deleted. */
1762 NO_DEFER_POP;
1763 expand_call (exp, target, 0);
1764 OK_DEFER_POP;
1765 emit_label (lab);
1769 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770 Return 0 if a normal call should be emitted rather than expanding the
1771 function in-line. EXP is the expression that is a call to the builtin
1772 function; if convenient, the result should be placed in TARGET.
1773 SUBTARGET may be used as the target for computing one of EXP's operands. */
1775 static rtx
1776 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1778 optab builtin_optab;
1779 rtx op0, insns, before_call;
1780 tree fndecl = get_callee_fndecl (exp);
1781 tree arglist = TREE_OPERAND (exp, 1);
1782 enum machine_mode mode;
1783 bool errno_set = false;
1784 tree arg, narg;
1786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1787 return 0;
1789 arg = TREE_VALUE (arglist);
1791 switch (DECL_FUNCTION_CODE (fndecl))
1793 CASE_FLT_FN (BUILT_IN_SQRT):
1794 errno_set = ! tree_expr_nonnegative_p (arg);
1795 builtin_optab = sqrt_optab;
1796 break;
1797 CASE_FLT_FN (BUILT_IN_EXP):
1798 errno_set = true; builtin_optab = exp_optab; break;
1799 CASE_FLT_FN (BUILT_IN_EXP10):
1800 CASE_FLT_FN (BUILT_IN_POW10):
1801 errno_set = true; builtin_optab = exp10_optab; break;
1802 CASE_FLT_FN (BUILT_IN_EXP2):
1803 errno_set = true; builtin_optab = exp2_optab; break;
1804 CASE_FLT_FN (BUILT_IN_EXPM1):
1805 errno_set = true; builtin_optab = expm1_optab; break;
1806 CASE_FLT_FN (BUILT_IN_LOGB):
1807 errno_set = true; builtin_optab = logb_optab; break;
1808 CASE_FLT_FN (BUILT_IN_ILOGB):
1809 errno_set = true; builtin_optab = ilogb_optab; break;
1810 CASE_FLT_FN (BUILT_IN_LOG):
1811 errno_set = true; builtin_optab = log_optab; break;
1812 CASE_FLT_FN (BUILT_IN_LOG10):
1813 errno_set = true; builtin_optab = log10_optab; break;
1814 CASE_FLT_FN (BUILT_IN_LOG2):
1815 errno_set = true; builtin_optab = log2_optab; break;
1816 CASE_FLT_FN (BUILT_IN_LOG1P):
1817 errno_set = true; builtin_optab = log1p_optab; break;
1818 CASE_FLT_FN (BUILT_IN_ASIN):
1819 builtin_optab = asin_optab; break;
1820 CASE_FLT_FN (BUILT_IN_ACOS):
1821 builtin_optab = acos_optab; break;
1822 CASE_FLT_FN (BUILT_IN_TAN):
1823 builtin_optab = tan_optab; break;
1824 CASE_FLT_FN (BUILT_IN_ATAN):
1825 builtin_optab = atan_optab; break;
1826 CASE_FLT_FN (BUILT_IN_FLOOR):
1827 builtin_optab = floor_optab; break;
1828 CASE_FLT_FN (BUILT_IN_CEIL):
1829 builtin_optab = ceil_optab; break;
1830 CASE_FLT_FN (BUILT_IN_TRUNC):
1831 builtin_optab = btrunc_optab; break;
1832 CASE_FLT_FN (BUILT_IN_ROUND):
1833 builtin_optab = round_optab; break;
1834 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1835 builtin_optab = nearbyint_optab; break;
1836 CASE_FLT_FN (BUILT_IN_RINT):
1837 builtin_optab = rint_optab; break;
1838 CASE_FLT_FN (BUILT_IN_LRINT):
1839 CASE_FLT_FN (BUILT_IN_LLRINT):
1840 builtin_optab = lrint_optab; break;
1841 default:
1842 gcc_unreachable ();
1845 /* Make a suitable register to place result in. */
1846 mode = TYPE_MODE (TREE_TYPE (exp));
1848 if (! flag_errno_math || ! HONOR_NANS (mode))
1849 errno_set = false;
1851 /* Before working hard, check whether the instruction is available. */
1852 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1854 target = gen_reg_rtx (mode);
1856 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1857 need to expand the argument again. This way, we will not perform
1858 side-effects more the once. */
1859 narg = builtin_save_expr (arg);
1860 if (narg != arg)
1862 arg = narg;
1863 arglist = build_tree_list (NULL_TREE, arg);
1864 exp = build_function_call_expr (fndecl, arglist);
1867 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1869 start_sequence ();
1871 /* Compute into TARGET.
1872 Set TARGET to wherever the result comes back. */
1873 target = expand_unop (mode, builtin_optab, op0, target, 0);
1875 if (target != 0)
1877 if (errno_set)
1878 expand_errno_check (exp, target);
1880 /* Output the entire sequence. */
1881 insns = get_insns ();
1882 end_sequence ();
1883 emit_insn (insns);
1884 return target;
1887 /* If we were unable to expand via the builtin, stop the sequence
1888 (without outputting the insns) and call to the library function
1889 with the stabilized argument list. */
1890 end_sequence ();
1893 before_call = get_last_insn ();
1895 target = expand_call (exp, target, target == const0_rtx);
1897 /* If this is a sqrt operation and we don't care about errno, try to
1898 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1899 This allows the semantics of the libcall to be visible to the RTL
1900 optimizers. */
1901 if (builtin_optab == sqrt_optab && !errno_set)
1903 /* Search backwards through the insns emitted by expand_call looking
1904 for the instruction with the REG_RETVAL note. */
1905 rtx last = get_last_insn ();
1906 while (last != before_call)
1908 if (find_reg_note (last, REG_RETVAL, NULL))
1910 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1911 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1912 two elements, i.e. symbol_ref(sqrt) and the operand. */
1913 if (note
1914 && GET_CODE (note) == EXPR_LIST
1915 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1916 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1917 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1919 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1920 /* Check operand is a register with expected mode. */
1921 if (operand
1922 && REG_P (operand)
1923 && GET_MODE (operand) == mode)
1925 /* Replace the REG_EQUAL note with a SQRT rtx. */
1926 rtx equiv = gen_rtx_SQRT (mode, operand);
1927 set_unique_reg_note (last, REG_EQUAL, equiv);
1930 break;
1932 last = PREV_INSN (last);
1936 return target;
1939 /* Expand a call to the builtin binary math functions (pow and atan2).
1940 Return 0 if a normal call should be emitted rather than expanding the
1941 function in-line. EXP is the expression that is a call to the builtin
1942 function; if convenient, the result should be placed in TARGET.
1943 SUBTARGET may be used as the target for computing one of EXP's
1944 operands. */
1946 static rtx
1947 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1949 optab builtin_optab;
1950 rtx op0, op1, insns;
1951 int op1_type = REAL_TYPE;
1952 tree fndecl = get_callee_fndecl (exp);
1953 tree arglist = TREE_OPERAND (exp, 1);
1954 tree arg0, arg1, temp, narg;
1955 enum machine_mode mode;
1956 bool errno_set = true;
1957 bool stable = true;
1959 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1960 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1961 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1962 op1_type = INTEGER_TYPE;
1964 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1965 return 0;
1967 arg0 = TREE_VALUE (arglist);
1968 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1970 switch (DECL_FUNCTION_CODE (fndecl))
1972 CASE_FLT_FN (BUILT_IN_POW):
1973 builtin_optab = pow_optab; break;
1974 CASE_FLT_FN (BUILT_IN_ATAN2):
1975 builtin_optab = atan2_optab; break;
1976 CASE_FLT_FN (BUILT_IN_LDEXP):
1977 builtin_optab = ldexp_optab; break;
1978 CASE_FLT_FN (BUILT_IN_FMOD):
1979 builtin_optab = fmod_optab; break;
1980 CASE_FLT_FN (BUILT_IN_DREM):
1981 builtin_optab = drem_optab; break;
1982 default:
1983 gcc_unreachable ();
1986 /* Make a suitable register to place result in. */
1987 mode = TYPE_MODE (TREE_TYPE (exp));
1989 /* Before working hard, check whether the instruction is available. */
1990 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1991 return 0;
1993 target = gen_reg_rtx (mode);
1995 if (! flag_errno_math || ! HONOR_NANS (mode))
1996 errno_set = false;
1998 /* Always stabilize the argument list. */
1999 narg = builtin_save_expr (arg1);
2000 if (narg != arg1)
2002 arg1 = narg;
2003 temp = build_tree_list (NULL_TREE, narg);
2004 stable = false;
2006 else
2007 temp = TREE_CHAIN (arglist);
2009 narg = builtin_save_expr (arg0);
2010 if (narg != arg0)
2012 arg0 = narg;
2013 arglist = tree_cons (NULL_TREE, narg, temp);
2014 stable = false;
2016 else if (! stable)
2017 arglist = tree_cons (NULL_TREE, arg0, temp);
2019 if (! stable)
2020 exp = build_function_call_expr (fndecl, arglist);
2022 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2023 op1 = expand_normal (arg1);
2025 start_sequence ();
2027 /* Compute into TARGET.
2028 Set TARGET to wherever the result comes back. */
2029 target = expand_binop (mode, builtin_optab, op0, op1,
2030 target, 0, OPTAB_DIRECT);
2032 /* If we were unable to expand via the builtin, stop the sequence
2033 (without outputting the insns) and call to the library function
2034 with the stabilized argument list. */
2035 if (target == 0)
2037 end_sequence ();
2038 return expand_call (exp, target, target == const0_rtx);
2041 if (errno_set)
2042 expand_errno_check (exp, target);
2044 /* Output the entire sequence. */
2045 insns = get_insns ();
2046 end_sequence ();
2047 emit_insn (insns);
2049 return target;
2052 /* Expand a call to the builtin sin and cos math functions.
2053 Return 0 if a normal call should be emitted rather than expanding the
2054 function in-line. EXP is the expression that is a call to the builtin
2055 function; if convenient, the result should be placed in TARGET.
2056 SUBTARGET may be used as the target for computing one of EXP's
2057 operands. */
2059 static rtx
2060 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2062 optab builtin_optab;
2063 rtx op0, insns;
2064 tree fndecl = get_callee_fndecl (exp);
2065 tree arglist = TREE_OPERAND (exp, 1);
2066 enum machine_mode mode;
2067 tree arg, narg;
2069 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2070 return 0;
2072 arg = TREE_VALUE (arglist);
2074 switch (DECL_FUNCTION_CODE (fndecl))
2076 CASE_FLT_FN (BUILT_IN_SIN):
2077 CASE_FLT_FN (BUILT_IN_COS):
2078 builtin_optab = sincos_optab; break;
2079 default:
2080 gcc_unreachable ();
2083 /* Make a suitable register to place result in. */
2084 mode = TYPE_MODE (TREE_TYPE (exp));
2086 /* Check if sincos insn is available, otherwise fallback
2087 to sin or cos insn. */
2088 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2089 switch (DECL_FUNCTION_CODE (fndecl))
2091 CASE_FLT_FN (BUILT_IN_SIN):
2092 builtin_optab = sin_optab; break;
2093 CASE_FLT_FN (BUILT_IN_COS):
2094 builtin_optab = cos_optab; break;
2095 default:
2096 gcc_unreachable ();
2100 /* Before working hard, check whether the instruction is available. */
2101 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2103 target = gen_reg_rtx (mode);
2105 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2106 need to expand the argument again. This way, we will not perform
2107 side-effects more the once. */
2108 narg = save_expr (arg);
2109 if (narg != arg)
2111 arg = narg;
2112 arglist = build_tree_list (NULL_TREE, arg);
2113 exp = build_function_call_expr (fndecl, arglist);
2116 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2118 start_sequence ();
2120 /* Compute into TARGET.
2121 Set TARGET to wherever the result comes back. */
2122 if (builtin_optab == sincos_optab)
2124 int result;
2126 switch (DECL_FUNCTION_CODE (fndecl))
2128 CASE_FLT_FN (BUILT_IN_SIN):
2129 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2130 break;
2131 CASE_FLT_FN (BUILT_IN_COS):
2132 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2133 break;
2134 default:
2135 gcc_unreachable ();
2137 gcc_assert (result);
2139 else
2141 target = expand_unop (mode, builtin_optab, op0, target, 0);
2144 if (target != 0)
2146 /* Output the entire sequence. */
2147 insns = get_insns ();
2148 end_sequence ();
2149 emit_insn (insns);
2150 return target;
2153 /* If we were unable to expand via the builtin, stop the sequence
2154 (without outputting the insns) and call to the library function
2155 with the stabilized argument list. */
2156 end_sequence ();
2159 target = expand_call (exp, target, target == const0_rtx);
2161 return target;
2164 /* Expand a call to the builtin sincos math function.
2165 Return 0 if a normal call should be emitted rather than expanding the
2166 function in-line. EXP is the expression that is a call to the builtin
2167 function. */
2169 static rtx
2170 expand_builtin_sincos (tree exp)
2172 rtx op0, op1, op2, target1, target2;
2173 tree arglist = TREE_OPERAND (exp, 1);
2174 enum machine_mode mode;
2175 tree arg, sinp, cosp;
2176 int result;
2178 if (!validate_arglist (arglist, REAL_TYPE,
2179 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2180 return 0;
2182 arg = TREE_VALUE (arglist);
2183 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2184 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2186 /* Make a suitable register to place result in. */
2187 mode = TYPE_MODE (TREE_TYPE (arg));
2189 /* Check if sincos insn is available, otherwise emit the call. */
2190 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2191 return NULL_RTX;
2193 target1 = gen_reg_rtx (mode);
2194 target2 = gen_reg_rtx (mode);
2196 op0 = expand_normal (arg);
2197 op1 = expand_normal (build_fold_indirect_ref (sinp));
2198 op2 = expand_normal (build_fold_indirect_ref (cosp));
2200 /* Compute into target1 and target2.
2201 Set TARGET to wherever the result comes back. */
2202 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2203 gcc_assert (result);
2205 /* Move target1 and target2 to the memory locations indicated
2206 by op1 and op2. */
2207 emit_move_insn (op1, target1);
2208 emit_move_insn (op2, target2);
2210 return const0_rtx;
2213 /* Expand a call to one of the builtin rounding functions (lfloor).
2214 If expanding via optab fails, lower expression to (int)(floor(x)).
2215 EXP is the expression that is a call to the builtin function;
2216 if convenient, the result should be placed in TARGET. SUBTARGET may
2217 be used as the target for computing one of EXP's operands. */
2219 static rtx
2220 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2222 optab builtin_optab;
2223 rtx op0, insns, tmp;
2224 tree fndecl = get_callee_fndecl (exp);
2225 tree arglist = TREE_OPERAND (exp, 1);
2226 enum built_in_function fallback_fn;
2227 tree fallback_fndecl;
2228 enum machine_mode mode;
2229 tree arg, narg;
2231 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2232 gcc_unreachable ();
2234 arg = TREE_VALUE (arglist);
2236 switch (DECL_FUNCTION_CODE (fndecl))
2238 CASE_FLT_FN (BUILT_IN_LCEIL):
2239 CASE_FLT_FN (BUILT_IN_LLCEIL):
2240 builtin_optab = lceil_optab;
2241 fallback_fn = BUILT_IN_CEIL;
2242 break;
2244 CASE_FLT_FN (BUILT_IN_LFLOOR):
2245 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2246 builtin_optab = lfloor_optab;
2247 fallback_fn = BUILT_IN_FLOOR;
2248 break;
2250 default:
2251 gcc_unreachable ();
2254 /* Make a suitable register to place result in. */
2255 mode = TYPE_MODE (TREE_TYPE (exp));
2257 /* Before working hard, check whether the instruction is available. */
2258 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2260 target = gen_reg_rtx (mode);
2262 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2263 need to expand the argument again. This way, we will not perform
2264 side-effects more the once. */
2265 narg = builtin_save_expr (arg);
2266 if (narg != arg)
2268 arg = narg;
2269 arglist = build_tree_list (NULL_TREE, arg);
2270 exp = build_function_call_expr (fndecl, arglist);
2273 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2275 start_sequence ();
2277 /* Compute into TARGET.
2278 Set TARGET to wherever the result comes back. */
2279 target = expand_unop (mode, builtin_optab, op0, target, 0);
2281 if (target != 0)
2283 /* Output the entire sequence. */
2284 insns = get_insns ();
2285 end_sequence ();
2286 emit_insn (insns);
2287 return target;
2290 /* If we were unable to expand via the builtin, stop the sequence
2291 (without outputting the insns). */
2292 end_sequence ();
2295 /* Fall back to floating point rounding optab. */
2296 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2297 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2298 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2299 gcc_assert (fallback_fndecl != NULL_TREE);
2300 exp = build_function_call_expr (fallback_fndecl, arglist);
2302 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2304 /* Truncate the result of floating point optab to integer
2305 via expand_fix (). */
2306 target = gen_reg_rtx (mode);
2307 expand_fix (target, tmp, 0);
2309 return target;
2312 /* To evaluate powi(x,n), the floating point value x raised to the
2313 constant integer exponent n, we use a hybrid algorithm that
2314 combines the "window method" with look-up tables. For an
2315 introduction to exponentiation algorithms and "addition chains",
2316 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2317 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2318 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2319 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2321 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2322 multiplications to inline before calling the system library's pow
2323 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2324 so this default never requires calling pow, powf or powl. */
2326 #ifndef POWI_MAX_MULTS
2327 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2328 #endif
2330 /* The size of the "optimal power tree" lookup table. All
2331 exponents less than this value are simply looked up in the
2332 powi_table below. This threshold is also used to size the
2333 cache of pseudo registers that hold intermediate results. */
2334 #define POWI_TABLE_SIZE 256
2336 /* The size, in bits of the window, used in the "window method"
2337 exponentiation algorithm. This is equivalent to a radix of
2338 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2339 #define POWI_WINDOW_SIZE 3
2341 /* The following table is an efficient representation of an
2342 "optimal power tree". For each value, i, the corresponding
2343 value, j, in the table states than an optimal evaluation
2344 sequence for calculating pow(x,i) can be found by evaluating
2345 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2346 100 integers is given in Knuth's "Seminumerical algorithms". */
2348 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2350 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2351 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2352 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2353 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2354 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2355 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2356 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2357 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2358 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2359 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2360 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2361 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2362 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2363 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2364 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2365 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2366 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2367 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2368 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2369 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2370 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2371 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2372 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2373 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2374 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2375 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2376 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2377 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2378 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2379 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2380 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2381 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2385 /* Return the number of multiplications required to calculate
2386 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2387 subroutine of powi_cost. CACHE is an array indicating
2388 which exponents have already been calculated. */
2390 static int
2391 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2393 /* If we've already calculated this exponent, then this evaluation
2394 doesn't require any additional multiplications. */
2395 if (cache[n])
2396 return 0;
2398 cache[n] = true;
2399 return powi_lookup_cost (n - powi_table[n], cache)
2400 + powi_lookup_cost (powi_table[n], cache) + 1;
2403 /* Return the number of multiplications required to calculate
2404 powi(x,n) for an arbitrary x, given the exponent N. This
2405 function needs to be kept in sync with expand_powi below. */
2407 static int
2408 powi_cost (HOST_WIDE_INT n)
2410 bool cache[POWI_TABLE_SIZE];
2411 unsigned HOST_WIDE_INT digit;
2412 unsigned HOST_WIDE_INT val;
2413 int result;
2415 if (n == 0)
2416 return 0;
2418 /* Ignore the reciprocal when calculating the cost. */
2419 val = (n < 0) ? -n : n;
2421 /* Initialize the exponent cache. */
2422 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2423 cache[1] = true;
2425 result = 0;
2427 while (val >= POWI_TABLE_SIZE)
2429 if (val & 1)
2431 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2432 result += powi_lookup_cost (digit, cache)
2433 + POWI_WINDOW_SIZE + 1;
2434 val >>= POWI_WINDOW_SIZE;
2436 else
2438 val >>= 1;
2439 result++;
2443 return result + powi_lookup_cost (val, cache);
2446 /* Recursive subroutine of expand_powi. This function takes the array,
2447 CACHE, of already calculated exponents and an exponent N and returns
2448 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2450 static rtx
2451 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2453 unsigned HOST_WIDE_INT digit;
2454 rtx target, result;
2455 rtx op0, op1;
2457 if (n < POWI_TABLE_SIZE)
2459 if (cache[n])
2460 return cache[n];
2462 target = gen_reg_rtx (mode);
2463 cache[n] = target;
2465 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2466 op1 = expand_powi_1 (mode, powi_table[n], cache);
2468 else if (n & 1)
2470 target = gen_reg_rtx (mode);
2471 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2472 op0 = expand_powi_1 (mode, n - digit, cache);
2473 op1 = expand_powi_1 (mode, digit, cache);
2475 else
2477 target = gen_reg_rtx (mode);
2478 op0 = expand_powi_1 (mode, n >> 1, cache);
2479 op1 = op0;
2482 result = expand_mult (mode, op0, op1, target, 0);
2483 if (result != target)
2484 emit_move_insn (target, result);
2485 return target;
2488 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2489 floating point operand in mode MODE, and N is the exponent. This
2490 function needs to be kept in sync with powi_cost above. */
2492 static rtx
2493 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2495 unsigned HOST_WIDE_INT val;
2496 rtx cache[POWI_TABLE_SIZE];
2497 rtx result;
2499 if (n == 0)
2500 return CONST1_RTX (mode);
2502 val = (n < 0) ? -n : n;
2504 memset (cache, 0, sizeof (cache));
2505 cache[1] = x;
2507 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2509 /* If the original exponent was negative, reciprocate the result. */
2510 if (n < 0)
2511 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2512 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2514 return result;
2517 /* Expand a call to the pow built-in mathematical function. Return 0 if
2518 a normal call should be emitted rather than expanding the function
2519 in-line. EXP is the expression that is a call to the builtin
2520 function; if convenient, the result should be placed in TARGET. */
2522 static rtx
2523 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2525 tree arglist = TREE_OPERAND (exp, 1);
2526 tree arg0, arg1;
2528 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2529 return 0;
2531 arg0 = TREE_VALUE (arglist);
2532 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2534 if (TREE_CODE (arg1) == REAL_CST
2535 && ! TREE_CONSTANT_OVERFLOW (arg1))
2537 REAL_VALUE_TYPE cint;
2538 REAL_VALUE_TYPE c;
2539 HOST_WIDE_INT n;
2541 c = TREE_REAL_CST (arg1);
2542 n = real_to_integer (&c);
2543 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2544 if (real_identical (&c, &cint))
2546 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2547 Otherwise, check the number of multiplications required.
2548 Note that pow never sets errno for an integer exponent. */
2549 if ((n >= -1 && n <= 2)
2550 || (flag_unsafe_math_optimizations
2551 && ! optimize_size
2552 && powi_cost (n) <= POWI_MAX_MULTS))
2554 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2555 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2556 op = force_reg (mode, op);
2557 return expand_powi (op, mode, n);
2562 if (! flag_unsafe_math_optimizations)
2563 return NULL_RTX;
2564 return expand_builtin_mathfn_2 (exp, target, subtarget);
2567 /* Expand a call to the powi built-in mathematical function. Return 0 if
2568 a normal call should be emitted rather than expanding the function
2569 in-line. EXP is the expression that is a call to the builtin
2570 function; if convenient, the result should be placed in TARGET. */
2572 static rtx
2573 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2575 tree arglist = TREE_OPERAND (exp, 1);
2576 tree arg0, arg1;
2577 rtx op0, op1;
2578 enum machine_mode mode;
2579 enum machine_mode mode2;
2581 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2582 return 0;
2584 arg0 = TREE_VALUE (arglist);
2585 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2586 mode = TYPE_MODE (TREE_TYPE (exp));
2588 /* Handle constant power. */
2590 if (TREE_CODE (arg1) == INTEGER_CST
2591 && ! TREE_CONSTANT_OVERFLOW (arg1))
2593 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2595 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2596 Otherwise, check the number of multiplications required. */
2597 if ((TREE_INT_CST_HIGH (arg1) == 0
2598 || TREE_INT_CST_HIGH (arg1) == -1)
2599 && ((n >= -1 && n <= 2)
2600 || (! optimize_size
2601 && powi_cost (n) <= POWI_MAX_MULTS)))
2603 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2604 op0 = force_reg (mode, op0);
2605 return expand_powi (op0, mode, n);
2609 /* Emit a libcall to libgcc. */
2611 /* Mode of the 2nd argument must match that of an int. */
2612 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2614 if (target == NULL_RTX)
2615 target = gen_reg_rtx (mode);
2617 op0 = expand_expr (arg0, subtarget, mode, 0);
2618 if (GET_MODE (op0) != mode)
2619 op0 = convert_to_mode (mode, op0, 0);
2620 op1 = expand_expr (arg1, 0, mode2, 0);
2621 if (GET_MODE (op1) != mode2)
2622 op1 = convert_to_mode (mode2, op1, 0);
2624 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2625 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2626 op0, mode, op1, mode2);
2628 return target;
2631 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2632 if we failed the caller should emit a normal call, otherwise
2633 try to get the result in TARGET, if convenient. */
2635 static rtx
2636 expand_builtin_strlen (tree arglist, rtx target,
2637 enum machine_mode target_mode)
2639 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2640 return 0;
2641 else
2643 rtx pat;
2644 tree len, src = TREE_VALUE (arglist);
2645 rtx result, src_reg, char_rtx, before_strlen;
2646 enum machine_mode insn_mode = target_mode, char_mode;
2647 enum insn_code icode = CODE_FOR_nothing;
2648 int align;
2650 /* If the length can be computed at compile-time, return it. */
2651 len = c_strlen (src, 0);
2652 if (len)
2653 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2655 /* If the length can be computed at compile-time and is constant
2656 integer, but there are side-effects in src, evaluate
2657 src for side-effects, then return len.
2658 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2659 can be optimized into: i++; x = 3; */
2660 len = c_strlen (src, 1);
2661 if (len && TREE_CODE (len) == INTEGER_CST)
2663 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2664 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2667 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2669 /* If SRC is not a pointer type, don't do this operation inline. */
2670 if (align == 0)
2671 return 0;
2673 /* Bail out if we can't compute strlen in the right mode. */
2674 while (insn_mode != VOIDmode)
2676 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2677 if (icode != CODE_FOR_nothing)
2678 break;
2680 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2682 if (insn_mode == VOIDmode)
2683 return 0;
2685 /* Make a place to write the result of the instruction. */
2686 result = target;
2687 if (! (result != 0
2688 && REG_P (result)
2689 && GET_MODE (result) == insn_mode
2690 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2691 result = gen_reg_rtx (insn_mode);
2693 /* Make a place to hold the source address. We will not expand
2694 the actual source until we are sure that the expansion will
2695 not fail -- there are trees that cannot be expanded twice. */
2696 src_reg = gen_reg_rtx (Pmode);
2698 /* Mark the beginning of the strlen sequence so we can emit the
2699 source operand later. */
2700 before_strlen = get_last_insn ();
2702 char_rtx = const0_rtx;
2703 char_mode = insn_data[(int) icode].operand[2].mode;
2704 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2705 char_mode))
2706 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2708 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2709 char_rtx, GEN_INT (align));
2710 if (! pat)
2711 return 0;
2712 emit_insn (pat);
2714 /* Now that we are assured of success, expand the source. */
2715 start_sequence ();
2716 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2717 if (pat != src_reg)
2718 emit_move_insn (src_reg, pat);
2719 pat = get_insns ();
2720 end_sequence ();
2722 if (before_strlen)
2723 emit_insn_after (pat, before_strlen);
2724 else
2725 emit_insn_before (pat, get_insns ());
2727 /* Return the value in the proper mode for this function. */
2728 if (GET_MODE (result) == target_mode)
2729 target = result;
2730 else if (target != 0)
2731 convert_move (target, result, 0);
2732 else
2733 target = convert_to_mode (target_mode, result, 0);
2735 return target;
2739 /* Expand a call to the strstr builtin. Return 0 if we failed the
2740 caller should emit a normal call, otherwise try to get the result
2741 in TARGET, if convenient (and in mode MODE if that's convenient). */
2743 static rtx
2744 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2746 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2748 tree result = fold_builtin_strstr (arglist, type);
2749 if (result)
2750 return expand_expr (result, target, mode, EXPAND_NORMAL);
2752 return 0;
2755 /* Expand a call to the strchr builtin. Return 0 if we failed the
2756 caller should emit a normal call, otherwise try to get the result
2757 in TARGET, if convenient (and in mode MODE if that's convenient). */
2759 static rtx
2760 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2762 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2764 tree result = fold_builtin_strchr (arglist, type);
2765 if (result)
2766 return expand_expr (result, target, mode, EXPAND_NORMAL);
2768 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2770 return 0;
2773 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2774 caller should emit a normal call, otherwise try to get the result
2775 in TARGET, if convenient (and in mode MODE if that's convenient). */
2777 static rtx
2778 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2780 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2782 tree result = fold_builtin_strrchr (arglist, type);
2783 if (result)
2784 return expand_expr (result, target, mode, EXPAND_NORMAL);
2786 return 0;
2789 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2790 caller should emit a normal call, otherwise try to get the result
2791 in TARGET, if convenient (and in mode MODE if that's convenient). */
2793 static rtx
2794 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2796 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2798 tree result = fold_builtin_strpbrk (arglist, type);
2799 if (result)
2800 return expand_expr (result, target, mode, EXPAND_NORMAL);
2802 return 0;
2805 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2806 bytes from constant string DATA + OFFSET and return it as target
2807 constant. */
2809 static rtx
2810 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2811 enum machine_mode mode)
2813 const char *str = (const char *) data;
2815 gcc_assert (offset >= 0
2816 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2817 <= strlen (str) + 1));
2819 return c_readstr (str + offset, mode);
2822 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2823 Return 0 if we failed, the caller should emit a normal call,
2824 otherwise try to get the result in TARGET, if convenient (and in
2825 mode MODE if that's convenient). */
2826 static rtx
2827 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2829 tree fndecl = get_callee_fndecl (exp);
2830 tree arglist = TREE_OPERAND (exp, 1);
2831 if (!validate_arglist (arglist,
2832 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2833 return 0;
2834 else
2836 tree dest = TREE_VALUE (arglist);
2837 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2838 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2839 const char *src_str;
2840 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2841 unsigned int dest_align
2842 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2843 rtx dest_mem, src_mem, dest_addr, len_rtx;
2844 tree result = fold_builtin_memcpy (fndecl, arglist);
2846 if (result)
2847 return expand_expr (result, target, mode, EXPAND_NORMAL);
2849 /* If DEST is not a pointer type, call the normal function. */
2850 if (dest_align == 0)
2851 return 0;
2853 /* If either SRC is not a pointer type, don't do this
2854 operation in-line. */
2855 if (src_align == 0)
2856 return 0;
2858 dest_mem = get_memory_rtx (dest, len);
2859 set_mem_align (dest_mem, dest_align);
2860 len_rtx = expand_normal (len);
2861 src_str = c_getstr (src);
2863 /* If SRC is a string constant and block move would be done
2864 by pieces, we can avoid loading the string from memory
2865 and only stored the computed constants. */
2866 if (src_str
2867 && GET_CODE (len_rtx) == CONST_INT
2868 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2869 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2870 (void *) src_str, dest_align))
2872 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2873 builtin_memcpy_read_str,
2874 (void *) src_str, dest_align, 0);
2875 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2876 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2877 return dest_mem;
2880 src_mem = get_memory_rtx (src, len);
2881 set_mem_align (src_mem, src_align);
2883 /* Copy word part most expediently. */
2884 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2885 CALL_EXPR_TAILCALL (exp)
2886 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2888 if (dest_addr == 0)
2890 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2891 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2893 return dest_addr;
2897 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2898 Return 0 if we failed; the caller should emit a normal call,
2899 otherwise try to get the result in TARGET, if convenient (and in
2900 mode MODE if that's convenient). If ENDP is 0 return the
2901 destination pointer, if ENDP is 1 return the end pointer ala
2902 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2903 stpcpy. */
2905 static rtx
2906 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2907 int endp)
2909 if (!validate_arglist (arglist,
2910 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2911 return 0;
2912 /* If return value is ignored, transform mempcpy into memcpy. */
2913 else if (target == const0_rtx)
2915 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2917 if (!fn)
2918 return 0;
2920 return expand_expr (build_function_call_expr (fn, arglist),
2921 target, mode, EXPAND_NORMAL);
2923 else
2925 tree dest = TREE_VALUE (arglist);
2926 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2927 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2928 const char *src_str;
2929 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2930 unsigned int dest_align
2931 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2932 rtx dest_mem, src_mem, len_rtx;
2933 tree result = fold_builtin_mempcpy (arglist, type, endp);
2935 if (result)
2936 return expand_expr (result, target, mode, EXPAND_NORMAL);
2938 /* If either SRC or DEST is not a pointer type, don't do this
2939 operation in-line. */
2940 if (dest_align == 0 || src_align == 0)
2941 return 0;
2943 /* If LEN is not constant, call the normal function. */
2944 if (! host_integerp (len, 1))
2945 return 0;
2947 len_rtx = expand_normal (len);
2948 src_str = c_getstr (src);
2950 /* If SRC is a string constant and block move would be done
2951 by pieces, we can avoid loading the string from memory
2952 and only stored the computed constants. */
2953 if (src_str
2954 && GET_CODE (len_rtx) == CONST_INT
2955 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2956 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2957 (void *) src_str, dest_align))
2959 dest_mem = get_memory_rtx (dest, len);
2960 set_mem_align (dest_mem, dest_align);
2961 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2962 builtin_memcpy_read_str,
2963 (void *) src_str, dest_align, endp);
2964 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2965 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2966 return dest_mem;
2969 if (GET_CODE (len_rtx) == CONST_INT
2970 && can_move_by_pieces (INTVAL (len_rtx),
2971 MIN (dest_align, src_align)))
2973 dest_mem = get_memory_rtx (dest, len);
2974 set_mem_align (dest_mem, dest_align);
2975 src_mem = get_memory_rtx (src, len);
2976 set_mem_align (src_mem, src_align);
2977 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2978 MIN (dest_align, src_align), endp);
2979 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2980 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2981 return dest_mem;
2984 return 0;
2988 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2989 if we failed; the caller should emit a normal call. */
2991 static rtx
2992 expand_builtin_memmove (tree arglist, tree type, rtx target,
2993 enum machine_mode mode, tree orig_exp)
2995 if (!validate_arglist (arglist,
2996 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2997 return 0;
2998 else
3000 tree dest = TREE_VALUE (arglist);
3001 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3002 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3004 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3005 unsigned int dest_align
3006 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3007 tree result = fold_builtin_memmove (arglist, type);
3009 if (result)
3010 return expand_expr (result, target, mode, EXPAND_NORMAL);
3012 /* If DEST is not a pointer type, call the normal function. */
3013 if (dest_align == 0)
3014 return 0;
3016 /* If either SRC is not a pointer type, don't do this
3017 operation in-line. */
3018 if (src_align == 0)
3019 return 0;
3021 /* If src is categorized for a readonly section we can use
3022 normal memcpy. */
3023 if (readonly_data_expr (src))
3025 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3026 if (!fn)
3027 return 0;
3028 fn = build_function_call_expr (fn, arglist);
3029 if (TREE_CODE (fn) == CALL_EXPR)
3030 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3031 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3034 /* If length is 1 and we can expand memcpy call inline,
3035 it is ok to use memcpy as well. */
3036 if (integer_onep (len))
3038 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3039 /*endp=*/0);
3040 if (ret)
3041 return ret;
3044 /* Otherwise, call the normal function. */
3045 return 0;
3049 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3050 if we failed the caller should emit a normal call. */
3052 static rtx
3053 expand_builtin_bcopy (tree exp)
3055 tree arglist = TREE_OPERAND (exp, 1);
3056 tree type = TREE_TYPE (exp);
3057 tree src, dest, size, newarglist;
3059 if (!validate_arglist (arglist,
3060 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3061 return NULL_RTX;
3063 src = TREE_VALUE (arglist);
3064 dest = TREE_VALUE (TREE_CHAIN (arglist));
3065 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3067 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3068 memmove(ptr y, ptr x, size_t z). This is done this way
3069 so that if it isn't expanded inline, we fallback to
3070 calling bcopy instead of memmove. */
3072 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3073 newarglist = tree_cons (NULL_TREE, src, newarglist);
3074 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3076 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3079 #ifndef HAVE_movstr
3080 # define HAVE_movstr 0
3081 # define CODE_FOR_movstr CODE_FOR_nothing
3082 #endif
3084 /* Expand into a movstr instruction, if one is available. Return 0 if
3085 we failed, the caller should emit a normal call, otherwise try to
3086 get the result in TARGET, if convenient. If ENDP is 0 return the
3087 destination pointer, if ENDP is 1 return the end pointer ala
3088 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3089 stpcpy. */
3091 static rtx
3092 expand_movstr (tree dest, tree src, rtx target, int endp)
3094 rtx end;
3095 rtx dest_mem;
3096 rtx src_mem;
3097 rtx insn;
3098 const struct insn_data * data;
3100 if (!HAVE_movstr)
3101 return 0;
3103 dest_mem = get_memory_rtx (dest, NULL);
3104 src_mem = get_memory_rtx (src, NULL);
3105 if (!endp)
3107 target = force_reg (Pmode, XEXP (dest_mem, 0));
3108 dest_mem = replace_equiv_address (dest_mem, target);
3109 end = gen_reg_rtx (Pmode);
3111 else
3113 if (target == 0 || target == const0_rtx)
3115 end = gen_reg_rtx (Pmode);
3116 if (target == 0)
3117 target = end;
3119 else
3120 end = target;
3123 data = insn_data + CODE_FOR_movstr;
3125 if (data->operand[0].mode != VOIDmode)
3126 end = gen_lowpart (data->operand[0].mode, end);
3128 insn = data->genfun (end, dest_mem, src_mem);
3130 gcc_assert (insn);
3132 emit_insn (insn);
3134 /* movstr is supposed to set end to the address of the NUL
3135 terminator. If the caller requested a mempcpy-like return value,
3136 adjust it. */
3137 if (endp == 1 && target != const0_rtx)
3139 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3140 emit_move_insn (target, force_operand (tem, NULL_RTX));
3143 return target;
3146 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3147 if we failed the caller should emit a normal call, otherwise try to get
3148 the result in TARGET, if convenient (and in mode MODE if that's
3149 convenient). */
3151 static rtx
3152 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3154 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3156 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3157 if (result)
3158 return expand_expr (result, target, mode, EXPAND_NORMAL);
3160 return expand_movstr (TREE_VALUE (arglist),
3161 TREE_VALUE (TREE_CHAIN (arglist)),
3162 target, /*endp=*/0);
3164 return 0;
3167 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3168 Return 0 if we failed the caller should emit a normal call,
3169 otherwise try to get the result in TARGET, if convenient (and in
3170 mode MODE if that's convenient). */
3172 static rtx
3173 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3175 tree arglist = TREE_OPERAND (exp, 1);
3176 /* If return value is ignored, transform stpcpy into strcpy. */
3177 if (target == const0_rtx)
3179 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3180 if (!fn)
3181 return 0;
3183 return expand_expr (build_function_call_expr (fn, arglist),
3184 target, mode, EXPAND_NORMAL);
3187 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3188 return 0;
3189 else
3191 tree dst, src, len, lenp1;
3192 tree narglist;
3193 rtx ret;
3195 /* Ensure we get an actual string whose length can be evaluated at
3196 compile-time, not an expression containing a string. This is
3197 because the latter will potentially produce pessimized code
3198 when used to produce the return value. */
3199 src = TREE_VALUE (TREE_CHAIN (arglist));
3200 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3201 return expand_movstr (TREE_VALUE (arglist),
3202 TREE_VALUE (TREE_CHAIN (arglist)),
3203 target, /*endp=*/2);
3205 dst = TREE_VALUE (arglist);
3206 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3207 narglist = build_tree_list (NULL_TREE, lenp1);
3208 narglist = tree_cons (NULL_TREE, src, narglist);
3209 narglist = tree_cons (NULL_TREE, dst, narglist);
3210 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3211 target, mode, /*endp=*/2);
3213 if (ret)
3214 return ret;
3216 if (TREE_CODE (len) == INTEGER_CST)
3218 rtx len_rtx = expand_normal (len);
3220 if (GET_CODE (len_rtx) == CONST_INT)
3222 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3223 arglist, target, mode);
3225 if (ret)
3227 if (! target)
3229 if (mode != VOIDmode)
3230 target = gen_reg_rtx (mode);
3231 else
3232 target = gen_reg_rtx (GET_MODE (ret));
3234 if (GET_MODE (target) != GET_MODE (ret))
3235 ret = gen_lowpart (GET_MODE (target), ret);
3237 ret = plus_constant (ret, INTVAL (len_rtx));
3238 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3239 gcc_assert (ret);
3241 return target;
3246 return expand_movstr (TREE_VALUE (arglist),
3247 TREE_VALUE (TREE_CHAIN (arglist)),
3248 target, /*endp=*/2);
3252 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3253 bytes from constant string DATA + OFFSET and return it as target
3254 constant. */
3256 static rtx
3257 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3258 enum machine_mode mode)
3260 const char *str = (const char *) data;
3262 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3263 return const0_rtx;
3265 return c_readstr (str + offset, mode);
3268 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3269 if we failed the caller should emit a normal call. */
3271 static rtx
3272 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3274 tree fndecl = get_callee_fndecl (exp);
3275 tree arglist = TREE_OPERAND (exp, 1);
3276 if (validate_arglist (arglist,
3277 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3279 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3280 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3281 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3283 if (result)
3284 return expand_expr (result, target, mode, EXPAND_NORMAL);
3286 /* We must be passed a constant len and src parameter. */
3287 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3288 return 0;
3290 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3292 /* We're required to pad with trailing zeros if the requested
3293 len is greater than strlen(s2)+1. In that case try to
3294 use store_by_pieces, if it fails, punt. */
3295 if (tree_int_cst_lt (slen, len))
3297 tree dest = TREE_VALUE (arglist);
3298 unsigned int dest_align
3299 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3300 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3301 rtx dest_mem;
3303 if (!p || dest_align == 0 || !host_integerp (len, 1)
3304 || !can_store_by_pieces (tree_low_cst (len, 1),
3305 builtin_strncpy_read_str,
3306 (void *) p, dest_align))
3307 return 0;
3309 dest_mem = get_memory_rtx (dest, len);
3310 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3311 builtin_strncpy_read_str,
3312 (void *) p, dest_align, 0);
3313 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3314 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3315 return dest_mem;
3318 return 0;
3321 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3322 bytes from constant string DATA + OFFSET and return it as target
3323 constant. */
3325 static rtx
3326 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3327 enum machine_mode mode)
3329 const char *c = (const char *) data;
3330 char *p = alloca (GET_MODE_SIZE (mode));
3332 memset (p, *c, GET_MODE_SIZE (mode));
3334 return c_readstr (p, mode);
3337 /* Callback routine for store_by_pieces. Return the RTL of a register
3338 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3339 char value given in the RTL register data. For example, if mode is
3340 4 bytes wide, return the RTL for 0x01010101*data. */
3342 static rtx
3343 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3344 enum machine_mode mode)
3346 rtx target, coeff;
3347 size_t size;
3348 char *p;
3350 size = GET_MODE_SIZE (mode);
3351 if (size == 1)
3352 return (rtx) data;
3354 p = alloca (size);
3355 memset (p, 1, size);
3356 coeff = c_readstr (p, mode);
3358 target = convert_to_mode (mode, (rtx) data, 1);
3359 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3360 return force_reg (mode, target);
3363 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3364 if we failed the caller should emit a normal call, otherwise try to get
3365 the result in TARGET, if convenient (and in mode MODE if that's
3366 convenient). */
3368 static rtx
3369 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3370 tree orig_exp)
3372 if (!validate_arglist (arglist,
3373 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3374 return 0;
3375 else
3377 tree dest = TREE_VALUE (arglist);
3378 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3379 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3380 char c;
3382 unsigned int dest_align
3383 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3384 rtx dest_mem, dest_addr, len_rtx;
3386 /* If DEST is not a pointer type, don't do this
3387 operation in-line. */
3388 if (dest_align == 0)
3389 return 0;
3391 /* If the LEN parameter is zero, return DEST. */
3392 if (integer_zerop (len))
3394 /* Evaluate and ignore VAL in case it has side-effects. */
3395 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3396 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3399 len_rtx = expand_normal (len);
3400 dest_mem = get_memory_rtx (dest, len);
3402 if (TREE_CODE (val) != INTEGER_CST)
3404 rtx val_rtx;
3406 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3407 val_rtx = expand_normal (val);
3409 /* Assume that we can memset by pieces if we can store the
3410 * the coefficients by pieces (in the required modes).
3411 * We can't pass builtin_memset_gen_str as that emits RTL. */
3412 c = 1;
3413 if (host_integerp (len, 1)
3414 && !(optimize_size && tree_low_cst (len, 1) > 1)
3415 && can_store_by_pieces (tree_low_cst (len, 1),
3416 builtin_memset_read_str, &c, dest_align))
3418 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3419 val_rtx);
3420 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3421 builtin_memset_gen_str, val_rtx, dest_align, 0);
3423 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3424 dest_align))
3425 return 0;
3427 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3428 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3429 return dest_mem;
3432 if (target_char_cast (val, &c))
3433 return 0;
3435 if (c)
3437 if (host_integerp (len, 1)
3438 && !(optimize_size && tree_low_cst (len, 1) > 1)
3439 && can_store_by_pieces (tree_low_cst (len, 1),
3440 builtin_memset_read_str, &c, dest_align))
3441 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3442 builtin_memset_read_str, &c, dest_align, 0);
3443 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3444 dest_align))
3445 return 0;
3447 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3448 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3449 return dest_mem;
3452 set_mem_align (dest_mem, dest_align);
3453 dest_addr = clear_storage (dest_mem, len_rtx,
3454 CALL_EXPR_TAILCALL (orig_exp)
3455 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3457 if (dest_addr == 0)
3459 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3460 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3463 return dest_addr;
3467 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3468 if we failed the caller should emit a normal call. */
3470 static rtx
3471 expand_builtin_bzero (tree exp)
3473 tree arglist = TREE_OPERAND (exp, 1);
3474 tree dest, size, newarglist;
3476 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3477 return NULL_RTX;
3479 dest = TREE_VALUE (arglist);
3480 size = TREE_VALUE (TREE_CHAIN (arglist));
3482 /* New argument list transforming bzero(ptr x, int y) to
3483 memset(ptr x, int 0, size_t y). This is done this way
3484 so that if it isn't expanded inline, we fallback to
3485 calling bzero instead of memset. */
3487 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3488 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3489 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3491 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3494 /* Expand expression EXP, which is a call to the memcmp built-in function.
3495 ARGLIST is the argument list for this call. Return 0 if we failed and the
3496 caller should emit a normal call, otherwise try to get the result in
3497 TARGET, if convenient (and in mode MODE, if that's convenient). */
3499 static rtx
3500 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3501 enum machine_mode mode)
3503 if (!validate_arglist (arglist,
3504 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3505 return 0;
3506 else
3508 tree result = fold_builtin_memcmp (arglist);
3509 if (result)
3510 return expand_expr (result, target, mode, EXPAND_NORMAL);
3513 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3515 tree arg1 = TREE_VALUE (arglist);
3516 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3517 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3518 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3519 rtx result;
3520 rtx insn;
3522 int arg1_align
3523 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3524 int arg2_align
3525 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3526 enum machine_mode insn_mode;
3528 #ifdef HAVE_cmpmemsi
3529 if (HAVE_cmpmemsi)
3530 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3531 else
3532 #endif
3533 #ifdef HAVE_cmpstrnsi
3534 if (HAVE_cmpstrnsi)
3535 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3536 else
3537 #endif
3538 return 0;
3540 /* If we don't have POINTER_TYPE, call the function. */
3541 if (arg1_align == 0 || arg2_align == 0)
3542 return 0;
3544 /* Make a place to write the result of the instruction. */
3545 result = target;
3546 if (! (result != 0
3547 && REG_P (result) && GET_MODE (result) == insn_mode
3548 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3549 result = gen_reg_rtx (insn_mode);
3551 arg1_rtx = get_memory_rtx (arg1, len);
3552 arg2_rtx = get_memory_rtx (arg2, len);
3553 arg3_rtx = expand_normal (len);
3555 /* Set MEM_SIZE as appropriate. */
3556 if (GET_CODE (arg3_rtx) == CONST_INT)
3558 set_mem_size (arg1_rtx, arg3_rtx);
3559 set_mem_size (arg2_rtx, arg3_rtx);
3562 #ifdef HAVE_cmpmemsi
3563 if (HAVE_cmpmemsi)
3564 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3565 GEN_INT (MIN (arg1_align, arg2_align)));
3566 else
3567 #endif
3568 #ifdef HAVE_cmpstrnsi
3569 if (HAVE_cmpstrnsi)
3570 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3571 GEN_INT (MIN (arg1_align, arg2_align)));
3572 else
3573 #endif
3574 gcc_unreachable ();
3576 if (insn)
3577 emit_insn (insn);
3578 else
3579 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3580 TYPE_MODE (integer_type_node), 3,
3581 XEXP (arg1_rtx, 0), Pmode,
3582 XEXP (arg2_rtx, 0), Pmode,
3583 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3584 TYPE_UNSIGNED (sizetype)),
3585 TYPE_MODE (sizetype));
3587 /* Return the value in the proper mode for this function. */
3588 mode = TYPE_MODE (TREE_TYPE (exp));
3589 if (GET_MODE (result) == mode)
3590 return result;
3591 else if (target != 0)
3593 convert_move (target, result, 0);
3594 return target;
3596 else
3597 return convert_to_mode (mode, result, 0);
3599 #endif
3601 return 0;
3604 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3605 if we failed the caller should emit a normal call, otherwise try to get
3606 the result in TARGET, if convenient. */
3608 static rtx
3609 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3611 tree arglist = TREE_OPERAND (exp, 1);
3613 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3614 return 0;
3615 else
3617 tree result = fold_builtin_strcmp (arglist);
3618 if (result)
3619 return expand_expr (result, target, mode, EXPAND_NORMAL);
3622 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3623 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3624 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3626 rtx arg1_rtx, arg2_rtx;
3627 rtx result, insn = NULL_RTX;
3628 tree fndecl, fn;
3630 tree arg1 = TREE_VALUE (arglist);
3631 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3632 int arg1_align
3633 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3634 int arg2_align
3635 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3637 /* If we don't have POINTER_TYPE, call the function. */
3638 if (arg1_align == 0 || arg2_align == 0)
3639 return 0;
3641 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3642 arg1 = builtin_save_expr (arg1);
3643 arg2 = builtin_save_expr (arg2);
3645 arg1_rtx = get_memory_rtx (arg1, NULL);
3646 arg2_rtx = get_memory_rtx (arg2, NULL);
3648 #ifdef HAVE_cmpstrsi
3649 /* Try to call cmpstrsi. */
3650 if (HAVE_cmpstrsi)
3652 enum machine_mode insn_mode
3653 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3655 /* Make a place to write the result of the instruction. */
3656 result = target;
3657 if (! (result != 0
3658 && REG_P (result) && GET_MODE (result) == insn_mode
3659 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3660 result = gen_reg_rtx (insn_mode);
3662 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3663 GEN_INT (MIN (arg1_align, arg2_align)));
3665 #endif
3666 #if HAVE_cmpstrnsi
3667 /* Try to determine at least one length and call cmpstrnsi. */
3668 if (!insn && HAVE_cmpstrnsi)
3670 tree len;
3671 rtx arg3_rtx;
3673 enum machine_mode insn_mode
3674 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3675 tree len1 = c_strlen (arg1, 1);
3676 tree len2 = c_strlen (arg2, 1);
3678 if (len1)
3679 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3680 if (len2)
3681 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3683 /* If we don't have a constant length for the first, use the length
3684 of the second, if we know it. We don't require a constant for
3685 this case; some cost analysis could be done if both are available
3686 but neither is constant. For now, assume they're equally cheap,
3687 unless one has side effects. If both strings have constant lengths,
3688 use the smaller. */
3690 if (!len1)
3691 len = len2;
3692 else if (!len2)
3693 len = len1;
3694 else if (TREE_SIDE_EFFECTS (len1))
3695 len = len2;
3696 else if (TREE_SIDE_EFFECTS (len2))
3697 len = len1;
3698 else if (TREE_CODE (len1) != INTEGER_CST)
3699 len = len2;
3700 else if (TREE_CODE (len2) != INTEGER_CST)
3701 len = len1;
3702 else if (tree_int_cst_lt (len1, len2))
3703 len = len1;
3704 else
3705 len = len2;
3707 /* If both arguments have side effects, we cannot optimize. */
3708 if (!len || TREE_SIDE_EFFECTS (len))
3709 return 0;
3711 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3712 arg3_rtx = expand_normal (len);
3714 /* Make a place to write the result of the instruction. */
3715 result = target;
3716 if (! (result != 0
3717 && REG_P (result) && GET_MODE (result) == insn_mode
3718 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3719 result = gen_reg_rtx (insn_mode);
3721 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3722 GEN_INT (MIN (arg1_align, arg2_align)));
3724 #endif
3726 if (insn)
3728 emit_insn (insn);
3730 /* Return the value in the proper mode for this function. */
3731 mode = TYPE_MODE (TREE_TYPE (exp));
3732 if (GET_MODE (result) == mode)
3733 return result;
3734 if (target == 0)
3735 return convert_to_mode (mode, result, 0);
3736 convert_move (target, result, 0);
3737 return target;
3740 /* Expand the library call ourselves using a stabilized argument
3741 list to avoid re-evaluating the function's arguments twice. */
3742 arglist = build_tree_list (NULL_TREE, arg2);
3743 arglist = tree_cons (NULL_TREE, arg1, arglist);
3744 fndecl = get_callee_fndecl (exp);
3745 fn = build_function_call_expr (fndecl, arglist);
3746 if (TREE_CODE (fn) == CALL_EXPR)
3747 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3748 return expand_call (fn, target, target == const0_rtx);
3750 #endif
3751 return 0;
3754 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3755 if we failed the caller should emit a normal call, otherwise try to get
3756 the result in TARGET, if convenient. */
3758 static rtx
3759 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3761 tree arglist = TREE_OPERAND (exp, 1);
3763 if (!validate_arglist (arglist,
3764 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3765 return 0;
3766 else
3768 tree result = fold_builtin_strncmp (arglist);
3769 if (result)
3770 return expand_expr (result, target, mode, EXPAND_NORMAL);
3773 /* If c_strlen can determine an expression for one of the string
3774 lengths, and it doesn't have side effects, then emit cmpstrnsi
3775 using length MIN(strlen(string)+1, arg3). */
3776 #ifdef HAVE_cmpstrnsi
3777 if (HAVE_cmpstrnsi)
3779 tree arg1 = TREE_VALUE (arglist);
3780 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3781 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3782 tree len, len1, len2;
3783 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3784 rtx result, insn;
3785 tree fndecl, fn;
3787 int arg1_align
3788 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3789 int arg2_align
3790 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3791 enum machine_mode insn_mode
3792 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3794 len1 = c_strlen (arg1, 1);
3795 len2 = c_strlen (arg2, 1);
3797 if (len1)
3798 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3799 if (len2)
3800 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3802 /* If we don't have a constant length for the first, use the length
3803 of the second, if we know it. We don't require a constant for
3804 this case; some cost analysis could be done if both are available
3805 but neither is constant. For now, assume they're equally cheap,
3806 unless one has side effects. If both strings have constant lengths,
3807 use the smaller. */
3809 if (!len1)
3810 len = len2;
3811 else if (!len2)
3812 len = len1;
3813 else if (TREE_SIDE_EFFECTS (len1))
3814 len = len2;
3815 else if (TREE_SIDE_EFFECTS (len2))
3816 len = len1;
3817 else if (TREE_CODE (len1) != INTEGER_CST)
3818 len = len2;
3819 else if (TREE_CODE (len2) != INTEGER_CST)
3820 len = len1;
3821 else if (tree_int_cst_lt (len1, len2))
3822 len = len1;
3823 else
3824 len = len2;
3826 /* If both arguments have side effects, we cannot optimize. */
3827 if (!len || TREE_SIDE_EFFECTS (len))
3828 return 0;
3830 /* The actual new length parameter is MIN(len,arg3). */
3831 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3832 fold_convert (TREE_TYPE (len), arg3));
3834 /* If we don't have POINTER_TYPE, call the function. */
3835 if (arg1_align == 0 || arg2_align == 0)
3836 return 0;
3838 /* Make a place to write the result of the instruction. */
3839 result = target;
3840 if (! (result != 0
3841 && REG_P (result) && GET_MODE (result) == insn_mode
3842 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3843 result = gen_reg_rtx (insn_mode);
3845 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3846 arg1 = builtin_save_expr (arg1);
3847 arg2 = builtin_save_expr (arg2);
3848 len = builtin_save_expr (len);
3850 arg1_rtx = get_memory_rtx (arg1, len);
3851 arg2_rtx = get_memory_rtx (arg2, len);
3852 arg3_rtx = expand_normal (len);
3853 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3854 GEN_INT (MIN (arg1_align, arg2_align)));
3855 if (insn)
3857 emit_insn (insn);
3859 /* Return the value in the proper mode for this function. */
3860 mode = TYPE_MODE (TREE_TYPE (exp));
3861 if (GET_MODE (result) == mode)
3862 return result;
3863 if (target == 0)
3864 return convert_to_mode (mode, result, 0);
3865 convert_move (target, result, 0);
3866 return target;
3869 /* Expand the library call ourselves using a stabilized argument
3870 list to avoid re-evaluating the function's arguments twice. */
3871 arglist = build_tree_list (NULL_TREE, len);
3872 arglist = tree_cons (NULL_TREE, arg2, arglist);
3873 arglist = tree_cons (NULL_TREE, arg1, arglist);
3874 fndecl = get_callee_fndecl (exp);
3875 fn = build_function_call_expr (fndecl, arglist);
3876 if (TREE_CODE (fn) == CALL_EXPR)
3877 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3878 return expand_call (fn, target, target == const0_rtx);
3880 #endif
3881 return 0;
3884 /* Expand expression EXP, which is a call to the strcat builtin.
3885 Return 0 if we failed the caller should emit a normal call,
3886 otherwise try to get the result in TARGET, if convenient. */
3888 static rtx
3889 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3891 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3892 return 0;
3893 else
3895 tree dst = TREE_VALUE (arglist),
3896 src = TREE_VALUE (TREE_CHAIN (arglist));
3897 const char *p = c_getstr (src);
3899 /* If the string length is zero, return the dst parameter. */
3900 if (p && *p == '\0')
3901 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3903 if (!optimize_size)
3905 /* See if we can store by pieces into (dst + strlen(dst)). */
3906 tree newsrc, newdst,
3907 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3908 rtx insns;
3910 /* Stabilize the argument list. */
3911 newsrc = builtin_save_expr (src);
3912 if (newsrc != src)
3913 arglist = build_tree_list (NULL_TREE, newsrc);
3914 else
3915 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3917 dst = builtin_save_expr (dst);
3919 start_sequence ();
3921 /* Create strlen (dst). */
3922 newdst =
3923 build_function_call_expr (strlen_fn,
3924 build_tree_list (NULL_TREE, dst));
3925 /* Create (dst + (cast) strlen (dst)). */
3926 newdst = fold_convert (TREE_TYPE (dst), newdst);
3927 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3929 newdst = builtin_save_expr (newdst);
3930 arglist = tree_cons (NULL_TREE, newdst, arglist);
3932 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3934 end_sequence (); /* Stop sequence. */
3935 return 0;
3938 /* Output the entire sequence. */
3939 insns = get_insns ();
3940 end_sequence ();
3941 emit_insn (insns);
3943 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3946 return 0;
3950 /* Expand expression EXP, which is a call to the strncat builtin.
3951 Return 0 if we failed the caller should emit a normal call,
3952 otherwise try to get the result in TARGET, if convenient. */
3954 static rtx
3955 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3957 if (validate_arglist (arglist,
3958 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3960 tree result = fold_builtin_strncat (arglist);
3961 if (result)
3962 return expand_expr (result, target, mode, EXPAND_NORMAL);
3964 return 0;
3967 /* Expand expression EXP, which is a call to the strspn builtin.
3968 Return 0 if we failed the caller should emit a normal call,
3969 otherwise try to get the result in TARGET, if convenient. */
3971 static rtx
3972 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3974 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3976 tree result = fold_builtin_strspn (arglist);
3977 if (result)
3978 return expand_expr (result, target, mode, EXPAND_NORMAL);
3980 return 0;
3983 /* Expand expression EXP, which is a call to the strcspn builtin.
3984 Return 0 if we failed the caller should emit a normal call,
3985 otherwise try to get the result in TARGET, if convenient. */
3987 static rtx
3988 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3990 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3992 tree result = fold_builtin_strcspn (arglist);
3993 if (result)
3994 return expand_expr (result, target, mode, EXPAND_NORMAL);
3996 return 0;
3999 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4000 if that's convenient. */
4003 expand_builtin_saveregs (void)
4005 rtx val, seq;
4007 /* Don't do __builtin_saveregs more than once in a function.
4008 Save the result of the first call and reuse it. */
4009 if (saveregs_value != 0)
4010 return saveregs_value;
4012 /* When this function is called, it means that registers must be
4013 saved on entry to this function. So we migrate the call to the
4014 first insn of this function. */
4016 start_sequence ();
4018 /* Do whatever the machine needs done in this case. */
4019 val = targetm.calls.expand_builtin_saveregs ();
4021 seq = get_insns ();
4022 end_sequence ();
4024 saveregs_value = val;
4026 /* Put the insns after the NOTE that starts the function. If this
4027 is inside a start_sequence, make the outer-level insn chain current, so
4028 the code is placed at the start of the function. */
4029 push_topmost_sequence ();
4030 emit_insn_after (seq, entry_of_function ());
4031 pop_topmost_sequence ();
4033 return val;
4036 /* __builtin_args_info (N) returns word N of the arg space info
4037 for the current function. The number and meanings of words
4038 is controlled by the definition of CUMULATIVE_ARGS. */
4040 static rtx
4041 expand_builtin_args_info (tree arglist)
4043 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4044 int *word_ptr = (int *) &current_function_args_info;
4046 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4048 if (arglist != 0)
4050 if (!host_integerp (TREE_VALUE (arglist), 0))
4051 error ("argument of %<__builtin_args_info%> must be constant");
4052 else
4054 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4056 if (wordnum < 0 || wordnum >= nwords)
4057 error ("argument of %<__builtin_args_info%> out of range");
4058 else
4059 return GEN_INT (word_ptr[wordnum]);
4062 else
4063 error ("missing argument in %<__builtin_args_info%>");
4065 return const0_rtx;
4068 /* Expand a call to __builtin_next_arg. */
4070 static rtx
4071 expand_builtin_next_arg (void)
4073 /* Checking arguments is already done in fold_builtin_next_arg
4074 that must be called before this function. */
4075 return expand_binop (Pmode, add_optab,
4076 current_function_internal_arg_pointer,
4077 current_function_arg_offset_rtx,
4078 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4081 /* Make it easier for the backends by protecting the valist argument
4082 from multiple evaluations. */
4084 static tree
4085 stabilize_va_list (tree valist, int needs_lvalue)
4087 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4089 if (TREE_SIDE_EFFECTS (valist))
4090 valist = save_expr (valist);
4092 /* For this case, the backends will be expecting a pointer to
4093 TREE_TYPE (va_list_type_node), but it's possible we've
4094 actually been given an array (an actual va_list_type_node).
4095 So fix it. */
4096 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4098 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4099 valist = build_fold_addr_expr_with_type (valist, p1);
4102 else
4104 tree pt;
4106 if (! needs_lvalue)
4108 if (! TREE_SIDE_EFFECTS (valist))
4109 return valist;
4111 pt = build_pointer_type (va_list_type_node);
4112 valist = fold_build1 (ADDR_EXPR, pt, valist);
4113 TREE_SIDE_EFFECTS (valist) = 1;
4116 if (TREE_SIDE_EFFECTS (valist))
4117 valist = save_expr (valist);
4118 valist = build_fold_indirect_ref (valist);
4121 return valist;
4124 /* The "standard" definition of va_list is void*. */
4126 tree
4127 std_build_builtin_va_list (void)
4129 return ptr_type_node;
4132 /* The "standard" implementation of va_start: just assign `nextarg' to
4133 the variable. */
4135 void
4136 std_expand_builtin_va_start (tree valist, rtx nextarg)
4138 tree t;
4140 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4141 make_tree (ptr_type_node, nextarg));
4142 TREE_SIDE_EFFECTS (t) = 1;
4144 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4147 /* Expand ARGLIST, from a call to __builtin_va_start. */
4149 static rtx
4150 expand_builtin_va_start (tree arglist)
4152 rtx nextarg;
4153 tree chain, valist;
4155 chain = TREE_CHAIN (arglist);
4157 if (!chain)
4159 error ("too few arguments to function %<va_start%>");
4160 return const0_rtx;
4163 if (fold_builtin_next_arg (chain))
4164 return const0_rtx;
4166 nextarg = expand_builtin_next_arg ();
4167 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4169 #ifdef EXPAND_BUILTIN_VA_START
4170 EXPAND_BUILTIN_VA_START (valist, nextarg);
4171 #else
4172 std_expand_builtin_va_start (valist, nextarg);
4173 #endif
4175 return const0_rtx;
4178 /* The "standard" implementation of va_arg: read the value from the
4179 current (padded) address and increment by the (padded) size. */
4181 tree
4182 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4184 tree addr, t, type_size, rounded_size, valist_tmp;
4185 unsigned HOST_WIDE_INT align, boundary;
4186 bool indirect;
4188 #ifdef ARGS_GROW_DOWNWARD
4189 /* All of the alignment and movement below is for args-grow-up machines.
4190 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4191 implement their own specialized gimplify_va_arg_expr routines. */
4192 gcc_unreachable ();
4193 #endif
4195 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4196 if (indirect)
4197 type = build_pointer_type (type);
4199 align = PARM_BOUNDARY / BITS_PER_UNIT;
4200 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4202 /* Hoist the valist value into a temporary for the moment. */
4203 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4205 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4206 requires greater alignment, we must perform dynamic alignment. */
4207 if (boundary > align
4208 && !integer_zerop (TYPE_SIZE (type)))
4210 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4211 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4212 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4213 gimplify_and_add (t, pre_p);
4215 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4216 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4217 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4218 gimplify_and_add (t, pre_p);
4220 else
4221 boundary = align;
4223 /* If the actual alignment is less than the alignment of the type,
4224 adjust the type accordingly so that we don't assume strict alignment
4225 when deferencing the pointer. */
4226 boundary *= BITS_PER_UNIT;
4227 if (boundary < TYPE_ALIGN (type))
4229 type = build_variant_type_copy (type);
4230 TYPE_ALIGN (type) = boundary;
4233 /* Compute the rounded size of the type. */
4234 type_size = size_in_bytes (type);
4235 rounded_size = round_up (type_size, align);
4237 /* Reduce rounded_size so it's sharable with the postqueue. */
4238 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4240 /* Get AP. */
4241 addr = valist_tmp;
4242 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4244 /* Small args are padded downward. */
4245 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4246 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4247 size_binop (MINUS_EXPR, rounded_size, type_size));
4248 t = fold_convert (TREE_TYPE (addr), t);
4249 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4252 /* Compute new value for AP. */
4253 t = fold_convert (TREE_TYPE (valist), rounded_size);
4254 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4255 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4256 gimplify_and_add (t, pre_p);
4258 addr = fold_convert (build_pointer_type (type), addr);
4260 if (indirect)
4261 addr = build_va_arg_indirect_ref (addr);
4263 return build_va_arg_indirect_ref (addr);
4266 /* Build an indirect-ref expression over the given TREE, which represents a
4267 piece of a va_arg() expansion. */
4268 tree
4269 build_va_arg_indirect_ref (tree addr)
4271 addr = build_fold_indirect_ref (addr);
4273 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4274 mf_mark (addr);
4276 return addr;
4279 /* Return a dummy expression of type TYPE in order to keep going after an
4280 error. */
4282 static tree
4283 dummy_object (tree type)
4285 tree t = convert (build_pointer_type (type), null_pointer_node);
4286 return build1 (INDIRECT_REF, type, t);
4289 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4290 builtin function, but a very special sort of operator. */
4292 enum gimplify_status
4293 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4295 tree promoted_type, want_va_type, have_va_type;
4296 tree valist = TREE_OPERAND (*expr_p, 0);
4297 tree type = TREE_TYPE (*expr_p);
4298 tree t;
4300 /* Verify that valist is of the proper type. */
4301 want_va_type = va_list_type_node;
4302 have_va_type = TREE_TYPE (valist);
4304 if (have_va_type == error_mark_node)
4305 return GS_ERROR;
4307 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4309 /* If va_list is an array type, the argument may have decayed
4310 to a pointer type, e.g. by being passed to another function.
4311 In that case, unwrap both types so that we can compare the
4312 underlying records. */
4313 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4314 || POINTER_TYPE_P (have_va_type))
4316 want_va_type = TREE_TYPE (want_va_type);
4317 have_va_type = TREE_TYPE (have_va_type);
4321 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4323 error ("first argument to %<va_arg%> not of type %<va_list%>");
4324 return GS_ERROR;
4327 /* Generate a diagnostic for requesting data of a type that cannot
4328 be passed through `...' due to type promotion at the call site. */
4329 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4330 != type)
4332 static bool gave_help;
4334 /* Unfortunately, this is merely undefined, rather than a constraint
4335 violation, so we cannot make this an error. If this call is never
4336 executed, the program is still strictly conforming. */
4337 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4338 type, promoted_type);
4339 if (! gave_help)
4341 gave_help = true;
4342 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4343 promoted_type, type);
4346 /* We can, however, treat "undefined" any way we please.
4347 Call abort to encourage the user to fix the program. */
4348 inform ("if this code is reached, the program will abort");
4349 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4350 NULL);
4351 append_to_statement_list (t, pre_p);
4353 /* This is dead code, but go ahead and finish so that the
4354 mode of the result comes out right. */
4355 *expr_p = dummy_object (type);
4356 return GS_ALL_DONE;
4358 else
4360 /* Make it easier for the backends by protecting the valist argument
4361 from multiple evaluations. */
4362 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4364 /* For this case, the backends will be expecting a pointer to
4365 TREE_TYPE (va_list_type_node), but it's possible we've
4366 actually been given an array (an actual va_list_type_node).
4367 So fix it. */
4368 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4370 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4371 valist = build_fold_addr_expr_with_type (valist, p1);
4373 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4375 else
4376 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4378 if (!targetm.gimplify_va_arg_expr)
4379 /* FIXME:Once most targets are converted we should merely
4380 assert this is non-null. */
4381 return GS_ALL_DONE;
4383 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4384 return GS_OK;
4388 /* Expand ARGLIST, from a call to __builtin_va_end. */
4390 static rtx
4391 expand_builtin_va_end (tree arglist)
4393 tree valist = TREE_VALUE (arglist);
4395 /* Evaluate for side effects, if needed. I hate macros that don't
4396 do that. */
4397 if (TREE_SIDE_EFFECTS (valist))
4398 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4400 return const0_rtx;
4403 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4404 builtin rather than just as an assignment in stdarg.h because of the
4405 nastiness of array-type va_list types. */
4407 static rtx
4408 expand_builtin_va_copy (tree arglist)
4410 tree dst, src, t;
4412 dst = TREE_VALUE (arglist);
4413 src = TREE_VALUE (TREE_CHAIN (arglist));
4415 dst = stabilize_va_list (dst, 1);
4416 src = stabilize_va_list (src, 0);
4418 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4420 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4421 TREE_SIDE_EFFECTS (t) = 1;
4422 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4424 else
4426 rtx dstb, srcb, size;
4428 /* Evaluate to pointers. */
4429 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4430 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4431 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4432 VOIDmode, EXPAND_NORMAL);
4434 dstb = convert_memory_address (Pmode, dstb);
4435 srcb = convert_memory_address (Pmode, srcb);
4437 /* "Dereference" to BLKmode memories. */
4438 dstb = gen_rtx_MEM (BLKmode, dstb);
4439 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4440 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4441 srcb = gen_rtx_MEM (BLKmode, srcb);
4442 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4443 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4445 /* Copy. */
4446 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4449 return const0_rtx;
4452 /* Expand a call to one of the builtin functions __builtin_frame_address or
4453 __builtin_return_address. */
4455 static rtx
4456 expand_builtin_frame_address (tree fndecl, tree arglist)
4458 /* The argument must be a nonnegative integer constant.
4459 It counts the number of frames to scan up the stack.
4460 The value is the return address saved in that frame. */
4461 if (arglist == 0)
4462 /* Warning about missing arg was already issued. */
4463 return const0_rtx;
4464 else if (! host_integerp (TREE_VALUE (arglist), 1))
4466 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4467 error ("invalid argument to %<__builtin_frame_address%>");
4468 else
4469 error ("invalid argument to %<__builtin_return_address%>");
4470 return const0_rtx;
4472 else
4474 rtx tem
4475 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4476 tree_low_cst (TREE_VALUE (arglist), 1));
4478 /* Some ports cannot access arbitrary stack frames. */
4479 if (tem == NULL)
4481 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4482 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4483 else
4484 warning (0, "unsupported argument to %<__builtin_return_address%>");
4485 return const0_rtx;
4488 /* For __builtin_frame_address, return what we've got. */
4489 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4490 return tem;
4492 if (!REG_P (tem)
4493 && ! CONSTANT_P (tem))
4494 tem = copy_to_mode_reg (Pmode, tem);
4495 return tem;
4499 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4500 we failed and the caller should emit a normal call, otherwise try to get
4501 the result in TARGET, if convenient. */
4503 static rtx
4504 expand_builtin_alloca (tree arglist, rtx target)
4506 rtx op0;
4507 rtx result;
4509 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4510 should always expand to function calls. These can be intercepted
4511 in libmudflap. */
4512 if (flag_mudflap)
4513 return 0;
4515 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4516 return 0;
4518 /* Compute the argument. */
4519 op0 = expand_normal (TREE_VALUE (arglist));
4521 /* Allocate the desired space. */
4522 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4523 result = convert_memory_address (ptr_mode, result);
4525 return result;
4528 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4529 Return 0 if a normal call should be emitted rather than expanding the
4530 function in-line. If convenient, the result should be placed in TARGET.
4531 SUBTARGET may be used as the target for computing one of EXP's operands. */
4533 static rtx
4534 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4535 rtx subtarget, optab op_optab)
4537 rtx op0;
4538 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4539 return 0;
4541 /* Compute the argument. */
4542 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4543 /* Compute op, into TARGET if possible.
4544 Set TARGET to wherever the result comes back. */
4545 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4546 op_optab, op0, target, 1);
4547 gcc_assert (target);
4549 return convert_to_mode (target_mode, target, 0);
4552 /* If the string passed to fputs is a constant and is one character
4553 long, we attempt to transform this call into __builtin_fputc(). */
4555 static rtx
4556 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4558 /* Verify the arguments in the original call. */
4559 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4561 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4562 unlocked, NULL_TREE);
4563 if (result)
4564 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4566 return 0;
4569 /* Expand a call to __builtin_expect. We return our argument and emit a
4570 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4571 a non-jump context. */
4573 static rtx
4574 expand_builtin_expect (tree arglist, rtx target)
4576 tree exp, c;
4577 rtx note, rtx_c;
4579 if (arglist == NULL_TREE
4580 || TREE_CHAIN (arglist) == NULL_TREE)
4581 return const0_rtx;
4582 exp = TREE_VALUE (arglist);
4583 c = TREE_VALUE (TREE_CHAIN (arglist));
4585 if (TREE_CODE (c) != INTEGER_CST)
4587 error ("second argument to %<__builtin_expect%> must be a constant");
4588 c = integer_zero_node;
4591 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4593 /* Don't bother with expected value notes for integral constants. */
4594 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4596 /* We do need to force this into a register so that we can be
4597 moderately sure to be able to correctly interpret the branch
4598 condition later. */
4599 target = force_reg (GET_MODE (target), target);
4601 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4603 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4604 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4607 return target;
4610 /* Like expand_builtin_expect, except do this in a jump context. This is
4611 called from do_jump if the conditional is a __builtin_expect. Return either
4612 a list of insns to emit the jump or NULL if we cannot optimize
4613 __builtin_expect. We need to optimize this at jump time so that machines
4614 like the PowerPC don't turn the test into a SCC operation, and then jump
4615 based on the test being 0/1. */
4618 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4620 tree arglist = TREE_OPERAND (exp, 1);
4621 tree arg0 = TREE_VALUE (arglist);
4622 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4623 rtx ret = NULL_RTX;
4625 /* Only handle __builtin_expect (test, 0) and
4626 __builtin_expect (test, 1). */
4627 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4628 && (integer_zerop (arg1) || integer_onep (arg1)))
4630 rtx insn, drop_through_label, temp;
4632 /* Expand the jump insns. */
4633 start_sequence ();
4634 do_jump (arg0, if_false_label, if_true_label);
4635 ret = get_insns ();
4637 drop_through_label = get_last_insn ();
4638 if (drop_through_label && NOTE_P (drop_through_label))
4639 drop_through_label = prev_nonnote_insn (drop_through_label);
4640 if (drop_through_label && !LABEL_P (drop_through_label))
4641 drop_through_label = NULL_RTX;
4642 end_sequence ();
4644 if (! if_true_label)
4645 if_true_label = drop_through_label;
4646 if (! if_false_label)
4647 if_false_label = drop_through_label;
4649 /* Go through and add the expect's to each of the conditional jumps. */
4650 insn = ret;
4651 while (insn != NULL_RTX)
4653 rtx next = NEXT_INSN (insn);
4655 if (JUMP_P (insn) && any_condjump_p (insn))
4657 rtx ifelse = SET_SRC (pc_set (insn));
4658 rtx then_dest = XEXP (ifelse, 1);
4659 rtx else_dest = XEXP (ifelse, 2);
4660 int taken = -1;
4662 /* First check if we recognize any of the labels. */
4663 if (GET_CODE (then_dest) == LABEL_REF
4664 && XEXP (then_dest, 0) == if_true_label)
4665 taken = 1;
4666 else if (GET_CODE (then_dest) == LABEL_REF
4667 && XEXP (then_dest, 0) == if_false_label)
4668 taken = 0;
4669 else if (GET_CODE (else_dest) == LABEL_REF
4670 && XEXP (else_dest, 0) == if_false_label)
4671 taken = 1;
4672 else if (GET_CODE (else_dest) == LABEL_REF
4673 && XEXP (else_dest, 0) == if_true_label)
4674 taken = 0;
4675 /* Otherwise check where we drop through. */
4676 else if (else_dest == pc_rtx)
4678 if (next && NOTE_P (next))
4679 next = next_nonnote_insn (next);
4681 if (next && JUMP_P (next)
4682 && any_uncondjump_p (next))
4683 temp = XEXP (SET_SRC (pc_set (next)), 0);
4684 else
4685 temp = next;
4687 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4688 else that can't possibly match either target label. */
4689 if (temp == if_false_label)
4690 taken = 1;
4691 else if (temp == if_true_label)
4692 taken = 0;
4694 else if (then_dest == pc_rtx)
4696 if (next && NOTE_P (next))
4697 next = next_nonnote_insn (next);
4699 if (next && JUMP_P (next)
4700 && any_uncondjump_p (next))
4701 temp = XEXP (SET_SRC (pc_set (next)), 0);
4702 else
4703 temp = next;
4705 if (temp == if_false_label)
4706 taken = 0;
4707 else if (temp == if_true_label)
4708 taken = 1;
4711 if (taken != -1)
4713 /* If the test is expected to fail, reverse the
4714 probabilities. */
4715 if (integer_zerop (arg1))
4716 taken = 1 - taken;
4717 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4721 insn = next;
4725 return ret;
4728 void
4729 expand_builtin_trap (void)
4731 #ifdef HAVE_trap
4732 if (HAVE_trap)
4733 emit_insn (gen_trap ());
4734 else
4735 #endif
4736 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4737 emit_barrier ();
4740 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4741 Return 0 if a normal call should be emitted rather than expanding
4742 the function inline. If convenient, the result should be placed
4743 in TARGET. SUBTARGET may be used as the target for computing
4744 the operand. */
4746 static rtx
4747 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4749 enum machine_mode mode;
4750 tree arg;
4751 rtx op0;
4753 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4754 return 0;
4756 arg = TREE_VALUE (arglist);
4757 mode = TYPE_MODE (TREE_TYPE (arg));
4758 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4759 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4762 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4763 Return NULL is a normal call should be emitted rather than expanding the
4764 function inline. If convenient, the result should be placed in TARGET.
4765 SUBTARGET may be used as the target for computing the operand. */
4767 static rtx
4768 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4770 rtx op0, op1;
4771 tree arg;
4773 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4774 return 0;
4776 arg = TREE_VALUE (arglist);
4777 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4779 arg = TREE_VALUE (TREE_CHAIN (arglist));
4780 op1 = expand_normal (arg);
4782 return expand_copysign (op0, op1, target);
4785 /* Create a new constant string literal and return a char* pointer to it.
4786 The STRING_CST value is the LEN characters at STR. */
4787 tree
4788 build_string_literal (int len, const char *str)
4790 tree t, elem, index, type;
4792 t = build_string (len, str);
4793 elem = build_type_variant (char_type_node, 1, 0);
4794 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4795 type = build_array_type (elem, index);
4796 TREE_TYPE (t) = type;
4797 TREE_CONSTANT (t) = 1;
4798 TREE_INVARIANT (t) = 1;
4799 TREE_READONLY (t) = 1;
4800 TREE_STATIC (t) = 1;
4802 type = build_pointer_type (type);
4803 t = build1 (ADDR_EXPR, type, t);
4805 type = build_pointer_type (elem);
4806 t = build1 (NOP_EXPR, type, t);
4807 return t;
4810 /* Expand EXP, a call to printf or printf_unlocked.
4811 Return 0 if a normal call should be emitted rather than transforming
4812 the function inline. If convenient, the result should be placed in
4813 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4814 call. */
4815 static rtx
4816 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4817 bool unlocked)
4819 tree arglist = TREE_OPERAND (exp, 1);
4820 /* If we're using an unlocked function, assume the other unlocked
4821 functions exist explicitly. */
4822 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4823 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4824 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4825 : implicit_built_in_decls[BUILT_IN_PUTS];
4826 const char *fmt_str;
4827 tree fn, fmt, arg;
4829 /* If the return value is used, don't do the transformation. */
4830 if (target != const0_rtx)
4831 return 0;
4833 /* Verify the required arguments in the original call. */
4834 if (! arglist)
4835 return 0;
4836 fmt = TREE_VALUE (arglist);
4837 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4838 return 0;
4839 arglist = TREE_CHAIN (arglist);
4841 /* Check whether the format is a literal string constant. */
4842 fmt_str = c_getstr (fmt);
4843 if (fmt_str == NULL)
4844 return 0;
4846 if (!init_target_chars())
4847 return 0;
4849 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4850 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4852 if (! arglist
4853 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4854 || TREE_CHAIN (arglist))
4855 return 0;
4856 fn = fn_puts;
4858 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4859 else if (strcmp (fmt_str, target_percent_c) == 0)
4861 if (! arglist
4862 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4863 || TREE_CHAIN (arglist))
4864 return 0;
4865 fn = fn_putchar;
4867 else
4869 /* We can't handle anything else with % args or %% ... yet. */
4870 if (strchr (fmt_str, target_percent))
4871 return 0;
4873 if (arglist)
4874 return 0;
4876 /* If the format specifier was "", printf does nothing. */
4877 if (fmt_str[0] == '\0')
4878 return const0_rtx;
4879 /* If the format specifier has length of 1, call putchar. */
4880 if (fmt_str[1] == '\0')
4882 /* Given printf("c"), (where c is any one character,)
4883 convert "c"[0] to an int and pass that to the replacement
4884 function. */
4885 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4886 arglist = build_tree_list (NULL_TREE, arg);
4887 fn = fn_putchar;
4889 else
4891 /* If the format specifier was "string\n", call puts("string"). */
4892 size_t len = strlen (fmt_str);
4893 if ((unsigned char)fmt_str[len - 1] == target_newline)
4895 /* Create a NUL-terminated string that's one char shorter
4896 than the original, stripping off the trailing '\n'. */
4897 char *newstr = alloca (len);
4898 memcpy (newstr, fmt_str, len - 1);
4899 newstr[len - 1] = 0;
4901 arg = build_string_literal (len, newstr);
4902 arglist = build_tree_list (NULL_TREE, arg);
4903 fn = fn_puts;
4905 else
4906 /* We'd like to arrange to call fputs(string,stdout) here,
4907 but we need stdout and don't have a way to get it yet. */
4908 return 0;
4912 if (!fn)
4913 return 0;
4914 fn = build_function_call_expr (fn, arglist);
4915 if (TREE_CODE (fn) == CALL_EXPR)
4916 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4917 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4920 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4921 Return 0 if a normal call should be emitted rather than transforming
4922 the function inline. If convenient, the result should be placed in
4923 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4924 call. */
4925 static rtx
4926 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4927 bool unlocked)
4929 tree arglist = TREE_OPERAND (exp, 1);
4930 /* If we're using an unlocked function, assume the other unlocked
4931 functions exist explicitly. */
4932 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4933 : implicit_built_in_decls[BUILT_IN_FPUTC];
4934 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4935 : implicit_built_in_decls[BUILT_IN_FPUTS];
4936 const char *fmt_str;
4937 tree fn, fmt, fp, arg;
4939 /* If the return value is used, don't do the transformation. */
4940 if (target != const0_rtx)
4941 return 0;
4943 /* Verify the required arguments in the original call. */
4944 if (! arglist)
4945 return 0;
4946 fp = TREE_VALUE (arglist);
4947 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4948 return 0;
4949 arglist = TREE_CHAIN (arglist);
4950 if (! arglist)
4951 return 0;
4952 fmt = TREE_VALUE (arglist);
4953 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4954 return 0;
4955 arglist = TREE_CHAIN (arglist);
4957 /* Check whether the format is a literal string constant. */
4958 fmt_str = c_getstr (fmt);
4959 if (fmt_str == NULL)
4960 return 0;
4962 if (!init_target_chars())
4963 return 0;
4965 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4966 if (strcmp (fmt_str, target_percent_s) == 0)
4968 if (! arglist
4969 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4970 || TREE_CHAIN (arglist))
4971 return 0;
4972 arg = TREE_VALUE (arglist);
4973 arglist = build_tree_list (NULL_TREE, fp);
4974 arglist = tree_cons (NULL_TREE, arg, arglist);
4975 fn = fn_fputs;
4977 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4978 else if (strcmp (fmt_str, target_percent_c) == 0)
4980 if (! arglist
4981 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4982 || TREE_CHAIN (arglist))
4983 return 0;
4984 arg = TREE_VALUE (arglist);
4985 arglist = build_tree_list (NULL_TREE, fp);
4986 arglist = tree_cons (NULL_TREE, arg, arglist);
4987 fn = fn_fputc;
4989 else
4991 /* We can't handle anything else with % args or %% ... yet. */
4992 if (strchr (fmt_str, target_percent))
4993 return 0;
4995 if (arglist)
4996 return 0;
4998 /* If the format specifier was "", fprintf does nothing. */
4999 if (fmt_str[0] == '\0')
5001 /* Evaluate and ignore FILE* argument for side-effects. */
5002 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5003 return const0_rtx;
5006 /* When "string" doesn't contain %, replace all cases of
5007 fprintf(stream,string) with fputs(string,stream). The fputs
5008 builtin will take care of special cases like length == 1. */
5009 arglist = build_tree_list (NULL_TREE, fp);
5010 arglist = tree_cons (NULL_TREE, fmt, arglist);
5011 fn = fn_fputs;
5014 if (!fn)
5015 return 0;
5016 fn = build_function_call_expr (fn, arglist);
5017 if (TREE_CODE (fn) == CALL_EXPR)
5018 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5019 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5022 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5023 a normal call should be emitted rather than expanding the function
5024 inline. If convenient, the result should be placed in TARGET with
5025 mode MODE. */
5027 static rtx
5028 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5030 tree orig_arglist, dest, fmt;
5031 const char *fmt_str;
5033 orig_arglist = arglist;
5035 /* Verify the required arguments in the original call. */
5036 if (! arglist)
5037 return 0;
5038 dest = TREE_VALUE (arglist);
5039 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5040 return 0;
5041 arglist = TREE_CHAIN (arglist);
5042 if (! arglist)
5043 return 0;
5044 fmt = TREE_VALUE (arglist);
5045 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5046 return 0;
5047 arglist = TREE_CHAIN (arglist);
5049 /* Check whether the format is a literal string constant. */
5050 fmt_str = c_getstr (fmt);
5051 if (fmt_str == NULL)
5052 return 0;
5054 if (!init_target_chars())
5055 return 0;
5057 /* If the format doesn't contain % args or %%, use strcpy. */
5058 if (strchr (fmt_str, target_percent) == 0)
5060 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5061 tree exp;
5063 if (arglist || ! fn)
5064 return 0;
5065 expand_expr (build_function_call_expr (fn, orig_arglist),
5066 const0_rtx, VOIDmode, EXPAND_NORMAL);
5067 if (target == const0_rtx)
5068 return const0_rtx;
5069 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5070 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5072 /* If the format is "%s", use strcpy if the result isn't used. */
5073 else if (strcmp (fmt_str, target_percent_s) == 0)
5075 tree fn, arg, len;
5076 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5078 if (! fn)
5079 return 0;
5081 if (! arglist || TREE_CHAIN (arglist))
5082 return 0;
5083 arg = TREE_VALUE (arglist);
5084 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5085 return 0;
5087 if (target != const0_rtx)
5089 len = c_strlen (arg, 1);
5090 if (! len || TREE_CODE (len) != INTEGER_CST)
5091 return 0;
5093 else
5094 len = NULL_TREE;
5096 arglist = build_tree_list (NULL_TREE, arg);
5097 arglist = tree_cons (NULL_TREE, dest, arglist);
5098 expand_expr (build_function_call_expr (fn, arglist),
5099 const0_rtx, VOIDmode, EXPAND_NORMAL);
5101 if (target == const0_rtx)
5102 return const0_rtx;
5103 return expand_expr (len, target, mode, EXPAND_NORMAL);
5106 return 0;
5109 /* Expand a call to either the entry or exit function profiler. */
5111 static rtx
5112 expand_builtin_profile_func (bool exitp)
5114 rtx this, which;
5116 this = DECL_RTL (current_function_decl);
5117 gcc_assert (MEM_P (this));
5118 this = XEXP (this, 0);
5120 if (exitp)
5121 which = profile_function_exit_libfunc;
5122 else
5123 which = profile_function_entry_libfunc;
5125 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5126 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5128 Pmode);
5130 return const0_rtx;
5133 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5135 static rtx
5136 round_trampoline_addr (rtx tramp)
5138 rtx temp, addend, mask;
5140 /* If we don't need too much alignment, we'll have been guaranteed
5141 proper alignment by get_trampoline_type. */
5142 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5143 return tramp;
5145 /* Round address up to desired boundary. */
5146 temp = gen_reg_rtx (Pmode);
5147 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5148 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5150 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5151 temp, 0, OPTAB_LIB_WIDEN);
5152 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5153 temp, 0, OPTAB_LIB_WIDEN);
5155 return tramp;
5158 static rtx
5159 expand_builtin_init_trampoline (tree arglist)
5161 tree t_tramp, t_func, t_chain;
5162 rtx r_tramp, r_func, r_chain;
5163 #ifdef TRAMPOLINE_TEMPLATE
5164 rtx blktramp;
5165 #endif
5167 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5168 POINTER_TYPE, VOID_TYPE))
5169 return NULL_RTX;
5171 t_tramp = TREE_VALUE (arglist);
5172 arglist = TREE_CHAIN (arglist);
5173 t_func = TREE_VALUE (arglist);
5174 arglist = TREE_CHAIN (arglist);
5175 t_chain = TREE_VALUE (arglist);
5177 r_tramp = expand_normal (t_tramp);
5178 r_func = expand_normal (t_func);
5179 r_chain = expand_normal (t_chain);
5181 /* Generate insns to initialize the trampoline. */
5182 r_tramp = round_trampoline_addr (r_tramp);
5183 #ifdef TRAMPOLINE_TEMPLATE
5184 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5185 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5186 emit_block_move (blktramp, assemble_trampoline_template (),
5187 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5188 #endif
5189 trampolines_created = 1;
5190 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5192 return const0_rtx;
5195 static rtx
5196 expand_builtin_adjust_trampoline (tree arglist)
5198 rtx tramp;
5200 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5201 return NULL_RTX;
5203 tramp = expand_normal (TREE_VALUE (arglist));
5204 tramp = round_trampoline_addr (tramp);
5205 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5206 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5207 #endif
5209 return tramp;
5212 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5213 Return NULL_RTX if a normal call should be emitted rather than expanding
5214 the function in-line. EXP is the expression that is a call to the builtin
5215 function; if convenient, the result should be placed in TARGET. */
5217 static rtx
5218 expand_builtin_signbit (tree exp, rtx target)
5220 const struct real_format *fmt;
5221 enum machine_mode fmode, imode, rmode;
5222 HOST_WIDE_INT hi, lo;
5223 tree arg, arglist;
5224 int word, bitpos;
5225 rtx temp;
5227 arglist = TREE_OPERAND (exp, 1);
5228 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5229 return 0;
5231 arg = TREE_VALUE (arglist);
5232 fmode = TYPE_MODE (TREE_TYPE (arg));
5233 rmode = TYPE_MODE (TREE_TYPE (exp));
5234 fmt = REAL_MODE_FORMAT (fmode);
5236 /* For floating point formats without a sign bit, implement signbit
5237 as "ARG < 0.0". */
5238 bitpos = fmt->signbit_ro;
5239 if (bitpos < 0)
5241 /* But we can't do this if the format supports signed zero. */
5242 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5243 return 0;
5245 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5246 build_real (TREE_TYPE (arg), dconst0));
5247 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5250 temp = expand_normal (arg);
5251 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5253 imode = int_mode_for_mode (fmode);
5254 if (imode == BLKmode)
5255 return 0;
5256 temp = gen_lowpart (imode, temp);
5258 else
5260 imode = word_mode;
5261 /* Handle targets with different FP word orders. */
5262 if (FLOAT_WORDS_BIG_ENDIAN)
5263 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5264 else
5265 word = bitpos / BITS_PER_WORD;
5266 temp = operand_subword_force (temp, word, fmode);
5267 bitpos = bitpos % BITS_PER_WORD;
5270 /* Force the intermediate word_mode (or narrower) result into a
5271 register. This avoids attempting to create paradoxical SUBREGs
5272 of floating point modes below. */
5273 temp = force_reg (imode, temp);
5275 /* If the bitpos is within the "result mode" lowpart, the operation
5276 can be implement with a single bitwise AND. Otherwise, we need
5277 a right shift and an AND. */
5279 if (bitpos < GET_MODE_BITSIZE (rmode))
5281 if (bitpos < HOST_BITS_PER_WIDE_INT)
5283 hi = 0;
5284 lo = (HOST_WIDE_INT) 1 << bitpos;
5286 else
5288 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5289 lo = 0;
5292 if (imode != rmode)
5293 temp = gen_lowpart (rmode, temp);
5294 temp = expand_binop (rmode, and_optab, temp,
5295 immed_double_const (lo, hi, rmode),
5296 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5298 else
5300 /* Perform a logical right shift to place the signbit in the least
5301 significant bit, then truncate the result to the desired mode
5302 and mask just this bit. */
5303 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5304 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5305 temp = gen_lowpart (rmode, temp);
5306 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5307 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5310 return temp;
5313 /* Expand fork or exec calls. TARGET is the desired target of the
5314 call. ARGLIST is the list of arguments of the call. FN is the
5315 identificator of the actual function. IGNORE is nonzero if the
5316 value is to be ignored. */
5318 static rtx
5319 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5321 tree id, decl;
5322 tree call;
5324 /* If we are not profiling, just call the function. */
5325 if (!profile_arc_flag)
5326 return NULL_RTX;
5328 /* Otherwise call the wrapper. This should be equivalent for the rest of
5329 compiler, so the code does not diverge, and the wrapper may run the
5330 code necessary for keeping the profiling sane. */
5332 switch (DECL_FUNCTION_CODE (fn))
5334 case BUILT_IN_FORK:
5335 id = get_identifier ("__gcov_fork");
5336 break;
5338 case BUILT_IN_EXECL:
5339 id = get_identifier ("__gcov_execl");
5340 break;
5342 case BUILT_IN_EXECV:
5343 id = get_identifier ("__gcov_execv");
5344 break;
5346 case BUILT_IN_EXECLP:
5347 id = get_identifier ("__gcov_execlp");
5348 break;
5350 case BUILT_IN_EXECLE:
5351 id = get_identifier ("__gcov_execle");
5352 break;
5354 case BUILT_IN_EXECVP:
5355 id = get_identifier ("__gcov_execvp");
5356 break;
5358 case BUILT_IN_EXECVE:
5359 id = get_identifier ("__gcov_execve");
5360 break;
5362 default:
5363 gcc_unreachable ();
5366 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5367 DECL_EXTERNAL (decl) = 1;
5368 TREE_PUBLIC (decl) = 1;
5369 DECL_ARTIFICIAL (decl) = 1;
5370 TREE_NOTHROW (decl) = 1;
5371 call = build_function_call_expr (decl, arglist);
5373 return expand_call (call, target, ignore);
5377 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5378 the pointer in these functions is void*, the tree optimizers may remove
5379 casts. The mode computed in expand_builtin isn't reliable either, due
5380 to __sync_bool_compare_and_swap.
5382 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5383 group of builtins. This gives us log2 of the mode size. */
5385 static inline enum machine_mode
5386 get_builtin_sync_mode (int fcode_diff)
5388 /* The size is not negotiable, so ask not to get BLKmode in return
5389 if the target indicates that a smaller size would be better. */
5390 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5393 /* Expand the memory expression LOC and return the appropriate memory operand
5394 for the builtin_sync operations. */
5396 static rtx
5397 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5399 rtx addr, mem;
5401 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5403 /* Note that we explicitly do not want any alias information for this
5404 memory, so that we kill all other live memories. Otherwise we don't
5405 satisfy the full barrier semantics of the intrinsic. */
5406 mem = validize_mem (gen_rtx_MEM (mode, addr));
5408 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5409 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5410 MEM_VOLATILE_P (mem) = 1;
5412 return mem;
5415 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5416 ARGLIST is the operands list to the function. CODE is the rtx code
5417 that corresponds to the arithmetic or logical operation from the name;
5418 an exception here is that NOT actually means NAND. TARGET is an optional
5419 place for us to store the results; AFTER is true if this is the
5420 fetch_and_xxx form. IGNORE is true if we don't actually care about
5421 the result of the operation at all. */
5423 static rtx
5424 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5425 enum rtx_code code, bool after,
5426 rtx target, bool ignore)
5428 rtx val, mem;
5430 /* Expand the operands. */
5431 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5433 arglist = TREE_CHAIN (arglist);
5434 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5436 if (ignore)
5437 return expand_sync_operation (mem, val, code);
5438 else
5439 return expand_sync_fetch_operation (mem, val, code, after, target);
5442 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5443 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5444 true if this is the boolean form. TARGET is a place for us to store the
5445 results; this is NOT optional if IS_BOOL is true. */
5447 static rtx
5448 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5449 bool is_bool, rtx target)
5451 rtx old_val, new_val, mem;
5453 /* Expand the operands. */
5454 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5456 arglist = TREE_CHAIN (arglist);
5457 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5459 arglist = TREE_CHAIN (arglist);
5460 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5462 if (is_bool)
5463 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5464 else
5465 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5468 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5469 general form is actually an atomic exchange, and some targets only
5470 support a reduced form with the second argument being a constant 1.
5471 ARGLIST is the operands list to the function; TARGET is an optional
5472 place for us to store the results. */
5474 static rtx
5475 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5476 rtx target)
5478 rtx val, mem;
5480 /* Expand the operands. */
5481 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5483 arglist = TREE_CHAIN (arglist);
5484 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5486 return expand_sync_lock_test_and_set (mem, val, target);
5489 /* Expand the __sync_synchronize intrinsic. */
5491 static void
5492 expand_builtin_synchronize (void)
5494 tree x;
5496 #ifdef HAVE_memory_barrier
5497 if (HAVE_memory_barrier)
5499 emit_insn (gen_memory_barrier ());
5500 return;
5502 #endif
5504 /* If no explicit memory barrier instruction is available, create an
5505 empty asm stmt with a memory clobber. */
5506 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5507 tree_cons (NULL, build_string (6, "memory"), NULL));
5508 ASM_VOLATILE_P (x) = 1;
5509 expand_asm_expr (x);
5512 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5513 to the function. */
5515 static void
5516 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5518 enum insn_code icode;
5519 rtx mem, insn;
5520 rtx val = const0_rtx;
5522 /* Expand the operands. */
5523 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5525 /* If there is an explicit operation in the md file, use it. */
5526 icode = sync_lock_release[mode];
5527 if (icode != CODE_FOR_nothing)
5529 if (!insn_data[icode].operand[1].predicate (val, mode))
5530 val = force_reg (mode, val);
5532 insn = GEN_FCN (icode) (mem, val);
5533 if (insn)
5535 emit_insn (insn);
5536 return;
5540 /* Otherwise we can implement this operation by emitting a barrier
5541 followed by a store of zero. */
5542 expand_builtin_synchronize ();
5543 emit_move_insn (mem, val);
5546 /* Expand an expression EXP that calls a built-in function,
5547 with result going to TARGET if that's convenient
5548 (and in mode MODE if that's convenient).
5549 SUBTARGET may be used as the target for computing one of EXP's operands.
5550 IGNORE is nonzero if the value is to be ignored. */
5553 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5554 int ignore)
5556 tree fndecl = get_callee_fndecl (exp);
5557 tree arglist = TREE_OPERAND (exp, 1);
5558 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5559 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5561 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5562 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5564 /* When not optimizing, generate calls to library functions for a certain
5565 set of builtins. */
5566 if (!optimize
5567 && !called_as_built_in (fndecl)
5568 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5569 && fcode != BUILT_IN_ALLOCA)
5570 return expand_call (exp, target, ignore);
5572 /* The built-in function expanders test for target == const0_rtx
5573 to determine whether the function's result will be ignored. */
5574 if (ignore)
5575 target = const0_rtx;
5577 /* If the result of a pure or const built-in function is ignored, and
5578 none of its arguments are volatile, we can avoid expanding the
5579 built-in call and just evaluate the arguments for side-effects. */
5580 if (target == const0_rtx
5581 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5583 bool volatilep = false;
5584 tree arg;
5586 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5587 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5589 volatilep = true;
5590 break;
5593 if (! volatilep)
5595 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5596 expand_expr (TREE_VALUE (arg), const0_rtx,
5597 VOIDmode, EXPAND_NORMAL);
5598 return const0_rtx;
5602 switch (fcode)
5604 CASE_FLT_FN (BUILT_IN_FABS):
5605 target = expand_builtin_fabs (arglist, target, subtarget);
5606 if (target)
5607 return target;
5608 break;
5610 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5611 target = expand_builtin_copysign (arglist, target, subtarget);
5612 if (target)
5613 return target;
5614 break;
5616 /* Just do a normal library call if we were unable to fold
5617 the values. */
5618 CASE_FLT_FN (BUILT_IN_CABS):
5619 break;
5621 CASE_FLT_FN (BUILT_IN_EXP):
5622 CASE_FLT_FN (BUILT_IN_EXP10):
5623 CASE_FLT_FN (BUILT_IN_POW10):
5624 CASE_FLT_FN (BUILT_IN_EXP2):
5625 CASE_FLT_FN (BUILT_IN_EXPM1):
5626 CASE_FLT_FN (BUILT_IN_LOGB):
5627 CASE_FLT_FN (BUILT_IN_ILOGB):
5628 CASE_FLT_FN (BUILT_IN_LOG):
5629 CASE_FLT_FN (BUILT_IN_LOG10):
5630 CASE_FLT_FN (BUILT_IN_LOG2):
5631 CASE_FLT_FN (BUILT_IN_LOG1P):
5632 CASE_FLT_FN (BUILT_IN_TAN):
5633 CASE_FLT_FN (BUILT_IN_ASIN):
5634 CASE_FLT_FN (BUILT_IN_ACOS):
5635 CASE_FLT_FN (BUILT_IN_ATAN):
5636 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5637 because of possible accuracy problems. */
5638 if (! flag_unsafe_math_optimizations)
5639 break;
5640 CASE_FLT_FN (BUILT_IN_SQRT):
5641 CASE_FLT_FN (BUILT_IN_FLOOR):
5642 CASE_FLT_FN (BUILT_IN_CEIL):
5643 CASE_FLT_FN (BUILT_IN_TRUNC):
5644 CASE_FLT_FN (BUILT_IN_ROUND):
5645 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5646 CASE_FLT_FN (BUILT_IN_RINT):
5647 CASE_FLT_FN (BUILT_IN_LRINT):
5648 CASE_FLT_FN (BUILT_IN_LLRINT):
5649 target = expand_builtin_mathfn (exp, target, subtarget);
5650 if (target)
5651 return target;
5652 break;
5654 CASE_FLT_FN (BUILT_IN_LCEIL):
5655 CASE_FLT_FN (BUILT_IN_LLCEIL):
5656 CASE_FLT_FN (BUILT_IN_LFLOOR):
5657 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5658 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5659 if (target)
5660 return target;
5661 break;
5663 CASE_FLT_FN (BUILT_IN_POW):
5664 target = expand_builtin_pow (exp, target, subtarget);
5665 if (target)
5666 return target;
5667 break;
5669 CASE_FLT_FN (BUILT_IN_POWI):
5670 target = expand_builtin_powi (exp, target, subtarget);
5671 if (target)
5672 return target;
5673 break;
5675 CASE_FLT_FN (BUILT_IN_ATAN2):
5676 CASE_FLT_FN (BUILT_IN_LDEXP):
5677 CASE_FLT_FN (BUILT_IN_FMOD):
5678 CASE_FLT_FN (BUILT_IN_DREM):
5679 if (! flag_unsafe_math_optimizations)
5680 break;
5681 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5682 if (target)
5683 return target;
5684 break;
5686 CASE_FLT_FN (BUILT_IN_SIN):
5687 CASE_FLT_FN (BUILT_IN_COS):
5688 if (! flag_unsafe_math_optimizations)
5689 break;
5690 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5691 if (target)
5692 return target;
5693 break;
5695 CASE_FLT_FN (BUILT_IN_SINCOS):
5696 if (! flag_unsafe_math_optimizations)
5697 break;
5698 target = expand_builtin_sincos (exp);
5699 if (target)
5700 return target;
5701 break;
5703 case BUILT_IN_APPLY_ARGS:
5704 return expand_builtin_apply_args ();
5706 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5707 FUNCTION with a copy of the parameters described by
5708 ARGUMENTS, and ARGSIZE. It returns a block of memory
5709 allocated on the stack into which is stored all the registers
5710 that might possibly be used for returning the result of a
5711 function. ARGUMENTS is the value returned by
5712 __builtin_apply_args. ARGSIZE is the number of bytes of
5713 arguments that must be copied. ??? How should this value be
5714 computed? We'll also need a safe worst case value for varargs
5715 functions. */
5716 case BUILT_IN_APPLY:
5717 if (!validate_arglist (arglist, POINTER_TYPE,
5718 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5719 && !validate_arglist (arglist, REFERENCE_TYPE,
5720 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5721 return const0_rtx;
5722 else
5724 int i;
5725 tree t;
5726 rtx ops[3];
5728 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5729 ops[i] = expand_normal (TREE_VALUE (t));
5731 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5734 /* __builtin_return (RESULT) causes the function to return the
5735 value described by RESULT. RESULT is address of the block of
5736 memory returned by __builtin_apply. */
5737 case BUILT_IN_RETURN:
5738 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5739 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5740 return const0_rtx;
5742 case BUILT_IN_SAVEREGS:
5743 return expand_builtin_saveregs ();
5745 case BUILT_IN_ARGS_INFO:
5746 return expand_builtin_args_info (arglist);
5748 /* Return the address of the first anonymous stack arg. */
5749 case BUILT_IN_NEXT_ARG:
5750 if (fold_builtin_next_arg (arglist))
5751 return const0_rtx;
5752 return expand_builtin_next_arg ();
5754 case BUILT_IN_CLASSIFY_TYPE:
5755 return expand_builtin_classify_type (arglist);
5757 case BUILT_IN_CONSTANT_P:
5758 return const0_rtx;
5760 case BUILT_IN_FRAME_ADDRESS:
5761 case BUILT_IN_RETURN_ADDRESS:
5762 return expand_builtin_frame_address (fndecl, arglist);
5764 /* Returns the address of the area where the structure is returned.
5765 0 otherwise. */
5766 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5767 if (arglist != 0
5768 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5769 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5770 return const0_rtx;
5771 else
5772 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5774 case BUILT_IN_ALLOCA:
5775 target = expand_builtin_alloca (arglist, target);
5776 if (target)
5777 return target;
5778 break;
5780 case BUILT_IN_STACK_SAVE:
5781 return expand_stack_save ();
5783 case BUILT_IN_STACK_RESTORE:
5784 expand_stack_restore (TREE_VALUE (arglist));
5785 return const0_rtx;
5787 CASE_INT_FN (BUILT_IN_FFS):
5788 case BUILT_IN_FFSIMAX:
5789 target = expand_builtin_unop (target_mode, arglist, target,
5790 subtarget, ffs_optab);
5791 if (target)
5792 return target;
5793 break;
5795 CASE_INT_FN (BUILT_IN_CLZ):
5796 case BUILT_IN_CLZIMAX:
5797 target = expand_builtin_unop (target_mode, arglist, target,
5798 subtarget, clz_optab);
5799 if (target)
5800 return target;
5801 break;
5803 CASE_INT_FN (BUILT_IN_CTZ):
5804 case BUILT_IN_CTZIMAX:
5805 target = expand_builtin_unop (target_mode, arglist, target,
5806 subtarget, ctz_optab);
5807 if (target)
5808 return target;
5809 break;
5811 CASE_INT_FN (BUILT_IN_POPCOUNT):
5812 case BUILT_IN_POPCOUNTIMAX:
5813 target = expand_builtin_unop (target_mode, arglist, target,
5814 subtarget, popcount_optab);
5815 if (target)
5816 return target;
5817 break;
5819 CASE_INT_FN (BUILT_IN_PARITY):
5820 case BUILT_IN_PARITYIMAX:
5821 target = expand_builtin_unop (target_mode, arglist, target,
5822 subtarget, parity_optab);
5823 if (target)
5824 return target;
5825 break;
5827 case BUILT_IN_STRLEN:
5828 target = expand_builtin_strlen (arglist, target, target_mode);
5829 if (target)
5830 return target;
5831 break;
5833 case BUILT_IN_STRCPY:
5834 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5835 if (target)
5836 return target;
5837 break;
5839 case BUILT_IN_STRNCPY:
5840 target = expand_builtin_strncpy (exp, target, mode);
5841 if (target)
5842 return target;
5843 break;
5845 case BUILT_IN_STPCPY:
5846 target = expand_builtin_stpcpy (exp, target, mode);
5847 if (target)
5848 return target;
5849 break;
5851 case BUILT_IN_STRCAT:
5852 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5853 if (target)
5854 return target;
5855 break;
5857 case BUILT_IN_STRNCAT:
5858 target = expand_builtin_strncat (arglist, target, mode);
5859 if (target)
5860 return target;
5861 break;
5863 case BUILT_IN_STRSPN:
5864 target = expand_builtin_strspn (arglist, target, mode);
5865 if (target)
5866 return target;
5867 break;
5869 case BUILT_IN_STRCSPN:
5870 target = expand_builtin_strcspn (arglist, target, mode);
5871 if (target)
5872 return target;
5873 break;
5875 case BUILT_IN_STRSTR:
5876 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5877 if (target)
5878 return target;
5879 break;
5881 case BUILT_IN_STRPBRK:
5882 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5883 if (target)
5884 return target;
5885 break;
5887 case BUILT_IN_INDEX:
5888 case BUILT_IN_STRCHR:
5889 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5890 if (target)
5891 return target;
5892 break;
5894 case BUILT_IN_RINDEX:
5895 case BUILT_IN_STRRCHR:
5896 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5897 if (target)
5898 return target;
5899 break;
5901 case BUILT_IN_MEMCPY:
5902 target = expand_builtin_memcpy (exp, target, mode);
5903 if (target)
5904 return target;
5905 break;
5907 case BUILT_IN_MEMPCPY:
5908 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5909 if (target)
5910 return target;
5911 break;
5913 case BUILT_IN_MEMMOVE:
5914 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5915 mode, exp);
5916 if (target)
5917 return target;
5918 break;
5920 case BUILT_IN_BCOPY:
5921 target = expand_builtin_bcopy (exp);
5922 if (target)
5923 return target;
5924 break;
5926 case BUILT_IN_MEMSET:
5927 target = expand_builtin_memset (arglist, target, mode, exp);
5928 if (target)
5929 return target;
5930 break;
5932 case BUILT_IN_BZERO:
5933 target = expand_builtin_bzero (exp);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_STRCMP:
5939 target = expand_builtin_strcmp (exp, target, mode);
5940 if (target)
5941 return target;
5942 break;
5944 case BUILT_IN_STRNCMP:
5945 target = expand_builtin_strncmp (exp, target, mode);
5946 if (target)
5947 return target;
5948 break;
5950 case BUILT_IN_BCMP:
5951 case BUILT_IN_MEMCMP:
5952 target = expand_builtin_memcmp (exp, arglist, target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_SETJMP:
5958 target = expand_builtin_setjmp (arglist, target);
5959 if (target)
5960 return target;
5961 break;
5963 /* __builtin_longjmp is passed a pointer to an array of five words.
5964 It's similar to the C library longjmp function but works with
5965 __builtin_setjmp above. */
5966 case BUILT_IN_LONGJMP:
5967 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5968 break;
5969 else
5971 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5972 VOIDmode, EXPAND_NORMAL);
5973 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
5975 if (value != const1_rtx)
5977 error ("%<__builtin_longjmp%> second argument must be 1");
5978 return const0_rtx;
5981 expand_builtin_longjmp (buf_addr, value);
5982 return const0_rtx;
5985 case BUILT_IN_NONLOCAL_GOTO:
5986 target = expand_builtin_nonlocal_goto (arglist);
5987 if (target)
5988 return target;
5989 break;
5991 /* This updates the setjmp buffer that is its argument with the value
5992 of the current stack pointer. */
5993 case BUILT_IN_UPDATE_SETJMP_BUF:
5994 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5996 rtx buf_addr
5997 = expand_normal (TREE_VALUE (arglist));
5999 expand_builtin_update_setjmp_buf (buf_addr);
6000 return const0_rtx;
6002 break;
6004 case BUILT_IN_TRAP:
6005 expand_builtin_trap ();
6006 return const0_rtx;
6008 case BUILT_IN_PRINTF:
6009 target = expand_builtin_printf (exp, target, mode, false);
6010 if (target)
6011 return target;
6012 break;
6014 case BUILT_IN_PRINTF_UNLOCKED:
6015 target = expand_builtin_printf (exp, target, mode, true);
6016 if (target)
6017 return target;
6018 break;
6020 case BUILT_IN_FPUTS:
6021 target = expand_builtin_fputs (arglist, target, false);
6022 if (target)
6023 return target;
6024 break;
6025 case BUILT_IN_FPUTS_UNLOCKED:
6026 target = expand_builtin_fputs (arglist, target, true);
6027 if (target)
6028 return target;
6029 break;
6031 case BUILT_IN_FPRINTF:
6032 target = expand_builtin_fprintf (exp, target, mode, false);
6033 if (target)
6034 return target;
6035 break;
6037 case BUILT_IN_FPRINTF_UNLOCKED:
6038 target = expand_builtin_fprintf (exp, target, mode, true);
6039 if (target)
6040 return target;
6041 break;
6043 case BUILT_IN_SPRINTF:
6044 target = expand_builtin_sprintf (arglist, target, mode);
6045 if (target)
6046 return target;
6047 break;
6049 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6050 target = expand_builtin_signbit (exp, target);
6051 if (target)
6052 return target;
6053 break;
6055 /* Various hooks for the DWARF 2 __throw routine. */
6056 case BUILT_IN_UNWIND_INIT:
6057 expand_builtin_unwind_init ();
6058 return const0_rtx;
6059 case BUILT_IN_DWARF_CFA:
6060 return virtual_cfa_rtx;
6061 #ifdef DWARF2_UNWIND_INFO
6062 case BUILT_IN_DWARF_SP_COLUMN:
6063 return expand_builtin_dwarf_sp_column ();
6064 case BUILT_IN_INIT_DWARF_REG_SIZES:
6065 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6066 return const0_rtx;
6067 #endif
6068 case BUILT_IN_FROB_RETURN_ADDR:
6069 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6070 case BUILT_IN_EXTRACT_RETURN_ADDR:
6071 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6072 case BUILT_IN_EH_RETURN:
6073 expand_builtin_eh_return (TREE_VALUE (arglist),
6074 TREE_VALUE (TREE_CHAIN (arglist)));
6075 return const0_rtx;
6076 #ifdef EH_RETURN_DATA_REGNO
6077 case BUILT_IN_EH_RETURN_DATA_REGNO:
6078 return expand_builtin_eh_return_data_regno (arglist);
6079 #endif
6080 case BUILT_IN_EXTEND_POINTER:
6081 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6083 case BUILT_IN_VA_START:
6084 case BUILT_IN_STDARG_START:
6085 return expand_builtin_va_start (arglist);
6086 case BUILT_IN_VA_END:
6087 return expand_builtin_va_end (arglist);
6088 case BUILT_IN_VA_COPY:
6089 return expand_builtin_va_copy (arglist);
6090 case BUILT_IN_EXPECT:
6091 return expand_builtin_expect (arglist, target);
6092 case BUILT_IN_PREFETCH:
6093 expand_builtin_prefetch (arglist);
6094 return const0_rtx;
6096 case BUILT_IN_PROFILE_FUNC_ENTER:
6097 return expand_builtin_profile_func (false);
6098 case BUILT_IN_PROFILE_FUNC_EXIT:
6099 return expand_builtin_profile_func (true);
6101 case BUILT_IN_INIT_TRAMPOLINE:
6102 return expand_builtin_init_trampoline (arglist);
6103 case BUILT_IN_ADJUST_TRAMPOLINE:
6104 return expand_builtin_adjust_trampoline (arglist);
6106 case BUILT_IN_FORK:
6107 case BUILT_IN_EXECL:
6108 case BUILT_IN_EXECV:
6109 case BUILT_IN_EXECLP:
6110 case BUILT_IN_EXECLE:
6111 case BUILT_IN_EXECVP:
6112 case BUILT_IN_EXECVE:
6113 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6114 if (target)
6115 return target;
6116 break;
6118 case BUILT_IN_FETCH_AND_ADD_1:
6119 case BUILT_IN_FETCH_AND_ADD_2:
6120 case BUILT_IN_FETCH_AND_ADD_4:
6121 case BUILT_IN_FETCH_AND_ADD_8:
6122 case BUILT_IN_FETCH_AND_ADD_16:
6123 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6124 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6125 false, target, ignore);
6126 if (target)
6127 return target;
6128 break;
6130 case BUILT_IN_FETCH_AND_SUB_1:
6131 case BUILT_IN_FETCH_AND_SUB_2:
6132 case BUILT_IN_FETCH_AND_SUB_4:
6133 case BUILT_IN_FETCH_AND_SUB_8:
6134 case BUILT_IN_FETCH_AND_SUB_16:
6135 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6136 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6137 false, target, ignore);
6138 if (target)
6139 return target;
6140 break;
6142 case BUILT_IN_FETCH_AND_OR_1:
6143 case BUILT_IN_FETCH_AND_OR_2:
6144 case BUILT_IN_FETCH_AND_OR_4:
6145 case BUILT_IN_FETCH_AND_OR_8:
6146 case BUILT_IN_FETCH_AND_OR_16:
6147 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6148 target = expand_builtin_sync_operation (mode, arglist, IOR,
6149 false, target, ignore);
6150 if (target)
6151 return target;
6152 break;
6154 case BUILT_IN_FETCH_AND_AND_1:
6155 case BUILT_IN_FETCH_AND_AND_2:
6156 case BUILT_IN_FETCH_AND_AND_4:
6157 case BUILT_IN_FETCH_AND_AND_8:
6158 case BUILT_IN_FETCH_AND_AND_16:
6159 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6160 target = expand_builtin_sync_operation (mode, arglist, AND,
6161 false, target, ignore);
6162 if (target)
6163 return target;
6164 break;
6166 case BUILT_IN_FETCH_AND_XOR_1:
6167 case BUILT_IN_FETCH_AND_XOR_2:
6168 case BUILT_IN_FETCH_AND_XOR_4:
6169 case BUILT_IN_FETCH_AND_XOR_8:
6170 case BUILT_IN_FETCH_AND_XOR_16:
6171 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6172 target = expand_builtin_sync_operation (mode, arglist, XOR,
6173 false, target, ignore);
6174 if (target)
6175 return target;
6176 break;
6178 case BUILT_IN_FETCH_AND_NAND_1:
6179 case BUILT_IN_FETCH_AND_NAND_2:
6180 case BUILT_IN_FETCH_AND_NAND_4:
6181 case BUILT_IN_FETCH_AND_NAND_8:
6182 case BUILT_IN_FETCH_AND_NAND_16:
6183 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6184 target = expand_builtin_sync_operation (mode, arglist, NOT,
6185 false, target, ignore);
6186 if (target)
6187 return target;
6188 break;
6190 case BUILT_IN_ADD_AND_FETCH_1:
6191 case BUILT_IN_ADD_AND_FETCH_2:
6192 case BUILT_IN_ADD_AND_FETCH_4:
6193 case BUILT_IN_ADD_AND_FETCH_8:
6194 case BUILT_IN_ADD_AND_FETCH_16:
6195 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6196 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6197 true, target, ignore);
6198 if (target)
6199 return target;
6200 break;
6202 case BUILT_IN_SUB_AND_FETCH_1:
6203 case BUILT_IN_SUB_AND_FETCH_2:
6204 case BUILT_IN_SUB_AND_FETCH_4:
6205 case BUILT_IN_SUB_AND_FETCH_8:
6206 case BUILT_IN_SUB_AND_FETCH_16:
6207 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6208 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6209 true, target, ignore);
6210 if (target)
6211 return target;
6212 break;
6214 case BUILT_IN_OR_AND_FETCH_1:
6215 case BUILT_IN_OR_AND_FETCH_2:
6216 case BUILT_IN_OR_AND_FETCH_4:
6217 case BUILT_IN_OR_AND_FETCH_8:
6218 case BUILT_IN_OR_AND_FETCH_16:
6219 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6220 target = expand_builtin_sync_operation (mode, arglist, IOR,
6221 true, target, ignore);
6222 if (target)
6223 return target;
6224 break;
6226 case BUILT_IN_AND_AND_FETCH_1:
6227 case BUILT_IN_AND_AND_FETCH_2:
6228 case BUILT_IN_AND_AND_FETCH_4:
6229 case BUILT_IN_AND_AND_FETCH_8:
6230 case BUILT_IN_AND_AND_FETCH_16:
6231 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6232 target = expand_builtin_sync_operation (mode, arglist, AND,
6233 true, target, ignore);
6234 if (target)
6235 return target;
6236 break;
6238 case BUILT_IN_XOR_AND_FETCH_1:
6239 case BUILT_IN_XOR_AND_FETCH_2:
6240 case BUILT_IN_XOR_AND_FETCH_4:
6241 case BUILT_IN_XOR_AND_FETCH_8:
6242 case BUILT_IN_XOR_AND_FETCH_16:
6243 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6244 target = expand_builtin_sync_operation (mode, arglist, XOR,
6245 true, target, ignore);
6246 if (target)
6247 return target;
6248 break;
6250 case BUILT_IN_NAND_AND_FETCH_1:
6251 case BUILT_IN_NAND_AND_FETCH_2:
6252 case BUILT_IN_NAND_AND_FETCH_4:
6253 case BUILT_IN_NAND_AND_FETCH_8:
6254 case BUILT_IN_NAND_AND_FETCH_16:
6255 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6256 target = expand_builtin_sync_operation (mode, arglist, NOT,
6257 true, target, ignore);
6258 if (target)
6259 return target;
6260 break;
6262 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6263 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6264 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6265 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6266 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6267 if (mode == VOIDmode)
6268 mode = TYPE_MODE (boolean_type_node);
6269 if (!target || !register_operand (target, mode))
6270 target = gen_reg_rtx (mode);
6272 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6273 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6274 if (target)
6275 return target;
6276 break;
6278 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6279 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6280 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6281 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6282 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6283 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6284 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6285 if (target)
6286 return target;
6287 break;
6289 case BUILT_IN_LOCK_TEST_AND_SET_1:
6290 case BUILT_IN_LOCK_TEST_AND_SET_2:
6291 case BUILT_IN_LOCK_TEST_AND_SET_4:
6292 case BUILT_IN_LOCK_TEST_AND_SET_8:
6293 case BUILT_IN_LOCK_TEST_AND_SET_16:
6294 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6295 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6296 if (target)
6297 return target;
6298 break;
6300 case BUILT_IN_LOCK_RELEASE_1:
6301 case BUILT_IN_LOCK_RELEASE_2:
6302 case BUILT_IN_LOCK_RELEASE_4:
6303 case BUILT_IN_LOCK_RELEASE_8:
6304 case BUILT_IN_LOCK_RELEASE_16:
6305 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6306 expand_builtin_lock_release (mode, arglist);
6307 return const0_rtx;
6309 case BUILT_IN_SYNCHRONIZE:
6310 expand_builtin_synchronize ();
6311 return const0_rtx;
6313 case BUILT_IN_OBJECT_SIZE:
6314 return expand_builtin_object_size (exp);
6316 case BUILT_IN_MEMCPY_CHK:
6317 case BUILT_IN_MEMPCPY_CHK:
6318 case BUILT_IN_MEMMOVE_CHK:
6319 case BUILT_IN_MEMSET_CHK:
6320 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6321 if (target)
6322 return target;
6323 break;
6325 case BUILT_IN_STRCPY_CHK:
6326 case BUILT_IN_STPCPY_CHK:
6327 case BUILT_IN_STRNCPY_CHK:
6328 case BUILT_IN_STRCAT_CHK:
6329 case BUILT_IN_SNPRINTF_CHK:
6330 case BUILT_IN_VSNPRINTF_CHK:
6331 maybe_emit_chk_warning (exp, fcode);
6332 break;
6334 case BUILT_IN_SPRINTF_CHK:
6335 case BUILT_IN_VSPRINTF_CHK:
6336 maybe_emit_sprintf_chk_warning (exp, fcode);
6337 break;
6339 default: /* just do library call, if unknown builtin */
6340 break;
6343 /* The switch statement above can drop through to cause the function
6344 to be called normally. */
6345 return expand_call (exp, target, ignore);
6348 /* Determine whether a tree node represents a call to a built-in
6349 function. If the tree T is a call to a built-in function with
6350 the right number of arguments of the appropriate types, return
6351 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6352 Otherwise the return value is END_BUILTINS. */
6354 enum built_in_function
6355 builtin_mathfn_code (tree t)
6357 tree fndecl, arglist, parmlist;
6358 tree argtype, parmtype;
6360 if (TREE_CODE (t) != CALL_EXPR
6361 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6362 return END_BUILTINS;
6364 fndecl = get_callee_fndecl (t);
6365 if (fndecl == NULL_TREE
6366 || TREE_CODE (fndecl) != FUNCTION_DECL
6367 || ! DECL_BUILT_IN (fndecl)
6368 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6369 return END_BUILTINS;
6371 arglist = TREE_OPERAND (t, 1);
6372 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6373 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6375 /* If a function doesn't take a variable number of arguments,
6376 the last element in the list will have type `void'. */
6377 parmtype = TREE_VALUE (parmlist);
6378 if (VOID_TYPE_P (parmtype))
6380 if (arglist)
6381 return END_BUILTINS;
6382 return DECL_FUNCTION_CODE (fndecl);
6385 if (! arglist)
6386 return END_BUILTINS;
6388 argtype = TREE_TYPE (TREE_VALUE (arglist));
6390 if (SCALAR_FLOAT_TYPE_P (parmtype))
6392 if (! SCALAR_FLOAT_TYPE_P (argtype))
6393 return END_BUILTINS;
6395 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6397 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6398 return END_BUILTINS;
6400 else if (POINTER_TYPE_P (parmtype))
6402 if (! POINTER_TYPE_P (argtype))
6403 return END_BUILTINS;
6405 else if (INTEGRAL_TYPE_P (parmtype))
6407 if (! INTEGRAL_TYPE_P (argtype))
6408 return END_BUILTINS;
6410 else
6411 return END_BUILTINS;
6413 arglist = TREE_CHAIN (arglist);
6416 /* Variable-length argument list. */
6417 return DECL_FUNCTION_CODE (fndecl);
6420 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6421 constant. ARGLIST is the argument list of the call. */
6423 static tree
6424 fold_builtin_constant_p (tree arglist)
6426 if (arglist == 0)
6427 return 0;
6429 arglist = TREE_VALUE (arglist);
6431 /* We return 1 for a numeric type that's known to be a constant
6432 value at compile-time or for an aggregate type that's a
6433 literal constant. */
6434 STRIP_NOPS (arglist);
6436 /* If we know this is a constant, emit the constant of one. */
6437 if (CONSTANT_CLASS_P (arglist)
6438 || (TREE_CODE (arglist) == CONSTRUCTOR
6439 && TREE_CONSTANT (arglist)))
6440 return integer_one_node;
6441 if (TREE_CODE (arglist) == ADDR_EXPR)
6443 tree op = TREE_OPERAND (arglist, 0);
6444 if (TREE_CODE (op) == STRING_CST
6445 || (TREE_CODE (op) == ARRAY_REF
6446 && integer_zerop (TREE_OPERAND (op, 1))
6447 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6448 return integer_one_node;
6451 /* If this expression has side effects, show we don't know it to be a
6452 constant. Likewise if it's a pointer or aggregate type since in
6453 those case we only want literals, since those are only optimized
6454 when generating RTL, not later.
6455 And finally, if we are compiling an initializer, not code, we
6456 need to return a definite result now; there's not going to be any
6457 more optimization done. */
6458 if (TREE_SIDE_EFFECTS (arglist)
6459 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6460 || POINTER_TYPE_P (TREE_TYPE (arglist))
6461 || cfun == 0)
6462 return integer_zero_node;
6464 return 0;
6467 /* Fold a call to __builtin_expect, if we expect that a comparison against
6468 the argument will fold to a constant. In practice, this means a true
6469 constant or the address of a non-weak symbol. ARGLIST is the argument
6470 list of the call. */
6472 static tree
6473 fold_builtin_expect (tree arglist)
6475 tree arg, inner;
6477 if (arglist == 0)
6478 return 0;
6480 arg = TREE_VALUE (arglist);
6482 /* If the argument isn't invariant, then there's nothing we can do. */
6483 if (!TREE_INVARIANT (arg))
6484 return 0;
6486 /* If we're looking at an address of a weak decl, then do not fold. */
6487 inner = arg;
6488 STRIP_NOPS (inner);
6489 if (TREE_CODE (inner) == ADDR_EXPR)
6493 inner = TREE_OPERAND (inner, 0);
6495 while (TREE_CODE (inner) == COMPONENT_REF
6496 || TREE_CODE (inner) == ARRAY_REF);
6497 if (DECL_P (inner) && DECL_WEAK (inner))
6498 return 0;
6501 /* Otherwise, ARG already has the proper type for the return value. */
6502 return arg;
6505 /* Fold a call to __builtin_classify_type. */
6507 static tree
6508 fold_builtin_classify_type (tree arglist)
6510 if (arglist == 0)
6511 return build_int_cst (NULL_TREE, no_type_class);
6513 return build_int_cst (NULL_TREE,
6514 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6517 /* Fold a call to __builtin_strlen. */
6519 static tree
6520 fold_builtin_strlen (tree arglist)
6522 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6523 return NULL_TREE;
6524 else
6526 tree len = c_strlen (TREE_VALUE (arglist), 0);
6528 if (len)
6530 /* Convert from the internal "sizetype" type to "size_t". */
6531 if (size_type_node)
6532 len = fold_convert (size_type_node, len);
6533 return len;
6536 return NULL_TREE;
6540 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6542 static tree
6543 fold_builtin_inf (tree type, int warn)
6545 REAL_VALUE_TYPE real;
6547 /* __builtin_inff is intended to be usable to define INFINITY on all
6548 targets. If an infinity is not available, INFINITY expands "to a
6549 positive constant of type float that overflows at translation
6550 time", footnote "In this case, using INFINITY will violate the
6551 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6552 Thus we pedwarn to ensure this constraint violation is
6553 diagnosed. */
6554 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6555 pedwarn ("target format does not support infinity");
6557 real_inf (&real);
6558 return build_real (type, real);
6561 /* Fold a call to __builtin_nan or __builtin_nans. */
6563 static tree
6564 fold_builtin_nan (tree arglist, tree type, int quiet)
6566 REAL_VALUE_TYPE real;
6567 const char *str;
6569 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6570 return 0;
6571 str = c_getstr (TREE_VALUE (arglist));
6572 if (!str)
6573 return 0;
6575 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6576 return 0;
6578 return build_real (type, real);
6581 /* Return true if the floating point expression T has an integer value.
6582 We also allow +Inf, -Inf and NaN to be considered integer values. */
6584 static bool
6585 integer_valued_real_p (tree t)
6587 switch (TREE_CODE (t))
6589 case FLOAT_EXPR:
6590 return true;
6592 case ABS_EXPR:
6593 case SAVE_EXPR:
6594 case NON_LVALUE_EXPR:
6595 return integer_valued_real_p (TREE_OPERAND (t, 0));
6597 case COMPOUND_EXPR:
6598 case MODIFY_EXPR:
6599 case BIND_EXPR:
6600 return integer_valued_real_p (TREE_OPERAND (t, 1));
6602 case PLUS_EXPR:
6603 case MINUS_EXPR:
6604 case MULT_EXPR:
6605 case MIN_EXPR:
6606 case MAX_EXPR:
6607 return integer_valued_real_p (TREE_OPERAND (t, 0))
6608 && integer_valued_real_p (TREE_OPERAND (t, 1));
6610 case COND_EXPR:
6611 return integer_valued_real_p (TREE_OPERAND (t, 1))
6612 && integer_valued_real_p (TREE_OPERAND (t, 2));
6614 case REAL_CST:
6615 if (! TREE_CONSTANT_OVERFLOW (t))
6617 REAL_VALUE_TYPE c, cint;
6619 c = TREE_REAL_CST (t);
6620 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6621 return real_identical (&c, &cint);
6623 break;
6625 case NOP_EXPR:
6627 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6628 if (TREE_CODE (type) == INTEGER_TYPE)
6629 return true;
6630 if (TREE_CODE (type) == REAL_TYPE)
6631 return integer_valued_real_p (TREE_OPERAND (t, 0));
6632 break;
6635 case CALL_EXPR:
6636 switch (builtin_mathfn_code (t))
6638 CASE_FLT_FN (BUILT_IN_CEIL):
6639 CASE_FLT_FN (BUILT_IN_FLOOR):
6640 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6641 CASE_FLT_FN (BUILT_IN_RINT):
6642 CASE_FLT_FN (BUILT_IN_ROUND):
6643 CASE_FLT_FN (BUILT_IN_TRUNC):
6644 return true;
6646 default:
6647 break;
6649 break;
6651 default:
6652 break;
6654 return false;
6657 /* EXP is assumed to be builtin call where truncation can be propagated
6658 across (for instance floor((double)f) == (double)floorf (f).
6659 Do the transformation. */
6661 static tree
6662 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6664 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6665 tree arg;
6667 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6668 return 0;
6670 arg = TREE_VALUE (arglist);
6671 /* Integer rounding functions are idempotent. */
6672 if (fcode == builtin_mathfn_code (arg))
6673 return arg;
6675 /* If argument is already integer valued, and we don't need to worry
6676 about setting errno, there's no need to perform rounding. */
6677 if (! flag_errno_math && integer_valued_real_p (arg))
6678 return arg;
6680 if (optimize)
6682 tree arg0 = strip_float_extensions (arg);
6683 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6684 tree newtype = TREE_TYPE (arg0);
6685 tree decl;
6687 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6688 && (decl = mathfn_built_in (newtype, fcode)))
6690 arglist =
6691 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6692 return fold_convert (ftype,
6693 build_function_call_expr (decl, arglist));
6696 return 0;
6699 /* EXP is assumed to be builtin call which can narrow the FP type of
6700 the argument, for instance lround((double)f) -> lroundf (f). */
6702 static tree
6703 fold_fixed_mathfn (tree fndecl, tree arglist)
6705 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6706 tree arg;
6708 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6709 return 0;
6711 arg = TREE_VALUE (arglist);
6713 /* If argument is already integer valued, and we don't need to worry
6714 about setting errno, there's no need to perform rounding. */
6715 if (! flag_errno_math && integer_valued_real_p (arg))
6716 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6718 if (optimize)
6720 tree ftype = TREE_TYPE (arg);
6721 tree arg0 = strip_float_extensions (arg);
6722 tree newtype = TREE_TYPE (arg0);
6723 tree decl;
6725 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6726 && (decl = mathfn_built_in (newtype, fcode)))
6728 arglist =
6729 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6730 return build_function_call_expr (decl, arglist);
6733 return 0;
6736 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6737 is the argument list and TYPE is the return type. Return
6738 NULL_TREE if no if no simplification can be made. */
6740 static tree
6741 fold_builtin_cabs (tree arglist, tree type)
6743 tree arg;
6745 if (!arglist || TREE_CHAIN (arglist))
6746 return NULL_TREE;
6748 arg = TREE_VALUE (arglist);
6749 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6750 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6751 return NULL_TREE;
6753 /* Evaluate cabs of a constant at compile-time. */
6754 if (flag_unsafe_math_optimizations
6755 && TREE_CODE (arg) == COMPLEX_CST
6756 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6757 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6758 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6759 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6761 REAL_VALUE_TYPE r, i;
6763 r = TREE_REAL_CST (TREE_REALPART (arg));
6764 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6766 real_arithmetic (&r, MULT_EXPR, &r, &r);
6767 real_arithmetic (&i, MULT_EXPR, &i, &i);
6768 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6769 if (real_sqrt (&r, TYPE_MODE (type), &r)
6770 || ! flag_trapping_math)
6771 return build_real (type, r);
6774 /* If either part is zero, cabs is fabs of the other. */
6775 if (TREE_CODE (arg) == COMPLEX_EXPR
6776 && real_zerop (TREE_OPERAND (arg, 0)))
6777 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6778 if (TREE_CODE (arg) == COMPLEX_EXPR
6779 && real_zerop (TREE_OPERAND (arg, 1)))
6780 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6782 /* Don't do this when optimizing for size. */
6783 if (flag_unsafe_math_optimizations
6784 && optimize && !optimize_size)
6786 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6788 if (sqrtfn != NULL_TREE)
6790 tree rpart, ipart, result, arglist;
6792 arg = builtin_save_expr (arg);
6794 rpart = fold_build1 (REALPART_EXPR, type, arg);
6795 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6797 rpart = builtin_save_expr (rpart);
6798 ipart = builtin_save_expr (ipart);
6800 result = fold_build2 (PLUS_EXPR, type,
6801 fold_build2 (MULT_EXPR, type,
6802 rpart, rpart),
6803 fold_build2 (MULT_EXPR, type,
6804 ipart, ipart));
6806 arglist = build_tree_list (NULL_TREE, result);
6807 return build_function_call_expr (sqrtfn, arglist);
6811 return NULL_TREE;
6814 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6815 NULL_TREE if no simplification can be made. */
6817 static tree
6818 fold_builtin_sqrt (tree arglist, tree type)
6821 enum built_in_function fcode;
6822 tree arg = TREE_VALUE (arglist);
6824 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6825 return NULL_TREE;
6827 /* Optimize sqrt of constant value. */
6828 if (TREE_CODE (arg) == REAL_CST
6829 && ! TREE_CONSTANT_OVERFLOW (arg))
6831 REAL_VALUE_TYPE r, x;
6833 x = TREE_REAL_CST (arg);
6834 if (real_sqrt (&r, TYPE_MODE (type), &x)
6835 || (!flag_trapping_math && !flag_errno_math))
6836 return build_real (type, r);
6839 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6840 fcode = builtin_mathfn_code (arg);
6841 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6843 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6844 arg = fold_build2 (MULT_EXPR, type,
6845 TREE_VALUE (TREE_OPERAND (arg, 1)),
6846 build_real (type, dconsthalf));
6847 arglist = build_tree_list (NULL_TREE, arg);
6848 return build_function_call_expr (expfn, arglist);
6851 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6852 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6854 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6856 if (powfn)
6858 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6859 tree tree_root;
6860 /* The inner root was either sqrt or cbrt. */
6861 REAL_VALUE_TYPE dconstroot =
6862 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6864 /* Adjust for the outer root. */
6865 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6866 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6867 tree_root = build_real (type, dconstroot);
6868 arglist = tree_cons (NULL_TREE, arg0,
6869 build_tree_list (NULL_TREE, tree_root));
6870 return build_function_call_expr (powfn, arglist);
6874 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6875 if (flag_unsafe_math_optimizations
6876 && (fcode == BUILT_IN_POW
6877 || fcode == BUILT_IN_POWF
6878 || fcode == BUILT_IN_POWL))
6880 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6881 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6882 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6883 tree narg1;
6884 if (!tree_expr_nonnegative_p (arg0))
6885 arg0 = build1 (ABS_EXPR, type, arg0);
6886 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6887 build_real (type, dconsthalf));
6888 arglist = tree_cons (NULL_TREE, arg0,
6889 build_tree_list (NULL_TREE, narg1));
6890 return build_function_call_expr (powfn, arglist);
6893 return NULL_TREE;
6896 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6897 NULL_TREE if no simplification can be made. */
6898 static tree
6899 fold_builtin_cbrt (tree arglist, tree type)
6901 tree arg = TREE_VALUE (arglist);
6902 const enum built_in_function fcode = builtin_mathfn_code (arg);
6904 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6905 return NULL_TREE;
6907 /* Optimize cbrt of constant value. */
6908 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6909 return arg;
6911 if (flag_unsafe_math_optimizations)
6913 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6914 if (BUILTIN_EXPONENT_P (fcode))
6916 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6917 const REAL_VALUE_TYPE third_trunc =
6918 real_value_truncate (TYPE_MODE (type), dconstthird);
6919 arg = fold_build2 (MULT_EXPR, type,
6920 TREE_VALUE (TREE_OPERAND (arg, 1)),
6921 build_real (type, third_trunc));
6922 arglist = build_tree_list (NULL_TREE, arg);
6923 return build_function_call_expr (expfn, arglist);
6926 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6927 if (BUILTIN_SQRT_P (fcode))
6929 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6931 if (powfn)
6933 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6934 tree tree_root;
6935 REAL_VALUE_TYPE dconstroot = dconstthird;
6937 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6938 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6939 tree_root = build_real (type, dconstroot);
6940 arglist = tree_cons (NULL_TREE, arg0,
6941 build_tree_list (NULL_TREE, tree_root));
6942 return build_function_call_expr (powfn, arglist);
6946 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6947 if (BUILTIN_CBRT_P (fcode))
6949 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6950 if (tree_expr_nonnegative_p (arg0))
6952 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6954 if (powfn)
6956 tree tree_root;
6957 REAL_VALUE_TYPE dconstroot;
6959 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6960 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6961 tree_root = build_real (type, dconstroot);
6962 arglist = tree_cons (NULL_TREE, arg0,
6963 build_tree_list (NULL_TREE, tree_root));
6964 return build_function_call_expr (powfn, arglist);
6969 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6970 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6971 || fcode == BUILT_IN_POWL)
6973 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6974 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6975 if (tree_expr_nonnegative_p (arg00))
6977 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6978 const REAL_VALUE_TYPE dconstroot
6979 = real_value_truncate (TYPE_MODE (type), dconstthird);
6980 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6981 build_real (type, dconstroot));
6982 arglist = tree_cons (NULL_TREE, arg00,
6983 build_tree_list (NULL_TREE, narg01));
6984 return build_function_call_expr (powfn, arglist);
6988 return NULL_TREE;
6991 /* Fold function call to builtin sin, sinf, or sinl. Return
6992 NULL_TREE if no simplification can be made. */
6993 static tree
6994 fold_builtin_sin (tree arglist)
6996 tree arg = TREE_VALUE (arglist);
6998 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6999 return NULL_TREE;
7001 /* Optimize sin (0.0) = 0.0. */
7002 if (real_zerop (arg))
7003 return arg;
7005 return NULL_TREE;
7008 /* Fold function call to builtin cos, cosf, or cosl. Return
7009 NULL_TREE if no simplification can be made. */
7010 static tree
7011 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7013 tree arg = TREE_VALUE (arglist);
7015 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7016 return NULL_TREE;
7018 /* Optimize cos (0.0) = 1.0. */
7019 if (real_zerop (arg))
7020 return build_real (type, dconst1);
7022 /* Optimize cos(-x) into cos (x). */
7023 if (TREE_CODE (arg) == NEGATE_EXPR)
7025 tree args = build_tree_list (NULL_TREE,
7026 TREE_OPERAND (arg, 0));
7027 return build_function_call_expr (fndecl, args);
7030 return NULL_TREE;
7033 /* Fold function call to builtin tan, tanf, or tanl. Return
7034 NULL_TREE if no simplification can be made. */
7035 static tree
7036 fold_builtin_tan (tree arglist)
7038 enum built_in_function fcode;
7039 tree arg = TREE_VALUE (arglist);
7041 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7042 return NULL_TREE;
7044 /* Optimize tan(0.0) = 0.0. */
7045 if (real_zerop (arg))
7046 return arg;
7048 /* Optimize tan(atan(x)) = x. */
7049 fcode = builtin_mathfn_code (arg);
7050 if (flag_unsafe_math_optimizations
7051 && (fcode == BUILT_IN_ATAN
7052 || fcode == BUILT_IN_ATANF
7053 || fcode == BUILT_IN_ATANL))
7054 return TREE_VALUE (TREE_OPERAND (arg, 1));
7056 return NULL_TREE;
7059 /* Fold function call to builtin atan, atanf, or atanl. Return
7060 NULL_TREE if no simplification can be made. */
7062 static tree
7063 fold_builtin_atan (tree arglist, tree type)
7066 tree arg = TREE_VALUE (arglist);
7068 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7069 return NULL_TREE;
7071 /* Optimize atan(0.0) = 0.0. */
7072 if (real_zerop (arg))
7073 return arg;
7075 /* Optimize atan(1.0) = pi/4. */
7076 if (real_onep (arg))
7078 REAL_VALUE_TYPE cst;
7080 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7081 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7082 return build_real (type, cst);
7085 return NULL_TREE;
7088 /* Fold function call to builtin trunc, truncf or truncl. Return
7089 NULL_TREE if no simplification can be made. */
7091 static tree
7092 fold_builtin_trunc (tree fndecl, tree arglist)
7094 tree arg;
7096 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7097 return 0;
7099 /* Optimize trunc of constant value. */
7100 arg = TREE_VALUE (arglist);
7101 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7103 REAL_VALUE_TYPE r, x;
7104 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7106 x = TREE_REAL_CST (arg);
7107 real_trunc (&r, TYPE_MODE (type), &x);
7108 return build_real (type, r);
7111 return fold_trunc_transparent_mathfn (fndecl, arglist);
7114 /* Fold function call to builtin floor, floorf or floorl. Return
7115 NULL_TREE if no simplification can be made. */
7117 static tree
7118 fold_builtin_floor (tree fndecl, tree arglist)
7120 tree arg;
7122 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7123 return 0;
7125 /* Optimize floor of constant value. */
7126 arg = TREE_VALUE (arglist);
7127 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7129 REAL_VALUE_TYPE x;
7131 x = TREE_REAL_CST (arg);
7132 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7134 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7135 REAL_VALUE_TYPE r;
7137 real_floor (&r, TYPE_MODE (type), &x);
7138 return build_real (type, r);
7142 return fold_trunc_transparent_mathfn (fndecl, arglist);
7145 /* Fold function call to builtin ceil, ceilf or ceill. Return
7146 NULL_TREE if no simplification can be made. */
7148 static tree
7149 fold_builtin_ceil (tree fndecl, tree arglist)
7151 tree arg;
7153 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7154 return 0;
7156 /* Optimize ceil of constant value. */
7157 arg = TREE_VALUE (arglist);
7158 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7160 REAL_VALUE_TYPE x;
7162 x = TREE_REAL_CST (arg);
7163 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7165 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7166 REAL_VALUE_TYPE r;
7168 real_ceil (&r, TYPE_MODE (type), &x);
7169 return build_real (type, r);
7173 return fold_trunc_transparent_mathfn (fndecl, arglist);
7176 /* Fold function call to builtin round, roundf or roundl. Return
7177 NULL_TREE if no simplification can be made. */
7179 static tree
7180 fold_builtin_round (tree fndecl, tree arglist)
7182 tree arg;
7184 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7185 return 0;
7187 /* Optimize round of constant value. */
7188 arg = TREE_VALUE (arglist);
7189 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7191 REAL_VALUE_TYPE x;
7193 x = TREE_REAL_CST (arg);
7194 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7196 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7197 REAL_VALUE_TYPE r;
7199 real_round (&r, TYPE_MODE (type), &x);
7200 return build_real (type, r);
7204 return fold_trunc_transparent_mathfn (fndecl, arglist);
7207 /* Fold function call to builtin lround, lroundf or lroundl (or the
7208 corresponding long long versions) and other rounding functions.
7209 Return NULL_TREE if no simplification can be made. */
7211 static tree
7212 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7214 tree arg;
7216 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7217 return 0;
7219 /* Optimize lround of constant value. */
7220 arg = TREE_VALUE (arglist);
7221 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7223 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7225 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7227 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7228 tree ftype = TREE_TYPE (arg), result;
7229 HOST_WIDE_INT hi, lo;
7230 REAL_VALUE_TYPE r;
7232 switch (DECL_FUNCTION_CODE (fndecl))
7234 CASE_FLT_FN (BUILT_IN_LFLOOR):
7235 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7236 real_floor (&r, TYPE_MODE (ftype), &x);
7237 break;
7239 CASE_FLT_FN (BUILT_IN_LCEIL):
7240 CASE_FLT_FN (BUILT_IN_LLCEIL):
7241 real_ceil (&r, TYPE_MODE (ftype), &x);
7242 break;
7244 CASE_FLT_FN (BUILT_IN_LROUND):
7245 CASE_FLT_FN (BUILT_IN_LLROUND):
7246 real_round (&r, TYPE_MODE (ftype), &x);
7247 break;
7249 default:
7250 gcc_unreachable ();
7253 REAL_VALUE_TO_INT (&lo, &hi, r);
7254 result = build_int_cst_wide (NULL_TREE, lo, hi);
7255 if (int_fits_type_p (result, itype))
7256 return fold_convert (itype, result);
7260 return fold_fixed_mathfn (fndecl, arglist);
7263 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7264 and their long and long long variants (i.e. ffsl and ffsll).
7265 Return NULL_TREE if no simplification can be made. */
7267 static tree
7268 fold_builtin_bitop (tree fndecl, tree arglist)
7270 tree arg;
7272 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7273 return NULL_TREE;
7275 /* Optimize for constant argument. */
7276 arg = TREE_VALUE (arglist);
7277 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7279 HOST_WIDE_INT hi, width, result;
7280 unsigned HOST_WIDE_INT lo;
7281 tree type;
7283 type = TREE_TYPE (arg);
7284 width = TYPE_PRECISION (type);
7285 lo = TREE_INT_CST_LOW (arg);
7287 /* Clear all the bits that are beyond the type's precision. */
7288 if (width > HOST_BITS_PER_WIDE_INT)
7290 hi = TREE_INT_CST_HIGH (arg);
7291 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7292 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7294 else
7296 hi = 0;
7297 if (width < HOST_BITS_PER_WIDE_INT)
7298 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7301 switch (DECL_FUNCTION_CODE (fndecl))
7303 CASE_INT_FN (BUILT_IN_FFS):
7304 if (lo != 0)
7305 result = exact_log2 (lo & -lo) + 1;
7306 else if (hi != 0)
7307 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7308 else
7309 result = 0;
7310 break;
7312 CASE_INT_FN (BUILT_IN_CLZ):
7313 if (hi != 0)
7314 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7315 else if (lo != 0)
7316 result = width - floor_log2 (lo) - 1;
7317 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7318 result = width;
7319 break;
7321 CASE_INT_FN (BUILT_IN_CTZ):
7322 if (lo != 0)
7323 result = exact_log2 (lo & -lo);
7324 else if (hi != 0)
7325 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7326 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7327 result = width;
7328 break;
7330 CASE_INT_FN (BUILT_IN_POPCOUNT):
7331 result = 0;
7332 while (lo)
7333 result++, lo &= lo - 1;
7334 while (hi)
7335 result++, hi &= hi - 1;
7336 break;
7338 CASE_INT_FN (BUILT_IN_PARITY):
7339 result = 0;
7340 while (lo)
7341 result++, lo &= lo - 1;
7342 while (hi)
7343 result++, hi &= hi - 1;
7344 result &= 1;
7345 break;
7347 default:
7348 gcc_unreachable ();
7351 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7354 return NULL_TREE;
7357 /* Return true if EXPR is the real constant contained in VALUE. */
7359 static bool
7360 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7362 STRIP_NOPS (expr);
7364 return ((TREE_CODE (expr) == REAL_CST
7365 && ! TREE_CONSTANT_OVERFLOW (expr)
7366 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7367 || (TREE_CODE (expr) == COMPLEX_CST
7368 && real_dconstp (TREE_REALPART (expr), value)
7369 && real_zerop (TREE_IMAGPART (expr))));
7372 /* A subroutine of fold_builtin to fold the various logarithmic
7373 functions. EXP is the CALL_EXPR of a call to a builtin logN
7374 function. VALUE is the base of the logN function. */
7376 static tree
7377 fold_builtin_logarithm (tree fndecl, tree arglist,
7378 const REAL_VALUE_TYPE *value)
7380 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7382 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7383 tree arg = TREE_VALUE (arglist);
7384 const enum built_in_function fcode = builtin_mathfn_code (arg);
7386 /* Optimize logN(1.0) = 0.0. */
7387 if (real_onep (arg))
7388 return build_real (type, dconst0);
7390 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7391 exactly, then only do this if flag_unsafe_math_optimizations. */
7392 if (exact_real_truncate (TYPE_MODE (type), value)
7393 || flag_unsafe_math_optimizations)
7395 const REAL_VALUE_TYPE value_truncate =
7396 real_value_truncate (TYPE_MODE (type), *value);
7397 if (real_dconstp (arg, &value_truncate))
7398 return build_real (type, dconst1);
7401 /* Special case, optimize logN(expN(x)) = x. */
7402 if (flag_unsafe_math_optimizations
7403 && ((value == &dconste
7404 && (fcode == BUILT_IN_EXP
7405 || fcode == BUILT_IN_EXPF
7406 || fcode == BUILT_IN_EXPL))
7407 || (value == &dconst2
7408 && (fcode == BUILT_IN_EXP2
7409 || fcode == BUILT_IN_EXP2F
7410 || fcode == BUILT_IN_EXP2L))
7411 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7412 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7414 /* Optimize logN(func()) for various exponential functions. We
7415 want to determine the value "x" and the power "exponent" in
7416 order to transform logN(x**exponent) into exponent*logN(x). */
7417 if (flag_unsafe_math_optimizations)
7419 tree exponent = 0, x = 0;
7421 switch (fcode)
7423 CASE_FLT_FN (BUILT_IN_EXP):
7424 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7425 x = build_real (type,
7426 real_value_truncate (TYPE_MODE (type), dconste));
7427 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7428 break;
7429 CASE_FLT_FN (BUILT_IN_EXP2):
7430 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7431 x = build_real (type, dconst2);
7432 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7433 break;
7434 CASE_FLT_FN (BUILT_IN_EXP10):
7435 CASE_FLT_FN (BUILT_IN_POW10):
7436 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7437 x = build_real (type, dconst10);
7438 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7439 break;
7440 CASE_FLT_FN (BUILT_IN_SQRT):
7441 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7442 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7443 exponent = build_real (type, dconsthalf);
7444 break;
7445 CASE_FLT_FN (BUILT_IN_CBRT):
7446 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7447 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7448 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7449 dconstthird));
7450 break;
7451 CASE_FLT_FN (BUILT_IN_POW):
7452 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7453 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7454 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7455 break;
7456 default:
7457 break;
7460 /* Now perform the optimization. */
7461 if (x && exponent)
7463 tree logfn;
7464 arglist = build_tree_list (NULL_TREE, x);
7465 logfn = build_function_call_expr (fndecl, arglist);
7466 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7471 return 0;
7474 /* Fold a builtin function call to pow, powf, or powl. Return
7475 NULL_TREE if no simplification can be made. */
7476 static tree
7477 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7479 tree arg0 = TREE_VALUE (arglist);
7480 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7482 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7483 return NULL_TREE;
7485 /* Optimize pow(1.0,y) = 1.0. */
7486 if (real_onep (arg0))
7487 return omit_one_operand (type, build_real (type, dconst1), arg1);
7489 if (TREE_CODE (arg1) == REAL_CST
7490 && ! TREE_CONSTANT_OVERFLOW (arg1))
7492 REAL_VALUE_TYPE cint;
7493 REAL_VALUE_TYPE c;
7494 HOST_WIDE_INT n;
7496 c = TREE_REAL_CST (arg1);
7498 /* Optimize pow(x,0.0) = 1.0. */
7499 if (REAL_VALUES_EQUAL (c, dconst0))
7500 return omit_one_operand (type, build_real (type, dconst1),
7501 arg0);
7503 /* Optimize pow(x,1.0) = x. */
7504 if (REAL_VALUES_EQUAL (c, dconst1))
7505 return arg0;
7507 /* Optimize pow(x,-1.0) = 1.0/x. */
7508 if (REAL_VALUES_EQUAL (c, dconstm1))
7509 return fold_build2 (RDIV_EXPR, type,
7510 build_real (type, dconst1), arg0);
7512 /* Optimize pow(x,0.5) = sqrt(x). */
7513 if (flag_unsafe_math_optimizations
7514 && REAL_VALUES_EQUAL (c, dconsthalf))
7516 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7518 if (sqrtfn != NULL_TREE)
7520 tree arglist = build_tree_list (NULL_TREE, arg0);
7521 return build_function_call_expr (sqrtfn, arglist);
7525 /* Check for an integer exponent. */
7526 n = real_to_integer (&c);
7527 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7528 if (real_identical (&c, &cint))
7530 /* Attempt to evaluate pow at compile-time. */
7531 if (TREE_CODE (arg0) == REAL_CST
7532 && ! TREE_CONSTANT_OVERFLOW (arg0))
7534 REAL_VALUE_TYPE x;
7535 bool inexact;
7537 x = TREE_REAL_CST (arg0);
7538 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7539 if (flag_unsafe_math_optimizations || !inexact)
7540 return build_real (type, x);
7543 /* Strip sign ops from even integer powers. */
7544 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7546 tree narg0 = fold_strip_sign_ops (arg0);
7547 if (narg0)
7549 arglist = build_tree_list (NULL_TREE, arg1);
7550 arglist = tree_cons (NULL_TREE, narg0, arglist);
7551 return build_function_call_expr (fndecl, arglist);
7557 if (flag_unsafe_math_optimizations)
7559 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7561 /* Optimize pow(expN(x),y) = expN(x*y). */
7562 if (BUILTIN_EXPONENT_P (fcode))
7564 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7565 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7566 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7567 arglist = build_tree_list (NULL_TREE, arg);
7568 return build_function_call_expr (expfn, arglist);
7571 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7572 if (BUILTIN_SQRT_P (fcode))
7574 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7575 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7576 build_real (type, dconsthalf));
7578 arglist = tree_cons (NULL_TREE, narg0,
7579 build_tree_list (NULL_TREE, narg1));
7580 return build_function_call_expr (fndecl, arglist);
7583 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7584 if (BUILTIN_CBRT_P (fcode))
7586 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7587 if (tree_expr_nonnegative_p (arg))
7589 const REAL_VALUE_TYPE dconstroot
7590 = real_value_truncate (TYPE_MODE (type), dconstthird);
7591 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7592 build_real (type, dconstroot));
7593 arglist = tree_cons (NULL_TREE, arg,
7594 build_tree_list (NULL_TREE, narg1));
7595 return build_function_call_expr (fndecl, arglist);
7599 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7600 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7601 || fcode == BUILT_IN_POWL)
7603 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7604 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7605 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7606 arglist = tree_cons (NULL_TREE, arg00,
7607 build_tree_list (NULL_TREE, narg1));
7608 return build_function_call_expr (fndecl, arglist);
7612 return NULL_TREE;
7615 /* Fold a builtin function call to powi, powif, or powil. Return
7616 NULL_TREE if no simplification can be made. */
7617 static tree
7618 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7620 tree arg0 = TREE_VALUE (arglist);
7621 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7623 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7624 return NULL_TREE;
7626 /* Optimize pow(1.0,y) = 1.0. */
7627 if (real_onep (arg0))
7628 return omit_one_operand (type, build_real (type, dconst1), arg1);
7630 if (host_integerp (arg1, 0))
7632 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7634 /* Evaluate powi at compile-time. */
7635 if (TREE_CODE (arg0) == REAL_CST
7636 && ! TREE_CONSTANT_OVERFLOW (arg0))
7638 REAL_VALUE_TYPE x;
7639 x = TREE_REAL_CST (arg0);
7640 real_powi (&x, TYPE_MODE (type), &x, c);
7641 return build_real (type, x);
7644 /* Optimize pow(x,0) = 1.0. */
7645 if (c == 0)
7646 return omit_one_operand (type, build_real (type, dconst1),
7647 arg0);
7649 /* Optimize pow(x,1) = x. */
7650 if (c == 1)
7651 return arg0;
7653 /* Optimize pow(x,-1) = 1.0/x. */
7654 if (c == -1)
7655 return fold_build2 (RDIV_EXPR, type,
7656 build_real (type, dconst1), arg0);
7659 return NULL_TREE;
7662 /* A subroutine of fold_builtin to fold the various exponent
7663 functions. EXP is the CALL_EXPR of a call to a builtin function.
7664 VALUE is the value which will be raised to a power. */
7666 static tree
7667 fold_builtin_exponent (tree fndecl, tree arglist,
7668 const REAL_VALUE_TYPE *value)
7670 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7672 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7673 tree arg = TREE_VALUE (arglist);
7675 /* Optimize exp*(0.0) = 1.0. */
7676 if (real_zerop (arg))
7677 return build_real (type, dconst1);
7679 /* Optimize expN(1.0) = N. */
7680 if (real_onep (arg))
7682 REAL_VALUE_TYPE cst;
7684 real_convert (&cst, TYPE_MODE (type), value);
7685 return build_real (type, cst);
7688 /* Attempt to evaluate expN(integer) at compile-time. */
7689 if (flag_unsafe_math_optimizations
7690 && TREE_CODE (arg) == REAL_CST
7691 && ! TREE_CONSTANT_OVERFLOW (arg))
7693 REAL_VALUE_TYPE cint;
7694 REAL_VALUE_TYPE c;
7695 HOST_WIDE_INT n;
7697 c = TREE_REAL_CST (arg);
7698 n = real_to_integer (&c);
7699 real_from_integer (&cint, VOIDmode, n,
7700 n < 0 ? -1 : 0, 0);
7701 if (real_identical (&c, &cint))
7703 REAL_VALUE_TYPE x;
7705 real_powi (&x, TYPE_MODE (type), value, n);
7706 return build_real (type, x);
7710 /* Optimize expN(logN(x)) = x. */
7711 if (flag_unsafe_math_optimizations)
7713 const enum built_in_function fcode = builtin_mathfn_code (arg);
7715 if ((value == &dconste
7716 && (fcode == BUILT_IN_LOG
7717 || fcode == BUILT_IN_LOGF
7718 || fcode == BUILT_IN_LOGL))
7719 || (value == &dconst2
7720 && (fcode == BUILT_IN_LOG2
7721 || fcode == BUILT_IN_LOG2F
7722 || fcode == BUILT_IN_LOG2L))
7723 || (value == &dconst10
7724 && (fcode == BUILT_IN_LOG10
7725 || fcode == BUILT_IN_LOG10F
7726 || fcode == BUILT_IN_LOG10L)))
7727 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7731 return 0;
7734 /* Fold function call to builtin memcpy. Return
7735 NULL_TREE if no simplification can be made. */
7737 static tree
7738 fold_builtin_memcpy (tree fndecl, tree arglist)
7740 tree dest, src, len;
7742 if (!validate_arglist (arglist,
7743 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7744 return 0;
7746 dest = TREE_VALUE (arglist);
7747 src = TREE_VALUE (TREE_CHAIN (arglist));
7748 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7750 /* If the LEN parameter is zero, return DEST. */
7751 if (integer_zerop (len))
7752 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7754 /* If SRC and DEST are the same (and not volatile), return DEST. */
7755 if (operand_equal_p (src, dest, 0))
7756 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7758 return 0;
7761 /* Fold function call to builtin mempcpy. Return
7762 NULL_TREE if no simplification can be made. */
7764 static tree
7765 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7767 if (validate_arglist (arglist,
7768 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7770 tree dest = TREE_VALUE (arglist);
7771 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7772 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7774 /* If the LEN parameter is zero, return DEST. */
7775 if (integer_zerop (len))
7776 return omit_one_operand (type, dest, src);
7778 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7779 if (operand_equal_p (src, dest, 0))
7781 if (endp == 0)
7782 return omit_one_operand (type, dest, len);
7784 if (endp == 2)
7785 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7786 ssize_int (1));
7788 len = fold_convert (TREE_TYPE (dest), len);
7789 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7790 return fold_convert (type, len);
7793 return 0;
7796 /* Fold function call to builtin memmove. Return
7797 NULL_TREE if no simplification can be made. */
7799 static tree
7800 fold_builtin_memmove (tree arglist, tree type)
7802 tree dest, src, len;
7804 if (!validate_arglist (arglist,
7805 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7806 return 0;
7808 dest = TREE_VALUE (arglist);
7809 src = TREE_VALUE (TREE_CHAIN (arglist));
7810 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7812 /* If the LEN parameter is zero, return DEST. */
7813 if (integer_zerop (len))
7814 return omit_one_operand (type, dest, src);
7816 /* If SRC and DEST are the same (and not volatile), return DEST. */
7817 if (operand_equal_p (src, dest, 0))
7818 return omit_one_operand (type, dest, len);
7820 return 0;
7823 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7824 the length of the string to be copied. Return NULL_TREE if no
7825 simplification can be made. */
7827 tree
7828 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7830 tree dest, src, fn;
7832 if (!validate_arglist (arglist,
7833 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7834 return 0;
7836 dest = TREE_VALUE (arglist);
7837 src = TREE_VALUE (TREE_CHAIN (arglist));
7839 /* If SRC and DEST are the same (and not volatile), return DEST. */
7840 if (operand_equal_p (src, dest, 0))
7841 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7843 if (optimize_size)
7844 return 0;
7846 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7847 if (!fn)
7848 return 0;
7850 if (!len)
7852 len = c_strlen (src, 1);
7853 if (! len || TREE_SIDE_EFFECTS (len))
7854 return 0;
7857 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7858 arglist = build_tree_list (NULL_TREE, len);
7859 arglist = tree_cons (NULL_TREE, src, arglist);
7860 arglist = tree_cons (NULL_TREE, dest, arglist);
7861 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7862 build_function_call_expr (fn, arglist));
7865 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7866 the length of the source string. Return NULL_TREE if no simplification
7867 can be made. */
7869 tree
7870 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7872 tree dest, src, len, fn;
7874 if (!validate_arglist (arglist,
7875 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7876 return 0;
7878 dest = TREE_VALUE (arglist);
7879 src = TREE_VALUE (TREE_CHAIN (arglist));
7880 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7882 /* If the LEN parameter is zero, return DEST. */
7883 if (integer_zerop (len))
7884 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7886 /* We can't compare slen with len as constants below if len is not a
7887 constant. */
7888 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7889 return 0;
7891 if (!slen)
7892 slen = c_strlen (src, 1);
7894 /* Now, we must be passed a constant src ptr parameter. */
7895 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7896 return 0;
7898 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7900 /* We do not support simplification of this case, though we do
7901 support it when expanding trees into RTL. */
7902 /* FIXME: generate a call to __builtin_memset. */
7903 if (tree_int_cst_lt (slen, len))
7904 return 0;
7906 /* OK transform into builtin memcpy. */
7907 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7908 if (!fn)
7909 return 0;
7910 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7911 build_function_call_expr (fn, arglist));
7914 /* Fold function call to builtin memcmp. Return
7915 NULL_TREE if no simplification can be made. */
7917 static tree
7918 fold_builtin_memcmp (tree arglist)
7920 tree arg1, arg2, len;
7921 const char *p1, *p2;
7923 if (!validate_arglist (arglist,
7924 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7925 return 0;
7927 arg1 = TREE_VALUE (arglist);
7928 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7929 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7931 /* If the LEN parameter is zero, return zero. */
7932 if (integer_zerop (len))
7933 return omit_two_operands (integer_type_node, integer_zero_node,
7934 arg1, arg2);
7936 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7937 if (operand_equal_p (arg1, arg2, 0))
7938 return omit_one_operand (integer_type_node, integer_zero_node, len);
7940 p1 = c_getstr (arg1);
7941 p2 = c_getstr (arg2);
7943 /* If all arguments are constant, and the value of len is not greater
7944 than the lengths of arg1 and arg2, evaluate at compile-time. */
7945 if (host_integerp (len, 1) && p1 && p2
7946 && compare_tree_int (len, strlen (p1) + 1) <= 0
7947 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7949 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7951 if (r > 0)
7952 return integer_one_node;
7953 else if (r < 0)
7954 return integer_minus_one_node;
7955 else
7956 return integer_zero_node;
7959 /* If len parameter is one, return an expression corresponding to
7960 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7961 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7963 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7964 tree cst_uchar_ptr_node
7965 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7967 tree ind1 = fold_convert (integer_type_node,
7968 build1 (INDIRECT_REF, cst_uchar_node,
7969 fold_convert (cst_uchar_ptr_node,
7970 arg1)));
7971 tree ind2 = fold_convert (integer_type_node,
7972 build1 (INDIRECT_REF, cst_uchar_node,
7973 fold_convert (cst_uchar_ptr_node,
7974 arg2)));
7975 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7978 return 0;
7981 /* Fold function call to builtin strcmp. Return
7982 NULL_TREE if no simplification can be made. */
7984 static tree
7985 fold_builtin_strcmp (tree arglist)
7987 tree arg1, arg2;
7988 const char *p1, *p2;
7990 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7991 return 0;
7993 arg1 = TREE_VALUE (arglist);
7994 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7996 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7997 if (operand_equal_p (arg1, arg2, 0))
7998 return integer_zero_node;
8000 p1 = c_getstr (arg1);
8001 p2 = c_getstr (arg2);
8003 if (p1 && p2)
8005 const int i = strcmp (p1, p2);
8006 if (i < 0)
8007 return integer_minus_one_node;
8008 else if (i > 0)
8009 return integer_one_node;
8010 else
8011 return integer_zero_node;
8014 /* If the second arg is "", return *(const unsigned char*)arg1. */
8015 if (p2 && *p2 == '\0')
8017 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8018 tree cst_uchar_ptr_node
8019 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8021 return fold_convert (integer_type_node,
8022 build1 (INDIRECT_REF, cst_uchar_node,
8023 fold_convert (cst_uchar_ptr_node,
8024 arg1)));
8027 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8028 if (p1 && *p1 == '\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 tree temp = fold_convert (integer_type_node,
8035 build1 (INDIRECT_REF, cst_uchar_node,
8036 fold_convert (cst_uchar_ptr_node,
8037 arg2)));
8038 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8041 return 0;
8044 /* Fold function call to builtin strncmp. Return
8045 NULL_TREE if no simplification can be made. */
8047 static tree
8048 fold_builtin_strncmp (tree arglist)
8050 tree arg1, arg2, len;
8051 const char *p1, *p2;
8053 if (!validate_arglist (arglist,
8054 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8055 return 0;
8057 arg1 = TREE_VALUE (arglist);
8058 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8059 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8061 /* If the LEN parameter is zero, return zero. */
8062 if (integer_zerop (len))
8063 return omit_two_operands (integer_type_node, integer_zero_node,
8064 arg1, arg2);
8066 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8067 if (operand_equal_p (arg1, arg2, 0))
8068 return omit_one_operand (integer_type_node, integer_zero_node, len);
8070 p1 = c_getstr (arg1);
8071 p2 = c_getstr (arg2);
8073 if (host_integerp (len, 1) && p1 && p2)
8075 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8076 if (i > 0)
8077 return integer_one_node;
8078 else if (i < 0)
8079 return integer_minus_one_node;
8080 else
8081 return integer_zero_node;
8084 /* If the second arg is "", and the length is greater than zero,
8085 return *(const unsigned char*)arg1. */
8086 if (p2 && *p2 == '\0'
8087 && TREE_CODE (len) == INTEGER_CST
8088 && tree_int_cst_sgn (len) == 1)
8090 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8091 tree cst_uchar_ptr_node
8092 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8094 return fold_convert (integer_type_node,
8095 build1 (INDIRECT_REF, cst_uchar_node,
8096 fold_convert (cst_uchar_ptr_node,
8097 arg1)));
8100 /* If the first arg is "", and the length is greater than zero,
8101 return -*(const unsigned char*)arg2. */
8102 if (p1 && *p1 == '\0'
8103 && TREE_CODE (len) == INTEGER_CST
8104 && tree_int_cst_sgn (len) == 1)
8106 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8107 tree cst_uchar_ptr_node
8108 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8110 tree temp = fold_convert (integer_type_node,
8111 build1 (INDIRECT_REF, cst_uchar_node,
8112 fold_convert (cst_uchar_ptr_node,
8113 arg2)));
8114 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8117 /* If len parameter is one, return an expression corresponding to
8118 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8119 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8121 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8122 tree cst_uchar_ptr_node
8123 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8125 tree ind1 = fold_convert (integer_type_node,
8126 build1 (INDIRECT_REF, cst_uchar_node,
8127 fold_convert (cst_uchar_ptr_node,
8128 arg1)));
8129 tree ind2 = fold_convert (integer_type_node,
8130 build1 (INDIRECT_REF, cst_uchar_node,
8131 fold_convert (cst_uchar_ptr_node,
8132 arg2)));
8133 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8136 return 0;
8139 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8140 NULL_TREE if no simplification can be made. */
8142 static tree
8143 fold_builtin_signbit (tree fndecl, tree arglist)
8145 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8146 tree arg, temp;
8148 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8149 return NULL_TREE;
8151 arg = TREE_VALUE (arglist);
8153 /* If ARG is a compile-time constant, determine the result. */
8154 if (TREE_CODE (arg) == REAL_CST
8155 && !TREE_CONSTANT_OVERFLOW (arg))
8157 REAL_VALUE_TYPE c;
8159 c = TREE_REAL_CST (arg);
8160 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8161 return fold_convert (type, temp);
8164 /* If ARG is non-negative, the result is always zero. */
8165 if (tree_expr_nonnegative_p (arg))
8166 return omit_one_operand (type, integer_zero_node, arg);
8168 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8169 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8170 return fold_build2 (LT_EXPR, type, arg,
8171 build_real (TREE_TYPE (arg), dconst0));
8173 return NULL_TREE;
8176 /* Fold function call to builtin copysign, copysignf or copysignl.
8177 Return NULL_TREE if no simplification can be made. */
8179 static tree
8180 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8182 tree arg1, arg2, tem;
8184 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8185 return NULL_TREE;
8187 arg1 = TREE_VALUE (arglist);
8188 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8190 /* copysign(X,X) is X. */
8191 if (operand_equal_p (arg1, arg2, 0))
8192 return fold_convert (type, arg1);
8194 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8195 if (TREE_CODE (arg1) == REAL_CST
8196 && TREE_CODE (arg2) == REAL_CST
8197 && !TREE_CONSTANT_OVERFLOW (arg1)
8198 && !TREE_CONSTANT_OVERFLOW (arg2))
8200 REAL_VALUE_TYPE c1, c2;
8202 c1 = TREE_REAL_CST (arg1);
8203 c2 = TREE_REAL_CST (arg2);
8204 real_copysign (&c1, &c2);
8205 return build_real (type, c1);
8206 c1.sign = c2.sign;
8209 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8210 Remember to evaluate Y for side-effects. */
8211 if (tree_expr_nonnegative_p (arg2))
8212 return omit_one_operand (type,
8213 fold_build1 (ABS_EXPR, type, arg1),
8214 arg2);
8216 /* Strip sign changing operations for the first argument. */
8217 tem = fold_strip_sign_ops (arg1);
8218 if (tem)
8220 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8221 return build_function_call_expr (fndecl, arglist);
8224 return NULL_TREE;
8227 /* Fold a call to builtin isascii. */
8229 static tree
8230 fold_builtin_isascii (tree arglist)
8232 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8233 return 0;
8234 else
8236 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8237 tree arg = TREE_VALUE (arglist);
8239 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8240 build_int_cst (NULL_TREE,
8241 ~ (unsigned HOST_WIDE_INT) 0x7f));
8242 arg = fold_build2 (EQ_EXPR, integer_type_node,
8243 arg, integer_zero_node);
8245 if (in_gimple_form && !TREE_CONSTANT (arg))
8246 return NULL_TREE;
8247 else
8248 return arg;
8252 /* Fold a call to builtin toascii. */
8254 static tree
8255 fold_builtin_toascii (tree arglist)
8257 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8258 return 0;
8259 else
8261 /* Transform toascii(c) -> (c & 0x7f). */
8262 tree arg = TREE_VALUE (arglist);
8264 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8265 build_int_cst (NULL_TREE, 0x7f));
8269 /* Fold a call to builtin isdigit. */
8271 static tree
8272 fold_builtin_isdigit (tree arglist)
8274 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8275 return 0;
8276 else
8278 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8279 /* According to the C standard, isdigit is unaffected by locale.
8280 However, it definitely is affected by the target character set. */
8281 tree arg;
8282 unsigned HOST_WIDE_INT target_digit0
8283 = lang_hooks.to_target_charset ('0');
8285 if (target_digit0 == 0)
8286 return NULL_TREE;
8288 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8289 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8290 build_int_cst (unsigned_type_node, target_digit0));
8291 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8292 build_int_cst (unsigned_type_node, 9));
8293 if (in_gimple_form && !TREE_CONSTANT (arg))
8294 return NULL_TREE;
8295 else
8296 return arg;
8300 /* Fold a call to fabs, fabsf or fabsl. */
8302 static tree
8303 fold_builtin_fabs (tree arglist, tree type)
8305 tree arg;
8307 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8308 return 0;
8310 arg = TREE_VALUE (arglist);
8311 arg = fold_convert (type, arg);
8312 if (TREE_CODE (arg) == REAL_CST)
8313 return fold_abs_const (arg, type);
8314 return fold_build1 (ABS_EXPR, type, arg);
8317 /* Fold a call to abs, labs, llabs or imaxabs. */
8319 static tree
8320 fold_builtin_abs (tree arglist, tree type)
8322 tree arg;
8324 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8325 return 0;
8327 arg = TREE_VALUE (arglist);
8328 arg = fold_convert (type, arg);
8329 if (TREE_CODE (arg) == INTEGER_CST)
8330 return fold_abs_const (arg, type);
8331 return fold_build1 (ABS_EXPR, type, arg);
8334 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8335 EXP is the CALL_EXPR for the call. */
8337 static tree
8338 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8340 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8341 tree arg;
8342 REAL_VALUE_TYPE r;
8344 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8346 /* Check that we have exactly one argument. */
8347 if (arglist == 0)
8349 error ("too few arguments to function %qs",
8350 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8351 return error_mark_node;
8353 else if (TREE_CHAIN (arglist) != 0)
8355 error ("too many arguments to function %qs",
8356 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8357 return error_mark_node;
8359 else
8361 error ("non-floating-point argument to function %qs",
8362 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8363 return error_mark_node;
8367 arg = TREE_VALUE (arglist);
8368 switch (builtin_index)
8370 case BUILT_IN_ISINF:
8371 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8372 return omit_one_operand (type, integer_zero_node, arg);
8374 if (TREE_CODE (arg) == REAL_CST)
8376 r = TREE_REAL_CST (arg);
8377 if (real_isinf (&r))
8378 return real_compare (GT_EXPR, &r, &dconst0)
8379 ? integer_one_node : integer_minus_one_node;
8380 else
8381 return integer_zero_node;
8384 return NULL_TREE;
8386 case BUILT_IN_FINITE:
8387 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8388 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8389 return omit_one_operand (type, integer_zero_node, arg);
8391 if (TREE_CODE (arg) == REAL_CST)
8393 r = TREE_REAL_CST (arg);
8394 return real_isinf (&r) || real_isnan (&r)
8395 ? integer_zero_node : integer_one_node;
8398 return NULL_TREE;
8400 case BUILT_IN_ISNAN:
8401 if (!MODE_HAS_NANS (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_isnan (&r) ? integer_one_node : integer_zero_node;
8410 arg = builtin_save_expr (arg);
8411 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8413 default:
8414 gcc_unreachable ();
8418 /* Fold a call to an unordered comparison function such as
8419 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8420 being called and ARGLIST is the argument list for the call.
8421 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8422 the opposite of the desired result. UNORDERED_CODE is used
8423 for modes that can hold NaNs and ORDERED_CODE is used for
8424 the rest. */
8426 static tree
8427 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8428 enum tree_code unordered_code,
8429 enum tree_code ordered_code)
8431 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8432 enum tree_code code;
8433 tree arg0, arg1;
8434 tree type0, type1;
8435 enum tree_code code0, code1;
8436 tree cmp_type = NULL_TREE;
8438 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8440 /* Check that we have exactly two arguments. */
8441 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8443 error ("too few arguments to function %qs",
8444 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8445 return error_mark_node;
8447 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8449 error ("too many arguments to function %qs",
8450 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8451 return error_mark_node;
8455 arg0 = TREE_VALUE (arglist);
8456 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8458 type0 = TREE_TYPE (arg0);
8459 type1 = TREE_TYPE (arg1);
8461 code0 = TREE_CODE (type0);
8462 code1 = TREE_CODE (type1);
8464 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8465 /* Choose the wider of two real types. */
8466 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8467 ? type0 : type1;
8468 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8469 cmp_type = type0;
8470 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8471 cmp_type = type1;
8472 else
8474 error ("non-floating-point argument to function %qs",
8475 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8476 return error_mark_node;
8479 arg0 = fold_convert (cmp_type, arg0);
8480 arg1 = fold_convert (cmp_type, arg1);
8482 if (unordered_code == UNORDERED_EXPR)
8484 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8485 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8486 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8489 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8490 : ordered_code;
8491 return fold_build1 (TRUTH_NOT_EXPR, type,
8492 fold_build2 (code, type, arg0, arg1));
8495 /* Used by constant folding to simplify calls to builtin functions. EXP is
8496 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8497 result of the function call is ignored. This function returns NULL_TREE
8498 if no simplification was possible. */
8500 static tree
8501 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8503 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8504 enum built_in_function fcode;
8506 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8507 return targetm.fold_builtin (fndecl, arglist, ignore);
8509 fcode = DECL_FUNCTION_CODE (fndecl);
8510 switch (fcode)
8512 case BUILT_IN_FPUTS:
8513 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8515 case BUILT_IN_FPUTS_UNLOCKED:
8516 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8518 case BUILT_IN_STRSTR:
8519 return fold_builtin_strstr (arglist, type);
8521 case BUILT_IN_STRCAT:
8522 return fold_builtin_strcat (arglist);
8524 case BUILT_IN_STRNCAT:
8525 return fold_builtin_strncat (arglist);
8527 case BUILT_IN_STRSPN:
8528 return fold_builtin_strspn (arglist);
8530 case BUILT_IN_STRCSPN:
8531 return fold_builtin_strcspn (arglist);
8533 case BUILT_IN_STRCHR:
8534 case BUILT_IN_INDEX:
8535 return fold_builtin_strchr (arglist, type);
8537 case BUILT_IN_STRRCHR:
8538 case BUILT_IN_RINDEX:
8539 return fold_builtin_strrchr (arglist, type);
8541 case BUILT_IN_STRCPY:
8542 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8544 case BUILT_IN_STRNCPY:
8545 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8547 case BUILT_IN_STRCMP:
8548 return fold_builtin_strcmp (arglist);
8550 case BUILT_IN_STRNCMP:
8551 return fold_builtin_strncmp (arglist);
8553 case BUILT_IN_STRPBRK:
8554 return fold_builtin_strpbrk (arglist, type);
8556 case BUILT_IN_BCMP:
8557 case BUILT_IN_MEMCMP:
8558 return fold_builtin_memcmp (arglist);
8560 case BUILT_IN_SPRINTF:
8561 return fold_builtin_sprintf (arglist, ignore);
8563 case BUILT_IN_CONSTANT_P:
8565 tree val;
8567 val = fold_builtin_constant_p (arglist);
8568 /* Gimplification will pull the CALL_EXPR for the builtin out of
8569 an if condition. When not optimizing, we'll not CSE it back.
8570 To avoid link error types of regressions, return false now. */
8571 if (!val && !optimize)
8572 val = integer_zero_node;
8574 return val;
8577 case BUILT_IN_EXPECT:
8578 return fold_builtin_expect (arglist);
8580 case BUILT_IN_CLASSIFY_TYPE:
8581 return fold_builtin_classify_type (arglist);
8583 case BUILT_IN_STRLEN:
8584 return fold_builtin_strlen (arglist);
8586 CASE_FLT_FN (BUILT_IN_FABS):
8587 return fold_builtin_fabs (arglist, type);
8589 case BUILT_IN_ABS:
8590 case BUILT_IN_LABS:
8591 case BUILT_IN_LLABS:
8592 case BUILT_IN_IMAXABS:
8593 return fold_builtin_abs (arglist, type);
8595 CASE_FLT_FN (BUILT_IN_CONJ):
8596 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8597 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8598 break;
8600 CASE_FLT_FN (BUILT_IN_CREAL):
8601 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8602 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8603 TREE_VALUE (arglist)));
8604 break;
8606 CASE_FLT_FN (BUILT_IN_CIMAG):
8607 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8608 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8609 TREE_VALUE (arglist)));
8610 break;
8612 CASE_FLT_FN (BUILT_IN_CABS):
8613 return fold_builtin_cabs (arglist, type);
8615 CASE_FLT_FN (BUILT_IN_SQRT):
8616 return fold_builtin_sqrt (arglist, type);
8618 CASE_FLT_FN (BUILT_IN_CBRT):
8619 return fold_builtin_cbrt (arglist, type);
8621 CASE_FLT_FN (BUILT_IN_SIN):
8622 return fold_builtin_sin (arglist);
8624 CASE_FLT_FN (BUILT_IN_COS):
8625 return fold_builtin_cos (arglist, type, fndecl);
8627 CASE_FLT_FN (BUILT_IN_EXP):
8628 return fold_builtin_exponent (fndecl, arglist, &dconste);
8630 CASE_FLT_FN (BUILT_IN_EXP2):
8631 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8633 CASE_FLT_FN (BUILT_IN_EXP10):
8634 CASE_FLT_FN (BUILT_IN_POW10):
8635 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8637 CASE_FLT_FN (BUILT_IN_LOG):
8638 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8640 CASE_FLT_FN (BUILT_IN_LOG2):
8641 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8643 CASE_FLT_FN (BUILT_IN_LOG10):
8644 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8646 CASE_FLT_FN (BUILT_IN_TAN):
8647 return fold_builtin_tan (arglist);
8649 CASE_FLT_FN (BUILT_IN_ATAN):
8650 return fold_builtin_atan (arglist, type);
8652 CASE_FLT_FN (BUILT_IN_POW):
8653 return fold_builtin_pow (fndecl, arglist, type);
8655 CASE_FLT_FN (BUILT_IN_POWI):
8656 return fold_builtin_powi (fndecl, arglist, type);
8658 CASE_FLT_FN (BUILT_IN_INF):
8659 case BUILT_IN_INFD32:
8660 case BUILT_IN_INFD64:
8661 case BUILT_IN_INFD128:
8662 return fold_builtin_inf (type, true);
8664 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8665 return fold_builtin_inf (type, false);
8667 CASE_FLT_FN (BUILT_IN_NAN):
8668 case BUILT_IN_NAND32:
8669 case BUILT_IN_NAND64:
8670 case BUILT_IN_NAND128:
8671 return fold_builtin_nan (arglist, type, true);
8673 CASE_FLT_FN (BUILT_IN_NANS):
8674 return fold_builtin_nan (arglist, type, false);
8676 CASE_FLT_FN (BUILT_IN_FLOOR):
8677 return fold_builtin_floor (fndecl, arglist);
8679 CASE_FLT_FN (BUILT_IN_CEIL):
8680 return fold_builtin_ceil (fndecl, arglist);
8682 CASE_FLT_FN (BUILT_IN_TRUNC):
8683 return fold_builtin_trunc (fndecl, arglist);
8685 CASE_FLT_FN (BUILT_IN_ROUND):
8686 return fold_builtin_round (fndecl, arglist);
8688 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8689 CASE_FLT_FN (BUILT_IN_RINT):
8690 return fold_trunc_transparent_mathfn (fndecl, arglist);
8692 CASE_FLT_FN (BUILT_IN_LCEIL):
8693 CASE_FLT_FN (BUILT_IN_LLCEIL):
8694 CASE_FLT_FN (BUILT_IN_LFLOOR):
8695 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8696 CASE_FLT_FN (BUILT_IN_LROUND):
8697 CASE_FLT_FN (BUILT_IN_LLROUND):
8698 return fold_builtin_int_roundingfn (fndecl, arglist);
8700 CASE_FLT_FN (BUILT_IN_LRINT):
8701 CASE_FLT_FN (BUILT_IN_LLRINT):
8702 return fold_fixed_mathfn (fndecl, arglist);
8704 CASE_INT_FN (BUILT_IN_FFS):
8705 CASE_INT_FN (BUILT_IN_CLZ):
8706 CASE_INT_FN (BUILT_IN_CTZ):
8707 CASE_INT_FN (BUILT_IN_POPCOUNT):
8708 CASE_INT_FN (BUILT_IN_PARITY):
8709 return fold_builtin_bitop (fndecl, arglist);
8711 case BUILT_IN_MEMCPY:
8712 return fold_builtin_memcpy (fndecl, arglist);
8714 case BUILT_IN_MEMPCPY:
8715 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8717 case BUILT_IN_MEMMOVE:
8718 return fold_builtin_memmove (arglist, type);
8720 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8721 return fold_builtin_signbit (fndecl, arglist);
8723 case BUILT_IN_ISASCII:
8724 return fold_builtin_isascii (arglist);
8726 case BUILT_IN_TOASCII:
8727 return fold_builtin_toascii (arglist);
8729 case BUILT_IN_ISDIGIT:
8730 return fold_builtin_isdigit (arglist);
8732 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8733 return fold_builtin_copysign (fndecl, arglist, type);
8735 CASE_FLT_FN (BUILT_IN_FINITE):
8736 case BUILT_IN_FINITED32:
8737 case BUILT_IN_FINITED64:
8738 case BUILT_IN_FINITED128:
8739 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8741 CASE_FLT_FN (BUILT_IN_ISINF):
8742 case BUILT_IN_ISINFD32:
8743 case BUILT_IN_ISINFD64:
8744 case BUILT_IN_ISINFD128:
8745 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8747 CASE_FLT_FN (BUILT_IN_ISNAN):
8748 case BUILT_IN_ISNAND32:
8749 case BUILT_IN_ISNAND64:
8750 case BUILT_IN_ISNAND128:
8751 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8753 case BUILT_IN_ISGREATER:
8754 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8755 case BUILT_IN_ISGREATEREQUAL:
8756 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8757 case BUILT_IN_ISLESS:
8758 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8759 case BUILT_IN_ISLESSEQUAL:
8760 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8761 case BUILT_IN_ISLESSGREATER:
8762 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8763 case BUILT_IN_ISUNORDERED:
8764 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8765 NOP_EXPR);
8767 /* We do the folding for va_start in the expander. */
8768 case BUILT_IN_VA_START:
8769 break;
8771 case BUILT_IN_OBJECT_SIZE:
8772 return fold_builtin_object_size (arglist);
8773 case BUILT_IN_MEMCPY_CHK:
8774 case BUILT_IN_MEMPCPY_CHK:
8775 case BUILT_IN_MEMMOVE_CHK:
8776 case BUILT_IN_MEMSET_CHK:
8777 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8778 DECL_FUNCTION_CODE (fndecl));
8779 case BUILT_IN_STRCPY_CHK:
8780 case BUILT_IN_STPCPY_CHK:
8781 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8782 DECL_FUNCTION_CODE (fndecl));
8783 case BUILT_IN_STRNCPY_CHK:
8784 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8785 case BUILT_IN_STRCAT_CHK:
8786 return fold_builtin_strcat_chk (fndecl, arglist);
8787 case BUILT_IN_STRNCAT_CHK:
8788 return fold_builtin_strncat_chk (fndecl, arglist);
8789 case BUILT_IN_SPRINTF_CHK:
8790 case BUILT_IN_VSPRINTF_CHK:
8791 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8792 case BUILT_IN_SNPRINTF_CHK:
8793 case BUILT_IN_VSNPRINTF_CHK:
8794 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8795 DECL_FUNCTION_CODE (fndecl));
8797 case BUILT_IN_PRINTF:
8798 case BUILT_IN_PRINTF_UNLOCKED:
8799 case BUILT_IN_VPRINTF:
8800 case BUILT_IN_PRINTF_CHK:
8801 case BUILT_IN_VPRINTF_CHK:
8802 return fold_builtin_printf (fndecl, arglist, ignore,
8803 DECL_FUNCTION_CODE (fndecl));
8805 case BUILT_IN_FPRINTF:
8806 case BUILT_IN_FPRINTF_UNLOCKED:
8807 case BUILT_IN_VFPRINTF:
8808 case BUILT_IN_FPRINTF_CHK:
8809 case BUILT_IN_VFPRINTF_CHK:
8810 return fold_builtin_fprintf (fndecl, arglist, ignore,
8811 DECL_FUNCTION_CODE (fndecl));
8813 default:
8814 break;
8817 return 0;
8820 /* A wrapper function for builtin folding that prevents warnings for
8821 "statement without effect" and the like, caused by removing the
8822 call node earlier than the warning is generated. */
8824 tree
8825 fold_builtin (tree fndecl, tree arglist, bool ignore)
8827 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8828 if (exp)
8830 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8831 TREE_NO_WARNING (exp) = 1;
8834 return exp;
8837 /* Conveniently construct a function call expression. */
8839 tree
8840 build_function_call_expr (tree fn, tree arglist)
8842 tree call_expr;
8844 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8845 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8846 call_expr, arglist, NULL_TREE);
8849 /* This function validates the types of a function call argument list
8850 represented as a tree chain of parameters against a specified list
8851 of tree_codes. If the last specifier is a 0, that represents an
8852 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8854 static int
8855 validate_arglist (tree arglist, ...)
8857 enum tree_code code;
8858 int res = 0;
8859 va_list ap;
8861 va_start (ap, arglist);
8865 code = va_arg (ap, enum tree_code);
8866 switch (code)
8868 case 0:
8869 /* This signifies an ellipses, any further arguments are all ok. */
8870 res = 1;
8871 goto end;
8872 case VOID_TYPE:
8873 /* This signifies an endlink, if no arguments remain, return
8874 true, otherwise return false. */
8875 res = arglist == 0;
8876 goto end;
8877 default:
8878 /* If no parameters remain or the parameter's code does not
8879 match the specified code, return false. Otherwise continue
8880 checking any remaining arguments. */
8881 if (arglist == 0)
8882 goto end;
8883 if (code == POINTER_TYPE)
8885 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8886 goto end;
8888 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8889 goto end;
8890 break;
8892 arglist = TREE_CHAIN (arglist);
8894 while (1);
8896 /* We need gotos here since we can only have one VA_CLOSE in a
8897 function. */
8898 end: ;
8899 va_end (ap);
8901 return res;
8904 /* Default target-specific builtin expander that does nothing. */
8907 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8908 rtx target ATTRIBUTE_UNUSED,
8909 rtx subtarget ATTRIBUTE_UNUSED,
8910 enum machine_mode mode ATTRIBUTE_UNUSED,
8911 int ignore ATTRIBUTE_UNUSED)
8913 return NULL_RTX;
8916 /* Returns true is EXP represents data that would potentially reside
8917 in a readonly section. */
8919 static bool
8920 readonly_data_expr (tree exp)
8922 STRIP_NOPS (exp);
8924 if (TREE_CODE (exp) != ADDR_EXPR)
8925 return false;
8927 exp = get_base_address (TREE_OPERAND (exp, 0));
8928 if (!exp)
8929 return false;
8931 /* Make sure we call decl_readonly_section only for trees it
8932 can handle (since it returns true for everything it doesn't
8933 understand). */
8934 if (TREE_CODE (exp) == STRING_CST
8935 || TREE_CODE (exp) == CONSTRUCTOR
8936 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8937 return decl_readonly_section (exp, 0);
8938 else
8939 return false;
8942 /* Simplify a call to the strstr builtin.
8944 Return 0 if no simplification was possible, otherwise return the
8945 simplified form of the call as a tree.
8947 The simplified form may be a constant or other expression which
8948 computes the same value, but in a more efficient manner (including
8949 calls to other builtin functions).
8951 The call may contain arguments which need to be evaluated, but
8952 which are not useful to determine the result of the call. In
8953 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8954 COMPOUND_EXPR will be an argument which must be evaluated.
8955 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8956 COMPOUND_EXPR in the chain will contain the tree for the simplified
8957 form of the builtin function call. */
8959 static tree
8960 fold_builtin_strstr (tree arglist, tree type)
8962 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8963 return 0;
8964 else
8966 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8967 tree fn;
8968 const char *p1, *p2;
8970 p2 = c_getstr (s2);
8971 if (p2 == NULL)
8972 return 0;
8974 p1 = c_getstr (s1);
8975 if (p1 != NULL)
8977 const char *r = strstr (p1, p2);
8978 tree tem;
8980 if (r == NULL)
8981 return build_int_cst (TREE_TYPE (s1), 0);
8983 /* Return an offset into the constant string argument. */
8984 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8985 s1, build_int_cst (TREE_TYPE (s1), r - p1));
8986 return fold_convert (type, tem);
8989 /* The argument is const char *, and the result is char *, so we need
8990 a type conversion here to avoid a warning. */
8991 if (p2[0] == '\0')
8992 return fold_convert (type, s1);
8994 if (p2[1] != '\0')
8995 return 0;
8997 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8998 if (!fn)
8999 return 0;
9001 /* New argument list transforming strstr(s1, s2) to
9002 strchr(s1, s2[0]). */
9003 arglist = build_tree_list (NULL_TREE,
9004 build_int_cst (NULL_TREE, p2[0]));
9005 arglist = tree_cons (NULL_TREE, s1, arglist);
9006 return build_function_call_expr (fn, arglist);
9010 /* Simplify a call to the strchr builtin.
9012 Return 0 if no simplification was possible, otherwise return the
9013 simplified form of the call as a tree.
9015 The simplified form may be a constant or other expression which
9016 computes the same value, but in a more efficient manner (including
9017 calls to other builtin functions).
9019 The call may contain arguments which need to be evaluated, but
9020 which are not useful to determine the result of the call. In
9021 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9022 COMPOUND_EXPR will be an argument which must be evaluated.
9023 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9024 COMPOUND_EXPR in the chain will contain the tree for the simplified
9025 form of the builtin function call. */
9027 static tree
9028 fold_builtin_strchr (tree arglist, tree type)
9030 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9031 return 0;
9032 else
9034 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9035 const char *p1;
9037 if (TREE_CODE (s2) != INTEGER_CST)
9038 return 0;
9040 p1 = c_getstr (s1);
9041 if (p1 != NULL)
9043 char c;
9044 const char *r;
9045 tree tem;
9047 if (target_char_cast (s2, &c))
9048 return 0;
9050 r = strchr (p1, c);
9052 if (r == NULL)
9053 return build_int_cst (TREE_TYPE (s1), 0);
9055 /* Return an offset into the constant string argument. */
9056 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9057 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9058 return fold_convert (type, tem);
9060 return 0;
9064 /* Simplify a call to the strrchr builtin.
9066 Return 0 if no simplification was possible, otherwise return the
9067 simplified form of the call as a tree.
9069 The simplified form may be a constant or other expression which
9070 computes the same value, but in a more efficient manner (including
9071 calls to other builtin functions).
9073 The call may contain arguments which need to be evaluated, but
9074 which are not useful to determine the result of the call. In
9075 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9076 COMPOUND_EXPR will be an argument which must be evaluated.
9077 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9078 COMPOUND_EXPR in the chain will contain the tree for the simplified
9079 form of the builtin function call. */
9081 static tree
9082 fold_builtin_strrchr (tree arglist, tree type)
9084 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9085 return 0;
9086 else
9088 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9089 tree fn;
9090 const char *p1;
9092 if (TREE_CODE (s2) != INTEGER_CST)
9093 return 0;
9095 p1 = c_getstr (s1);
9096 if (p1 != NULL)
9098 char c;
9099 const char *r;
9100 tree tem;
9102 if (target_char_cast (s2, &c))
9103 return 0;
9105 r = strrchr (p1, c);
9107 if (r == NULL)
9108 return build_int_cst (TREE_TYPE (s1), 0);
9110 /* Return an offset into the constant string argument. */
9111 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9112 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9113 return fold_convert (type, tem);
9116 if (! integer_zerop (s2))
9117 return 0;
9119 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9120 if (!fn)
9121 return 0;
9123 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9124 return build_function_call_expr (fn, arglist);
9128 /* Simplify a call to the strpbrk builtin.
9130 Return 0 if no simplification was possible, otherwise return the
9131 simplified form of the call as a tree.
9133 The simplified form may be a constant or other expression which
9134 computes the same value, but in a more efficient manner (including
9135 calls to other builtin functions).
9137 The call may contain arguments which need to be evaluated, but
9138 which are not useful to determine the result of the call. In
9139 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9140 COMPOUND_EXPR will be an argument which must be evaluated.
9141 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9142 COMPOUND_EXPR in the chain will contain the tree for the simplified
9143 form of the builtin function call. */
9145 static tree
9146 fold_builtin_strpbrk (tree arglist, tree type)
9148 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9149 return 0;
9150 else
9152 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9153 tree fn;
9154 const char *p1, *p2;
9156 p2 = c_getstr (s2);
9157 if (p2 == NULL)
9158 return 0;
9160 p1 = c_getstr (s1);
9161 if (p1 != NULL)
9163 const char *r = strpbrk (p1, p2);
9164 tree tem;
9166 if (r == NULL)
9167 return build_int_cst (TREE_TYPE (s1), 0);
9169 /* Return an offset into the constant string argument. */
9170 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9171 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9172 return fold_convert (type, tem);
9175 if (p2[0] == '\0')
9176 /* strpbrk(x, "") == NULL.
9177 Evaluate and ignore s1 in case it had side-effects. */
9178 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9180 if (p2[1] != '\0')
9181 return 0; /* Really call strpbrk. */
9183 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9184 if (!fn)
9185 return 0;
9187 /* New argument list transforming strpbrk(s1, s2) to
9188 strchr(s1, s2[0]). */
9189 arglist = build_tree_list (NULL_TREE,
9190 build_int_cst (NULL_TREE, p2[0]));
9191 arglist = tree_cons (NULL_TREE, s1, arglist);
9192 return build_function_call_expr (fn, arglist);
9196 /* Simplify a call to the strcat builtin.
9198 Return 0 if no simplification was possible, otherwise return the
9199 simplified form of the call as a tree.
9201 The simplified form may be a constant or other expression which
9202 computes the same value, but in a more efficient manner (including
9203 calls to other builtin functions).
9205 The call may contain arguments which need to be evaluated, but
9206 which are not useful to determine the result of the call. In
9207 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9208 COMPOUND_EXPR will be an argument which must be evaluated.
9209 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9210 COMPOUND_EXPR in the chain will contain the tree for the simplified
9211 form of the builtin function call. */
9213 static tree
9214 fold_builtin_strcat (tree arglist)
9216 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9217 return 0;
9218 else
9220 tree dst = TREE_VALUE (arglist),
9221 src = TREE_VALUE (TREE_CHAIN (arglist));
9222 const char *p = c_getstr (src);
9224 /* If the string length is zero, return the dst parameter. */
9225 if (p && *p == '\0')
9226 return dst;
9228 return 0;
9232 /* Simplify a call to the strncat builtin.
9234 Return 0 if no simplification was possible, otherwise return the
9235 simplified form of the call as a tree.
9237 The simplified form may be a constant or other expression which
9238 computes the same value, but in a more efficient manner (including
9239 calls to other builtin functions).
9241 The call may contain arguments which need to be evaluated, but
9242 which are not useful to determine the result of the call. In
9243 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9244 COMPOUND_EXPR will be an argument which must be evaluated.
9245 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9246 COMPOUND_EXPR in the chain will contain the tree for the simplified
9247 form of the builtin function call. */
9249 static tree
9250 fold_builtin_strncat (tree arglist)
9252 if (!validate_arglist (arglist,
9253 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9254 return 0;
9255 else
9257 tree dst = TREE_VALUE (arglist);
9258 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9259 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9260 const char *p = c_getstr (src);
9262 /* If the requested length is zero, or the src parameter string
9263 length is zero, return the dst parameter. */
9264 if (integer_zerop (len) || (p && *p == '\0'))
9265 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9267 /* If the requested len is greater than or equal to the string
9268 length, call strcat. */
9269 if (TREE_CODE (len) == INTEGER_CST && p
9270 && compare_tree_int (len, strlen (p)) >= 0)
9272 tree newarglist
9273 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9274 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9276 /* If the replacement _DECL isn't initialized, don't do the
9277 transformation. */
9278 if (!fn)
9279 return 0;
9281 return build_function_call_expr (fn, newarglist);
9283 return 0;
9287 /* Simplify a call to the strspn builtin.
9289 Return 0 if no simplification was possible, otherwise return the
9290 simplified form of the call as a tree.
9292 The simplified form may be a constant or other expression which
9293 computes the same value, but in a more efficient manner (including
9294 calls to other builtin functions).
9296 The call may contain arguments which need to be evaluated, but
9297 which are not useful to determine the result of the call. In
9298 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9299 COMPOUND_EXPR will be an argument which must be evaluated.
9300 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9301 COMPOUND_EXPR in the chain will contain the tree for the simplified
9302 form of the builtin function call. */
9304 static tree
9305 fold_builtin_strspn (tree arglist)
9307 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9308 return 0;
9309 else
9311 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9312 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9314 /* If both arguments are constants, evaluate at compile-time. */
9315 if (p1 && p2)
9317 const size_t r = strspn (p1, p2);
9318 return size_int (r);
9321 /* If either argument is "", return 0. */
9322 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9323 /* Evaluate and ignore both arguments in case either one has
9324 side-effects. */
9325 return omit_two_operands (integer_type_node, integer_zero_node,
9326 s1, s2);
9327 return 0;
9331 /* Simplify a call to the strcspn builtin.
9333 Return 0 if no simplification was possible, otherwise return the
9334 simplified form of the call as a tree.
9336 The simplified form may be a constant or other expression which
9337 computes the same value, but in a more efficient manner (including
9338 calls to other builtin functions).
9340 The call may contain arguments which need to be evaluated, but
9341 which are not useful to determine the result of the call. In
9342 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9343 COMPOUND_EXPR will be an argument which must be evaluated.
9344 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9345 COMPOUND_EXPR in the chain will contain the tree for the simplified
9346 form of the builtin function call. */
9348 static tree
9349 fold_builtin_strcspn (tree arglist)
9351 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9352 return 0;
9353 else
9355 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9356 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9358 /* If both arguments are constants, evaluate at compile-time. */
9359 if (p1 && p2)
9361 const size_t r = strcspn (p1, p2);
9362 return size_int (r);
9365 /* If the first argument is "", return 0. */
9366 if (p1 && *p1 == '\0')
9368 /* Evaluate and ignore argument s2 in case it has
9369 side-effects. */
9370 return omit_one_operand (integer_type_node,
9371 integer_zero_node, s2);
9374 /* If the second argument is "", return __builtin_strlen(s1). */
9375 if (p2 && *p2 == '\0')
9377 tree newarglist = build_tree_list (NULL_TREE, s1),
9378 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9380 /* If the replacement _DECL isn't initialized, don't do the
9381 transformation. */
9382 if (!fn)
9383 return 0;
9385 return build_function_call_expr (fn, newarglist);
9387 return 0;
9391 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9392 by the builtin will be ignored. UNLOCKED is true is true if this
9393 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9394 the known length of the string. Return NULL_TREE if no simplification
9395 was possible. */
9397 tree
9398 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9400 tree fn;
9401 /* If we're using an unlocked function, assume the other unlocked
9402 functions exist explicitly. */
9403 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9404 : implicit_built_in_decls[BUILT_IN_FPUTC];
9405 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9406 : implicit_built_in_decls[BUILT_IN_FWRITE];
9408 /* If the return value is used, don't do the transformation. */
9409 if (!ignore)
9410 return 0;
9412 /* Verify the arguments in the original call. */
9413 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9414 return 0;
9416 if (! len)
9417 len = c_strlen (TREE_VALUE (arglist), 0);
9419 /* Get the length of the string passed to fputs. If the length
9420 can't be determined, punt. */
9421 if (!len
9422 || TREE_CODE (len) != INTEGER_CST)
9423 return 0;
9425 switch (compare_tree_int (len, 1))
9427 case -1: /* length is 0, delete the call entirely . */
9428 return omit_one_operand (integer_type_node, integer_zero_node,
9429 TREE_VALUE (TREE_CHAIN (arglist)));
9431 case 0: /* length is 1, call fputc. */
9433 const char *p = c_getstr (TREE_VALUE (arglist));
9435 if (p != NULL)
9437 /* New argument list transforming fputs(string, stream) to
9438 fputc(string[0], stream). */
9439 arglist = build_tree_list (NULL_TREE,
9440 TREE_VALUE (TREE_CHAIN (arglist)));
9441 arglist = tree_cons (NULL_TREE,
9442 build_int_cst (NULL_TREE, p[0]),
9443 arglist);
9444 fn = fn_fputc;
9445 break;
9448 /* FALLTHROUGH */
9449 case 1: /* length is greater than 1, call fwrite. */
9451 tree string_arg;
9453 /* If optimizing for size keep fputs. */
9454 if (optimize_size)
9455 return 0;
9456 string_arg = TREE_VALUE (arglist);
9457 /* New argument list transforming fputs(string, stream) to
9458 fwrite(string, 1, len, stream). */
9459 arglist = build_tree_list (NULL_TREE,
9460 TREE_VALUE (TREE_CHAIN (arglist)));
9461 arglist = tree_cons (NULL_TREE, len, arglist);
9462 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9463 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9464 fn = fn_fwrite;
9465 break;
9467 default:
9468 gcc_unreachable ();
9471 /* If the replacement _DECL isn't initialized, don't do the
9472 transformation. */
9473 if (!fn)
9474 return 0;
9476 /* These optimizations are only performed when the result is ignored,
9477 hence there's no need to cast the result to integer_type_node. */
9478 return build_function_call_expr (fn, arglist);
9481 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9482 produced. False otherwise. This is done so that we don't output the error
9483 or warning twice or three times. */
9484 bool
9485 fold_builtin_next_arg (tree arglist)
9487 tree fntype = TREE_TYPE (current_function_decl);
9489 if (TYPE_ARG_TYPES (fntype) == 0
9490 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9491 == void_type_node))
9493 error ("%<va_start%> used in function with fixed args");
9494 return true;
9496 else if (!arglist)
9498 /* Evidently an out of date version of <stdarg.h>; can't validate
9499 va_start's second argument, but can still work as intended. */
9500 warning (0, "%<__builtin_next_arg%> called without an argument");
9501 return true;
9503 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9504 when we checked the arguments and if needed issued a warning. */
9505 else if (!TREE_CHAIN (arglist)
9506 || !integer_zerop (TREE_VALUE (arglist))
9507 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9508 || TREE_CHAIN (TREE_CHAIN (arglist)))
9510 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9511 tree arg = TREE_VALUE (arglist);
9513 if (TREE_CHAIN (arglist))
9515 error ("%<va_start%> used with too many arguments");
9516 return true;
9519 /* Strip off all nops for the sake of the comparison. This
9520 is not quite the same as STRIP_NOPS. It does more.
9521 We must also strip off INDIRECT_EXPR for C++ reference
9522 parameters. */
9523 while (TREE_CODE (arg) == NOP_EXPR
9524 || TREE_CODE (arg) == CONVERT_EXPR
9525 || TREE_CODE (arg) == NON_LVALUE_EXPR
9526 || TREE_CODE (arg) == INDIRECT_REF)
9527 arg = TREE_OPERAND (arg, 0);
9528 if (arg != last_parm)
9530 /* FIXME: Sometimes with the tree optimizers we can get the
9531 not the last argument even though the user used the last
9532 argument. We just warn and set the arg to be the last
9533 argument so that we will get wrong-code because of
9534 it. */
9535 warning (0, "second parameter of %<va_start%> not last named argument");
9537 /* We want to verify the second parameter just once before the tree
9538 optimizers are run and then avoid keeping it in the tree,
9539 as otherwise we could warn even for correct code like:
9540 void foo (int i, ...)
9541 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9542 TREE_VALUE (arglist) = integer_zero_node;
9543 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9545 return false;
9549 /* Simplify a call to the sprintf builtin.
9551 Return 0 if no simplification was possible, otherwise return the
9552 simplified form of the call as a tree. If IGNORED is true, it means that
9553 the caller does not use the returned value of the function. */
9555 static tree
9556 fold_builtin_sprintf (tree arglist, int ignored)
9558 tree call, retval, dest, fmt;
9559 const char *fmt_str = NULL;
9561 /* Verify the required arguments in the original call. We deal with two
9562 types of sprintf() calls: 'sprintf (str, fmt)' and
9563 'sprintf (dest, "%s", orig)'. */
9564 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9565 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9566 VOID_TYPE))
9567 return NULL_TREE;
9569 /* Get the destination string and the format specifier. */
9570 dest = TREE_VALUE (arglist);
9571 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9573 /* Check whether the format is a literal string constant. */
9574 fmt_str = c_getstr (fmt);
9575 if (fmt_str == NULL)
9576 return NULL_TREE;
9578 call = NULL_TREE;
9579 retval = NULL_TREE;
9581 if (!init_target_chars())
9582 return 0;
9584 /* If the format doesn't contain % args or %%, use strcpy. */
9585 if (strchr (fmt_str, target_percent) == NULL)
9587 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9589 if (!fn)
9590 return NULL_TREE;
9592 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9593 'format' is known to contain no % formats. */
9594 arglist = build_tree_list (NULL_TREE, fmt);
9595 arglist = tree_cons (NULL_TREE, dest, arglist);
9596 call = build_function_call_expr (fn, arglist);
9597 if (!ignored)
9598 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9601 /* If the format is "%s", use strcpy if the result isn't used. */
9602 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9604 tree fn, orig;
9605 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9607 if (!fn)
9608 return NULL_TREE;
9610 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9611 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9612 arglist = build_tree_list (NULL_TREE, orig);
9613 arglist = tree_cons (NULL_TREE, dest, arglist);
9614 if (!ignored)
9616 retval = c_strlen (orig, 1);
9617 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9618 return NULL_TREE;
9620 call = build_function_call_expr (fn, arglist);
9623 if (call && retval)
9625 retval = convert
9626 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9627 retval);
9628 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9630 else
9631 return call;
9634 /* Expand a call to __builtin_object_size. */
9637 expand_builtin_object_size (tree exp)
9639 tree ost;
9640 int object_size_type;
9641 tree fndecl = get_callee_fndecl (exp);
9642 tree arglist = TREE_OPERAND (exp, 1);
9643 location_t locus = EXPR_LOCATION (exp);
9645 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9647 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9648 &locus, fndecl);
9649 expand_builtin_trap ();
9650 return const0_rtx;
9653 ost = TREE_VALUE (TREE_CHAIN (arglist));
9654 STRIP_NOPS (ost);
9656 if (TREE_CODE (ost) != INTEGER_CST
9657 || tree_int_cst_sgn (ost) < 0
9658 || compare_tree_int (ost, 3) > 0)
9660 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9661 &locus, fndecl);
9662 expand_builtin_trap ();
9663 return const0_rtx;
9666 object_size_type = tree_low_cst (ost, 0);
9668 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9671 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9672 FCODE is the BUILT_IN_* to use.
9673 Return 0 if we failed; the caller should emit a normal call,
9674 otherwise try to get the result in TARGET, if convenient (and in
9675 mode MODE if that's convenient). */
9677 static rtx
9678 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9679 enum built_in_function fcode)
9681 tree arglist = TREE_OPERAND (exp, 1);
9682 tree dest, src, len, size;
9684 if (!validate_arglist (arglist,
9685 POINTER_TYPE,
9686 fcode == BUILT_IN_MEMSET_CHK
9687 ? INTEGER_TYPE : POINTER_TYPE,
9688 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9689 return 0;
9691 dest = TREE_VALUE (arglist);
9692 src = TREE_VALUE (TREE_CHAIN (arglist));
9693 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9694 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9696 if (! host_integerp (size, 1))
9697 return 0;
9699 if (host_integerp (len, 1) || integer_all_onesp (size))
9701 tree fn;
9703 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9705 location_t locus = EXPR_LOCATION (exp);
9706 warning (0, "%Hcall to %D will always overflow destination buffer",
9707 &locus, get_callee_fndecl (exp));
9708 return 0;
9711 arglist = build_tree_list (NULL_TREE, len);
9712 arglist = tree_cons (NULL_TREE, src, arglist);
9713 arglist = tree_cons (NULL_TREE, dest, arglist);
9715 fn = NULL_TREE;
9716 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9717 mem{cpy,pcpy,move,set} is available. */
9718 switch (fcode)
9720 case BUILT_IN_MEMCPY_CHK:
9721 fn = built_in_decls[BUILT_IN_MEMCPY];
9722 break;
9723 case BUILT_IN_MEMPCPY_CHK:
9724 fn = built_in_decls[BUILT_IN_MEMPCPY];
9725 break;
9726 case BUILT_IN_MEMMOVE_CHK:
9727 fn = built_in_decls[BUILT_IN_MEMMOVE];
9728 break;
9729 case BUILT_IN_MEMSET_CHK:
9730 fn = built_in_decls[BUILT_IN_MEMSET];
9731 break;
9732 default:
9733 break;
9736 if (! fn)
9737 return 0;
9739 fn = build_function_call_expr (fn, arglist);
9740 if (TREE_CODE (fn) == CALL_EXPR)
9741 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9742 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9744 else if (fcode == BUILT_IN_MEMSET_CHK)
9745 return 0;
9746 else
9748 unsigned int dest_align
9749 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9751 /* If DEST is not a pointer type, call the normal function. */
9752 if (dest_align == 0)
9753 return 0;
9755 /* If SRC and DEST are the same (and not volatile), do nothing. */
9756 if (operand_equal_p (src, dest, 0))
9758 tree expr;
9760 if (fcode != BUILT_IN_MEMPCPY_CHK)
9762 /* Evaluate and ignore LEN in case it has side-effects. */
9763 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9764 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9767 len = fold_convert (TREE_TYPE (dest), len);
9768 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9769 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9772 /* __memmove_chk special case. */
9773 if (fcode == BUILT_IN_MEMMOVE_CHK)
9775 unsigned int src_align
9776 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9778 if (src_align == 0)
9779 return 0;
9781 /* If src is categorized for a readonly section we can use
9782 normal __memcpy_chk. */
9783 if (readonly_data_expr (src))
9785 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9786 if (!fn)
9787 return 0;
9788 fn = build_function_call_expr (fn, arglist);
9789 if (TREE_CODE (fn) == CALL_EXPR)
9790 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9791 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9794 return 0;
9798 /* Emit warning if a buffer overflow is detected at compile time. */
9800 static void
9801 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9803 int arg_mask, is_strlen = 0;
9804 tree arglist = TREE_OPERAND (exp, 1), a;
9805 tree len, size;
9806 location_t locus;
9808 switch (fcode)
9810 case BUILT_IN_STRCPY_CHK:
9811 case BUILT_IN_STPCPY_CHK:
9812 /* For __strcat_chk the warning will be emitted only if overflowing
9813 by at least strlen (dest) + 1 bytes. */
9814 case BUILT_IN_STRCAT_CHK:
9815 arg_mask = 6;
9816 is_strlen = 1;
9817 break;
9818 case BUILT_IN_STRNCPY_CHK:
9819 arg_mask = 12;
9820 break;
9821 case BUILT_IN_SNPRINTF_CHK:
9822 case BUILT_IN_VSNPRINTF_CHK:
9823 arg_mask = 10;
9824 break;
9825 default:
9826 gcc_unreachable ();
9829 len = NULL_TREE;
9830 size = NULL_TREE;
9831 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9832 if (arg_mask & 1)
9834 if (len)
9835 size = a;
9836 else
9837 len = a;
9840 if (!len || !size)
9841 return;
9843 len = TREE_VALUE (len);
9844 size = TREE_VALUE (size);
9846 if (! host_integerp (size, 1) || integer_all_onesp (size))
9847 return;
9849 if (is_strlen)
9851 len = c_strlen (len, 1);
9852 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9853 return;
9855 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9856 return;
9858 locus = EXPR_LOCATION (exp);
9859 warning (0, "%Hcall to %D will always overflow destination buffer",
9860 &locus, get_callee_fndecl (exp));
9863 /* Emit warning if a buffer overflow is detected at compile time
9864 in __sprintf_chk/__vsprintf_chk calls. */
9866 static void
9867 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9869 tree arglist = TREE_OPERAND (exp, 1);
9870 tree dest, size, len, fmt, flag;
9871 const char *fmt_str;
9873 /* Verify the required arguments in the original call. */
9874 if (! arglist)
9875 return;
9876 dest = TREE_VALUE (arglist);
9877 arglist = TREE_CHAIN (arglist);
9878 if (! arglist)
9879 return;
9880 flag = TREE_VALUE (arglist);
9881 arglist = TREE_CHAIN (arglist);
9882 if (! arglist)
9883 return;
9884 size = TREE_VALUE (arglist);
9885 arglist = TREE_CHAIN (arglist);
9886 if (! arglist)
9887 return;
9888 fmt = TREE_VALUE (arglist);
9889 arglist = TREE_CHAIN (arglist);
9891 if (! host_integerp (size, 1) || integer_all_onesp (size))
9892 return;
9894 /* Check whether the format is a literal string constant. */
9895 fmt_str = c_getstr (fmt);
9896 if (fmt_str == NULL)
9897 return;
9899 if (!init_target_chars())
9900 return;
9902 /* If the format doesn't contain % args or %%, we know its size. */
9903 if (strchr (fmt_str, target_percent) == 0)
9904 len = build_int_cstu (size_type_node, strlen (fmt_str));
9905 /* If the format is "%s" and first ... argument is a string literal,
9906 we know it too. */
9907 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9909 tree arg;
9911 if (! arglist)
9912 return;
9913 arg = TREE_VALUE (arglist);
9914 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9915 return;
9917 len = c_strlen (arg, 1);
9918 if (!len || ! host_integerp (len, 1))
9919 return;
9921 else
9922 return;
9924 if (! tree_int_cst_lt (len, size))
9926 location_t locus = EXPR_LOCATION (exp);
9927 warning (0, "%Hcall to %D will always overflow destination buffer",
9928 &locus, get_callee_fndecl (exp));
9932 /* Fold a call to __builtin_object_size, if possible. */
9934 tree
9935 fold_builtin_object_size (tree arglist)
9937 tree ptr, ost, ret = 0;
9938 int object_size_type;
9940 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9941 return 0;
9943 ptr = TREE_VALUE (arglist);
9944 ost = TREE_VALUE (TREE_CHAIN (arglist));
9945 STRIP_NOPS (ost);
9947 if (TREE_CODE (ost) != INTEGER_CST
9948 || tree_int_cst_sgn (ost) < 0
9949 || compare_tree_int (ost, 3) > 0)
9950 return 0;
9952 object_size_type = tree_low_cst (ost, 0);
9954 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9955 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9956 and (size_t) 0 for types 2 and 3. */
9957 if (TREE_SIDE_EFFECTS (ptr))
9958 return fold_convert (size_type_node,
9959 object_size_type < 2
9960 ? integer_minus_one_node : integer_zero_node);
9962 if (TREE_CODE (ptr) == ADDR_EXPR)
9963 ret = build_int_cstu (size_type_node,
9964 compute_builtin_object_size (ptr, object_size_type));
9966 else if (TREE_CODE (ptr) == SSA_NAME)
9968 unsigned HOST_WIDE_INT bytes;
9970 /* If object size is not known yet, delay folding until
9971 later. Maybe subsequent passes will help determining
9972 it. */
9973 bytes = compute_builtin_object_size (ptr, object_size_type);
9974 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
9975 ? -1 : 0))
9976 ret = build_int_cstu (size_type_node, bytes);
9979 if (ret)
9981 ret = force_fit_type (ret, -1, false, false);
9982 if (TREE_CONSTANT_OVERFLOW (ret))
9983 ret = 0;
9986 return ret;
9989 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9990 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
9991 code of the builtin. If MAXLEN is not NULL, it is maximum length
9992 passed as third argument. */
9994 tree
9995 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
9996 enum built_in_function fcode)
9998 tree dest, src, len, size, fn;
10000 if (!validate_arglist (arglist,
10001 POINTER_TYPE,
10002 fcode == BUILT_IN_MEMSET_CHK
10003 ? INTEGER_TYPE : POINTER_TYPE,
10004 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10005 return 0;
10007 dest = TREE_VALUE (arglist);
10008 /* Actually val for __memset_chk, but it doesn't matter. */
10009 src = TREE_VALUE (TREE_CHAIN (arglist));
10010 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10011 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10013 /* If SRC and DEST are the same (and not volatile), return DEST
10014 (resp. DEST+LEN for __mempcpy_chk). */
10015 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10017 if (fcode != BUILT_IN_MEMPCPY_CHK)
10018 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10019 else
10021 tree temp = fold_convert (TREE_TYPE (dest), len);
10022 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10023 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10027 if (! host_integerp (size, 1))
10028 return 0;
10030 if (! integer_all_onesp (size))
10032 if (! host_integerp (len, 1))
10034 /* If LEN is not constant, try MAXLEN too.
10035 For MAXLEN only allow optimizing into non-_ocs function
10036 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10037 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10039 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10041 /* (void) __mempcpy_chk () can be optimized into
10042 (void) __memcpy_chk (). */
10043 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10044 if (!fn)
10045 return 0;
10047 return build_function_call_expr (fn, arglist);
10049 return 0;
10052 else
10053 maxlen = len;
10055 if (tree_int_cst_lt (size, maxlen))
10056 return 0;
10059 arglist = build_tree_list (NULL_TREE, len);
10060 arglist = tree_cons (NULL_TREE, src, arglist);
10061 arglist = tree_cons (NULL_TREE, dest, arglist);
10063 fn = NULL_TREE;
10064 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10065 mem{cpy,pcpy,move,set} is available. */
10066 switch (fcode)
10068 case BUILT_IN_MEMCPY_CHK:
10069 fn = built_in_decls[BUILT_IN_MEMCPY];
10070 break;
10071 case BUILT_IN_MEMPCPY_CHK:
10072 fn = built_in_decls[BUILT_IN_MEMPCPY];
10073 break;
10074 case BUILT_IN_MEMMOVE_CHK:
10075 fn = built_in_decls[BUILT_IN_MEMMOVE];
10076 break;
10077 case BUILT_IN_MEMSET_CHK:
10078 fn = built_in_decls[BUILT_IN_MEMSET];
10079 break;
10080 default:
10081 break;
10084 if (!fn)
10085 return 0;
10087 return build_function_call_expr (fn, arglist);
10090 /* Fold a call to the __st[rp]cpy_chk builtin.
10091 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10092 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10093 strings passed as second argument. */
10095 tree
10096 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10097 enum built_in_function fcode)
10099 tree dest, src, size, len, fn;
10101 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10102 VOID_TYPE))
10103 return 0;
10105 dest = TREE_VALUE (arglist);
10106 src = TREE_VALUE (TREE_CHAIN (arglist));
10107 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10109 /* If SRC and DEST are the same (and not volatile), return DEST. */
10110 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10111 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10113 if (! host_integerp (size, 1))
10114 return 0;
10116 if (! integer_all_onesp (size))
10118 len = c_strlen (src, 1);
10119 if (! len || ! host_integerp (len, 1))
10121 /* If LEN is not constant, try MAXLEN too.
10122 For MAXLEN only allow optimizing into non-_ocs function
10123 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10124 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10126 if (fcode == BUILT_IN_STPCPY_CHK)
10128 if (! ignore)
10129 return 0;
10131 /* If return value of __stpcpy_chk is ignored,
10132 optimize into __strcpy_chk. */
10133 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10134 if (!fn)
10135 return 0;
10137 return build_function_call_expr (fn, arglist);
10140 if (! len || TREE_SIDE_EFFECTS (len))
10141 return 0;
10143 /* If c_strlen returned something, but not a constant,
10144 transform __strcpy_chk into __memcpy_chk. */
10145 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10146 if (!fn)
10147 return 0;
10149 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10150 arglist = build_tree_list (NULL_TREE, size);
10151 arglist = tree_cons (NULL_TREE, len, arglist);
10152 arglist = tree_cons (NULL_TREE, src, arglist);
10153 arglist = tree_cons (NULL_TREE, dest, arglist);
10154 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10155 build_function_call_expr (fn, arglist));
10158 else
10159 maxlen = len;
10161 if (! tree_int_cst_lt (maxlen, size))
10162 return 0;
10165 arglist = build_tree_list (NULL_TREE, src);
10166 arglist = tree_cons (NULL_TREE, dest, arglist);
10168 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10169 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10170 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10171 if (!fn)
10172 return 0;
10174 return build_function_call_expr (fn, arglist);
10177 /* Fold a call to the __strncpy_chk builtin.
10178 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10180 tree
10181 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10183 tree dest, src, size, len, fn;
10185 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10186 INTEGER_TYPE, VOID_TYPE))
10187 return 0;
10189 dest = TREE_VALUE (arglist);
10190 src = TREE_VALUE (TREE_CHAIN (arglist));
10191 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10192 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10194 if (! host_integerp (size, 1))
10195 return 0;
10197 if (! integer_all_onesp (size))
10199 if (! host_integerp (len, 1))
10201 /* If LEN is not constant, try MAXLEN too.
10202 For MAXLEN only allow optimizing into non-_ocs function
10203 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10204 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10205 return 0;
10207 else
10208 maxlen = len;
10210 if (tree_int_cst_lt (size, maxlen))
10211 return 0;
10214 arglist = build_tree_list (NULL_TREE, len);
10215 arglist = tree_cons (NULL_TREE, src, arglist);
10216 arglist = tree_cons (NULL_TREE, dest, arglist);
10218 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10219 fn = built_in_decls[BUILT_IN_STRNCPY];
10220 if (!fn)
10221 return 0;
10223 return build_function_call_expr (fn, arglist);
10226 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10228 static tree
10229 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10231 tree dest, src, size, fn;
10232 const char *p;
10234 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10235 VOID_TYPE))
10236 return 0;
10238 dest = TREE_VALUE (arglist);
10239 src = TREE_VALUE (TREE_CHAIN (arglist));
10240 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10242 p = c_getstr (src);
10243 /* If the SRC parameter is "", return DEST. */
10244 if (p && *p == '\0')
10245 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10247 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10248 return 0;
10250 arglist = build_tree_list (NULL_TREE, src);
10251 arglist = tree_cons (NULL_TREE, dest, arglist);
10253 /* If __builtin_strcat_chk is used, assume strcat is available. */
10254 fn = built_in_decls[BUILT_IN_STRCAT];
10255 if (!fn)
10256 return 0;
10258 return build_function_call_expr (fn, arglist);
10261 /* Fold a call to the __strncat_chk builtin EXP. */
10263 static tree
10264 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10266 tree dest, src, size, len, fn;
10267 const char *p;
10269 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10270 INTEGER_TYPE, VOID_TYPE))
10271 return 0;
10273 dest = TREE_VALUE (arglist);
10274 src = TREE_VALUE (TREE_CHAIN (arglist));
10275 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10276 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10278 p = c_getstr (src);
10279 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10280 if (p && *p == '\0')
10281 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10282 else if (integer_zerop (len))
10283 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10285 if (! host_integerp (size, 1))
10286 return 0;
10288 if (! integer_all_onesp (size))
10290 tree src_len = c_strlen (src, 1);
10291 if (src_len
10292 && host_integerp (src_len, 1)
10293 && host_integerp (len, 1)
10294 && ! tree_int_cst_lt (len, src_len))
10296 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10297 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10298 if (!fn)
10299 return 0;
10301 arglist = build_tree_list (NULL_TREE, size);
10302 arglist = tree_cons (NULL_TREE, src, arglist);
10303 arglist = tree_cons (NULL_TREE, dest, arglist);
10304 return build_function_call_expr (fn, arglist);
10306 return 0;
10309 arglist = build_tree_list (NULL_TREE, len);
10310 arglist = tree_cons (NULL_TREE, src, arglist);
10311 arglist = tree_cons (NULL_TREE, dest, arglist);
10313 /* If __builtin_strncat_chk is used, assume strncat is available. */
10314 fn = built_in_decls[BUILT_IN_STRNCAT];
10315 if (!fn)
10316 return 0;
10318 return build_function_call_expr (fn, arglist);
10321 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10322 a normal call should be emitted rather than expanding the function
10323 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10325 static tree
10326 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10328 tree dest, size, len, fn, fmt, flag;
10329 const char *fmt_str;
10331 /* Verify the required arguments in the original call. */
10332 if (! arglist)
10333 return 0;
10334 dest = TREE_VALUE (arglist);
10335 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10336 return 0;
10337 arglist = TREE_CHAIN (arglist);
10338 if (! arglist)
10339 return 0;
10340 flag = TREE_VALUE (arglist);
10341 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10342 return 0;
10343 arglist = TREE_CHAIN (arglist);
10344 if (! arglist)
10345 return 0;
10346 size = TREE_VALUE (arglist);
10347 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10348 return 0;
10349 arglist = TREE_CHAIN (arglist);
10350 if (! arglist)
10351 return 0;
10352 fmt = TREE_VALUE (arglist);
10353 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10354 return 0;
10355 arglist = TREE_CHAIN (arglist);
10357 if (! host_integerp (size, 1))
10358 return 0;
10360 len = NULL_TREE;
10362 if (!init_target_chars())
10363 return 0;
10365 /* Check whether the format is a literal string constant. */
10366 fmt_str = c_getstr (fmt);
10367 if (fmt_str != NULL)
10369 /* If the format doesn't contain % args or %%, we know the size. */
10370 if (strchr (fmt_str, target_percent) == 0)
10372 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10373 len = build_int_cstu (size_type_node, strlen (fmt_str));
10375 /* If the format is "%s" and first ... argument is a string literal,
10376 we know the size too. */
10377 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10379 tree arg;
10381 if (arglist && !TREE_CHAIN (arglist))
10383 arg = TREE_VALUE (arglist);
10384 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10386 len = c_strlen (arg, 1);
10387 if (! len || ! host_integerp (len, 1))
10388 len = NULL_TREE;
10394 if (! integer_all_onesp (size))
10396 if (! len || ! tree_int_cst_lt (len, size))
10397 return 0;
10400 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10401 or if format doesn't contain % chars or is "%s". */
10402 if (! integer_zerop (flag))
10404 if (fmt_str == NULL)
10405 return 0;
10406 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10407 return 0;
10410 arglist = tree_cons (NULL_TREE, fmt, arglist);
10411 arglist = tree_cons (NULL_TREE, dest, arglist);
10413 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10414 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10415 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10416 if (!fn)
10417 return 0;
10419 return build_function_call_expr (fn, arglist);
10422 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10423 a normal call should be emitted rather than expanding the function
10424 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10425 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10426 passed as second argument. */
10428 tree
10429 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10430 enum built_in_function fcode)
10432 tree dest, size, len, fn, fmt, flag;
10433 const char *fmt_str;
10435 /* Verify the required arguments in the original call. */
10436 if (! arglist)
10437 return 0;
10438 dest = TREE_VALUE (arglist);
10439 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10440 return 0;
10441 arglist = TREE_CHAIN (arglist);
10442 if (! arglist)
10443 return 0;
10444 len = TREE_VALUE (arglist);
10445 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10446 return 0;
10447 arglist = TREE_CHAIN (arglist);
10448 if (! arglist)
10449 return 0;
10450 flag = TREE_VALUE (arglist);
10451 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10452 return 0;
10453 arglist = TREE_CHAIN (arglist);
10454 if (! arglist)
10455 return 0;
10456 size = TREE_VALUE (arglist);
10457 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10458 return 0;
10459 arglist = TREE_CHAIN (arglist);
10460 if (! arglist)
10461 return 0;
10462 fmt = TREE_VALUE (arglist);
10463 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10464 return 0;
10465 arglist = TREE_CHAIN (arglist);
10467 if (! host_integerp (size, 1))
10468 return 0;
10470 if (! integer_all_onesp (size))
10472 if (! host_integerp (len, 1))
10474 /* If LEN is not constant, try MAXLEN too.
10475 For MAXLEN only allow optimizing into non-_ocs function
10476 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10477 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10478 return 0;
10480 else
10481 maxlen = len;
10483 if (tree_int_cst_lt (size, maxlen))
10484 return 0;
10487 if (!init_target_chars())
10488 return 0;
10490 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10491 or if format doesn't contain % chars or is "%s". */
10492 if (! integer_zerop (flag))
10494 fmt_str = c_getstr (fmt);
10495 if (fmt_str == NULL)
10496 return 0;
10497 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10498 return 0;
10501 arglist = tree_cons (NULL_TREE, fmt, arglist);
10502 arglist = tree_cons (NULL_TREE, len, arglist);
10503 arglist = tree_cons (NULL_TREE, dest, arglist);
10505 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10506 available. */
10507 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10508 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10509 if (!fn)
10510 return 0;
10512 return build_function_call_expr (fn, arglist);
10515 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10517 Return 0 if no simplification was possible, otherwise return the
10518 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10519 code of the function to be simplified. */
10521 static tree
10522 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10523 enum built_in_function fcode)
10525 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10526 const char *fmt_str = NULL;
10528 /* If the return value is used, don't do the transformation. */
10529 if (! ignore)
10530 return 0;
10532 /* Verify the required arguments in the original call. */
10533 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10535 tree flag;
10537 if (! arglist)
10538 return 0;
10539 flag = TREE_VALUE (arglist);
10540 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10541 || TREE_SIDE_EFFECTS (flag))
10542 return 0;
10543 arglist = TREE_CHAIN (arglist);
10546 if (! arglist)
10547 return 0;
10548 fmt = TREE_VALUE (arglist);
10549 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10550 return 0;
10551 arglist = TREE_CHAIN (arglist);
10553 /* Check whether the format is a literal string constant. */
10554 fmt_str = c_getstr (fmt);
10555 if (fmt_str == NULL)
10556 return NULL_TREE;
10558 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10560 /* If we're using an unlocked function, assume the other
10561 unlocked functions exist explicitly. */
10562 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10563 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10565 else
10567 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10568 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10571 if (!init_target_chars())
10572 return 0;
10574 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10576 const char *str;
10578 if (strcmp (fmt_str, target_percent_s) == 0)
10580 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10581 return 0;
10583 if (! arglist
10584 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10585 || TREE_CHAIN (arglist))
10586 return 0;
10588 str = c_getstr (TREE_VALUE (arglist));
10589 if (str == NULL)
10590 return 0;
10592 else
10594 /* The format specifier doesn't contain any '%' characters. */
10595 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10596 && arglist)
10597 return 0;
10598 str = fmt_str;
10601 /* If the string was "", printf does nothing. */
10602 if (str[0] == '\0')
10603 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10605 /* If the string has length of 1, call putchar. */
10606 if (str[1] == '\0')
10608 /* Given printf("c"), (where c is any one character,)
10609 convert "c"[0] to an int and pass that to the replacement
10610 function. */
10611 arg = build_int_cst (NULL_TREE, str[0]);
10612 arglist = build_tree_list (NULL_TREE, arg);
10613 fn = fn_putchar;
10615 else
10617 /* If the string was "string\n", call puts("string"). */
10618 size_t len = strlen (str);
10619 if ((unsigned char)str[len - 1] == target_newline)
10621 /* Create a NUL-terminated string that's one char shorter
10622 than the original, stripping off the trailing '\n'. */
10623 char *newstr = alloca (len);
10624 memcpy (newstr, str, len - 1);
10625 newstr[len - 1] = 0;
10627 arg = build_string_literal (len, newstr);
10628 arglist = build_tree_list (NULL_TREE, arg);
10629 fn = fn_puts;
10631 else
10632 /* We'd like to arrange to call fputs(string,stdout) here,
10633 but we need stdout and don't have a way to get it yet. */
10634 return 0;
10638 /* The other optimizations can be done only on the non-va_list variants. */
10639 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10640 return 0;
10642 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10643 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10645 if (! arglist
10646 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10647 || TREE_CHAIN (arglist))
10648 return 0;
10649 fn = fn_puts;
10652 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10653 else if (strcmp (fmt_str, target_percent_c) == 0)
10655 if (! arglist
10656 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10657 || TREE_CHAIN (arglist))
10658 return 0;
10659 fn = fn_putchar;
10662 if (!fn)
10663 return 0;
10665 call = build_function_call_expr (fn, arglist);
10666 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10669 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10671 Return 0 if no simplification was possible, otherwise return the
10672 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10673 code of the function to be simplified. */
10675 static tree
10676 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10677 enum built_in_function fcode)
10679 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10680 const char *fmt_str = NULL;
10682 /* If the return value is used, don't do the transformation. */
10683 if (! ignore)
10684 return 0;
10686 /* Verify the required arguments in the original call. */
10687 if (! arglist)
10688 return 0;
10689 fp = TREE_VALUE (arglist);
10690 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10691 return 0;
10692 arglist = TREE_CHAIN (arglist);
10694 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10696 tree flag;
10698 if (! arglist)
10699 return 0;
10700 flag = TREE_VALUE (arglist);
10701 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10702 || TREE_SIDE_EFFECTS (flag))
10703 return 0;
10704 arglist = TREE_CHAIN (arglist);
10707 if (! arglist)
10708 return 0;
10709 fmt = TREE_VALUE (arglist);
10710 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10711 return 0;
10712 arglist = TREE_CHAIN (arglist);
10714 /* Check whether the format is a literal string constant. */
10715 fmt_str = c_getstr (fmt);
10716 if (fmt_str == NULL)
10717 return NULL_TREE;
10719 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10721 /* If we're using an unlocked function, assume the other
10722 unlocked functions exist explicitly. */
10723 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10724 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10726 else
10728 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10729 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10732 if (!init_target_chars())
10733 return 0;
10735 /* If the format doesn't contain % args or %%, use strcpy. */
10736 if (strchr (fmt_str, target_percent) == NULL)
10738 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10739 && arglist)
10740 return 0;
10742 /* If the format specifier was "", fprintf does nothing. */
10743 if (fmt_str[0] == '\0')
10745 /* If FP has side-effects, just wait until gimplification is
10746 done. */
10747 if (TREE_SIDE_EFFECTS (fp))
10748 return 0;
10750 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10753 /* When "string" doesn't contain %, replace all cases of
10754 fprintf (fp, string) with fputs (string, fp). The fputs
10755 builtin will take care of special cases like length == 1. */
10756 arglist = build_tree_list (NULL_TREE, fp);
10757 arglist = tree_cons (NULL_TREE, fmt, arglist);
10758 fn = fn_fputs;
10761 /* The other optimizations can be done only on the non-va_list variants. */
10762 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10763 return 0;
10765 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10766 else if (strcmp (fmt_str, target_percent_s) == 0)
10768 if (! arglist
10769 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10770 || TREE_CHAIN (arglist))
10771 return 0;
10772 arg = TREE_VALUE (arglist);
10773 arglist = build_tree_list (NULL_TREE, fp);
10774 arglist = tree_cons (NULL_TREE, arg, arglist);
10775 fn = fn_fputs;
10778 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10779 else if (strcmp (fmt_str, target_percent_c) == 0)
10781 if (! arglist
10782 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10783 || TREE_CHAIN (arglist))
10784 return 0;
10785 arg = TREE_VALUE (arglist);
10786 arglist = build_tree_list (NULL_TREE, fp);
10787 arglist = tree_cons (NULL_TREE, arg, arglist);
10788 fn = fn_fputc;
10791 if (!fn)
10792 return 0;
10794 call = build_function_call_expr (fn, arglist);
10795 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10798 /* Initialize format string characters in the target charset. */
10800 static bool
10801 init_target_chars (void)
10803 static bool init;
10804 if (!init)
10806 target_newline = lang_hooks.to_target_charset ('\n');
10807 target_percent = lang_hooks.to_target_charset ('%');
10808 target_c = lang_hooks.to_target_charset ('c');
10809 target_s = lang_hooks.to_target_charset ('s');
10810 if (target_newline == 0 || target_percent == 0 || target_c == 0
10811 || target_s == 0)
10812 return false;
10814 target_percent_c[0] = target_percent;
10815 target_percent_c[1] = target_c;
10816 target_percent_c[2] = '\0';
10818 target_percent_s[0] = target_percent;
10819 target_percent_s[1] = target_s;
10820 target_percent_s[2] = '\0';
10822 target_percent_s_newline[0] = target_percent;
10823 target_percent_s_newline[1] = target_s;
10824 target_percent_s_newline[2] = target_newline;
10825 target_percent_s_newline[3] = '\0';
10827 init = true;
10829 return true;