Dead
[official-gcc.git] / gomp-20050608-branch / gcc / builtins.c
blobe0cf55ec732510efca6d561e7d207727297c88ff
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 ENUMERAL_TYPE: return enumeral_type_class;
1589 case BOOLEAN_TYPE: return boolean_type_class;
1590 case POINTER_TYPE: return pointer_type_class;
1591 case REFERENCE_TYPE: return reference_type_class;
1592 case OFFSET_TYPE: return offset_type_class;
1593 case REAL_TYPE: return real_type_class;
1594 case COMPLEX_TYPE: return complex_type_class;
1595 case FUNCTION_TYPE: return function_type_class;
1596 case METHOD_TYPE: return method_type_class;
1597 case RECORD_TYPE: return record_type_class;
1598 case UNION_TYPE:
1599 case QUAL_UNION_TYPE: return union_type_class;
1600 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1601 ? string_type_class : array_type_class);
1602 case LANG_TYPE: return lang_type_class;
1603 default: return no_type_class;
1607 /* Expand a call to __builtin_classify_type with arguments found in
1608 ARGLIST. */
1610 static rtx
1611 expand_builtin_classify_type (tree arglist)
1613 if (arglist != 0)
1614 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1615 return GEN_INT (no_type_class);
1618 /* This helper macro, meant to be used in mathfn_built_in below,
1619 determines which among a set of three builtin math functions is
1620 appropriate for a given type mode. The `F' and `L' cases are
1621 automatically generated from the `double' case. */
1622 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1623 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1624 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1625 fcodel = BUILT_IN_MATHFN##L ; break;
1627 /* Return mathematic function equivalent to FN but operating directly
1628 on TYPE, if available. If we can't do the conversion, return zero. */
1629 tree
1630 mathfn_built_in (tree type, enum built_in_function fn)
1632 enum built_in_function fcode, fcodef, fcodel;
1634 switch (fn)
1636 CASE_MATHFN (BUILT_IN_ACOS)
1637 CASE_MATHFN (BUILT_IN_ACOSH)
1638 CASE_MATHFN (BUILT_IN_ASIN)
1639 CASE_MATHFN (BUILT_IN_ASINH)
1640 CASE_MATHFN (BUILT_IN_ATAN)
1641 CASE_MATHFN (BUILT_IN_ATAN2)
1642 CASE_MATHFN (BUILT_IN_ATANH)
1643 CASE_MATHFN (BUILT_IN_CBRT)
1644 CASE_MATHFN (BUILT_IN_CEIL)
1645 CASE_MATHFN (BUILT_IN_COPYSIGN)
1646 CASE_MATHFN (BUILT_IN_COS)
1647 CASE_MATHFN (BUILT_IN_COSH)
1648 CASE_MATHFN (BUILT_IN_DREM)
1649 CASE_MATHFN (BUILT_IN_ERF)
1650 CASE_MATHFN (BUILT_IN_ERFC)
1651 CASE_MATHFN (BUILT_IN_EXP)
1652 CASE_MATHFN (BUILT_IN_EXP10)
1653 CASE_MATHFN (BUILT_IN_EXP2)
1654 CASE_MATHFN (BUILT_IN_EXPM1)
1655 CASE_MATHFN (BUILT_IN_FABS)
1656 CASE_MATHFN (BUILT_IN_FDIM)
1657 CASE_MATHFN (BUILT_IN_FLOOR)
1658 CASE_MATHFN (BUILT_IN_FMA)
1659 CASE_MATHFN (BUILT_IN_FMAX)
1660 CASE_MATHFN (BUILT_IN_FMIN)
1661 CASE_MATHFN (BUILT_IN_FMOD)
1662 CASE_MATHFN (BUILT_IN_FREXP)
1663 CASE_MATHFN (BUILT_IN_GAMMA)
1664 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1665 CASE_MATHFN (BUILT_IN_HYPOT)
1666 CASE_MATHFN (BUILT_IN_ILOGB)
1667 CASE_MATHFN (BUILT_IN_INF)
1668 CASE_MATHFN (BUILT_IN_J0)
1669 CASE_MATHFN (BUILT_IN_J1)
1670 CASE_MATHFN (BUILT_IN_JN)
1671 CASE_MATHFN (BUILT_IN_LCEIL)
1672 CASE_MATHFN (BUILT_IN_LDEXP)
1673 CASE_MATHFN (BUILT_IN_LFLOOR)
1674 CASE_MATHFN (BUILT_IN_LGAMMA)
1675 CASE_MATHFN (BUILT_IN_LLCEIL)
1676 CASE_MATHFN (BUILT_IN_LLFLOOR)
1677 CASE_MATHFN (BUILT_IN_LLRINT)
1678 CASE_MATHFN (BUILT_IN_LLROUND)
1679 CASE_MATHFN (BUILT_IN_LOG)
1680 CASE_MATHFN (BUILT_IN_LOG10)
1681 CASE_MATHFN (BUILT_IN_LOG1P)
1682 CASE_MATHFN (BUILT_IN_LOG2)
1683 CASE_MATHFN (BUILT_IN_LOGB)
1684 CASE_MATHFN (BUILT_IN_LRINT)
1685 CASE_MATHFN (BUILT_IN_LROUND)
1686 CASE_MATHFN (BUILT_IN_MODF)
1687 CASE_MATHFN (BUILT_IN_NAN)
1688 CASE_MATHFN (BUILT_IN_NANS)
1689 CASE_MATHFN (BUILT_IN_NEARBYINT)
1690 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1691 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1692 CASE_MATHFN (BUILT_IN_POW)
1693 CASE_MATHFN (BUILT_IN_POWI)
1694 CASE_MATHFN (BUILT_IN_POW10)
1695 CASE_MATHFN (BUILT_IN_REMAINDER)
1696 CASE_MATHFN (BUILT_IN_REMQUO)
1697 CASE_MATHFN (BUILT_IN_RINT)
1698 CASE_MATHFN (BUILT_IN_ROUND)
1699 CASE_MATHFN (BUILT_IN_SCALB)
1700 CASE_MATHFN (BUILT_IN_SCALBLN)
1701 CASE_MATHFN (BUILT_IN_SCALBN)
1702 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1703 CASE_MATHFN (BUILT_IN_SIN)
1704 CASE_MATHFN (BUILT_IN_SINCOS)
1705 CASE_MATHFN (BUILT_IN_SINH)
1706 CASE_MATHFN (BUILT_IN_SQRT)
1707 CASE_MATHFN (BUILT_IN_TAN)
1708 CASE_MATHFN (BUILT_IN_TANH)
1709 CASE_MATHFN (BUILT_IN_TGAMMA)
1710 CASE_MATHFN (BUILT_IN_TRUNC)
1711 CASE_MATHFN (BUILT_IN_Y0)
1712 CASE_MATHFN (BUILT_IN_Y1)
1713 CASE_MATHFN (BUILT_IN_YN)
1715 default:
1716 return 0;
1719 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1720 return implicit_built_in_decls[fcode];
1721 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1722 return implicit_built_in_decls[fcodef];
1723 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1724 return implicit_built_in_decls[fcodel];
1725 else
1726 return 0;
1729 /* If errno must be maintained, expand the RTL to check if the result,
1730 TARGET, of a built-in function call, EXP, is NaN, and if so set
1731 errno to EDOM. */
1733 static void
1734 expand_errno_check (tree exp, rtx target)
1736 rtx lab = gen_label_rtx ();
1738 /* Test the result; if it is NaN, set errno=EDOM because
1739 the argument was not in the domain. */
1740 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1741 0, lab);
1743 #ifdef TARGET_EDOM
1744 /* If this built-in doesn't throw an exception, set errno directly. */
1745 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1747 #ifdef GEN_ERRNO_RTX
1748 rtx errno_rtx = GEN_ERRNO_RTX;
1749 #else
1750 rtx errno_rtx
1751 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1752 #endif
1753 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1754 emit_label (lab);
1755 return;
1757 #endif
1759 /* We can't set errno=EDOM directly; let the library call do it.
1760 Pop the arguments right away in case the call gets deleted. */
1761 NO_DEFER_POP;
1762 expand_call (exp, target, 0);
1763 OK_DEFER_POP;
1764 emit_label (lab);
1768 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1769 Return 0 if a normal call should be emitted rather than expanding the
1770 function in-line. EXP is the expression that is a call to the builtin
1771 function; if convenient, the result should be placed in TARGET.
1772 SUBTARGET may be used as the target for computing one of EXP's operands. */
1774 static rtx
1775 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1777 optab builtin_optab;
1778 rtx op0, insns, before_call;
1779 tree fndecl = get_callee_fndecl (exp);
1780 tree arglist = TREE_OPERAND (exp, 1);
1781 enum machine_mode mode;
1782 bool errno_set = false;
1783 tree arg, narg;
1785 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1786 return 0;
1788 arg = TREE_VALUE (arglist);
1790 switch (DECL_FUNCTION_CODE (fndecl))
1792 CASE_FLT_FN (BUILT_IN_SQRT):
1793 errno_set = ! tree_expr_nonnegative_p (arg);
1794 builtin_optab = sqrt_optab;
1795 break;
1796 CASE_FLT_FN (BUILT_IN_EXP):
1797 errno_set = true; builtin_optab = exp_optab; break;
1798 CASE_FLT_FN (BUILT_IN_EXP10):
1799 CASE_FLT_FN (BUILT_IN_POW10):
1800 errno_set = true; builtin_optab = exp10_optab; break;
1801 CASE_FLT_FN (BUILT_IN_EXP2):
1802 errno_set = true; builtin_optab = exp2_optab; break;
1803 CASE_FLT_FN (BUILT_IN_EXPM1):
1804 errno_set = true; builtin_optab = expm1_optab; break;
1805 CASE_FLT_FN (BUILT_IN_LOGB):
1806 errno_set = true; builtin_optab = logb_optab; break;
1807 CASE_FLT_FN (BUILT_IN_ILOGB):
1808 errno_set = true; builtin_optab = ilogb_optab; break;
1809 CASE_FLT_FN (BUILT_IN_LOG):
1810 errno_set = true; builtin_optab = log_optab; break;
1811 CASE_FLT_FN (BUILT_IN_LOG10):
1812 errno_set = true; builtin_optab = log10_optab; break;
1813 CASE_FLT_FN (BUILT_IN_LOG2):
1814 errno_set = true; builtin_optab = log2_optab; break;
1815 CASE_FLT_FN (BUILT_IN_LOG1P):
1816 errno_set = true; builtin_optab = log1p_optab; break;
1817 CASE_FLT_FN (BUILT_IN_ASIN):
1818 builtin_optab = asin_optab; break;
1819 CASE_FLT_FN (BUILT_IN_ACOS):
1820 builtin_optab = acos_optab; break;
1821 CASE_FLT_FN (BUILT_IN_TAN):
1822 builtin_optab = tan_optab; break;
1823 CASE_FLT_FN (BUILT_IN_ATAN):
1824 builtin_optab = atan_optab; break;
1825 CASE_FLT_FN (BUILT_IN_FLOOR):
1826 builtin_optab = floor_optab; break;
1827 CASE_FLT_FN (BUILT_IN_CEIL):
1828 builtin_optab = ceil_optab; break;
1829 CASE_FLT_FN (BUILT_IN_TRUNC):
1830 builtin_optab = btrunc_optab; break;
1831 CASE_FLT_FN (BUILT_IN_ROUND):
1832 builtin_optab = round_optab; break;
1833 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1834 builtin_optab = nearbyint_optab; break;
1835 CASE_FLT_FN (BUILT_IN_RINT):
1836 builtin_optab = rint_optab; break;
1837 CASE_FLT_FN (BUILT_IN_LRINT):
1838 CASE_FLT_FN (BUILT_IN_LLRINT):
1839 builtin_optab = lrint_optab; break;
1840 default:
1841 gcc_unreachable ();
1844 /* Make a suitable register to place result in. */
1845 mode = TYPE_MODE (TREE_TYPE (exp));
1847 if (! flag_errno_math || ! HONOR_NANS (mode))
1848 errno_set = false;
1850 /* Before working hard, check whether the instruction is available. */
1851 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1853 target = gen_reg_rtx (mode);
1855 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1856 need to expand the argument again. This way, we will not perform
1857 side-effects more the once. */
1858 narg = builtin_save_expr (arg);
1859 if (narg != arg)
1861 arg = narg;
1862 arglist = build_tree_list (NULL_TREE, arg);
1863 exp = build_function_call_expr (fndecl, arglist);
1866 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1868 start_sequence ();
1870 /* Compute into TARGET.
1871 Set TARGET to wherever the result comes back. */
1872 target = expand_unop (mode, builtin_optab, op0, target, 0);
1874 if (target != 0)
1876 if (errno_set)
1877 expand_errno_check (exp, target);
1879 /* Output the entire sequence. */
1880 insns = get_insns ();
1881 end_sequence ();
1882 emit_insn (insns);
1883 return target;
1886 /* If we were unable to expand via the builtin, stop the sequence
1887 (without outputting the insns) and call to the library function
1888 with the stabilized argument list. */
1889 end_sequence ();
1892 before_call = get_last_insn ();
1894 target = expand_call (exp, target, target == const0_rtx);
1896 /* If this is a sqrt operation and we don't care about errno, try to
1897 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1898 This allows the semantics of the libcall to be visible to the RTL
1899 optimizers. */
1900 if (builtin_optab == sqrt_optab && !errno_set)
1902 /* Search backwards through the insns emitted by expand_call looking
1903 for the instruction with the REG_RETVAL note. */
1904 rtx last = get_last_insn ();
1905 while (last != before_call)
1907 if (find_reg_note (last, REG_RETVAL, NULL))
1909 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1910 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1911 two elements, i.e. symbol_ref(sqrt) and the operand. */
1912 if (note
1913 && GET_CODE (note) == EXPR_LIST
1914 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1915 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1916 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1918 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1919 /* Check operand is a register with expected mode. */
1920 if (operand
1921 && REG_P (operand)
1922 && GET_MODE (operand) == mode)
1924 /* Replace the REG_EQUAL note with a SQRT rtx. */
1925 rtx equiv = gen_rtx_SQRT (mode, operand);
1926 set_unique_reg_note (last, REG_EQUAL, equiv);
1929 break;
1931 last = PREV_INSN (last);
1935 return target;
1938 /* Expand a call to the builtin binary math functions (pow and atan2).
1939 Return 0 if a normal call should be emitted rather than expanding the
1940 function in-line. EXP is the expression that is a call to the builtin
1941 function; if convenient, the result should be placed in TARGET.
1942 SUBTARGET may be used as the target for computing one of EXP's
1943 operands. */
1945 static rtx
1946 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1948 optab builtin_optab;
1949 rtx op0, op1, insns;
1950 int op1_type = REAL_TYPE;
1951 tree fndecl = get_callee_fndecl (exp);
1952 tree arglist = TREE_OPERAND (exp, 1);
1953 tree arg0, arg1, temp, narg;
1954 enum machine_mode mode;
1955 bool errno_set = true;
1956 bool stable = true;
1958 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1959 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1960 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1961 op1_type = INTEGER_TYPE;
1963 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1964 return 0;
1966 arg0 = TREE_VALUE (arglist);
1967 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1969 switch (DECL_FUNCTION_CODE (fndecl))
1971 CASE_FLT_FN (BUILT_IN_POW):
1972 builtin_optab = pow_optab; break;
1973 CASE_FLT_FN (BUILT_IN_ATAN2):
1974 builtin_optab = atan2_optab; break;
1975 CASE_FLT_FN (BUILT_IN_LDEXP):
1976 builtin_optab = ldexp_optab; break;
1977 CASE_FLT_FN (BUILT_IN_FMOD):
1978 builtin_optab = fmod_optab; break;
1979 CASE_FLT_FN (BUILT_IN_DREM):
1980 builtin_optab = drem_optab; break;
1981 default:
1982 gcc_unreachable ();
1985 /* Make a suitable register to place result in. */
1986 mode = TYPE_MODE (TREE_TYPE (exp));
1988 /* Before working hard, check whether the instruction is available. */
1989 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1990 return 0;
1992 target = gen_reg_rtx (mode);
1994 if (! flag_errno_math || ! HONOR_NANS (mode))
1995 errno_set = false;
1997 /* Always stabilize the argument list. */
1998 narg = builtin_save_expr (arg1);
1999 if (narg != arg1)
2001 arg1 = narg;
2002 temp = build_tree_list (NULL_TREE, narg);
2003 stable = false;
2005 else
2006 temp = TREE_CHAIN (arglist);
2008 narg = builtin_save_expr (arg0);
2009 if (narg != arg0)
2011 arg0 = narg;
2012 arglist = tree_cons (NULL_TREE, narg, temp);
2013 stable = false;
2015 else if (! stable)
2016 arglist = tree_cons (NULL_TREE, arg0, temp);
2018 if (! stable)
2019 exp = build_function_call_expr (fndecl, arglist);
2021 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2022 op1 = expand_normal (arg1);
2024 start_sequence ();
2026 /* Compute into TARGET.
2027 Set TARGET to wherever the result comes back. */
2028 target = expand_binop (mode, builtin_optab, op0, op1,
2029 target, 0, OPTAB_DIRECT);
2031 /* If we were unable to expand via the builtin, stop the sequence
2032 (without outputting the insns) and call to the library function
2033 with the stabilized argument list. */
2034 if (target == 0)
2036 end_sequence ();
2037 return expand_call (exp, target, target == const0_rtx);
2040 if (errno_set)
2041 expand_errno_check (exp, target);
2043 /* Output the entire sequence. */
2044 insns = get_insns ();
2045 end_sequence ();
2046 emit_insn (insns);
2048 return target;
2051 /* Expand a call to the builtin sin and cos math functions.
2052 Return 0 if a normal call should be emitted rather than expanding the
2053 function in-line. EXP is the expression that is a call to the builtin
2054 function; if convenient, the result should be placed in TARGET.
2055 SUBTARGET may be used as the target for computing one of EXP's
2056 operands. */
2058 static rtx
2059 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2061 optab builtin_optab;
2062 rtx op0, insns;
2063 tree fndecl = get_callee_fndecl (exp);
2064 tree arglist = TREE_OPERAND (exp, 1);
2065 enum machine_mode mode;
2066 tree arg, narg;
2068 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2069 return 0;
2071 arg = TREE_VALUE (arglist);
2073 switch (DECL_FUNCTION_CODE (fndecl))
2075 CASE_FLT_FN (BUILT_IN_SIN):
2076 CASE_FLT_FN (BUILT_IN_COS):
2077 builtin_optab = sincos_optab; break;
2078 default:
2079 gcc_unreachable ();
2082 /* Make a suitable register to place result in. */
2083 mode = TYPE_MODE (TREE_TYPE (exp));
2085 /* Check if sincos insn is available, otherwise fallback
2086 to sin or cos insn. */
2087 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2088 switch (DECL_FUNCTION_CODE (fndecl))
2090 CASE_FLT_FN (BUILT_IN_SIN):
2091 builtin_optab = sin_optab; break;
2092 CASE_FLT_FN (BUILT_IN_COS):
2093 builtin_optab = cos_optab; break;
2094 default:
2095 gcc_unreachable ();
2099 /* Before working hard, check whether the instruction is available. */
2100 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2102 target = gen_reg_rtx (mode);
2104 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2105 need to expand the argument again. This way, we will not perform
2106 side-effects more the once. */
2107 narg = save_expr (arg);
2108 if (narg != arg)
2110 arg = narg;
2111 arglist = build_tree_list (NULL_TREE, arg);
2112 exp = build_function_call_expr (fndecl, arglist);
2115 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2117 start_sequence ();
2119 /* Compute into TARGET.
2120 Set TARGET to wherever the result comes back. */
2121 if (builtin_optab == sincos_optab)
2123 int result;
2125 switch (DECL_FUNCTION_CODE (fndecl))
2127 CASE_FLT_FN (BUILT_IN_SIN):
2128 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2129 break;
2130 CASE_FLT_FN (BUILT_IN_COS):
2131 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2132 break;
2133 default:
2134 gcc_unreachable ();
2136 gcc_assert (result);
2138 else
2140 target = expand_unop (mode, builtin_optab, op0, target, 0);
2143 if (target != 0)
2145 /* Output the entire sequence. */
2146 insns = get_insns ();
2147 end_sequence ();
2148 emit_insn (insns);
2149 return target;
2152 /* If we were unable to expand via the builtin, stop the sequence
2153 (without outputting the insns) and call to the library function
2154 with the stabilized argument list. */
2155 end_sequence ();
2158 target = expand_call (exp, target, target == const0_rtx);
2160 return target;
2163 /* Expand a call to the builtin sincos math function.
2164 Return 0 if a normal call should be emitted rather than expanding the
2165 function in-line. EXP is the expression that is a call to the builtin
2166 function. */
2168 static rtx
2169 expand_builtin_sincos (tree exp)
2171 rtx op0, op1, op2, target1, target2;
2172 tree arglist = TREE_OPERAND (exp, 1);
2173 enum machine_mode mode;
2174 tree arg, sinp, cosp;
2175 int result;
2177 if (!validate_arglist (arglist, REAL_TYPE,
2178 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2179 return 0;
2181 arg = TREE_VALUE (arglist);
2182 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2183 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2185 /* Make a suitable register to place result in. */
2186 mode = TYPE_MODE (TREE_TYPE (arg));
2188 /* Check if sincos insn is available, otherwise emit the call. */
2189 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2190 return NULL_RTX;
2192 target1 = gen_reg_rtx (mode);
2193 target2 = gen_reg_rtx (mode);
2195 op0 = expand_normal (arg);
2196 op1 = expand_normal (build_fold_indirect_ref (sinp));
2197 op2 = expand_normal (build_fold_indirect_ref (cosp));
2199 /* Compute into target1 and target2.
2200 Set TARGET to wherever the result comes back. */
2201 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2202 gcc_assert (result);
2204 /* Move target1 and target2 to the memory locations indicated
2205 by op1 and op2. */
2206 emit_move_insn (op1, target1);
2207 emit_move_insn (op2, target2);
2209 return const0_rtx;
2212 /* Expand a call to one of the builtin rounding functions (lfloor).
2213 If expanding via optab fails, lower expression to (int)(floor(x)).
2214 EXP is the expression that is a call to the builtin function;
2215 if convenient, the result should be placed in TARGET. SUBTARGET may
2216 be used as the target for computing one of EXP's operands. */
2218 static rtx
2219 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2221 optab builtin_optab;
2222 rtx op0, insns, tmp;
2223 tree fndecl = get_callee_fndecl (exp);
2224 tree arglist = TREE_OPERAND (exp, 1);
2225 enum built_in_function fallback_fn;
2226 tree fallback_fndecl;
2227 enum machine_mode mode;
2228 tree arg, narg;
2230 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2231 gcc_unreachable ();
2233 arg = TREE_VALUE (arglist);
2235 switch (DECL_FUNCTION_CODE (fndecl))
2237 CASE_FLT_FN (BUILT_IN_LCEIL):
2238 CASE_FLT_FN (BUILT_IN_LLCEIL):
2239 builtin_optab = lceil_optab;
2240 fallback_fn = BUILT_IN_CEIL;
2241 break;
2243 CASE_FLT_FN (BUILT_IN_LFLOOR):
2244 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2245 builtin_optab = lfloor_optab;
2246 fallback_fn = BUILT_IN_FLOOR;
2247 break;
2249 default:
2250 gcc_unreachable ();
2253 /* Make a suitable register to place result in. */
2254 mode = TYPE_MODE (TREE_TYPE (exp));
2256 /* Before working hard, check whether the instruction is available. */
2257 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2259 target = gen_reg_rtx (mode);
2261 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2262 need to expand the argument again. This way, we will not perform
2263 side-effects more the once. */
2264 narg = builtin_save_expr (arg);
2265 if (narg != arg)
2267 arg = narg;
2268 arglist = build_tree_list (NULL_TREE, arg);
2269 exp = build_function_call_expr (fndecl, arglist);
2272 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2274 start_sequence ();
2276 /* Compute into TARGET.
2277 Set TARGET to wherever the result comes back. */
2278 target = expand_unop (mode, builtin_optab, op0, target, 0);
2280 if (target != 0)
2282 /* Output the entire sequence. */
2283 insns = get_insns ();
2284 end_sequence ();
2285 emit_insn (insns);
2286 return target;
2289 /* If we were unable to expand via the builtin, stop the sequence
2290 (without outputting the insns). */
2291 end_sequence ();
2294 /* Fall back to floating point rounding optab. */
2295 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2296 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2297 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2298 gcc_assert (fallback_fndecl != NULL_TREE);
2299 exp = build_function_call_expr (fallback_fndecl, arglist);
2301 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2303 /* Truncate the result of floating point optab to integer
2304 via expand_fix (). */
2305 target = gen_reg_rtx (mode);
2306 expand_fix (target, tmp, 0);
2308 return target;
2311 /* To evaluate powi(x,n), the floating point value x raised to the
2312 constant integer exponent n, we use a hybrid algorithm that
2313 combines the "window method" with look-up tables. For an
2314 introduction to exponentiation algorithms and "addition chains",
2315 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2316 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2317 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2318 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2320 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2321 multiplications to inline before calling the system library's pow
2322 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2323 so this default never requires calling pow, powf or powl. */
2325 #ifndef POWI_MAX_MULTS
2326 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2327 #endif
2329 /* The size of the "optimal power tree" lookup table. All
2330 exponents less than this value are simply looked up in the
2331 powi_table below. This threshold is also used to size the
2332 cache of pseudo registers that hold intermediate results. */
2333 #define POWI_TABLE_SIZE 256
2335 /* The size, in bits of the window, used in the "window method"
2336 exponentiation algorithm. This is equivalent to a radix of
2337 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2338 #define POWI_WINDOW_SIZE 3
2340 /* The following table is an efficient representation of an
2341 "optimal power tree". For each value, i, the corresponding
2342 value, j, in the table states than an optimal evaluation
2343 sequence for calculating pow(x,i) can be found by evaluating
2344 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2345 100 integers is given in Knuth's "Seminumerical algorithms". */
2347 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2349 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2350 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2351 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2352 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2353 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2354 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2355 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2356 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2357 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2358 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2359 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2360 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2361 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2362 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2363 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2364 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2365 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2366 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2367 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2368 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2369 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2370 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2371 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2372 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2373 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2374 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2375 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2376 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2377 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2378 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2379 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2380 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2384 /* Return the number of multiplications required to calculate
2385 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2386 subroutine of powi_cost. CACHE is an array indicating
2387 which exponents have already been calculated. */
2389 static int
2390 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2392 /* If we've already calculated this exponent, then this evaluation
2393 doesn't require any additional multiplications. */
2394 if (cache[n])
2395 return 0;
2397 cache[n] = true;
2398 return powi_lookup_cost (n - powi_table[n], cache)
2399 + powi_lookup_cost (powi_table[n], cache) + 1;
2402 /* Return the number of multiplications required to calculate
2403 powi(x,n) for an arbitrary x, given the exponent N. This
2404 function needs to be kept in sync with expand_powi below. */
2406 static int
2407 powi_cost (HOST_WIDE_INT n)
2409 bool cache[POWI_TABLE_SIZE];
2410 unsigned HOST_WIDE_INT digit;
2411 unsigned HOST_WIDE_INT val;
2412 int result;
2414 if (n == 0)
2415 return 0;
2417 /* Ignore the reciprocal when calculating the cost. */
2418 val = (n < 0) ? -n : n;
2420 /* Initialize the exponent cache. */
2421 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2422 cache[1] = true;
2424 result = 0;
2426 while (val >= POWI_TABLE_SIZE)
2428 if (val & 1)
2430 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2431 result += powi_lookup_cost (digit, cache)
2432 + POWI_WINDOW_SIZE + 1;
2433 val >>= POWI_WINDOW_SIZE;
2435 else
2437 val >>= 1;
2438 result++;
2442 return result + powi_lookup_cost (val, cache);
2445 /* Recursive subroutine of expand_powi. This function takes the array,
2446 CACHE, of already calculated exponents and an exponent N and returns
2447 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2449 static rtx
2450 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2452 unsigned HOST_WIDE_INT digit;
2453 rtx target, result;
2454 rtx op0, op1;
2456 if (n < POWI_TABLE_SIZE)
2458 if (cache[n])
2459 return cache[n];
2461 target = gen_reg_rtx (mode);
2462 cache[n] = target;
2464 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2465 op1 = expand_powi_1 (mode, powi_table[n], cache);
2467 else if (n & 1)
2469 target = gen_reg_rtx (mode);
2470 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2471 op0 = expand_powi_1 (mode, n - digit, cache);
2472 op1 = expand_powi_1 (mode, digit, cache);
2474 else
2476 target = gen_reg_rtx (mode);
2477 op0 = expand_powi_1 (mode, n >> 1, cache);
2478 op1 = op0;
2481 result = expand_mult (mode, op0, op1, target, 0);
2482 if (result != target)
2483 emit_move_insn (target, result);
2484 return target;
2487 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2488 floating point operand in mode MODE, and N is the exponent. This
2489 function needs to be kept in sync with powi_cost above. */
2491 static rtx
2492 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2494 unsigned HOST_WIDE_INT val;
2495 rtx cache[POWI_TABLE_SIZE];
2496 rtx result;
2498 if (n == 0)
2499 return CONST1_RTX (mode);
2501 val = (n < 0) ? -n : n;
2503 memset (cache, 0, sizeof (cache));
2504 cache[1] = x;
2506 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2508 /* If the original exponent was negative, reciprocate the result. */
2509 if (n < 0)
2510 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2511 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2513 return result;
2516 /* Expand a call to the pow built-in mathematical function. Return 0 if
2517 a normal call should be emitted rather than expanding the function
2518 in-line. EXP is the expression that is a call to the builtin
2519 function; if convenient, the result should be placed in TARGET. */
2521 static rtx
2522 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2524 tree arglist = TREE_OPERAND (exp, 1);
2525 tree arg0, arg1;
2527 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2528 return 0;
2530 arg0 = TREE_VALUE (arglist);
2531 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2533 if (TREE_CODE (arg1) == REAL_CST
2534 && ! TREE_CONSTANT_OVERFLOW (arg1))
2536 REAL_VALUE_TYPE cint;
2537 REAL_VALUE_TYPE c;
2538 HOST_WIDE_INT n;
2540 c = TREE_REAL_CST (arg1);
2541 n = real_to_integer (&c);
2542 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2543 if (real_identical (&c, &cint))
2545 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2546 Otherwise, check the number of multiplications required.
2547 Note that pow never sets errno for an integer exponent. */
2548 if ((n >= -1 && n <= 2)
2549 || (flag_unsafe_math_optimizations
2550 && ! optimize_size
2551 && powi_cost (n) <= POWI_MAX_MULTS))
2553 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2554 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2555 op = force_reg (mode, op);
2556 return expand_powi (op, mode, n);
2561 if (! flag_unsafe_math_optimizations)
2562 return NULL_RTX;
2563 return expand_builtin_mathfn_2 (exp, target, subtarget);
2566 /* Expand a call to the powi built-in mathematical function. Return 0 if
2567 a normal call should be emitted rather than expanding the function
2568 in-line. EXP is the expression that is a call to the builtin
2569 function; if convenient, the result should be placed in TARGET. */
2571 static rtx
2572 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2574 tree arglist = TREE_OPERAND (exp, 1);
2575 tree arg0, arg1;
2576 rtx op0, op1;
2577 enum machine_mode mode;
2578 enum machine_mode mode2;
2580 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2581 return 0;
2583 arg0 = TREE_VALUE (arglist);
2584 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2585 mode = TYPE_MODE (TREE_TYPE (exp));
2587 /* Handle constant power. */
2589 if (TREE_CODE (arg1) == INTEGER_CST
2590 && ! TREE_CONSTANT_OVERFLOW (arg1))
2592 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2594 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2595 Otherwise, check the number of multiplications required. */
2596 if ((TREE_INT_CST_HIGH (arg1) == 0
2597 || TREE_INT_CST_HIGH (arg1) == -1)
2598 && ((n >= -1 && n <= 2)
2599 || (! optimize_size
2600 && powi_cost (n) <= POWI_MAX_MULTS)))
2602 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2603 op0 = force_reg (mode, op0);
2604 return expand_powi (op0, mode, n);
2608 /* Emit a libcall to libgcc. */
2610 /* Mode of the 2nd argument must match that of an int. */
2611 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2613 if (target == NULL_RTX)
2614 target = gen_reg_rtx (mode);
2616 op0 = expand_expr (arg0, subtarget, mode, 0);
2617 if (GET_MODE (op0) != mode)
2618 op0 = convert_to_mode (mode, op0, 0);
2619 op1 = expand_expr (arg1, 0, mode2, 0);
2620 if (GET_MODE (op1) != mode2)
2621 op1 = convert_to_mode (mode2, op1, 0);
2623 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2624 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2625 op0, mode, op1, mode2);
2627 return target;
2630 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2631 if we failed the caller should emit a normal call, otherwise
2632 try to get the result in TARGET, if convenient. */
2634 static rtx
2635 expand_builtin_strlen (tree arglist, rtx target,
2636 enum machine_mode target_mode)
2638 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2639 return 0;
2640 else
2642 rtx pat;
2643 tree len, src = TREE_VALUE (arglist);
2644 rtx result, src_reg, char_rtx, before_strlen;
2645 enum machine_mode insn_mode = target_mode, char_mode;
2646 enum insn_code icode = CODE_FOR_nothing;
2647 int align;
2649 /* If the length can be computed at compile-time, return it. */
2650 len = c_strlen (src, 0);
2651 if (len)
2652 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2654 /* If the length can be computed at compile-time and is constant
2655 integer, but there are side-effects in src, evaluate
2656 src for side-effects, then return len.
2657 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2658 can be optimized into: i++; x = 3; */
2659 len = c_strlen (src, 1);
2660 if (len && TREE_CODE (len) == INTEGER_CST)
2662 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2663 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2666 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2668 /* If SRC is not a pointer type, don't do this operation inline. */
2669 if (align == 0)
2670 return 0;
2672 /* Bail out if we can't compute strlen in the right mode. */
2673 while (insn_mode != VOIDmode)
2675 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2676 if (icode != CODE_FOR_nothing)
2677 break;
2679 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2681 if (insn_mode == VOIDmode)
2682 return 0;
2684 /* Make a place to write the result of the instruction. */
2685 result = target;
2686 if (! (result != 0
2687 && REG_P (result)
2688 && GET_MODE (result) == insn_mode
2689 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2690 result = gen_reg_rtx (insn_mode);
2692 /* Make a place to hold the source address. We will not expand
2693 the actual source until we are sure that the expansion will
2694 not fail -- there are trees that cannot be expanded twice. */
2695 src_reg = gen_reg_rtx (Pmode);
2697 /* Mark the beginning of the strlen sequence so we can emit the
2698 source operand later. */
2699 before_strlen = get_last_insn ();
2701 char_rtx = const0_rtx;
2702 char_mode = insn_data[(int) icode].operand[2].mode;
2703 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2704 char_mode))
2705 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2707 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2708 char_rtx, GEN_INT (align));
2709 if (! pat)
2710 return 0;
2711 emit_insn (pat);
2713 /* Now that we are assured of success, expand the source. */
2714 start_sequence ();
2715 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2716 if (pat != src_reg)
2717 emit_move_insn (src_reg, pat);
2718 pat = get_insns ();
2719 end_sequence ();
2721 if (before_strlen)
2722 emit_insn_after (pat, before_strlen);
2723 else
2724 emit_insn_before (pat, get_insns ());
2726 /* Return the value in the proper mode for this function. */
2727 if (GET_MODE (result) == target_mode)
2728 target = result;
2729 else if (target != 0)
2730 convert_move (target, result, 0);
2731 else
2732 target = convert_to_mode (target_mode, result, 0);
2734 return target;
2738 /* Expand a call to the strstr builtin. Return 0 if we failed the
2739 caller should emit a normal call, otherwise try to get the result
2740 in TARGET, if convenient (and in mode MODE if that's convenient). */
2742 static rtx
2743 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2745 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2747 tree result = fold_builtin_strstr (arglist, type);
2748 if (result)
2749 return expand_expr (result, target, mode, EXPAND_NORMAL);
2751 return 0;
2754 /* Expand a call to the strchr builtin. Return 0 if we failed the
2755 caller should emit a normal call, otherwise try to get the result
2756 in TARGET, if convenient (and in mode MODE if that's convenient). */
2758 static rtx
2759 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2761 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2763 tree result = fold_builtin_strchr (arglist, type);
2764 if (result)
2765 return expand_expr (result, target, mode, EXPAND_NORMAL);
2767 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2769 return 0;
2772 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2773 caller should emit a normal call, otherwise try to get the result
2774 in TARGET, if convenient (and in mode MODE if that's convenient). */
2776 static rtx
2777 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2779 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2781 tree result = fold_builtin_strrchr (arglist, type);
2782 if (result)
2783 return expand_expr (result, target, mode, EXPAND_NORMAL);
2785 return 0;
2788 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2789 caller should emit a normal call, otherwise try to get the result
2790 in TARGET, if convenient (and in mode MODE if that's convenient). */
2792 static rtx
2793 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2795 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2797 tree result = fold_builtin_strpbrk (arglist, type);
2798 if (result)
2799 return expand_expr (result, target, mode, EXPAND_NORMAL);
2801 return 0;
2804 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2805 bytes from constant string DATA + OFFSET and return it as target
2806 constant. */
2808 static rtx
2809 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2810 enum machine_mode mode)
2812 const char *str = (const char *) data;
2814 gcc_assert (offset >= 0
2815 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2816 <= strlen (str) + 1));
2818 return c_readstr (str + offset, mode);
2821 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2822 Return 0 if we failed, the caller should emit a normal call,
2823 otherwise try to get the result in TARGET, if convenient (and in
2824 mode MODE if that's convenient). */
2825 static rtx
2826 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2828 tree fndecl = get_callee_fndecl (exp);
2829 tree arglist = TREE_OPERAND (exp, 1);
2830 if (!validate_arglist (arglist,
2831 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2832 return 0;
2833 else
2835 tree dest = TREE_VALUE (arglist);
2836 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2837 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2838 const char *src_str;
2839 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2840 unsigned int dest_align
2841 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2842 rtx dest_mem, src_mem, dest_addr, len_rtx;
2843 tree result = fold_builtin_memcpy (fndecl, arglist);
2845 if (result)
2846 return expand_expr (result, target, mode, EXPAND_NORMAL);
2848 /* If DEST is not a pointer type, call the normal function. */
2849 if (dest_align == 0)
2850 return 0;
2852 /* If either SRC is not a pointer type, don't do this
2853 operation in-line. */
2854 if (src_align == 0)
2855 return 0;
2857 dest_mem = get_memory_rtx (dest, len);
2858 set_mem_align (dest_mem, dest_align);
2859 len_rtx = expand_normal (len);
2860 src_str = c_getstr (src);
2862 /* If SRC is a string constant and block move would be done
2863 by pieces, we can avoid loading the string from memory
2864 and only stored the computed constants. */
2865 if (src_str
2866 && GET_CODE (len_rtx) == CONST_INT
2867 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2868 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2869 (void *) src_str, dest_align))
2871 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2872 builtin_memcpy_read_str,
2873 (void *) src_str, dest_align, 0);
2874 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2875 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2876 return dest_mem;
2879 src_mem = get_memory_rtx (src, len);
2880 set_mem_align (src_mem, src_align);
2882 /* Copy word part most expediently. */
2883 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2884 CALL_EXPR_TAILCALL (exp)
2885 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2887 if (dest_addr == 0)
2889 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2890 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2892 return dest_addr;
2896 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2897 Return 0 if we failed; the caller should emit a normal call,
2898 otherwise try to get the result in TARGET, if convenient (and in
2899 mode MODE if that's convenient). If ENDP is 0 return the
2900 destination pointer, if ENDP is 1 return the end pointer ala
2901 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2902 stpcpy. */
2904 static rtx
2905 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2906 int endp)
2908 if (!validate_arglist (arglist,
2909 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2910 return 0;
2911 /* If return value is ignored, transform mempcpy into memcpy. */
2912 else if (target == const0_rtx)
2914 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2916 if (!fn)
2917 return 0;
2919 return expand_expr (build_function_call_expr (fn, arglist),
2920 target, mode, EXPAND_NORMAL);
2922 else
2924 tree dest = TREE_VALUE (arglist);
2925 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2926 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2927 const char *src_str;
2928 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2929 unsigned int dest_align
2930 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2931 rtx dest_mem, src_mem, len_rtx;
2932 tree result = fold_builtin_mempcpy (arglist, type, endp);
2934 if (result)
2935 return expand_expr (result, target, mode, EXPAND_NORMAL);
2937 /* If either SRC or DEST is not a pointer type, don't do this
2938 operation in-line. */
2939 if (dest_align == 0 || src_align == 0)
2940 return 0;
2942 /* If LEN is not constant, call the normal function. */
2943 if (! host_integerp (len, 1))
2944 return 0;
2946 len_rtx = expand_normal (len);
2947 src_str = c_getstr (src);
2949 /* If SRC is a string constant and block move would be done
2950 by pieces, we can avoid loading the string from memory
2951 and only stored the computed constants. */
2952 if (src_str
2953 && GET_CODE (len_rtx) == CONST_INT
2954 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2955 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2956 (void *) src_str, dest_align))
2958 dest_mem = get_memory_rtx (dest, len);
2959 set_mem_align (dest_mem, dest_align);
2960 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2961 builtin_memcpy_read_str,
2962 (void *) src_str, dest_align, endp);
2963 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2964 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2965 return dest_mem;
2968 if (GET_CODE (len_rtx) == CONST_INT
2969 && can_move_by_pieces (INTVAL (len_rtx),
2970 MIN (dest_align, src_align)))
2972 dest_mem = get_memory_rtx (dest, len);
2973 set_mem_align (dest_mem, dest_align);
2974 src_mem = get_memory_rtx (src, len);
2975 set_mem_align (src_mem, src_align);
2976 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2977 MIN (dest_align, src_align), endp);
2978 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2979 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2980 return dest_mem;
2983 return 0;
2987 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2988 if we failed; the caller should emit a normal call. */
2990 static rtx
2991 expand_builtin_memmove (tree arglist, tree type, rtx target,
2992 enum machine_mode mode, tree orig_exp)
2994 if (!validate_arglist (arglist,
2995 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2996 return 0;
2997 else
2999 tree dest = TREE_VALUE (arglist);
3000 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3001 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3003 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3004 unsigned int dest_align
3005 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3006 tree result = fold_builtin_memmove (arglist, type);
3008 if (result)
3009 return expand_expr (result, target, mode, EXPAND_NORMAL);
3011 /* If DEST is not a pointer type, call the normal function. */
3012 if (dest_align == 0)
3013 return 0;
3015 /* If either SRC is not a pointer type, don't do this
3016 operation in-line. */
3017 if (src_align == 0)
3018 return 0;
3020 /* If src is categorized for a readonly section we can use
3021 normal memcpy. */
3022 if (readonly_data_expr (src))
3024 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3025 if (!fn)
3026 return 0;
3027 fn = build_function_call_expr (fn, arglist);
3028 if (TREE_CODE (fn) == CALL_EXPR)
3029 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3030 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3033 /* If length is 1 and we can expand memcpy call inline,
3034 it is ok to use memcpy as well. */
3035 if (integer_onep (len))
3037 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3038 /*endp=*/0);
3039 if (ret)
3040 return ret;
3043 /* Otherwise, call the normal function. */
3044 return 0;
3048 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3049 if we failed the caller should emit a normal call. */
3051 static rtx
3052 expand_builtin_bcopy (tree exp)
3054 tree arglist = TREE_OPERAND (exp, 1);
3055 tree type = TREE_TYPE (exp);
3056 tree src, dest, size, newarglist;
3058 if (!validate_arglist (arglist,
3059 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3060 return NULL_RTX;
3062 src = TREE_VALUE (arglist);
3063 dest = TREE_VALUE (TREE_CHAIN (arglist));
3064 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3066 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3067 memmove(ptr y, ptr x, size_t z). This is done this way
3068 so that if it isn't expanded inline, we fallback to
3069 calling bcopy instead of memmove. */
3071 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3072 newarglist = tree_cons (NULL_TREE, src, newarglist);
3073 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3075 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3078 #ifndef HAVE_movstr
3079 # define HAVE_movstr 0
3080 # define CODE_FOR_movstr CODE_FOR_nothing
3081 #endif
3083 /* Expand into a movstr instruction, if one is available. Return 0 if
3084 we failed, the caller should emit a normal call, otherwise try to
3085 get the result in TARGET, if convenient. If ENDP is 0 return the
3086 destination pointer, if ENDP is 1 return the end pointer ala
3087 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3088 stpcpy. */
3090 static rtx
3091 expand_movstr (tree dest, tree src, rtx target, int endp)
3093 rtx end;
3094 rtx dest_mem;
3095 rtx src_mem;
3096 rtx insn;
3097 const struct insn_data * data;
3099 if (!HAVE_movstr)
3100 return 0;
3102 dest_mem = get_memory_rtx (dest, NULL);
3103 src_mem = get_memory_rtx (src, NULL);
3104 if (!endp)
3106 target = force_reg (Pmode, XEXP (dest_mem, 0));
3107 dest_mem = replace_equiv_address (dest_mem, target);
3108 end = gen_reg_rtx (Pmode);
3110 else
3112 if (target == 0 || target == const0_rtx)
3114 end = gen_reg_rtx (Pmode);
3115 if (target == 0)
3116 target = end;
3118 else
3119 end = target;
3122 data = insn_data + CODE_FOR_movstr;
3124 if (data->operand[0].mode != VOIDmode)
3125 end = gen_lowpart (data->operand[0].mode, end);
3127 insn = data->genfun (end, dest_mem, src_mem);
3129 gcc_assert (insn);
3131 emit_insn (insn);
3133 /* movstr is supposed to set end to the address of the NUL
3134 terminator. If the caller requested a mempcpy-like return value,
3135 adjust it. */
3136 if (endp == 1 && target != const0_rtx)
3138 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3139 emit_move_insn (target, force_operand (tem, NULL_RTX));
3142 return target;
3145 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3146 if we failed the caller should emit a normal call, otherwise try to get
3147 the result in TARGET, if convenient (and in mode MODE if that's
3148 convenient). */
3150 static rtx
3151 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3153 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3155 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3156 if (result)
3157 return expand_expr (result, target, mode, EXPAND_NORMAL);
3159 return expand_movstr (TREE_VALUE (arglist),
3160 TREE_VALUE (TREE_CHAIN (arglist)),
3161 target, /*endp=*/0);
3163 return 0;
3166 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3167 Return 0 if we failed the caller should emit a normal call,
3168 otherwise try to get the result in TARGET, if convenient (and in
3169 mode MODE if that's convenient). */
3171 static rtx
3172 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3174 tree arglist = TREE_OPERAND (exp, 1);
3175 /* If return value is ignored, transform stpcpy into strcpy. */
3176 if (target == const0_rtx)
3178 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3179 if (!fn)
3180 return 0;
3182 return expand_expr (build_function_call_expr (fn, arglist),
3183 target, mode, EXPAND_NORMAL);
3186 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3187 return 0;
3188 else
3190 tree dst, src, len, lenp1;
3191 tree narglist;
3192 rtx ret;
3194 /* Ensure we get an actual string whose length can be evaluated at
3195 compile-time, not an expression containing a string. This is
3196 because the latter will potentially produce pessimized code
3197 when used to produce the return value. */
3198 src = TREE_VALUE (TREE_CHAIN (arglist));
3199 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3200 return expand_movstr (TREE_VALUE (arglist),
3201 TREE_VALUE (TREE_CHAIN (arglist)),
3202 target, /*endp=*/2);
3204 dst = TREE_VALUE (arglist);
3205 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3206 narglist = build_tree_list (NULL_TREE, lenp1);
3207 narglist = tree_cons (NULL_TREE, src, narglist);
3208 narglist = tree_cons (NULL_TREE, dst, narglist);
3209 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3210 target, mode, /*endp=*/2);
3212 if (ret)
3213 return ret;
3215 if (TREE_CODE (len) == INTEGER_CST)
3217 rtx len_rtx = expand_normal (len);
3219 if (GET_CODE (len_rtx) == CONST_INT)
3221 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3222 arglist, target, mode);
3224 if (ret)
3226 if (! target)
3228 if (mode != VOIDmode)
3229 target = gen_reg_rtx (mode);
3230 else
3231 target = gen_reg_rtx (GET_MODE (ret));
3233 if (GET_MODE (target) != GET_MODE (ret))
3234 ret = gen_lowpart (GET_MODE (target), ret);
3236 ret = plus_constant (ret, INTVAL (len_rtx));
3237 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3238 gcc_assert (ret);
3240 return target;
3245 return expand_movstr (TREE_VALUE (arglist),
3246 TREE_VALUE (TREE_CHAIN (arglist)),
3247 target, /*endp=*/2);
3251 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3252 bytes from constant string DATA + OFFSET and return it as target
3253 constant. */
3255 static rtx
3256 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3257 enum machine_mode mode)
3259 const char *str = (const char *) data;
3261 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3262 return const0_rtx;
3264 return c_readstr (str + offset, mode);
3267 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3268 if we failed the caller should emit a normal call. */
3270 static rtx
3271 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3273 tree fndecl = get_callee_fndecl (exp);
3274 tree arglist = TREE_OPERAND (exp, 1);
3275 if (validate_arglist (arglist,
3276 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3278 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3279 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3280 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3282 if (result)
3283 return expand_expr (result, target, mode, EXPAND_NORMAL);
3285 /* We must be passed a constant len and src parameter. */
3286 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3287 return 0;
3289 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3291 /* We're required to pad with trailing zeros if the requested
3292 len is greater than strlen(s2)+1. In that case try to
3293 use store_by_pieces, if it fails, punt. */
3294 if (tree_int_cst_lt (slen, len))
3296 tree dest = TREE_VALUE (arglist);
3297 unsigned int dest_align
3298 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3299 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3300 rtx dest_mem;
3302 if (!p || dest_align == 0 || !host_integerp (len, 1)
3303 || !can_store_by_pieces (tree_low_cst (len, 1),
3304 builtin_strncpy_read_str,
3305 (void *) p, dest_align))
3306 return 0;
3308 dest_mem = get_memory_rtx (dest, len);
3309 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3310 builtin_strncpy_read_str,
3311 (void *) p, dest_align, 0);
3312 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3313 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3314 return dest_mem;
3317 return 0;
3320 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3321 bytes from constant string DATA + OFFSET and return it as target
3322 constant. */
3324 static rtx
3325 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3326 enum machine_mode mode)
3328 const char *c = (const char *) data;
3329 char *p = alloca (GET_MODE_SIZE (mode));
3331 memset (p, *c, GET_MODE_SIZE (mode));
3333 return c_readstr (p, mode);
3336 /* Callback routine for store_by_pieces. Return the RTL of a register
3337 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3338 char value given in the RTL register data. For example, if mode is
3339 4 bytes wide, return the RTL for 0x01010101*data. */
3341 static rtx
3342 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3343 enum machine_mode mode)
3345 rtx target, coeff;
3346 size_t size;
3347 char *p;
3349 size = GET_MODE_SIZE (mode);
3350 if (size == 1)
3351 return (rtx) data;
3353 p = alloca (size);
3354 memset (p, 1, size);
3355 coeff = c_readstr (p, mode);
3357 target = convert_to_mode (mode, (rtx) data, 1);
3358 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3359 return force_reg (mode, target);
3362 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3363 if we failed the caller should emit a normal call, otherwise try to get
3364 the result in TARGET, if convenient (and in mode MODE if that's
3365 convenient). */
3367 static rtx
3368 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3369 tree orig_exp)
3371 if (!validate_arglist (arglist,
3372 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3373 return 0;
3374 else
3376 tree dest = TREE_VALUE (arglist);
3377 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3378 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3379 char c;
3381 unsigned int dest_align
3382 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3383 rtx dest_mem, dest_addr, len_rtx;
3385 /* If DEST is not a pointer type, don't do this
3386 operation in-line. */
3387 if (dest_align == 0)
3388 return 0;
3390 /* If the LEN parameter is zero, return DEST. */
3391 if (integer_zerop (len))
3393 /* Evaluate and ignore VAL in case it has side-effects. */
3394 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3395 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3398 len_rtx = expand_normal (len);
3399 dest_mem = get_memory_rtx (dest, len);
3401 if (TREE_CODE (val) != INTEGER_CST)
3403 rtx val_rtx;
3405 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3406 val_rtx = expand_normal (val);
3408 /* Assume that we can memset by pieces if we can store the
3409 * the coefficients by pieces (in the required modes).
3410 * We can't pass builtin_memset_gen_str as that emits RTL. */
3411 c = 1;
3412 if (host_integerp (len, 1)
3413 && !(optimize_size && tree_low_cst (len, 1) > 1)
3414 && can_store_by_pieces (tree_low_cst (len, 1),
3415 builtin_memset_read_str, &c, dest_align))
3417 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3418 val_rtx);
3419 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3420 builtin_memset_gen_str, val_rtx, dest_align, 0);
3422 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3423 dest_align))
3424 return 0;
3426 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3427 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3428 return dest_mem;
3431 if (target_char_cast (val, &c))
3432 return 0;
3434 if (c)
3436 if (host_integerp (len, 1)
3437 && !(optimize_size && tree_low_cst (len, 1) > 1)
3438 && can_store_by_pieces (tree_low_cst (len, 1),
3439 builtin_memset_read_str, &c, dest_align))
3440 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3441 builtin_memset_read_str, &c, dest_align, 0);
3442 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3443 dest_align))
3444 return 0;
3446 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3447 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3448 return dest_mem;
3451 set_mem_align (dest_mem, dest_align);
3452 dest_addr = clear_storage (dest_mem, len_rtx,
3453 CALL_EXPR_TAILCALL (orig_exp)
3454 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3456 if (dest_addr == 0)
3458 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3459 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3462 return dest_addr;
3466 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3467 if we failed the caller should emit a normal call. */
3469 static rtx
3470 expand_builtin_bzero (tree exp)
3472 tree arglist = TREE_OPERAND (exp, 1);
3473 tree dest, size, newarglist;
3475 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3476 return NULL_RTX;
3478 dest = TREE_VALUE (arglist);
3479 size = TREE_VALUE (TREE_CHAIN (arglist));
3481 /* New argument list transforming bzero(ptr x, int y) to
3482 memset(ptr x, int 0, size_t y). This is done this way
3483 so that if it isn't expanded inline, we fallback to
3484 calling bzero instead of memset. */
3486 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3487 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3488 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3490 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3493 /* Expand expression EXP, which is a call to the memcmp built-in function.
3494 ARGLIST is the argument list for this call. Return 0 if we failed and the
3495 caller should emit a normal call, otherwise try to get the result in
3496 TARGET, if convenient (and in mode MODE, if that's convenient). */
3498 static rtx
3499 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3500 enum machine_mode mode)
3502 if (!validate_arglist (arglist,
3503 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3504 return 0;
3505 else
3507 tree result = fold_builtin_memcmp (arglist);
3508 if (result)
3509 return expand_expr (result, target, mode, EXPAND_NORMAL);
3512 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3514 tree arg1 = TREE_VALUE (arglist);
3515 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3516 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3517 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3518 rtx result;
3519 rtx insn;
3521 int arg1_align
3522 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3523 int arg2_align
3524 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3525 enum machine_mode insn_mode;
3527 #ifdef HAVE_cmpmemsi
3528 if (HAVE_cmpmemsi)
3529 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3530 else
3531 #endif
3532 #ifdef HAVE_cmpstrnsi
3533 if (HAVE_cmpstrnsi)
3534 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3535 else
3536 #endif
3537 return 0;
3539 /* If we don't have POINTER_TYPE, call the function. */
3540 if (arg1_align == 0 || arg2_align == 0)
3541 return 0;
3543 /* Make a place to write the result of the instruction. */
3544 result = target;
3545 if (! (result != 0
3546 && REG_P (result) && GET_MODE (result) == insn_mode
3547 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3548 result = gen_reg_rtx (insn_mode);
3550 arg1_rtx = get_memory_rtx (arg1, len);
3551 arg2_rtx = get_memory_rtx (arg2, len);
3552 arg3_rtx = expand_normal (len);
3554 /* Set MEM_SIZE as appropriate. */
3555 if (GET_CODE (arg3_rtx) == CONST_INT)
3557 set_mem_size (arg1_rtx, arg3_rtx);
3558 set_mem_size (arg2_rtx, arg3_rtx);
3561 #ifdef HAVE_cmpmemsi
3562 if (HAVE_cmpmemsi)
3563 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3564 GEN_INT (MIN (arg1_align, arg2_align)));
3565 else
3566 #endif
3567 #ifdef HAVE_cmpstrnsi
3568 if (HAVE_cmpstrnsi)
3569 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3570 GEN_INT (MIN (arg1_align, arg2_align)));
3571 else
3572 #endif
3573 gcc_unreachable ();
3575 if (insn)
3576 emit_insn (insn);
3577 else
3578 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3579 TYPE_MODE (integer_type_node), 3,
3580 XEXP (arg1_rtx, 0), Pmode,
3581 XEXP (arg2_rtx, 0), Pmode,
3582 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3583 TYPE_UNSIGNED (sizetype)),
3584 TYPE_MODE (sizetype));
3586 /* Return the value in the proper mode for this function. */
3587 mode = TYPE_MODE (TREE_TYPE (exp));
3588 if (GET_MODE (result) == mode)
3589 return result;
3590 else if (target != 0)
3592 convert_move (target, result, 0);
3593 return target;
3595 else
3596 return convert_to_mode (mode, result, 0);
3598 #endif
3600 return 0;
3603 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3604 if we failed the caller should emit a normal call, otherwise try to get
3605 the result in TARGET, if convenient. */
3607 static rtx
3608 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3610 tree arglist = TREE_OPERAND (exp, 1);
3612 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3613 return 0;
3614 else
3616 tree result = fold_builtin_strcmp (arglist);
3617 if (result)
3618 return expand_expr (result, target, mode, EXPAND_NORMAL);
3621 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3622 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3623 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3625 rtx arg1_rtx, arg2_rtx;
3626 rtx result, insn = NULL_RTX;
3627 tree fndecl, fn;
3629 tree arg1 = TREE_VALUE (arglist);
3630 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3631 int arg1_align
3632 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3633 int arg2_align
3634 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3636 /* If we don't have POINTER_TYPE, call the function. */
3637 if (arg1_align == 0 || arg2_align == 0)
3638 return 0;
3640 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3641 arg1 = builtin_save_expr (arg1);
3642 arg2 = builtin_save_expr (arg2);
3644 arg1_rtx = get_memory_rtx (arg1, NULL);
3645 arg2_rtx = get_memory_rtx (arg2, NULL);
3647 #ifdef HAVE_cmpstrsi
3648 /* Try to call cmpstrsi. */
3649 if (HAVE_cmpstrsi)
3651 enum machine_mode insn_mode
3652 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3654 /* Make a place to write the result of the instruction. */
3655 result = target;
3656 if (! (result != 0
3657 && REG_P (result) && GET_MODE (result) == insn_mode
3658 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3659 result = gen_reg_rtx (insn_mode);
3661 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3662 GEN_INT (MIN (arg1_align, arg2_align)));
3664 #endif
3665 #if HAVE_cmpstrnsi
3666 /* Try to determine at least one length and call cmpstrnsi. */
3667 if (!insn && HAVE_cmpstrnsi)
3669 tree len;
3670 rtx arg3_rtx;
3672 enum machine_mode insn_mode
3673 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3674 tree len1 = c_strlen (arg1, 1);
3675 tree len2 = c_strlen (arg2, 1);
3677 if (len1)
3678 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3679 if (len2)
3680 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3682 /* If we don't have a constant length for the first, use the length
3683 of the second, if we know it. We don't require a constant for
3684 this case; some cost analysis could be done if both are available
3685 but neither is constant. For now, assume they're equally cheap,
3686 unless one has side effects. If both strings have constant lengths,
3687 use the smaller. */
3689 if (!len1)
3690 len = len2;
3691 else if (!len2)
3692 len = len1;
3693 else if (TREE_SIDE_EFFECTS (len1))
3694 len = len2;
3695 else if (TREE_SIDE_EFFECTS (len2))
3696 len = len1;
3697 else if (TREE_CODE (len1) != INTEGER_CST)
3698 len = len2;
3699 else if (TREE_CODE (len2) != INTEGER_CST)
3700 len = len1;
3701 else if (tree_int_cst_lt (len1, len2))
3702 len = len1;
3703 else
3704 len = len2;
3706 /* If both arguments have side effects, we cannot optimize. */
3707 if (!len || TREE_SIDE_EFFECTS (len))
3708 return 0;
3710 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3711 arg3_rtx = expand_normal (len);
3713 /* Make a place to write the result of the instruction. */
3714 result = target;
3715 if (! (result != 0
3716 && REG_P (result) && GET_MODE (result) == insn_mode
3717 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3718 result = gen_reg_rtx (insn_mode);
3720 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3721 GEN_INT (MIN (arg1_align, arg2_align)));
3723 #endif
3725 if (insn)
3727 emit_insn (insn);
3729 /* Return the value in the proper mode for this function. */
3730 mode = TYPE_MODE (TREE_TYPE (exp));
3731 if (GET_MODE (result) == mode)
3732 return result;
3733 if (target == 0)
3734 return convert_to_mode (mode, result, 0);
3735 convert_move (target, result, 0);
3736 return target;
3739 /* Expand the library call ourselves using a stabilized argument
3740 list to avoid re-evaluating the function's arguments twice. */
3741 arglist = build_tree_list (NULL_TREE, arg2);
3742 arglist = tree_cons (NULL_TREE, arg1, arglist);
3743 fndecl = get_callee_fndecl (exp);
3744 fn = build_function_call_expr (fndecl, arglist);
3745 if (TREE_CODE (fn) == CALL_EXPR)
3746 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3747 return expand_call (fn, target, target == const0_rtx);
3749 #endif
3750 return 0;
3753 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3754 if we failed the caller should emit a normal call, otherwise try to get
3755 the result in TARGET, if convenient. */
3757 static rtx
3758 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3760 tree arglist = TREE_OPERAND (exp, 1);
3762 if (!validate_arglist (arglist,
3763 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3764 return 0;
3765 else
3767 tree result = fold_builtin_strncmp (arglist);
3768 if (result)
3769 return expand_expr (result, target, mode, EXPAND_NORMAL);
3772 /* If c_strlen can determine an expression for one of the string
3773 lengths, and it doesn't have side effects, then emit cmpstrnsi
3774 using length MIN(strlen(string)+1, arg3). */
3775 #ifdef HAVE_cmpstrnsi
3776 if (HAVE_cmpstrnsi)
3778 tree arg1 = TREE_VALUE (arglist);
3779 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3780 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3781 tree len, len1, len2;
3782 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3783 rtx result, insn;
3784 tree fndecl, fn;
3786 int arg1_align
3787 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3788 int arg2_align
3789 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3790 enum machine_mode insn_mode
3791 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3793 len1 = c_strlen (arg1, 1);
3794 len2 = c_strlen (arg2, 1);
3796 if (len1)
3797 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3798 if (len2)
3799 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3801 /* If we don't have a constant length for the first, use the length
3802 of the second, if we know it. We don't require a constant for
3803 this case; some cost analysis could be done if both are available
3804 but neither is constant. For now, assume they're equally cheap,
3805 unless one has side effects. If both strings have constant lengths,
3806 use the smaller. */
3808 if (!len1)
3809 len = len2;
3810 else if (!len2)
3811 len = len1;
3812 else if (TREE_SIDE_EFFECTS (len1))
3813 len = len2;
3814 else if (TREE_SIDE_EFFECTS (len2))
3815 len = len1;
3816 else if (TREE_CODE (len1) != INTEGER_CST)
3817 len = len2;
3818 else if (TREE_CODE (len2) != INTEGER_CST)
3819 len = len1;
3820 else if (tree_int_cst_lt (len1, len2))
3821 len = len1;
3822 else
3823 len = len2;
3825 /* If both arguments have side effects, we cannot optimize. */
3826 if (!len || TREE_SIDE_EFFECTS (len))
3827 return 0;
3829 /* The actual new length parameter is MIN(len,arg3). */
3830 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3831 fold_convert (TREE_TYPE (len), arg3));
3833 /* If we don't have POINTER_TYPE, call the function. */
3834 if (arg1_align == 0 || arg2_align == 0)
3835 return 0;
3837 /* Make a place to write the result of the instruction. */
3838 result = target;
3839 if (! (result != 0
3840 && REG_P (result) && GET_MODE (result) == insn_mode
3841 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3842 result = gen_reg_rtx (insn_mode);
3844 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3845 arg1 = builtin_save_expr (arg1);
3846 arg2 = builtin_save_expr (arg2);
3847 len = builtin_save_expr (len);
3849 arg1_rtx = get_memory_rtx (arg1, len);
3850 arg2_rtx = get_memory_rtx (arg2, len);
3851 arg3_rtx = expand_normal (len);
3852 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3853 GEN_INT (MIN (arg1_align, arg2_align)));
3854 if (insn)
3856 emit_insn (insn);
3858 /* Return the value in the proper mode for this function. */
3859 mode = TYPE_MODE (TREE_TYPE (exp));
3860 if (GET_MODE (result) == mode)
3861 return result;
3862 if (target == 0)
3863 return convert_to_mode (mode, result, 0);
3864 convert_move (target, result, 0);
3865 return target;
3868 /* Expand the library call ourselves using a stabilized argument
3869 list to avoid re-evaluating the function's arguments twice. */
3870 arglist = build_tree_list (NULL_TREE, len);
3871 arglist = tree_cons (NULL_TREE, arg2, arglist);
3872 arglist = tree_cons (NULL_TREE, arg1, arglist);
3873 fndecl = get_callee_fndecl (exp);
3874 fn = build_function_call_expr (fndecl, arglist);
3875 if (TREE_CODE (fn) == CALL_EXPR)
3876 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3877 return expand_call (fn, target, target == const0_rtx);
3879 #endif
3880 return 0;
3883 /* Expand expression EXP, which is a call to the strcat builtin.
3884 Return 0 if we failed the caller should emit a normal call,
3885 otherwise try to get the result in TARGET, if convenient. */
3887 static rtx
3888 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3890 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3891 return 0;
3892 else
3894 tree dst = TREE_VALUE (arglist),
3895 src = TREE_VALUE (TREE_CHAIN (arglist));
3896 const char *p = c_getstr (src);
3898 /* If the string length is zero, return the dst parameter. */
3899 if (p && *p == '\0')
3900 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3902 if (!optimize_size)
3904 /* See if we can store by pieces into (dst + strlen(dst)). */
3905 tree newsrc, newdst,
3906 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3907 rtx insns;
3909 /* Stabilize the argument list. */
3910 newsrc = builtin_save_expr (src);
3911 if (newsrc != src)
3912 arglist = build_tree_list (NULL_TREE, newsrc);
3913 else
3914 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3916 dst = builtin_save_expr (dst);
3918 start_sequence ();
3920 /* Create strlen (dst). */
3921 newdst =
3922 build_function_call_expr (strlen_fn,
3923 build_tree_list (NULL_TREE, dst));
3924 /* Create (dst + (cast) strlen (dst)). */
3925 newdst = fold_convert (TREE_TYPE (dst), newdst);
3926 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3928 newdst = builtin_save_expr (newdst);
3929 arglist = tree_cons (NULL_TREE, newdst, arglist);
3931 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3933 end_sequence (); /* Stop sequence. */
3934 return 0;
3937 /* Output the entire sequence. */
3938 insns = get_insns ();
3939 end_sequence ();
3940 emit_insn (insns);
3942 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3945 return 0;
3949 /* Expand expression EXP, which is a call to the strncat builtin.
3950 Return 0 if we failed the caller should emit a normal call,
3951 otherwise try to get the result in TARGET, if convenient. */
3953 static rtx
3954 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3956 if (validate_arglist (arglist,
3957 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3959 tree result = fold_builtin_strncat (arglist);
3960 if (result)
3961 return expand_expr (result, target, mode, EXPAND_NORMAL);
3963 return 0;
3966 /* Expand expression EXP, which is a call to the strspn builtin.
3967 Return 0 if we failed the caller should emit a normal call,
3968 otherwise try to get the result in TARGET, if convenient. */
3970 static rtx
3971 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3973 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3975 tree result = fold_builtin_strspn (arglist);
3976 if (result)
3977 return expand_expr (result, target, mode, EXPAND_NORMAL);
3979 return 0;
3982 /* Expand expression EXP, which is a call to the strcspn builtin.
3983 Return 0 if we failed the caller should emit a normal call,
3984 otherwise try to get the result in TARGET, if convenient. */
3986 static rtx
3987 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3989 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3991 tree result = fold_builtin_strcspn (arglist);
3992 if (result)
3993 return expand_expr (result, target, mode, EXPAND_NORMAL);
3995 return 0;
3998 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3999 if that's convenient. */
4002 expand_builtin_saveregs (void)
4004 rtx val, seq;
4006 /* Don't do __builtin_saveregs more than once in a function.
4007 Save the result of the first call and reuse it. */
4008 if (saveregs_value != 0)
4009 return saveregs_value;
4011 /* When this function is called, it means that registers must be
4012 saved on entry to this function. So we migrate the call to the
4013 first insn of this function. */
4015 start_sequence ();
4017 /* Do whatever the machine needs done in this case. */
4018 val = targetm.calls.expand_builtin_saveregs ();
4020 seq = get_insns ();
4021 end_sequence ();
4023 saveregs_value = val;
4025 /* Put the insns after the NOTE that starts the function. If this
4026 is inside a start_sequence, make the outer-level insn chain current, so
4027 the code is placed at the start of the function. */
4028 push_topmost_sequence ();
4029 emit_insn_after (seq, entry_of_function ());
4030 pop_topmost_sequence ();
4032 return val;
4035 /* __builtin_args_info (N) returns word N of the arg space info
4036 for the current function. The number and meanings of words
4037 is controlled by the definition of CUMULATIVE_ARGS. */
4039 static rtx
4040 expand_builtin_args_info (tree arglist)
4042 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4043 int *word_ptr = (int *) &current_function_args_info;
4045 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4047 if (arglist != 0)
4049 if (!host_integerp (TREE_VALUE (arglist), 0))
4050 error ("argument of %<__builtin_args_info%> must be constant");
4051 else
4053 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4055 if (wordnum < 0 || wordnum >= nwords)
4056 error ("argument of %<__builtin_args_info%> out of range");
4057 else
4058 return GEN_INT (word_ptr[wordnum]);
4061 else
4062 error ("missing argument in %<__builtin_args_info%>");
4064 return const0_rtx;
4067 /* Expand a call to __builtin_next_arg. */
4069 static rtx
4070 expand_builtin_next_arg (void)
4072 /* Checking arguments is already done in fold_builtin_next_arg
4073 that must be called before this function. */
4074 return expand_binop (Pmode, add_optab,
4075 current_function_internal_arg_pointer,
4076 current_function_arg_offset_rtx,
4077 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4080 /* Make it easier for the backends by protecting the valist argument
4081 from multiple evaluations. */
4083 static tree
4084 stabilize_va_list (tree valist, int needs_lvalue)
4086 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4088 if (TREE_SIDE_EFFECTS (valist))
4089 valist = save_expr (valist);
4091 /* For this case, the backends will be expecting a pointer to
4092 TREE_TYPE (va_list_type_node), but it's possible we've
4093 actually been given an array (an actual va_list_type_node).
4094 So fix it. */
4095 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4097 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4098 valist = build_fold_addr_expr_with_type (valist, p1);
4101 else
4103 tree pt;
4105 if (! needs_lvalue)
4107 if (! TREE_SIDE_EFFECTS (valist))
4108 return valist;
4110 pt = build_pointer_type (va_list_type_node);
4111 valist = fold_build1 (ADDR_EXPR, pt, valist);
4112 TREE_SIDE_EFFECTS (valist) = 1;
4115 if (TREE_SIDE_EFFECTS (valist))
4116 valist = save_expr (valist);
4117 valist = build_fold_indirect_ref (valist);
4120 return valist;
4123 /* The "standard" definition of va_list is void*. */
4125 tree
4126 std_build_builtin_va_list (void)
4128 return ptr_type_node;
4131 /* The "standard" implementation of va_start: just assign `nextarg' to
4132 the variable. */
4134 void
4135 std_expand_builtin_va_start (tree valist, rtx nextarg)
4137 tree t;
4139 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4140 make_tree (ptr_type_node, nextarg));
4141 TREE_SIDE_EFFECTS (t) = 1;
4143 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4146 /* Expand ARGLIST, from a call to __builtin_va_start. */
4148 static rtx
4149 expand_builtin_va_start (tree arglist)
4151 rtx nextarg;
4152 tree chain, valist;
4154 chain = TREE_CHAIN (arglist);
4156 if (!chain)
4158 error ("too few arguments to function %<va_start%>");
4159 return const0_rtx;
4162 if (fold_builtin_next_arg (chain))
4163 return const0_rtx;
4165 nextarg = expand_builtin_next_arg ();
4166 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4168 #ifdef EXPAND_BUILTIN_VA_START
4169 EXPAND_BUILTIN_VA_START (valist, nextarg);
4170 #else
4171 std_expand_builtin_va_start (valist, nextarg);
4172 #endif
4174 return const0_rtx;
4177 /* The "standard" implementation of va_arg: read the value from the
4178 current (padded) address and increment by the (padded) size. */
4180 tree
4181 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4183 tree addr, t, type_size, rounded_size, valist_tmp;
4184 unsigned HOST_WIDE_INT align, boundary;
4185 bool indirect;
4187 #ifdef ARGS_GROW_DOWNWARD
4188 /* All of the alignment and movement below is for args-grow-up machines.
4189 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4190 implement their own specialized gimplify_va_arg_expr routines. */
4191 gcc_unreachable ();
4192 #endif
4194 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4195 if (indirect)
4196 type = build_pointer_type (type);
4198 align = PARM_BOUNDARY / BITS_PER_UNIT;
4199 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4201 /* Hoist the valist value into a temporary for the moment. */
4202 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4204 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4205 requires greater alignment, we must perform dynamic alignment. */
4206 if (boundary > align
4207 && !integer_zerop (TYPE_SIZE (type)))
4209 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4210 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4211 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4212 gimplify_and_add (t, pre_p);
4214 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4215 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4216 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4217 gimplify_and_add (t, pre_p);
4219 else
4220 boundary = align;
4222 /* If the actual alignment is less than the alignment of the type,
4223 adjust the type accordingly so that we don't assume strict alignment
4224 when deferencing the pointer. */
4225 boundary *= BITS_PER_UNIT;
4226 if (boundary < TYPE_ALIGN (type))
4228 type = build_variant_type_copy (type);
4229 TYPE_ALIGN (type) = boundary;
4232 /* Compute the rounded size of the type. */
4233 type_size = size_in_bytes (type);
4234 rounded_size = round_up (type_size, align);
4236 /* Reduce rounded_size so it's sharable with the postqueue. */
4237 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4239 /* Get AP. */
4240 addr = valist_tmp;
4241 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4243 /* Small args are padded downward. */
4244 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4245 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4246 size_binop (MINUS_EXPR, rounded_size, type_size));
4247 t = fold_convert (TREE_TYPE (addr), t);
4248 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4251 /* Compute new value for AP. */
4252 t = fold_convert (TREE_TYPE (valist), rounded_size);
4253 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4254 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4255 gimplify_and_add (t, pre_p);
4257 addr = fold_convert (build_pointer_type (type), addr);
4259 if (indirect)
4260 addr = build_va_arg_indirect_ref (addr);
4262 return build_va_arg_indirect_ref (addr);
4265 /* Build an indirect-ref expression over the given TREE, which represents a
4266 piece of a va_arg() expansion. */
4267 tree
4268 build_va_arg_indirect_ref (tree addr)
4270 addr = build_fold_indirect_ref (addr);
4272 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4273 mf_mark (addr);
4275 return addr;
4278 /* Return a dummy expression of type TYPE in order to keep going after an
4279 error. */
4281 static tree
4282 dummy_object (tree type)
4284 tree t = convert (build_pointer_type (type), null_pointer_node);
4285 return build1 (INDIRECT_REF, type, t);
4288 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4289 builtin function, but a very special sort of operator. */
4291 enum gimplify_status
4292 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4294 tree promoted_type, want_va_type, have_va_type;
4295 tree valist = TREE_OPERAND (*expr_p, 0);
4296 tree type = TREE_TYPE (*expr_p);
4297 tree t;
4299 /* Verify that valist is of the proper type. */
4300 want_va_type = va_list_type_node;
4301 have_va_type = TREE_TYPE (valist);
4303 if (have_va_type == error_mark_node)
4304 return GS_ERROR;
4306 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4308 /* If va_list is an array type, the argument may have decayed
4309 to a pointer type, e.g. by being passed to another function.
4310 In that case, unwrap both types so that we can compare the
4311 underlying records. */
4312 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4313 || POINTER_TYPE_P (have_va_type))
4315 want_va_type = TREE_TYPE (want_va_type);
4316 have_va_type = TREE_TYPE (have_va_type);
4320 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4322 error ("first argument to %<va_arg%> not of type %<va_list%>");
4323 return GS_ERROR;
4326 /* Generate a diagnostic for requesting data of a type that cannot
4327 be passed through `...' due to type promotion at the call site. */
4328 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4329 != type)
4331 static bool gave_help;
4333 /* Unfortunately, this is merely undefined, rather than a constraint
4334 violation, so we cannot make this an error. If this call is never
4335 executed, the program is still strictly conforming. */
4336 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4337 type, promoted_type);
4338 if (! gave_help)
4340 gave_help = true;
4341 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4342 promoted_type, type);
4345 /* We can, however, treat "undefined" any way we please.
4346 Call abort to encourage the user to fix the program. */
4347 inform ("if this code is reached, the program will abort");
4348 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4349 NULL);
4350 append_to_statement_list (t, pre_p);
4352 /* This is dead code, but go ahead and finish so that the
4353 mode of the result comes out right. */
4354 *expr_p = dummy_object (type);
4355 return GS_ALL_DONE;
4357 else
4359 /* Make it easier for the backends by protecting the valist argument
4360 from multiple evaluations. */
4361 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4363 /* For this case, the backends will be expecting a pointer to
4364 TREE_TYPE (va_list_type_node), but it's possible we've
4365 actually been given an array (an actual va_list_type_node).
4366 So fix it. */
4367 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4369 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4370 valist = build_fold_addr_expr_with_type (valist, p1);
4372 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4374 else
4375 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4377 if (!targetm.gimplify_va_arg_expr)
4378 /* FIXME:Once most targets are converted we should merely
4379 assert this is non-null. */
4380 return GS_ALL_DONE;
4382 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4383 return GS_OK;
4387 /* Expand ARGLIST, from a call to __builtin_va_end. */
4389 static rtx
4390 expand_builtin_va_end (tree arglist)
4392 tree valist = TREE_VALUE (arglist);
4394 /* Evaluate for side effects, if needed. I hate macros that don't
4395 do that. */
4396 if (TREE_SIDE_EFFECTS (valist))
4397 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4399 return const0_rtx;
4402 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4403 builtin rather than just as an assignment in stdarg.h because of the
4404 nastiness of array-type va_list types. */
4406 static rtx
4407 expand_builtin_va_copy (tree arglist)
4409 tree dst, src, t;
4411 dst = TREE_VALUE (arglist);
4412 src = TREE_VALUE (TREE_CHAIN (arglist));
4414 dst = stabilize_va_list (dst, 1);
4415 src = stabilize_va_list (src, 0);
4417 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4419 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4420 TREE_SIDE_EFFECTS (t) = 1;
4421 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4423 else
4425 rtx dstb, srcb, size;
4427 /* Evaluate to pointers. */
4428 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4429 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4430 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4431 VOIDmode, EXPAND_NORMAL);
4433 dstb = convert_memory_address (Pmode, dstb);
4434 srcb = convert_memory_address (Pmode, srcb);
4436 /* "Dereference" to BLKmode memories. */
4437 dstb = gen_rtx_MEM (BLKmode, dstb);
4438 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4439 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4440 srcb = gen_rtx_MEM (BLKmode, srcb);
4441 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4442 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4444 /* Copy. */
4445 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4448 return const0_rtx;
4451 /* Expand a call to one of the builtin functions __builtin_frame_address or
4452 __builtin_return_address. */
4454 static rtx
4455 expand_builtin_frame_address (tree fndecl, tree arglist)
4457 /* The argument must be a nonnegative integer constant.
4458 It counts the number of frames to scan up the stack.
4459 The value is the return address saved in that frame. */
4460 if (arglist == 0)
4461 /* Warning about missing arg was already issued. */
4462 return const0_rtx;
4463 else if (! host_integerp (TREE_VALUE (arglist), 1))
4465 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4466 error ("invalid argument to %<__builtin_frame_address%>");
4467 else
4468 error ("invalid argument to %<__builtin_return_address%>");
4469 return const0_rtx;
4471 else
4473 rtx tem
4474 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4475 tree_low_cst (TREE_VALUE (arglist), 1));
4477 /* Some ports cannot access arbitrary stack frames. */
4478 if (tem == NULL)
4480 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4481 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4482 else
4483 warning (0, "unsupported argument to %<__builtin_return_address%>");
4484 return const0_rtx;
4487 /* For __builtin_frame_address, return what we've got. */
4488 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4489 return tem;
4491 if (!REG_P (tem)
4492 && ! CONSTANT_P (tem))
4493 tem = copy_to_mode_reg (Pmode, tem);
4494 return tem;
4498 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4499 we failed and the caller should emit a normal call, otherwise try to get
4500 the result in TARGET, if convenient. */
4502 static rtx
4503 expand_builtin_alloca (tree arglist, rtx target)
4505 rtx op0;
4506 rtx result;
4508 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4509 should always expand to function calls. These can be intercepted
4510 in libmudflap. */
4511 if (flag_mudflap)
4512 return 0;
4514 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4515 return 0;
4517 /* Compute the argument. */
4518 op0 = expand_normal (TREE_VALUE (arglist));
4520 /* Allocate the desired space. */
4521 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4522 result = convert_memory_address (ptr_mode, result);
4524 return result;
4527 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4528 Return 0 if a normal call should be emitted rather than expanding the
4529 function in-line. If convenient, the result should be placed in TARGET.
4530 SUBTARGET may be used as the target for computing one of EXP's operands. */
4532 static rtx
4533 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4534 rtx subtarget, optab op_optab)
4536 rtx op0;
4537 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4538 return 0;
4540 /* Compute the argument. */
4541 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4542 /* Compute op, into TARGET if possible.
4543 Set TARGET to wherever the result comes back. */
4544 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4545 op_optab, op0, target, 1);
4546 gcc_assert (target);
4548 return convert_to_mode (target_mode, target, 0);
4551 /* If the string passed to fputs is a constant and is one character
4552 long, we attempt to transform this call into __builtin_fputc(). */
4554 static rtx
4555 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4557 /* Verify the arguments in the original call. */
4558 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4560 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4561 unlocked, NULL_TREE);
4562 if (result)
4563 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4565 return 0;
4568 /* Expand a call to __builtin_expect. We return our argument and emit a
4569 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4570 a non-jump context. */
4572 static rtx
4573 expand_builtin_expect (tree arglist, rtx target)
4575 tree exp, c;
4576 rtx note, rtx_c;
4578 if (arglist == NULL_TREE
4579 || TREE_CHAIN (arglist) == NULL_TREE)
4580 return const0_rtx;
4581 exp = TREE_VALUE (arglist);
4582 c = TREE_VALUE (TREE_CHAIN (arglist));
4584 if (TREE_CODE (c) != INTEGER_CST)
4586 error ("second argument to %<__builtin_expect%> must be a constant");
4587 c = integer_zero_node;
4590 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4592 /* Don't bother with expected value notes for integral constants. */
4593 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4595 /* We do need to force this into a register so that we can be
4596 moderately sure to be able to correctly interpret the branch
4597 condition later. */
4598 target = force_reg (GET_MODE (target), target);
4600 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4602 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4603 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4606 return target;
4609 /* Like expand_builtin_expect, except do this in a jump context. This is
4610 called from do_jump if the conditional is a __builtin_expect. Return either
4611 a list of insns to emit the jump or NULL if we cannot optimize
4612 __builtin_expect. We need to optimize this at jump time so that machines
4613 like the PowerPC don't turn the test into a SCC operation, and then jump
4614 based on the test being 0/1. */
4617 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4619 tree arglist = TREE_OPERAND (exp, 1);
4620 tree arg0 = TREE_VALUE (arglist);
4621 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4622 rtx ret = NULL_RTX;
4624 /* Only handle __builtin_expect (test, 0) and
4625 __builtin_expect (test, 1). */
4626 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4627 && (integer_zerop (arg1) || integer_onep (arg1)))
4629 rtx insn, drop_through_label, temp;
4631 /* Expand the jump insns. */
4632 start_sequence ();
4633 do_jump (arg0, if_false_label, if_true_label);
4634 ret = get_insns ();
4636 drop_through_label = get_last_insn ();
4637 if (drop_through_label && NOTE_P (drop_through_label))
4638 drop_through_label = prev_nonnote_insn (drop_through_label);
4639 if (drop_through_label && !LABEL_P (drop_through_label))
4640 drop_through_label = NULL_RTX;
4641 end_sequence ();
4643 if (! if_true_label)
4644 if_true_label = drop_through_label;
4645 if (! if_false_label)
4646 if_false_label = drop_through_label;
4648 /* Go through and add the expect's to each of the conditional jumps. */
4649 insn = ret;
4650 while (insn != NULL_RTX)
4652 rtx next = NEXT_INSN (insn);
4654 if (JUMP_P (insn) && any_condjump_p (insn))
4656 rtx ifelse = SET_SRC (pc_set (insn));
4657 rtx then_dest = XEXP (ifelse, 1);
4658 rtx else_dest = XEXP (ifelse, 2);
4659 int taken = -1;
4661 /* First check if we recognize any of the labels. */
4662 if (GET_CODE (then_dest) == LABEL_REF
4663 && XEXP (then_dest, 0) == if_true_label)
4664 taken = 1;
4665 else if (GET_CODE (then_dest) == LABEL_REF
4666 && XEXP (then_dest, 0) == if_false_label)
4667 taken = 0;
4668 else if (GET_CODE (else_dest) == LABEL_REF
4669 && XEXP (else_dest, 0) == if_false_label)
4670 taken = 1;
4671 else if (GET_CODE (else_dest) == LABEL_REF
4672 && XEXP (else_dest, 0) == if_true_label)
4673 taken = 0;
4674 /* Otherwise check where we drop through. */
4675 else if (else_dest == pc_rtx)
4677 if (next && NOTE_P (next))
4678 next = next_nonnote_insn (next);
4680 if (next && JUMP_P (next)
4681 && any_uncondjump_p (next))
4682 temp = XEXP (SET_SRC (pc_set (next)), 0);
4683 else
4684 temp = next;
4686 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4687 else that can't possibly match either target label. */
4688 if (temp == if_false_label)
4689 taken = 1;
4690 else if (temp == if_true_label)
4691 taken = 0;
4693 else if (then_dest == pc_rtx)
4695 if (next && NOTE_P (next))
4696 next = next_nonnote_insn (next);
4698 if (next && JUMP_P (next)
4699 && any_uncondjump_p (next))
4700 temp = XEXP (SET_SRC (pc_set (next)), 0);
4701 else
4702 temp = next;
4704 if (temp == if_false_label)
4705 taken = 0;
4706 else if (temp == if_true_label)
4707 taken = 1;
4710 if (taken != -1)
4712 /* If the test is expected to fail, reverse the
4713 probabilities. */
4714 if (integer_zerop (arg1))
4715 taken = 1 - taken;
4716 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4720 insn = next;
4724 return ret;
4727 void
4728 expand_builtin_trap (void)
4730 #ifdef HAVE_trap
4731 if (HAVE_trap)
4732 emit_insn (gen_trap ());
4733 else
4734 #endif
4735 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4736 emit_barrier ();
4739 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4740 Return 0 if a normal call should be emitted rather than expanding
4741 the function inline. If convenient, the result should be placed
4742 in TARGET. SUBTARGET may be used as the target for computing
4743 the operand. */
4745 static rtx
4746 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4748 enum machine_mode mode;
4749 tree arg;
4750 rtx op0;
4752 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4753 return 0;
4755 arg = TREE_VALUE (arglist);
4756 mode = TYPE_MODE (TREE_TYPE (arg));
4757 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4758 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4761 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4762 Return NULL is a normal call should be emitted rather than expanding the
4763 function inline. If convenient, the result should be placed in TARGET.
4764 SUBTARGET may be used as the target for computing the operand. */
4766 static rtx
4767 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4769 rtx op0, op1;
4770 tree arg;
4772 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4773 return 0;
4775 arg = TREE_VALUE (arglist);
4776 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4778 arg = TREE_VALUE (TREE_CHAIN (arglist));
4779 op1 = expand_normal (arg);
4781 return expand_copysign (op0, op1, target);
4784 /* Create a new constant string literal and return a char* pointer to it.
4785 The STRING_CST value is the LEN characters at STR. */
4786 tree
4787 build_string_literal (int len, const char *str)
4789 tree t, elem, index, type;
4791 t = build_string (len, str);
4792 elem = build_type_variant (char_type_node, 1, 0);
4793 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4794 type = build_array_type (elem, index);
4795 TREE_TYPE (t) = type;
4796 TREE_CONSTANT (t) = 1;
4797 TREE_INVARIANT (t) = 1;
4798 TREE_READONLY (t) = 1;
4799 TREE_STATIC (t) = 1;
4801 type = build_pointer_type (type);
4802 t = build1 (ADDR_EXPR, type, t);
4804 type = build_pointer_type (elem);
4805 t = build1 (NOP_EXPR, type, t);
4806 return t;
4809 /* Expand EXP, a call to printf or printf_unlocked.
4810 Return 0 if a normal call should be emitted rather than transforming
4811 the function inline. If convenient, the result should be placed in
4812 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4813 call. */
4814 static rtx
4815 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4816 bool unlocked)
4818 tree arglist = TREE_OPERAND (exp, 1);
4819 /* If we're using an unlocked function, assume the other unlocked
4820 functions exist explicitly. */
4821 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4822 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4823 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4824 : implicit_built_in_decls[BUILT_IN_PUTS];
4825 const char *fmt_str;
4826 tree fn, fmt, arg;
4828 /* If the return value is used, don't do the transformation. */
4829 if (target != const0_rtx)
4830 return 0;
4832 /* Verify the required arguments in the original call. */
4833 if (! arglist)
4834 return 0;
4835 fmt = TREE_VALUE (arglist);
4836 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4837 return 0;
4838 arglist = TREE_CHAIN (arglist);
4840 /* Check whether the format is a literal string constant. */
4841 fmt_str = c_getstr (fmt);
4842 if (fmt_str == NULL)
4843 return 0;
4845 if (!init_target_chars())
4846 return 0;
4848 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4849 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4851 if (! arglist
4852 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4853 || TREE_CHAIN (arglist))
4854 return 0;
4855 fn = fn_puts;
4857 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4858 else if (strcmp (fmt_str, target_percent_c) == 0)
4860 if (! arglist
4861 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4862 || TREE_CHAIN (arglist))
4863 return 0;
4864 fn = fn_putchar;
4866 else
4868 /* We can't handle anything else with % args or %% ... yet. */
4869 if (strchr (fmt_str, target_percent))
4870 return 0;
4872 if (arglist)
4873 return 0;
4875 /* If the format specifier was "", printf does nothing. */
4876 if (fmt_str[0] == '\0')
4877 return const0_rtx;
4878 /* If the format specifier has length of 1, call putchar. */
4879 if (fmt_str[1] == '\0')
4881 /* Given printf("c"), (where c is any one character,)
4882 convert "c"[0] to an int and pass that to the replacement
4883 function. */
4884 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4885 arglist = build_tree_list (NULL_TREE, arg);
4886 fn = fn_putchar;
4888 else
4890 /* If the format specifier was "string\n", call puts("string"). */
4891 size_t len = strlen (fmt_str);
4892 if ((unsigned char)fmt_str[len - 1] == target_newline)
4894 /* Create a NUL-terminated string that's one char shorter
4895 than the original, stripping off the trailing '\n'. */
4896 char *newstr = alloca (len);
4897 memcpy (newstr, fmt_str, len - 1);
4898 newstr[len - 1] = 0;
4900 arg = build_string_literal (len, newstr);
4901 arglist = build_tree_list (NULL_TREE, arg);
4902 fn = fn_puts;
4904 else
4905 /* We'd like to arrange to call fputs(string,stdout) here,
4906 but we need stdout and don't have a way to get it yet. */
4907 return 0;
4911 if (!fn)
4912 return 0;
4913 fn = build_function_call_expr (fn, arglist);
4914 if (TREE_CODE (fn) == CALL_EXPR)
4915 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4916 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4919 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4920 Return 0 if a normal call should be emitted rather than transforming
4921 the function inline. If convenient, the result should be placed in
4922 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4923 call. */
4924 static rtx
4925 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4926 bool unlocked)
4928 tree arglist = TREE_OPERAND (exp, 1);
4929 /* If we're using an unlocked function, assume the other unlocked
4930 functions exist explicitly. */
4931 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4932 : implicit_built_in_decls[BUILT_IN_FPUTC];
4933 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4934 : implicit_built_in_decls[BUILT_IN_FPUTS];
4935 const char *fmt_str;
4936 tree fn, fmt, fp, arg;
4938 /* If the return value is used, don't do the transformation. */
4939 if (target != const0_rtx)
4940 return 0;
4942 /* Verify the required arguments in the original call. */
4943 if (! arglist)
4944 return 0;
4945 fp = TREE_VALUE (arglist);
4946 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4947 return 0;
4948 arglist = TREE_CHAIN (arglist);
4949 if (! arglist)
4950 return 0;
4951 fmt = TREE_VALUE (arglist);
4952 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4953 return 0;
4954 arglist = TREE_CHAIN (arglist);
4956 /* Check whether the format is a literal string constant. */
4957 fmt_str = c_getstr (fmt);
4958 if (fmt_str == NULL)
4959 return 0;
4961 if (!init_target_chars())
4962 return 0;
4964 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4965 if (strcmp (fmt_str, target_percent_s) == 0)
4967 if (! arglist
4968 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4969 || TREE_CHAIN (arglist))
4970 return 0;
4971 arg = TREE_VALUE (arglist);
4972 arglist = build_tree_list (NULL_TREE, fp);
4973 arglist = tree_cons (NULL_TREE, arg, arglist);
4974 fn = fn_fputs;
4976 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4977 else if (strcmp (fmt_str, target_percent_c) == 0)
4979 if (! arglist
4980 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4981 || TREE_CHAIN (arglist))
4982 return 0;
4983 arg = TREE_VALUE (arglist);
4984 arglist = build_tree_list (NULL_TREE, fp);
4985 arglist = tree_cons (NULL_TREE, arg, arglist);
4986 fn = fn_fputc;
4988 else
4990 /* We can't handle anything else with % args or %% ... yet. */
4991 if (strchr (fmt_str, target_percent))
4992 return 0;
4994 if (arglist)
4995 return 0;
4997 /* If the format specifier was "", fprintf does nothing. */
4998 if (fmt_str[0] == '\0')
5000 /* Evaluate and ignore FILE* argument for side-effects. */
5001 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5002 return const0_rtx;
5005 /* When "string" doesn't contain %, replace all cases of
5006 fprintf(stream,string) with fputs(string,stream). The fputs
5007 builtin will take care of special cases like length == 1. */
5008 arglist = build_tree_list (NULL_TREE, fp);
5009 arglist = tree_cons (NULL_TREE, fmt, arglist);
5010 fn = fn_fputs;
5013 if (!fn)
5014 return 0;
5015 fn = build_function_call_expr (fn, arglist);
5016 if (TREE_CODE (fn) == CALL_EXPR)
5017 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5018 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5021 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5022 a normal call should be emitted rather than expanding the function
5023 inline. If convenient, the result should be placed in TARGET with
5024 mode MODE. */
5026 static rtx
5027 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5029 tree orig_arglist, dest, fmt;
5030 const char *fmt_str;
5032 orig_arglist = arglist;
5034 /* Verify the required arguments in the original call. */
5035 if (! arglist)
5036 return 0;
5037 dest = TREE_VALUE (arglist);
5038 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5039 return 0;
5040 arglist = TREE_CHAIN (arglist);
5041 if (! arglist)
5042 return 0;
5043 fmt = TREE_VALUE (arglist);
5044 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5045 return 0;
5046 arglist = TREE_CHAIN (arglist);
5048 /* Check whether the format is a literal string constant. */
5049 fmt_str = c_getstr (fmt);
5050 if (fmt_str == NULL)
5051 return 0;
5053 if (!init_target_chars())
5054 return 0;
5056 /* If the format doesn't contain % args or %%, use strcpy. */
5057 if (strchr (fmt_str, target_percent) == 0)
5059 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5060 tree exp;
5062 if (arglist || ! fn)
5063 return 0;
5064 expand_expr (build_function_call_expr (fn, orig_arglist),
5065 const0_rtx, VOIDmode, EXPAND_NORMAL);
5066 if (target == const0_rtx)
5067 return const0_rtx;
5068 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5069 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5071 /* If the format is "%s", use strcpy if the result isn't used. */
5072 else if (strcmp (fmt_str, target_percent_s) == 0)
5074 tree fn, arg, len;
5075 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5077 if (! fn)
5078 return 0;
5080 if (! arglist || TREE_CHAIN (arglist))
5081 return 0;
5082 arg = TREE_VALUE (arglist);
5083 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5084 return 0;
5086 if (target != const0_rtx)
5088 len = c_strlen (arg, 1);
5089 if (! len || TREE_CODE (len) != INTEGER_CST)
5090 return 0;
5092 else
5093 len = NULL_TREE;
5095 arglist = build_tree_list (NULL_TREE, arg);
5096 arglist = tree_cons (NULL_TREE, dest, arglist);
5097 expand_expr (build_function_call_expr (fn, arglist),
5098 const0_rtx, VOIDmode, EXPAND_NORMAL);
5100 if (target == const0_rtx)
5101 return const0_rtx;
5102 return expand_expr (len, target, mode, EXPAND_NORMAL);
5105 return 0;
5108 /* Expand a call to either the entry or exit function profiler. */
5110 static rtx
5111 expand_builtin_profile_func (bool exitp)
5113 rtx this, which;
5115 this = DECL_RTL (current_function_decl);
5116 gcc_assert (MEM_P (this));
5117 this = XEXP (this, 0);
5119 if (exitp)
5120 which = profile_function_exit_libfunc;
5121 else
5122 which = profile_function_entry_libfunc;
5124 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5125 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5127 Pmode);
5129 return const0_rtx;
5132 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5134 static rtx
5135 round_trampoline_addr (rtx tramp)
5137 rtx temp, addend, mask;
5139 /* If we don't need too much alignment, we'll have been guaranteed
5140 proper alignment by get_trampoline_type. */
5141 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5142 return tramp;
5144 /* Round address up to desired boundary. */
5145 temp = gen_reg_rtx (Pmode);
5146 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5147 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5149 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5150 temp, 0, OPTAB_LIB_WIDEN);
5151 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5152 temp, 0, OPTAB_LIB_WIDEN);
5154 return tramp;
5157 static rtx
5158 expand_builtin_init_trampoline (tree arglist)
5160 tree t_tramp, t_func, t_chain;
5161 rtx r_tramp, r_func, r_chain;
5162 #ifdef TRAMPOLINE_TEMPLATE
5163 rtx blktramp;
5164 #endif
5166 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5167 POINTER_TYPE, VOID_TYPE))
5168 return NULL_RTX;
5170 t_tramp = TREE_VALUE (arglist);
5171 arglist = TREE_CHAIN (arglist);
5172 t_func = TREE_VALUE (arglist);
5173 arglist = TREE_CHAIN (arglist);
5174 t_chain = TREE_VALUE (arglist);
5176 r_tramp = expand_normal (t_tramp);
5177 r_func = expand_normal (t_func);
5178 r_chain = expand_normal (t_chain);
5180 /* Generate insns to initialize the trampoline. */
5181 r_tramp = round_trampoline_addr (r_tramp);
5182 #ifdef TRAMPOLINE_TEMPLATE
5183 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5184 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5185 emit_block_move (blktramp, assemble_trampoline_template (),
5186 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5187 #endif
5188 trampolines_created = 1;
5189 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5191 return const0_rtx;
5194 static rtx
5195 expand_builtin_adjust_trampoline (tree arglist)
5197 rtx tramp;
5199 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5200 return NULL_RTX;
5202 tramp = expand_normal (TREE_VALUE (arglist));
5203 tramp = round_trampoline_addr (tramp);
5204 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5205 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5206 #endif
5208 return tramp;
5211 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5212 Return NULL_RTX if a normal call should be emitted rather than expanding
5213 the function in-line. EXP is the expression that is a call to the builtin
5214 function; if convenient, the result should be placed in TARGET. */
5216 static rtx
5217 expand_builtin_signbit (tree exp, rtx target)
5219 const struct real_format *fmt;
5220 enum machine_mode fmode, imode, rmode;
5221 HOST_WIDE_INT hi, lo;
5222 tree arg, arglist;
5223 int word, bitpos;
5224 rtx temp;
5226 arglist = TREE_OPERAND (exp, 1);
5227 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5228 return 0;
5230 arg = TREE_VALUE (arglist);
5231 fmode = TYPE_MODE (TREE_TYPE (arg));
5232 rmode = TYPE_MODE (TREE_TYPE (exp));
5233 fmt = REAL_MODE_FORMAT (fmode);
5235 /* For floating point formats without a sign bit, implement signbit
5236 as "ARG < 0.0". */
5237 bitpos = fmt->signbit_ro;
5238 if (bitpos < 0)
5240 /* But we can't do this if the format supports signed zero. */
5241 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5242 return 0;
5244 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5245 build_real (TREE_TYPE (arg), dconst0));
5246 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5249 temp = expand_normal (arg);
5250 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5252 imode = int_mode_for_mode (fmode);
5253 if (imode == BLKmode)
5254 return 0;
5255 temp = gen_lowpart (imode, temp);
5257 else
5259 imode = word_mode;
5260 /* Handle targets with different FP word orders. */
5261 if (FLOAT_WORDS_BIG_ENDIAN)
5262 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5263 else
5264 word = bitpos / BITS_PER_WORD;
5265 temp = operand_subword_force (temp, word, fmode);
5266 bitpos = bitpos % BITS_PER_WORD;
5269 /* Force the intermediate word_mode (or narrower) result into a
5270 register. This avoids attempting to create paradoxical SUBREGs
5271 of floating point modes below. */
5272 temp = force_reg (imode, temp);
5274 /* If the bitpos is within the "result mode" lowpart, the operation
5275 can be implement with a single bitwise AND. Otherwise, we need
5276 a right shift and an AND. */
5278 if (bitpos < GET_MODE_BITSIZE (rmode))
5280 if (bitpos < HOST_BITS_PER_WIDE_INT)
5282 hi = 0;
5283 lo = (HOST_WIDE_INT) 1 << bitpos;
5285 else
5287 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5288 lo = 0;
5291 if (imode != rmode)
5292 temp = gen_lowpart (rmode, temp);
5293 temp = expand_binop (rmode, and_optab, temp,
5294 immed_double_const (lo, hi, rmode),
5295 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5297 else
5299 /* Perform a logical right shift to place the signbit in the least
5300 significant bit, then truncate the result to the desired mode
5301 and mask just this bit. */
5302 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5303 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5304 temp = gen_lowpart (rmode, temp);
5305 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5306 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5309 return temp;
5312 /* Expand fork or exec calls. TARGET is the desired target of the
5313 call. ARGLIST is the list of arguments of the call. FN is the
5314 identificator of the actual function. IGNORE is nonzero if the
5315 value is to be ignored. */
5317 static rtx
5318 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5320 tree id, decl;
5321 tree call;
5323 /* If we are not profiling, just call the function. */
5324 if (!profile_arc_flag)
5325 return NULL_RTX;
5327 /* Otherwise call the wrapper. This should be equivalent for the rest of
5328 compiler, so the code does not diverge, and the wrapper may run the
5329 code necessary for keeping the profiling sane. */
5331 switch (DECL_FUNCTION_CODE (fn))
5333 case BUILT_IN_FORK:
5334 id = get_identifier ("__gcov_fork");
5335 break;
5337 case BUILT_IN_EXECL:
5338 id = get_identifier ("__gcov_execl");
5339 break;
5341 case BUILT_IN_EXECV:
5342 id = get_identifier ("__gcov_execv");
5343 break;
5345 case BUILT_IN_EXECLP:
5346 id = get_identifier ("__gcov_execlp");
5347 break;
5349 case BUILT_IN_EXECLE:
5350 id = get_identifier ("__gcov_execle");
5351 break;
5353 case BUILT_IN_EXECVP:
5354 id = get_identifier ("__gcov_execvp");
5355 break;
5357 case BUILT_IN_EXECVE:
5358 id = get_identifier ("__gcov_execve");
5359 break;
5361 default:
5362 gcc_unreachable ();
5365 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5366 DECL_EXTERNAL (decl) = 1;
5367 TREE_PUBLIC (decl) = 1;
5368 DECL_ARTIFICIAL (decl) = 1;
5369 TREE_NOTHROW (decl) = 1;
5370 call = build_function_call_expr (decl, arglist);
5372 return expand_call (call, target, ignore);
5376 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5377 the pointer in these functions is void*, the tree optimizers may remove
5378 casts. The mode computed in expand_builtin isn't reliable either, due
5379 to __sync_bool_compare_and_swap.
5381 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5382 group of builtins. This gives us log2 of the mode size. */
5384 static inline enum machine_mode
5385 get_builtin_sync_mode (int fcode_diff)
5387 /* The size is not negotiable, so ask not to get BLKmode in return
5388 if the target indicates that a smaller size would be better. */
5389 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5392 /* Expand the memory expression LOC and return the appropriate memory operand
5393 for the builtin_sync operations. */
5395 static rtx
5396 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5398 rtx addr, mem;
5400 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5402 /* Note that we explicitly do not want any alias information for this
5403 memory, so that we kill all other live memories. Otherwise we don't
5404 satisfy the full barrier semantics of the intrinsic. */
5405 mem = validize_mem (gen_rtx_MEM (mode, addr));
5407 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5408 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5409 MEM_VOLATILE_P (mem) = 1;
5411 return mem;
5414 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5415 ARGLIST is the operands list to the function. CODE is the rtx code
5416 that corresponds to the arithmetic or logical operation from the name;
5417 an exception here is that NOT actually means NAND. TARGET is an optional
5418 place for us to store the results; AFTER is true if this is the
5419 fetch_and_xxx form. IGNORE is true if we don't actually care about
5420 the result of the operation at all. */
5422 static rtx
5423 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5424 enum rtx_code code, bool after,
5425 rtx target, bool ignore)
5427 rtx val, mem;
5429 /* Expand the operands. */
5430 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5432 arglist = TREE_CHAIN (arglist);
5433 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5435 if (ignore)
5436 return expand_sync_operation (mem, val, code);
5437 else
5438 return expand_sync_fetch_operation (mem, val, code, after, target);
5441 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5442 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5443 true if this is the boolean form. TARGET is a place for us to store the
5444 results; this is NOT optional if IS_BOOL is true. */
5446 static rtx
5447 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5448 bool is_bool, rtx target)
5450 rtx old_val, new_val, mem;
5452 /* Expand the operands. */
5453 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5455 arglist = TREE_CHAIN (arglist);
5456 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5458 arglist = TREE_CHAIN (arglist);
5459 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5461 if (is_bool)
5462 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5463 else
5464 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5467 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5468 general form is actually an atomic exchange, and some targets only
5469 support a reduced form with the second argument being a constant 1.
5470 ARGLIST is the operands list to the function; TARGET is an optional
5471 place for us to store the results. */
5473 static rtx
5474 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5475 rtx target)
5477 rtx val, mem;
5479 /* Expand the operands. */
5480 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5482 arglist = TREE_CHAIN (arglist);
5483 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5485 return expand_sync_lock_test_and_set (mem, val, target);
5488 /* Expand the __sync_synchronize intrinsic. */
5490 static void
5491 expand_builtin_synchronize (void)
5493 tree x;
5495 #ifdef HAVE_memory_barrier
5496 if (HAVE_memory_barrier)
5498 emit_insn (gen_memory_barrier ());
5499 return;
5501 #endif
5503 /* If no explicit memory barrier instruction is available, create an
5504 empty asm stmt with a memory clobber. */
5505 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5506 tree_cons (NULL, build_string (6, "memory"), NULL));
5507 ASM_VOLATILE_P (x) = 1;
5508 expand_asm_expr (x);
5511 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5512 to the function. */
5514 static void
5515 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5517 enum insn_code icode;
5518 rtx mem, insn;
5519 rtx val = const0_rtx;
5521 /* Expand the operands. */
5522 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5524 /* If there is an explicit operation in the md file, use it. */
5525 icode = sync_lock_release[mode];
5526 if (icode != CODE_FOR_nothing)
5528 if (!insn_data[icode].operand[1].predicate (val, mode))
5529 val = force_reg (mode, val);
5531 insn = GEN_FCN (icode) (mem, val);
5532 if (insn)
5534 emit_insn (insn);
5535 return;
5539 /* Otherwise we can implement this operation by emitting a barrier
5540 followed by a store of zero. */
5541 expand_builtin_synchronize ();
5542 emit_move_insn (mem, val);
5545 /* Expand an expression EXP that calls a built-in function,
5546 with result going to TARGET if that's convenient
5547 (and in mode MODE if that's convenient).
5548 SUBTARGET may be used as the target for computing one of EXP's operands.
5549 IGNORE is nonzero if the value is to be ignored. */
5552 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5553 int ignore)
5555 tree fndecl = get_callee_fndecl (exp);
5556 tree arglist = TREE_OPERAND (exp, 1);
5557 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5558 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5560 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5561 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5562 else
5564 /* Try expanding the builtin via the generic target hook. */
5565 rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
5566 mode, ignore);
5567 if (tmp != NULL_RTX)
5568 return tmp;
5571 /* When not optimizing, generate calls to library functions for a certain
5572 set of builtins. */
5573 if (!optimize
5574 && !called_as_built_in (fndecl)
5575 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5576 && fcode != BUILT_IN_ALLOCA)
5577 return expand_call (exp, target, ignore);
5579 /* The built-in function expanders test for target == const0_rtx
5580 to determine whether the function's result will be ignored. */
5581 if (ignore)
5582 target = const0_rtx;
5584 /* If the result of a pure or const built-in function is ignored, and
5585 none of its arguments are volatile, we can avoid expanding the
5586 built-in call and just evaluate the arguments for side-effects. */
5587 if (target == const0_rtx
5588 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5590 bool volatilep = false;
5591 tree arg;
5593 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5594 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5596 volatilep = true;
5597 break;
5600 if (! volatilep)
5602 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5603 expand_expr (TREE_VALUE (arg), const0_rtx,
5604 VOIDmode, EXPAND_NORMAL);
5605 return const0_rtx;
5609 switch (fcode)
5611 CASE_FLT_FN (BUILT_IN_FABS):
5612 target = expand_builtin_fabs (arglist, target, subtarget);
5613 if (target)
5614 return target;
5615 break;
5617 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5618 target = expand_builtin_copysign (arglist, target, subtarget);
5619 if (target)
5620 return target;
5621 break;
5623 /* Just do a normal library call if we were unable to fold
5624 the values. */
5625 CASE_FLT_FN (BUILT_IN_CABS):
5626 break;
5628 CASE_FLT_FN (BUILT_IN_EXP):
5629 CASE_FLT_FN (BUILT_IN_EXP10):
5630 CASE_FLT_FN (BUILT_IN_POW10):
5631 CASE_FLT_FN (BUILT_IN_EXP2):
5632 CASE_FLT_FN (BUILT_IN_EXPM1):
5633 CASE_FLT_FN (BUILT_IN_LOGB):
5634 CASE_FLT_FN (BUILT_IN_ILOGB):
5635 CASE_FLT_FN (BUILT_IN_LOG):
5636 CASE_FLT_FN (BUILT_IN_LOG10):
5637 CASE_FLT_FN (BUILT_IN_LOG2):
5638 CASE_FLT_FN (BUILT_IN_LOG1P):
5639 CASE_FLT_FN (BUILT_IN_TAN):
5640 CASE_FLT_FN (BUILT_IN_ASIN):
5641 CASE_FLT_FN (BUILT_IN_ACOS):
5642 CASE_FLT_FN (BUILT_IN_ATAN):
5643 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5644 because of possible accuracy problems. */
5645 if (! flag_unsafe_math_optimizations)
5646 break;
5647 CASE_FLT_FN (BUILT_IN_SQRT):
5648 CASE_FLT_FN (BUILT_IN_FLOOR):
5649 CASE_FLT_FN (BUILT_IN_CEIL):
5650 CASE_FLT_FN (BUILT_IN_TRUNC):
5651 CASE_FLT_FN (BUILT_IN_ROUND):
5652 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5653 CASE_FLT_FN (BUILT_IN_RINT):
5654 CASE_FLT_FN (BUILT_IN_LRINT):
5655 CASE_FLT_FN (BUILT_IN_LLRINT):
5656 target = expand_builtin_mathfn (exp, target, subtarget);
5657 if (target)
5658 return target;
5659 break;
5661 CASE_FLT_FN (BUILT_IN_LCEIL):
5662 CASE_FLT_FN (BUILT_IN_LLCEIL):
5663 CASE_FLT_FN (BUILT_IN_LFLOOR):
5664 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5665 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5666 if (target)
5667 return target;
5668 break;
5670 CASE_FLT_FN (BUILT_IN_POW):
5671 target = expand_builtin_pow (exp, target, subtarget);
5672 if (target)
5673 return target;
5674 break;
5676 CASE_FLT_FN (BUILT_IN_POWI):
5677 target = expand_builtin_powi (exp, target, subtarget);
5678 if (target)
5679 return target;
5680 break;
5682 CASE_FLT_FN (BUILT_IN_ATAN2):
5683 CASE_FLT_FN (BUILT_IN_LDEXP):
5684 CASE_FLT_FN (BUILT_IN_FMOD):
5685 CASE_FLT_FN (BUILT_IN_DREM):
5686 if (! flag_unsafe_math_optimizations)
5687 break;
5688 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5689 if (target)
5690 return target;
5691 break;
5693 CASE_FLT_FN (BUILT_IN_SIN):
5694 CASE_FLT_FN (BUILT_IN_COS):
5695 if (! flag_unsafe_math_optimizations)
5696 break;
5697 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5698 if (target)
5699 return target;
5700 break;
5702 CASE_FLT_FN (BUILT_IN_SINCOS):
5703 if (! flag_unsafe_math_optimizations)
5704 break;
5705 target = expand_builtin_sincos (exp);
5706 if (target)
5707 return target;
5708 break;
5710 case BUILT_IN_APPLY_ARGS:
5711 return expand_builtin_apply_args ();
5713 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5714 FUNCTION with a copy of the parameters described by
5715 ARGUMENTS, and ARGSIZE. It returns a block of memory
5716 allocated on the stack into which is stored all the registers
5717 that might possibly be used for returning the result of a
5718 function. ARGUMENTS is the value returned by
5719 __builtin_apply_args. ARGSIZE is the number of bytes of
5720 arguments that must be copied. ??? How should this value be
5721 computed? We'll also need a safe worst case value for varargs
5722 functions. */
5723 case BUILT_IN_APPLY:
5724 if (!validate_arglist (arglist, POINTER_TYPE,
5725 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5726 && !validate_arglist (arglist, REFERENCE_TYPE,
5727 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5728 return const0_rtx;
5729 else
5731 int i;
5732 tree t;
5733 rtx ops[3];
5735 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5736 ops[i] = expand_normal (TREE_VALUE (t));
5738 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5741 /* __builtin_return (RESULT) causes the function to return the
5742 value described by RESULT. RESULT is address of the block of
5743 memory returned by __builtin_apply. */
5744 case BUILT_IN_RETURN:
5745 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5746 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5747 return const0_rtx;
5749 case BUILT_IN_SAVEREGS:
5750 return expand_builtin_saveregs ();
5752 case BUILT_IN_ARGS_INFO:
5753 return expand_builtin_args_info (arglist);
5755 /* Return the address of the first anonymous stack arg. */
5756 case BUILT_IN_NEXT_ARG:
5757 if (fold_builtin_next_arg (arglist))
5758 return const0_rtx;
5759 return expand_builtin_next_arg ();
5761 case BUILT_IN_CLASSIFY_TYPE:
5762 return expand_builtin_classify_type (arglist);
5764 case BUILT_IN_CONSTANT_P:
5765 return const0_rtx;
5767 case BUILT_IN_FRAME_ADDRESS:
5768 case BUILT_IN_RETURN_ADDRESS:
5769 return expand_builtin_frame_address (fndecl, arglist);
5771 /* Returns the address of the area where the structure is returned.
5772 0 otherwise. */
5773 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5774 if (arglist != 0
5775 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5776 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5777 return const0_rtx;
5778 else
5779 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5781 case BUILT_IN_ALLOCA:
5782 target = expand_builtin_alloca (arglist, target);
5783 if (target)
5784 return target;
5785 break;
5787 case BUILT_IN_STACK_SAVE:
5788 return expand_stack_save ();
5790 case BUILT_IN_STACK_RESTORE:
5791 expand_stack_restore (TREE_VALUE (arglist));
5792 return const0_rtx;
5794 CASE_INT_FN (BUILT_IN_FFS):
5795 case BUILT_IN_FFSIMAX:
5796 target = expand_builtin_unop (target_mode, arglist, target,
5797 subtarget, ffs_optab);
5798 if (target)
5799 return target;
5800 break;
5802 CASE_INT_FN (BUILT_IN_CLZ):
5803 case BUILT_IN_CLZIMAX:
5804 target = expand_builtin_unop (target_mode, arglist, target,
5805 subtarget, clz_optab);
5806 if (target)
5807 return target;
5808 break;
5810 CASE_INT_FN (BUILT_IN_CTZ):
5811 case BUILT_IN_CTZIMAX:
5812 target = expand_builtin_unop (target_mode, arglist, target,
5813 subtarget, ctz_optab);
5814 if (target)
5815 return target;
5816 break;
5818 CASE_INT_FN (BUILT_IN_POPCOUNT):
5819 case BUILT_IN_POPCOUNTIMAX:
5820 target = expand_builtin_unop (target_mode, arglist, target,
5821 subtarget, popcount_optab);
5822 if (target)
5823 return target;
5824 break;
5826 CASE_INT_FN (BUILT_IN_PARITY):
5827 case BUILT_IN_PARITYIMAX:
5828 target = expand_builtin_unop (target_mode, arglist, target,
5829 subtarget, parity_optab);
5830 if (target)
5831 return target;
5832 break;
5834 case BUILT_IN_STRLEN:
5835 target = expand_builtin_strlen (arglist, target, target_mode);
5836 if (target)
5837 return target;
5838 break;
5840 case BUILT_IN_STRCPY:
5841 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5842 if (target)
5843 return target;
5844 break;
5846 case BUILT_IN_STRNCPY:
5847 target = expand_builtin_strncpy (exp, target, mode);
5848 if (target)
5849 return target;
5850 break;
5852 case BUILT_IN_STPCPY:
5853 target = expand_builtin_stpcpy (exp, target, mode);
5854 if (target)
5855 return target;
5856 break;
5858 case BUILT_IN_STRCAT:
5859 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_STRNCAT:
5865 target = expand_builtin_strncat (arglist, target, mode);
5866 if (target)
5867 return target;
5868 break;
5870 case BUILT_IN_STRSPN:
5871 target = expand_builtin_strspn (arglist, target, mode);
5872 if (target)
5873 return target;
5874 break;
5876 case BUILT_IN_STRCSPN:
5877 target = expand_builtin_strcspn (arglist, target, mode);
5878 if (target)
5879 return target;
5880 break;
5882 case BUILT_IN_STRSTR:
5883 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5884 if (target)
5885 return target;
5886 break;
5888 case BUILT_IN_STRPBRK:
5889 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5890 if (target)
5891 return target;
5892 break;
5894 case BUILT_IN_INDEX:
5895 case BUILT_IN_STRCHR:
5896 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5897 if (target)
5898 return target;
5899 break;
5901 case BUILT_IN_RINDEX:
5902 case BUILT_IN_STRRCHR:
5903 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5904 if (target)
5905 return target;
5906 break;
5908 case BUILT_IN_MEMCPY:
5909 target = expand_builtin_memcpy (exp, target, mode);
5910 if (target)
5911 return target;
5912 break;
5914 case BUILT_IN_MEMPCPY:
5915 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5916 if (target)
5917 return target;
5918 break;
5920 case BUILT_IN_MEMMOVE:
5921 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5922 mode, exp);
5923 if (target)
5924 return target;
5925 break;
5927 case BUILT_IN_BCOPY:
5928 target = expand_builtin_bcopy (exp);
5929 if (target)
5930 return target;
5931 break;
5933 case BUILT_IN_MEMSET:
5934 target = expand_builtin_memset (arglist, target, mode, exp);
5935 if (target)
5936 return target;
5937 break;
5939 case BUILT_IN_BZERO:
5940 target = expand_builtin_bzero (exp);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_STRCMP:
5946 target = expand_builtin_strcmp (exp, target, mode);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_STRNCMP:
5952 target = expand_builtin_strncmp (exp, target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_BCMP:
5958 case BUILT_IN_MEMCMP:
5959 target = expand_builtin_memcmp (exp, arglist, target, mode);
5960 if (target)
5961 return target;
5962 break;
5964 case BUILT_IN_SETJMP:
5965 target = expand_builtin_setjmp (arglist, target);
5966 if (target)
5967 return target;
5968 break;
5970 /* __builtin_longjmp is passed a pointer to an array of five words.
5971 It's similar to the C library longjmp function but works with
5972 __builtin_setjmp above. */
5973 case BUILT_IN_LONGJMP:
5974 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5975 break;
5976 else
5978 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5979 VOIDmode, EXPAND_NORMAL);
5980 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
5982 if (value != const1_rtx)
5984 error ("%<__builtin_longjmp%> second argument must be 1");
5985 return const0_rtx;
5988 expand_builtin_longjmp (buf_addr, value);
5989 return const0_rtx;
5992 case BUILT_IN_NONLOCAL_GOTO:
5993 target = expand_builtin_nonlocal_goto (arglist);
5994 if (target)
5995 return target;
5996 break;
5998 /* This updates the setjmp buffer that is its argument with the value
5999 of the current stack pointer. */
6000 case BUILT_IN_UPDATE_SETJMP_BUF:
6001 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6003 rtx buf_addr
6004 = expand_normal (TREE_VALUE (arglist));
6006 expand_builtin_update_setjmp_buf (buf_addr);
6007 return const0_rtx;
6009 break;
6011 case BUILT_IN_TRAP:
6012 expand_builtin_trap ();
6013 return const0_rtx;
6015 case BUILT_IN_PRINTF:
6016 target = expand_builtin_printf (exp, target, mode, false);
6017 if (target)
6018 return target;
6019 break;
6021 case BUILT_IN_PRINTF_UNLOCKED:
6022 target = expand_builtin_printf (exp, target, mode, true);
6023 if (target)
6024 return target;
6025 break;
6027 case BUILT_IN_FPUTS:
6028 target = expand_builtin_fputs (arglist, target, false);
6029 if (target)
6030 return target;
6031 break;
6032 case BUILT_IN_FPUTS_UNLOCKED:
6033 target = expand_builtin_fputs (arglist, target, true);
6034 if (target)
6035 return target;
6036 break;
6038 case BUILT_IN_FPRINTF:
6039 target = expand_builtin_fprintf (exp, target, mode, false);
6040 if (target)
6041 return target;
6042 break;
6044 case BUILT_IN_FPRINTF_UNLOCKED:
6045 target = expand_builtin_fprintf (exp, target, mode, true);
6046 if (target)
6047 return target;
6048 break;
6050 case BUILT_IN_SPRINTF:
6051 target = expand_builtin_sprintf (arglist, target, mode);
6052 if (target)
6053 return target;
6054 break;
6056 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6057 target = expand_builtin_signbit (exp, target);
6058 if (target)
6059 return target;
6060 break;
6062 /* Various hooks for the DWARF 2 __throw routine. */
6063 case BUILT_IN_UNWIND_INIT:
6064 expand_builtin_unwind_init ();
6065 return const0_rtx;
6066 case BUILT_IN_DWARF_CFA:
6067 return virtual_cfa_rtx;
6068 #ifdef DWARF2_UNWIND_INFO
6069 case BUILT_IN_DWARF_SP_COLUMN:
6070 return expand_builtin_dwarf_sp_column ();
6071 case BUILT_IN_INIT_DWARF_REG_SIZES:
6072 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6073 return const0_rtx;
6074 #endif
6075 case BUILT_IN_FROB_RETURN_ADDR:
6076 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6077 case BUILT_IN_EXTRACT_RETURN_ADDR:
6078 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6079 case BUILT_IN_EH_RETURN:
6080 expand_builtin_eh_return (TREE_VALUE (arglist),
6081 TREE_VALUE (TREE_CHAIN (arglist)));
6082 return const0_rtx;
6083 #ifdef EH_RETURN_DATA_REGNO
6084 case BUILT_IN_EH_RETURN_DATA_REGNO:
6085 return expand_builtin_eh_return_data_regno (arglist);
6086 #endif
6087 case BUILT_IN_EXTEND_POINTER:
6088 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6090 case BUILT_IN_VA_START:
6091 case BUILT_IN_STDARG_START:
6092 return expand_builtin_va_start (arglist);
6093 case BUILT_IN_VA_END:
6094 return expand_builtin_va_end (arglist);
6095 case BUILT_IN_VA_COPY:
6096 return expand_builtin_va_copy (arglist);
6097 case BUILT_IN_EXPECT:
6098 return expand_builtin_expect (arglist, target);
6099 case BUILT_IN_PREFETCH:
6100 expand_builtin_prefetch (arglist);
6101 return const0_rtx;
6103 case BUILT_IN_PROFILE_FUNC_ENTER:
6104 return expand_builtin_profile_func (false);
6105 case BUILT_IN_PROFILE_FUNC_EXIT:
6106 return expand_builtin_profile_func (true);
6108 case BUILT_IN_INIT_TRAMPOLINE:
6109 return expand_builtin_init_trampoline (arglist);
6110 case BUILT_IN_ADJUST_TRAMPOLINE:
6111 return expand_builtin_adjust_trampoline (arglist);
6113 case BUILT_IN_FORK:
6114 case BUILT_IN_EXECL:
6115 case BUILT_IN_EXECV:
6116 case BUILT_IN_EXECLP:
6117 case BUILT_IN_EXECLE:
6118 case BUILT_IN_EXECVP:
6119 case BUILT_IN_EXECVE:
6120 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6121 if (target)
6122 return target;
6123 break;
6125 case BUILT_IN_FETCH_AND_ADD_1:
6126 case BUILT_IN_FETCH_AND_ADD_2:
6127 case BUILT_IN_FETCH_AND_ADD_4:
6128 case BUILT_IN_FETCH_AND_ADD_8:
6129 case BUILT_IN_FETCH_AND_ADD_16:
6130 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6131 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6132 false, target, ignore);
6133 if (target)
6134 return target;
6135 break;
6137 case BUILT_IN_FETCH_AND_SUB_1:
6138 case BUILT_IN_FETCH_AND_SUB_2:
6139 case BUILT_IN_FETCH_AND_SUB_4:
6140 case BUILT_IN_FETCH_AND_SUB_8:
6141 case BUILT_IN_FETCH_AND_SUB_16:
6142 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6143 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6144 false, target, ignore);
6145 if (target)
6146 return target;
6147 break;
6149 case BUILT_IN_FETCH_AND_OR_1:
6150 case BUILT_IN_FETCH_AND_OR_2:
6151 case BUILT_IN_FETCH_AND_OR_4:
6152 case BUILT_IN_FETCH_AND_OR_8:
6153 case BUILT_IN_FETCH_AND_OR_16:
6154 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6155 target = expand_builtin_sync_operation (mode, arglist, IOR,
6156 false, target, ignore);
6157 if (target)
6158 return target;
6159 break;
6161 case BUILT_IN_FETCH_AND_AND_1:
6162 case BUILT_IN_FETCH_AND_AND_2:
6163 case BUILT_IN_FETCH_AND_AND_4:
6164 case BUILT_IN_FETCH_AND_AND_8:
6165 case BUILT_IN_FETCH_AND_AND_16:
6166 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6167 target = expand_builtin_sync_operation (mode, arglist, AND,
6168 false, target, ignore);
6169 if (target)
6170 return target;
6171 break;
6173 case BUILT_IN_FETCH_AND_XOR_1:
6174 case BUILT_IN_FETCH_AND_XOR_2:
6175 case BUILT_IN_FETCH_AND_XOR_4:
6176 case BUILT_IN_FETCH_AND_XOR_8:
6177 case BUILT_IN_FETCH_AND_XOR_16:
6178 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6179 target = expand_builtin_sync_operation (mode, arglist, XOR,
6180 false, target, ignore);
6181 if (target)
6182 return target;
6183 break;
6185 case BUILT_IN_FETCH_AND_NAND_1:
6186 case BUILT_IN_FETCH_AND_NAND_2:
6187 case BUILT_IN_FETCH_AND_NAND_4:
6188 case BUILT_IN_FETCH_AND_NAND_8:
6189 case BUILT_IN_FETCH_AND_NAND_16:
6190 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6191 target = expand_builtin_sync_operation (mode, arglist, NOT,
6192 false, target, ignore);
6193 if (target)
6194 return target;
6195 break;
6197 case BUILT_IN_ADD_AND_FETCH_1:
6198 case BUILT_IN_ADD_AND_FETCH_2:
6199 case BUILT_IN_ADD_AND_FETCH_4:
6200 case BUILT_IN_ADD_AND_FETCH_8:
6201 case BUILT_IN_ADD_AND_FETCH_16:
6202 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6203 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6204 true, target, ignore);
6205 if (target)
6206 return target;
6207 break;
6209 case BUILT_IN_SUB_AND_FETCH_1:
6210 case BUILT_IN_SUB_AND_FETCH_2:
6211 case BUILT_IN_SUB_AND_FETCH_4:
6212 case BUILT_IN_SUB_AND_FETCH_8:
6213 case BUILT_IN_SUB_AND_FETCH_16:
6214 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6215 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6216 true, target, ignore);
6217 if (target)
6218 return target;
6219 break;
6221 case BUILT_IN_OR_AND_FETCH_1:
6222 case BUILT_IN_OR_AND_FETCH_2:
6223 case BUILT_IN_OR_AND_FETCH_4:
6224 case BUILT_IN_OR_AND_FETCH_8:
6225 case BUILT_IN_OR_AND_FETCH_16:
6226 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6227 target = expand_builtin_sync_operation (mode, arglist, IOR,
6228 true, target, ignore);
6229 if (target)
6230 return target;
6231 break;
6233 case BUILT_IN_AND_AND_FETCH_1:
6234 case BUILT_IN_AND_AND_FETCH_2:
6235 case BUILT_IN_AND_AND_FETCH_4:
6236 case BUILT_IN_AND_AND_FETCH_8:
6237 case BUILT_IN_AND_AND_FETCH_16:
6238 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6239 target = expand_builtin_sync_operation (mode, arglist, AND,
6240 true, target, ignore);
6241 if (target)
6242 return target;
6243 break;
6245 case BUILT_IN_XOR_AND_FETCH_1:
6246 case BUILT_IN_XOR_AND_FETCH_2:
6247 case BUILT_IN_XOR_AND_FETCH_4:
6248 case BUILT_IN_XOR_AND_FETCH_8:
6249 case BUILT_IN_XOR_AND_FETCH_16:
6250 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6251 target = expand_builtin_sync_operation (mode, arglist, XOR,
6252 true, target, ignore);
6253 if (target)
6254 return target;
6255 break;
6257 case BUILT_IN_NAND_AND_FETCH_1:
6258 case BUILT_IN_NAND_AND_FETCH_2:
6259 case BUILT_IN_NAND_AND_FETCH_4:
6260 case BUILT_IN_NAND_AND_FETCH_8:
6261 case BUILT_IN_NAND_AND_FETCH_16:
6262 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6263 target = expand_builtin_sync_operation (mode, arglist, NOT,
6264 true, target, ignore);
6265 if (target)
6266 return target;
6267 break;
6269 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6270 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6271 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6272 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6273 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6274 if (mode == VOIDmode)
6275 mode = TYPE_MODE (boolean_type_node);
6276 if (!target || !register_operand (target, mode))
6277 target = gen_reg_rtx (mode);
6279 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6280 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6281 if (target)
6282 return target;
6283 break;
6285 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6286 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6287 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6288 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6289 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6290 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6291 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6292 if (target)
6293 return target;
6294 break;
6296 case BUILT_IN_LOCK_TEST_AND_SET_1:
6297 case BUILT_IN_LOCK_TEST_AND_SET_2:
6298 case BUILT_IN_LOCK_TEST_AND_SET_4:
6299 case BUILT_IN_LOCK_TEST_AND_SET_8:
6300 case BUILT_IN_LOCK_TEST_AND_SET_16:
6301 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6302 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6303 if (target)
6304 return target;
6305 break;
6307 case BUILT_IN_LOCK_RELEASE_1:
6308 case BUILT_IN_LOCK_RELEASE_2:
6309 case BUILT_IN_LOCK_RELEASE_4:
6310 case BUILT_IN_LOCK_RELEASE_8:
6311 case BUILT_IN_LOCK_RELEASE_16:
6312 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6313 expand_builtin_lock_release (mode, arglist);
6314 return const0_rtx;
6316 case BUILT_IN_SYNCHRONIZE:
6317 expand_builtin_synchronize ();
6318 return const0_rtx;
6320 case BUILT_IN_OBJECT_SIZE:
6321 return expand_builtin_object_size (exp);
6323 case BUILT_IN_MEMCPY_CHK:
6324 case BUILT_IN_MEMPCPY_CHK:
6325 case BUILT_IN_MEMMOVE_CHK:
6326 case BUILT_IN_MEMSET_CHK:
6327 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6328 if (target)
6329 return target;
6330 break;
6332 case BUILT_IN_STRCPY_CHK:
6333 case BUILT_IN_STPCPY_CHK:
6334 case BUILT_IN_STRNCPY_CHK:
6335 case BUILT_IN_STRCAT_CHK:
6336 case BUILT_IN_SNPRINTF_CHK:
6337 case BUILT_IN_VSNPRINTF_CHK:
6338 maybe_emit_chk_warning (exp, fcode);
6339 break;
6341 case BUILT_IN_SPRINTF_CHK:
6342 case BUILT_IN_VSPRINTF_CHK:
6343 maybe_emit_sprintf_chk_warning (exp, fcode);
6344 break;
6346 default: /* just do library call, if unknown builtin */
6347 break;
6350 /* The switch statement above can drop through to cause the function
6351 to be called normally. */
6352 return expand_call (exp, target, ignore);
6355 /* Determine whether a tree node represents a call to a built-in
6356 function. If the tree T is a call to a built-in function with
6357 the right number of arguments of the appropriate types, return
6358 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6359 Otherwise the return value is END_BUILTINS. */
6361 enum built_in_function
6362 builtin_mathfn_code (tree t)
6364 tree fndecl, arglist, parmlist;
6365 tree argtype, parmtype;
6367 if (TREE_CODE (t) != CALL_EXPR
6368 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6369 return END_BUILTINS;
6371 fndecl = get_callee_fndecl (t);
6372 if (fndecl == NULL_TREE
6373 || TREE_CODE (fndecl) != FUNCTION_DECL
6374 || ! DECL_BUILT_IN (fndecl)
6375 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6376 return END_BUILTINS;
6378 arglist = TREE_OPERAND (t, 1);
6379 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6380 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6382 /* If a function doesn't take a variable number of arguments,
6383 the last element in the list will have type `void'. */
6384 parmtype = TREE_VALUE (parmlist);
6385 if (VOID_TYPE_P (parmtype))
6387 if (arglist)
6388 return END_BUILTINS;
6389 return DECL_FUNCTION_CODE (fndecl);
6392 if (! arglist)
6393 return END_BUILTINS;
6395 argtype = TREE_TYPE (TREE_VALUE (arglist));
6397 if (SCALAR_FLOAT_TYPE_P (parmtype))
6399 if (! SCALAR_FLOAT_TYPE_P (argtype))
6400 return END_BUILTINS;
6402 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6404 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6405 return END_BUILTINS;
6407 else if (POINTER_TYPE_P (parmtype))
6409 if (! POINTER_TYPE_P (argtype))
6410 return END_BUILTINS;
6412 else if (INTEGRAL_TYPE_P (parmtype))
6414 if (! INTEGRAL_TYPE_P (argtype))
6415 return END_BUILTINS;
6417 else
6418 return END_BUILTINS;
6420 arglist = TREE_CHAIN (arglist);
6423 /* Variable-length argument list. */
6424 return DECL_FUNCTION_CODE (fndecl);
6427 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6428 constant. ARGLIST is the argument list of the call. */
6430 static tree
6431 fold_builtin_constant_p (tree arglist)
6433 if (arglist == 0)
6434 return 0;
6436 arglist = TREE_VALUE (arglist);
6438 /* We return 1 for a numeric type that's known to be a constant
6439 value at compile-time or for an aggregate type that's a
6440 literal constant. */
6441 STRIP_NOPS (arglist);
6443 /* If we know this is a constant, emit the constant of one. */
6444 if (CONSTANT_CLASS_P (arglist)
6445 || (TREE_CODE (arglist) == CONSTRUCTOR
6446 && TREE_CONSTANT (arglist)))
6447 return integer_one_node;
6448 if (TREE_CODE (arglist) == ADDR_EXPR)
6450 tree op = TREE_OPERAND (arglist, 0);
6451 if (TREE_CODE (op) == STRING_CST
6452 || (TREE_CODE (op) == ARRAY_REF
6453 && integer_zerop (TREE_OPERAND (op, 1))
6454 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6455 return integer_one_node;
6458 /* If this expression has side effects, show we don't know it to be a
6459 constant. Likewise if it's a pointer or aggregate type since in
6460 those case we only want literals, since those are only optimized
6461 when generating RTL, not later.
6462 And finally, if we are compiling an initializer, not code, we
6463 need to return a definite result now; there's not going to be any
6464 more optimization done. */
6465 if (TREE_SIDE_EFFECTS (arglist)
6466 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6467 || POINTER_TYPE_P (TREE_TYPE (arglist))
6468 || cfun == 0)
6469 return integer_zero_node;
6471 return 0;
6474 /* Fold a call to __builtin_expect, if we expect that a comparison against
6475 the argument will fold to a constant. In practice, this means a true
6476 constant or the address of a non-weak symbol. ARGLIST is the argument
6477 list of the call. */
6479 static tree
6480 fold_builtin_expect (tree arglist)
6482 tree arg, inner;
6484 if (arglist == 0)
6485 return 0;
6487 arg = TREE_VALUE (arglist);
6489 /* If the argument isn't invariant, then there's nothing we can do. */
6490 if (!TREE_INVARIANT (arg))
6491 return 0;
6493 /* If we're looking at an address of a weak decl, then do not fold. */
6494 inner = arg;
6495 STRIP_NOPS (inner);
6496 if (TREE_CODE (inner) == ADDR_EXPR)
6500 inner = TREE_OPERAND (inner, 0);
6502 while (TREE_CODE (inner) == COMPONENT_REF
6503 || TREE_CODE (inner) == ARRAY_REF);
6504 if (DECL_P (inner) && DECL_WEAK (inner))
6505 return 0;
6508 /* Otherwise, ARG already has the proper type for the return value. */
6509 return arg;
6512 /* Fold a call to __builtin_classify_type. */
6514 static tree
6515 fold_builtin_classify_type (tree arglist)
6517 if (arglist == 0)
6518 return build_int_cst (NULL_TREE, no_type_class);
6520 return build_int_cst (NULL_TREE,
6521 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6524 /* Fold a call to __builtin_strlen. */
6526 static tree
6527 fold_builtin_strlen (tree arglist)
6529 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6530 return NULL_TREE;
6531 else
6533 tree len = c_strlen (TREE_VALUE (arglist), 0);
6535 if (len)
6537 /* Convert from the internal "sizetype" type to "size_t". */
6538 if (size_type_node)
6539 len = fold_convert (size_type_node, len);
6540 return len;
6543 return NULL_TREE;
6547 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6549 static tree
6550 fold_builtin_inf (tree type, int warn)
6552 REAL_VALUE_TYPE real;
6554 /* __builtin_inff is intended to be usable to define INFINITY on all
6555 targets. If an infinity is not available, INFINITY expands "to a
6556 positive constant of type float that overflows at translation
6557 time", footnote "In this case, using INFINITY will violate the
6558 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6559 Thus we pedwarn to ensure this constraint violation is
6560 diagnosed. */
6561 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6562 pedwarn ("target format does not support infinity");
6564 real_inf (&real);
6565 return build_real (type, real);
6568 /* Fold a call to __builtin_nan or __builtin_nans. */
6570 static tree
6571 fold_builtin_nan (tree arglist, tree type, int quiet)
6573 REAL_VALUE_TYPE real;
6574 const char *str;
6576 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6577 return 0;
6578 str = c_getstr (TREE_VALUE (arglist));
6579 if (!str)
6580 return 0;
6582 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6583 return 0;
6585 return build_real (type, real);
6588 /* Return true if the floating point expression T has an integer value.
6589 We also allow +Inf, -Inf and NaN to be considered integer values. */
6591 static bool
6592 integer_valued_real_p (tree t)
6594 switch (TREE_CODE (t))
6596 case FLOAT_EXPR:
6597 return true;
6599 case ABS_EXPR:
6600 case SAVE_EXPR:
6601 case NON_LVALUE_EXPR:
6602 return integer_valued_real_p (TREE_OPERAND (t, 0));
6604 case COMPOUND_EXPR:
6605 case MODIFY_EXPR:
6606 case BIND_EXPR:
6607 return integer_valued_real_p (TREE_OPERAND (t, 1));
6609 case PLUS_EXPR:
6610 case MINUS_EXPR:
6611 case MULT_EXPR:
6612 case MIN_EXPR:
6613 case MAX_EXPR:
6614 return integer_valued_real_p (TREE_OPERAND (t, 0))
6615 && integer_valued_real_p (TREE_OPERAND (t, 1));
6617 case COND_EXPR:
6618 return integer_valued_real_p (TREE_OPERAND (t, 1))
6619 && integer_valued_real_p (TREE_OPERAND (t, 2));
6621 case REAL_CST:
6622 if (! TREE_CONSTANT_OVERFLOW (t))
6624 REAL_VALUE_TYPE c, cint;
6626 c = TREE_REAL_CST (t);
6627 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6628 return real_identical (&c, &cint);
6630 break;
6632 case NOP_EXPR:
6634 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6635 if (TREE_CODE (type) == INTEGER_TYPE)
6636 return true;
6637 if (TREE_CODE (type) == REAL_TYPE)
6638 return integer_valued_real_p (TREE_OPERAND (t, 0));
6639 break;
6642 case CALL_EXPR:
6643 switch (builtin_mathfn_code (t))
6645 CASE_FLT_FN (BUILT_IN_CEIL):
6646 CASE_FLT_FN (BUILT_IN_FLOOR):
6647 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6648 CASE_FLT_FN (BUILT_IN_RINT):
6649 CASE_FLT_FN (BUILT_IN_ROUND):
6650 CASE_FLT_FN (BUILT_IN_TRUNC):
6651 return true;
6653 default:
6654 break;
6656 break;
6658 default:
6659 break;
6661 return false;
6664 /* EXP is assumed to be builtin call where truncation can be propagated
6665 across (for instance floor((double)f) == (double)floorf (f).
6666 Do the transformation. */
6668 static tree
6669 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6671 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6672 tree arg;
6674 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6675 return 0;
6677 arg = TREE_VALUE (arglist);
6678 /* Integer rounding functions are idempotent. */
6679 if (fcode == builtin_mathfn_code (arg))
6680 return arg;
6682 /* If argument is already integer valued, and we don't need to worry
6683 about setting errno, there's no need to perform rounding. */
6684 if (! flag_errno_math && integer_valued_real_p (arg))
6685 return arg;
6687 if (optimize)
6689 tree arg0 = strip_float_extensions (arg);
6690 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6691 tree newtype = TREE_TYPE (arg0);
6692 tree decl;
6694 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6695 && (decl = mathfn_built_in (newtype, fcode)))
6697 arglist =
6698 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6699 return fold_convert (ftype,
6700 build_function_call_expr (decl, arglist));
6703 return 0;
6706 /* EXP is assumed to be builtin call which can narrow the FP type of
6707 the argument, for instance lround((double)f) -> lroundf (f). */
6709 static tree
6710 fold_fixed_mathfn (tree fndecl, tree arglist)
6712 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6713 tree arg;
6715 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6716 return 0;
6718 arg = TREE_VALUE (arglist);
6720 /* If argument is already integer valued, and we don't need to worry
6721 about setting errno, there's no need to perform rounding. */
6722 if (! flag_errno_math && integer_valued_real_p (arg))
6723 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6725 if (optimize)
6727 tree ftype = TREE_TYPE (arg);
6728 tree arg0 = strip_float_extensions (arg);
6729 tree newtype = TREE_TYPE (arg0);
6730 tree decl;
6732 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6733 && (decl = mathfn_built_in (newtype, fcode)))
6735 arglist =
6736 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6737 return build_function_call_expr (decl, arglist);
6740 return 0;
6743 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6744 is the argument list and TYPE is the return type. Return
6745 NULL_TREE if no if no simplification can be made. */
6747 static tree
6748 fold_builtin_cabs (tree arglist, tree type)
6750 tree arg;
6752 if (!arglist || TREE_CHAIN (arglist))
6753 return NULL_TREE;
6755 arg = TREE_VALUE (arglist);
6756 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6757 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6758 return NULL_TREE;
6760 /* Evaluate cabs of a constant at compile-time. */
6761 if (flag_unsafe_math_optimizations
6762 && TREE_CODE (arg) == COMPLEX_CST
6763 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6764 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6765 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6766 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6768 REAL_VALUE_TYPE r, i;
6770 r = TREE_REAL_CST (TREE_REALPART (arg));
6771 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6773 real_arithmetic (&r, MULT_EXPR, &r, &r);
6774 real_arithmetic (&i, MULT_EXPR, &i, &i);
6775 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6776 if (real_sqrt (&r, TYPE_MODE (type), &r)
6777 || ! flag_trapping_math)
6778 return build_real (type, r);
6781 /* If either part is zero, cabs is fabs of the other. */
6782 if (TREE_CODE (arg) == COMPLEX_EXPR
6783 && real_zerop (TREE_OPERAND (arg, 0)))
6784 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6785 if (TREE_CODE (arg) == COMPLEX_EXPR
6786 && real_zerop (TREE_OPERAND (arg, 1)))
6787 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6789 /* Don't do this when optimizing for size. */
6790 if (flag_unsafe_math_optimizations
6791 && optimize && !optimize_size)
6793 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6795 if (sqrtfn != NULL_TREE)
6797 tree rpart, ipart, result, arglist;
6799 arg = builtin_save_expr (arg);
6801 rpart = fold_build1 (REALPART_EXPR, type, arg);
6802 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6804 rpart = builtin_save_expr (rpart);
6805 ipart = builtin_save_expr (ipart);
6807 result = fold_build2 (PLUS_EXPR, type,
6808 fold_build2 (MULT_EXPR, type,
6809 rpart, rpart),
6810 fold_build2 (MULT_EXPR, type,
6811 ipart, ipart));
6813 arglist = build_tree_list (NULL_TREE, result);
6814 return build_function_call_expr (sqrtfn, arglist);
6818 return NULL_TREE;
6821 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6822 NULL_TREE if no simplification can be made. */
6824 static tree
6825 fold_builtin_sqrt (tree arglist, tree type)
6828 enum built_in_function fcode;
6829 tree arg = TREE_VALUE (arglist);
6831 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6832 return NULL_TREE;
6834 /* Optimize sqrt of constant value. */
6835 if (TREE_CODE (arg) == REAL_CST
6836 && ! TREE_CONSTANT_OVERFLOW (arg))
6838 REAL_VALUE_TYPE r, x;
6840 x = TREE_REAL_CST (arg);
6841 if (real_sqrt (&r, TYPE_MODE (type), &x)
6842 || (!flag_trapping_math && !flag_errno_math))
6843 return build_real (type, r);
6846 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6847 fcode = builtin_mathfn_code (arg);
6848 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6850 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6851 arg = fold_build2 (MULT_EXPR, type,
6852 TREE_VALUE (TREE_OPERAND (arg, 1)),
6853 build_real (type, dconsthalf));
6854 arglist = build_tree_list (NULL_TREE, arg);
6855 return build_function_call_expr (expfn, arglist);
6858 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6859 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6861 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6863 if (powfn)
6865 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6866 tree tree_root;
6867 /* The inner root was either sqrt or cbrt. */
6868 REAL_VALUE_TYPE dconstroot =
6869 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6871 /* Adjust for the outer root. */
6872 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6873 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6874 tree_root = build_real (type, dconstroot);
6875 arglist = tree_cons (NULL_TREE, arg0,
6876 build_tree_list (NULL_TREE, tree_root));
6877 return build_function_call_expr (powfn, arglist);
6881 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6882 if (flag_unsafe_math_optimizations
6883 && (fcode == BUILT_IN_POW
6884 || fcode == BUILT_IN_POWF
6885 || fcode == BUILT_IN_POWL))
6887 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6888 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6889 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6890 tree narg1;
6891 if (!tree_expr_nonnegative_p (arg0))
6892 arg0 = build1 (ABS_EXPR, type, arg0);
6893 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6894 build_real (type, dconsthalf));
6895 arglist = tree_cons (NULL_TREE, arg0,
6896 build_tree_list (NULL_TREE, narg1));
6897 return build_function_call_expr (powfn, arglist);
6900 return NULL_TREE;
6903 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6904 NULL_TREE if no simplification can be made. */
6905 static tree
6906 fold_builtin_cbrt (tree arglist, tree type)
6908 tree arg = TREE_VALUE (arglist);
6909 const enum built_in_function fcode = builtin_mathfn_code (arg);
6911 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6912 return NULL_TREE;
6914 /* Optimize cbrt of constant value. */
6915 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6916 return arg;
6918 if (flag_unsafe_math_optimizations)
6920 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6921 if (BUILTIN_EXPONENT_P (fcode))
6923 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6924 const REAL_VALUE_TYPE third_trunc =
6925 real_value_truncate (TYPE_MODE (type), dconstthird);
6926 arg = fold_build2 (MULT_EXPR, type,
6927 TREE_VALUE (TREE_OPERAND (arg, 1)),
6928 build_real (type, third_trunc));
6929 arglist = build_tree_list (NULL_TREE, arg);
6930 return build_function_call_expr (expfn, arglist);
6933 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6934 if (BUILTIN_SQRT_P (fcode))
6936 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6938 if (powfn)
6940 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6941 tree tree_root;
6942 REAL_VALUE_TYPE dconstroot = dconstthird;
6944 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6945 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6946 tree_root = build_real (type, dconstroot);
6947 arglist = tree_cons (NULL_TREE, arg0,
6948 build_tree_list (NULL_TREE, tree_root));
6949 return build_function_call_expr (powfn, arglist);
6953 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6954 if (BUILTIN_CBRT_P (fcode))
6956 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6957 if (tree_expr_nonnegative_p (arg0))
6959 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6961 if (powfn)
6963 tree tree_root;
6964 REAL_VALUE_TYPE dconstroot;
6966 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6967 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6968 tree_root = build_real (type, dconstroot);
6969 arglist = tree_cons (NULL_TREE, arg0,
6970 build_tree_list (NULL_TREE, tree_root));
6971 return build_function_call_expr (powfn, arglist);
6976 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6977 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6978 || fcode == BUILT_IN_POWL)
6980 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6981 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6982 if (tree_expr_nonnegative_p (arg00))
6984 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6985 const REAL_VALUE_TYPE dconstroot
6986 = real_value_truncate (TYPE_MODE (type), dconstthird);
6987 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6988 build_real (type, dconstroot));
6989 arglist = tree_cons (NULL_TREE, arg00,
6990 build_tree_list (NULL_TREE, narg01));
6991 return build_function_call_expr (powfn, arglist);
6995 return NULL_TREE;
6998 /* Fold function call to builtin sin, sinf, or sinl. Return
6999 NULL_TREE if no simplification can be made. */
7000 static tree
7001 fold_builtin_sin (tree arglist)
7003 tree arg = TREE_VALUE (arglist);
7005 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7006 return NULL_TREE;
7008 /* Optimize sin (0.0) = 0.0. */
7009 if (real_zerop (arg))
7010 return arg;
7012 return NULL_TREE;
7015 /* Fold function call to builtin cos, cosf, or cosl. Return
7016 NULL_TREE if no simplification can be made. */
7017 static tree
7018 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7020 tree arg = TREE_VALUE (arglist);
7022 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7023 return NULL_TREE;
7025 /* Optimize cos (0.0) = 1.0. */
7026 if (real_zerop (arg))
7027 return build_real (type, dconst1);
7029 /* Optimize cos(-x) into cos (x). */
7030 if (TREE_CODE (arg) == NEGATE_EXPR)
7032 tree args = build_tree_list (NULL_TREE,
7033 TREE_OPERAND (arg, 0));
7034 return build_function_call_expr (fndecl, args);
7037 return NULL_TREE;
7040 /* Fold function call to builtin tan, tanf, or tanl. Return
7041 NULL_TREE if no simplification can be made. */
7042 static tree
7043 fold_builtin_tan (tree arglist)
7045 enum built_in_function fcode;
7046 tree arg = TREE_VALUE (arglist);
7048 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7049 return NULL_TREE;
7051 /* Optimize tan(0.0) = 0.0. */
7052 if (real_zerop (arg))
7053 return arg;
7055 /* Optimize tan(atan(x)) = x. */
7056 fcode = builtin_mathfn_code (arg);
7057 if (flag_unsafe_math_optimizations
7058 && (fcode == BUILT_IN_ATAN
7059 || fcode == BUILT_IN_ATANF
7060 || fcode == BUILT_IN_ATANL))
7061 return TREE_VALUE (TREE_OPERAND (arg, 1));
7063 return NULL_TREE;
7066 /* Fold function call to builtin atan, atanf, or atanl. Return
7067 NULL_TREE if no simplification can be made. */
7069 static tree
7070 fold_builtin_atan (tree arglist, tree type)
7073 tree arg = TREE_VALUE (arglist);
7075 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7076 return NULL_TREE;
7078 /* Optimize atan(0.0) = 0.0. */
7079 if (real_zerop (arg))
7080 return arg;
7082 /* Optimize atan(1.0) = pi/4. */
7083 if (real_onep (arg))
7085 REAL_VALUE_TYPE cst;
7087 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7088 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7089 return build_real (type, cst);
7092 return NULL_TREE;
7095 /* Fold function call to builtin trunc, truncf or truncl. Return
7096 NULL_TREE if no simplification can be made. */
7098 static tree
7099 fold_builtin_trunc (tree fndecl, tree arglist)
7101 tree arg;
7103 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7104 return 0;
7106 /* Optimize trunc of constant value. */
7107 arg = TREE_VALUE (arglist);
7108 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7110 REAL_VALUE_TYPE r, x;
7111 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7113 x = TREE_REAL_CST (arg);
7114 real_trunc (&r, TYPE_MODE (type), &x);
7115 return build_real (type, r);
7118 return fold_trunc_transparent_mathfn (fndecl, arglist);
7121 /* Fold function call to builtin floor, floorf or floorl. Return
7122 NULL_TREE if no simplification can be made. */
7124 static tree
7125 fold_builtin_floor (tree fndecl, tree arglist)
7127 tree arg;
7129 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7130 return 0;
7132 /* Optimize floor of constant value. */
7133 arg = TREE_VALUE (arglist);
7134 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7136 REAL_VALUE_TYPE x;
7138 x = TREE_REAL_CST (arg);
7139 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7141 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7142 REAL_VALUE_TYPE r;
7144 real_floor (&r, TYPE_MODE (type), &x);
7145 return build_real (type, r);
7149 return fold_trunc_transparent_mathfn (fndecl, arglist);
7152 /* Fold function call to builtin ceil, ceilf or ceill. Return
7153 NULL_TREE if no simplification can be made. */
7155 static tree
7156 fold_builtin_ceil (tree fndecl, tree arglist)
7158 tree arg;
7160 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7161 return 0;
7163 /* Optimize ceil of constant value. */
7164 arg = TREE_VALUE (arglist);
7165 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7167 REAL_VALUE_TYPE x;
7169 x = TREE_REAL_CST (arg);
7170 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7172 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7173 REAL_VALUE_TYPE r;
7175 real_ceil (&r, TYPE_MODE (type), &x);
7176 return build_real (type, r);
7180 return fold_trunc_transparent_mathfn (fndecl, arglist);
7183 /* Fold function call to builtin round, roundf or roundl. Return
7184 NULL_TREE if no simplification can be made. */
7186 static tree
7187 fold_builtin_round (tree fndecl, tree arglist)
7189 tree arg;
7191 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7192 return 0;
7194 /* Optimize round of constant value. */
7195 arg = TREE_VALUE (arglist);
7196 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7198 REAL_VALUE_TYPE x;
7200 x = TREE_REAL_CST (arg);
7201 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7203 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7204 REAL_VALUE_TYPE r;
7206 real_round (&r, TYPE_MODE (type), &x);
7207 return build_real (type, r);
7211 return fold_trunc_transparent_mathfn (fndecl, arglist);
7214 /* Fold function call to builtin lround, lroundf or lroundl (or the
7215 corresponding long long versions) and other rounding functions.
7216 Return NULL_TREE if no simplification can be made. */
7218 static tree
7219 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7221 tree arg;
7223 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7224 return 0;
7226 /* Optimize lround of constant value. */
7227 arg = TREE_VALUE (arglist);
7228 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7230 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7232 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7234 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7235 tree ftype = TREE_TYPE (arg), result;
7236 HOST_WIDE_INT hi, lo;
7237 REAL_VALUE_TYPE r;
7239 switch (DECL_FUNCTION_CODE (fndecl))
7241 CASE_FLT_FN (BUILT_IN_LFLOOR):
7242 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7243 real_floor (&r, TYPE_MODE (ftype), &x);
7244 break;
7246 CASE_FLT_FN (BUILT_IN_LCEIL):
7247 CASE_FLT_FN (BUILT_IN_LLCEIL):
7248 real_ceil (&r, TYPE_MODE (ftype), &x);
7249 break;
7251 CASE_FLT_FN (BUILT_IN_LROUND):
7252 CASE_FLT_FN (BUILT_IN_LLROUND):
7253 real_round (&r, TYPE_MODE (ftype), &x);
7254 break;
7256 default:
7257 gcc_unreachable ();
7260 REAL_VALUE_TO_INT (&lo, &hi, r);
7261 result = build_int_cst_wide (NULL_TREE, lo, hi);
7262 if (int_fits_type_p (result, itype))
7263 return fold_convert (itype, result);
7267 return fold_fixed_mathfn (fndecl, arglist);
7270 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7271 and their long and long long variants (i.e. ffsl and ffsll).
7272 Return NULL_TREE if no simplification can be made. */
7274 static tree
7275 fold_builtin_bitop (tree fndecl, tree arglist)
7277 tree arg;
7279 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7280 return NULL_TREE;
7282 /* Optimize for constant argument. */
7283 arg = TREE_VALUE (arglist);
7284 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7286 HOST_WIDE_INT hi, width, result;
7287 unsigned HOST_WIDE_INT lo;
7288 tree type;
7290 type = TREE_TYPE (arg);
7291 width = TYPE_PRECISION (type);
7292 lo = TREE_INT_CST_LOW (arg);
7294 /* Clear all the bits that are beyond the type's precision. */
7295 if (width > HOST_BITS_PER_WIDE_INT)
7297 hi = TREE_INT_CST_HIGH (arg);
7298 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7299 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7301 else
7303 hi = 0;
7304 if (width < HOST_BITS_PER_WIDE_INT)
7305 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7308 switch (DECL_FUNCTION_CODE (fndecl))
7310 CASE_INT_FN (BUILT_IN_FFS):
7311 if (lo != 0)
7312 result = exact_log2 (lo & -lo) + 1;
7313 else if (hi != 0)
7314 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7315 else
7316 result = 0;
7317 break;
7319 CASE_INT_FN (BUILT_IN_CLZ):
7320 if (hi != 0)
7321 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7322 else if (lo != 0)
7323 result = width - floor_log2 (lo) - 1;
7324 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7325 result = width;
7326 break;
7328 CASE_INT_FN (BUILT_IN_CTZ):
7329 if (lo != 0)
7330 result = exact_log2 (lo & -lo);
7331 else if (hi != 0)
7332 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7333 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7334 result = width;
7335 break;
7337 CASE_INT_FN (BUILT_IN_POPCOUNT):
7338 result = 0;
7339 while (lo)
7340 result++, lo &= lo - 1;
7341 while (hi)
7342 result++, hi &= hi - 1;
7343 break;
7345 CASE_INT_FN (BUILT_IN_PARITY):
7346 result = 0;
7347 while (lo)
7348 result++, lo &= lo - 1;
7349 while (hi)
7350 result++, hi &= hi - 1;
7351 result &= 1;
7352 break;
7354 default:
7355 gcc_unreachable ();
7358 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7361 return NULL_TREE;
7364 /* Return true if EXPR is the real constant contained in VALUE. */
7366 static bool
7367 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7369 STRIP_NOPS (expr);
7371 return ((TREE_CODE (expr) == REAL_CST
7372 && ! TREE_CONSTANT_OVERFLOW (expr)
7373 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7374 || (TREE_CODE (expr) == COMPLEX_CST
7375 && real_dconstp (TREE_REALPART (expr), value)
7376 && real_zerop (TREE_IMAGPART (expr))));
7379 /* A subroutine of fold_builtin to fold the various logarithmic
7380 functions. EXP is the CALL_EXPR of a call to a builtin logN
7381 function. VALUE is the base of the logN function. */
7383 static tree
7384 fold_builtin_logarithm (tree fndecl, tree arglist,
7385 const REAL_VALUE_TYPE *value)
7387 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7389 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7390 tree arg = TREE_VALUE (arglist);
7391 const enum built_in_function fcode = builtin_mathfn_code (arg);
7393 /* Optimize logN(1.0) = 0.0. */
7394 if (real_onep (arg))
7395 return build_real (type, dconst0);
7397 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7398 exactly, then only do this if flag_unsafe_math_optimizations. */
7399 if (exact_real_truncate (TYPE_MODE (type), value)
7400 || flag_unsafe_math_optimizations)
7402 const REAL_VALUE_TYPE value_truncate =
7403 real_value_truncate (TYPE_MODE (type), *value);
7404 if (real_dconstp (arg, &value_truncate))
7405 return build_real (type, dconst1);
7408 /* Special case, optimize logN(expN(x)) = x. */
7409 if (flag_unsafe_math_optimizations
7410 && ((value == &dconste
7411 && (fcode == BUILT_IN_EXP
7412 || fcode == BUILT_IN_EXPF
7413 || fcode == BUILT_IN_EXPL))
7414 || (value == &dconst2
7415 && (fcode == BUILT_IN_EXP2
7416 || fcode == BUILT_IN_EXP2F
7417 || fcode == BUILT_IN_EXP2L))
7418 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7419 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7421 /* Optimize logN(func()) for various exponential functions. We
7422 want to determine the value "x" and the power "exponent" in
7423 order to transform logN(x**exponent) into exponent*logN(x). */
7424 if (flag_unsafe_math_optimizations)
7426 tree exponent = 0, x = 0;
7428 switch (fcode)
7430 CASE_FLT_FN (BUILT_IN_EXP):
7431 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7432 x = build_real (type,
7433 real_value_truncate (TYPE_MODE (type), dconste));
7434 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7435 break;
7436 CASE_FLT_FN (BUILT_IN_EXP2):
7437 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7438 x = build_real (type, dconst2);
7439 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7440 break;
7441 CASE_FLT_FN (BUILT_IN_EXP10):
7442 CASE_FLT_FN (BUILT_IN_POW10):
7443 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7444 x = build_real (type, dconst10);
7445 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7446 break;
7447 CASE_FLT_FN (BUILT_IN_SQRT):
7448 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7449 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7450 exponent = build_real (type, dconsthalf);
7451 break;
7452 CASE_FLT_FN (BUILT_IN_CBRT):
7453 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7454 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7455 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7456 dconstthird));
7457 break;
7458 CASE_FLT_FN (BUILT_IN_POW):
7459 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7460 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7461 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7462 break;
7463 default:
7464 break;
7467 /* Now perform the optimization. */
7468 if (x && exponent)
7470 tree logfn;
7471 arglist = build_tree_list (NULL_TREE, x);
7472 logfn = build_function_call_expr (fndecl, arglist);
7473 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7478 return 0;
7481 /* Fold a builtin function call to pow, powf, or powl. Return
7482 NULL_TREE if no simplification can be made. */
7483 static tree
7484 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7486 tree arg0 = TREE_VALUE (arglist);
7487 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7489 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7490 return NULL_TREE;
7492 /* Optimize pow(1.0,y) = 1.0. */
7493 if (real_onep (arg0))
7494 return omit_one_operand (type, build_real (type, dconst1), arg1);
7496 if (TREE_CODE (arg1) == REAL_CST
7497 && ! TREE_CONSTANT_OVERFLOW (arg1))
7499 REAL_VALUE_TYPE cint;
7500 REAL_VALUE_TYPE c;
7501 HOST_WIDE_INT n;
7503 c = TREE_REAL_CST (arg1);
7505 /* Optimize pow(x,0.0) = 1.0. */
7506 if (REAL_VALUES_EQUAL (c, dconst0))
7507 return omit_one_operand (type, build_real (type, dconst1),
7508 arg0);
7510 /* Optimize pow(x,1.0) = x. */
7511 if (REAL_VALUES_EQUAL (c, dconst1))
7512 return arg0;
7514 /* Optimize pow(x,-1.0) = 1.0/x. */
7515 if (REAL_VALUES_EQUAL (c, dconstm1))
7516 return fold_build2 (RDIV_EXPR, type,
7517 build_real (type, dconst1), arg0);
7519 /* Optimize pow(x,0.5) = sqrt(x). */
7520 if (flag_unsafe_math_optimizations
7521 && REAL_VALUES_EQUAL (c, dconsthalf))
7523 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7525 if (sqrtfn != NULL_TREE)
7527 tree arglist = build_tree_list (NULL_TREE, arg0);
7528 return build_function_call_expr (sqrtfn, arglist);
7532 /* Check for an integer exponent. */
7533 n = real_to_integer (&c);
7534 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7535 if (real_identical (&c, &cint))
7537 /* Attempt to evaluate pow at compile-time. */
7538 if (TREE_CODE (arg0) == REAL_CST
7539 && ! TREE_CONSTANT_OVERFLOW (arg0))
7541 REAL_VALUE_TYPE x;
7542 bool inexact;
7544 x = TREE_REAL_CST (arg0);
7545 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7546 if (flag_unsafe_math_optimizations || !inexact)
7547 return build_real (type, x);
7550 /* Strip sign ops from even integer powers. */
7551 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7553 tree narg0 = fold_strip_sign_ops (arg0);
7554 if (narg0)
7556 arglist = build_tree_list (NULL_TREE, arg1);
7557 arglist = tree_cons (NULL_TREE, narg0, arglist);
7558 return build_function_call_expr (fndecl, arglist);
7564 if (flag_unsafe_math_optimizations)
7566 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7568 /* Optimize pow(expN(x),y) = expN(x*y). */
7569 if (BUILTIN_EXPONENT_P (fcode))
7571 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7572 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7573 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7574 arglist = build_tree_list (NULL_TREE, arg);
7575 return build_function_call_expr (expfn, arglist);
7578 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7579 if (BUILTIN_SQRT_P (fcode))
7581 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7582 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7583 build_real (type, dconsthalf));
7585 arglist = tree_cons (NULL_TREE, narg0,
7586 build_tree_list (NULL_TREE, narg1));
7587 return build_function_call_expr (fndecl, arglist);
7590 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7591 if (BUILTIN_CBRT_P (fcode))
7593 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7594 if (tree_expr_nonnegative_p (arg))
7596 const REAL_VALUE_TYPE dconstroot
7597 = real_value_truncate (TYPE_MODE (type), dconstthird);
7598 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7599 build_real (type, dconstroot));
7600 arglist = tree_cons (NULL_TREE, arg,
7601 build_tree_list (NULL_TREE, narg1));
7602 return build_function_call_expr (fndecl, arglist);
7606 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7607 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7608 || fcode == BUILT_IN_POWL)
7610 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7611 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7612 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7613 arglist = tree_cons (NULL_TREE, arg00,
7614 build_tree_list (NULL_TREE, narg1));
7615 return build_function_call_expr (fndecl, arglist);
7619 return NULL_TREE;
7622 /* Fold a builtin function call to powi, powif, or powil. Return
7623 NULL_TREE if no simplification can be made. */
7624 static tree
7625 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7627 tree arg0 = TREE_VALUE (arglist);
7628 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7630 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7631 return NULL_TREE;
7633 /* Optimize pow(1.0,y) = 1.0. */
7634 if (real_onep (arg0))
7635 return omit_one_operand (type, build_real (type, dconst1), arg1);
7637 if (host_integerp (arg1, 0))
7639 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7641 /* Evaluate powi at compile-time. */
7642 if (TREE_CODE (arg0) == REAL_CST
7643 && ! TREE_CONSTANT_OVERFLOW (arg0))
7645 REAL_VALUE_TYPE x;
7646 x = TREE_REAL_CST (arg0);
7647 real_powi (&x, TYPE_MODE (type), &x, c);
7648 return build_real (type, x);
7651 /* Optimize pow(x,0) = 1.0. */
7652 if (c == 0)
7653 return omit_one_operand (type, build_real (type, dconst1),
7654 arg0);
7656 /* Optimize pow(x,1) = x. */
7657 if (c == 1)
7658 return arg0;
7660 /* Optimize pow(x,-1) = 1.0/x. */
7661 if (c == -1)
7662 return fold_build2 (RDIV_EXPR, type,
7663 build_real (type, dconst1), arg0);
7666 return NULL_TREE;
7669 /* A subroutine of fold_builtin to fold the various exponent
7670 functions. EXP is the CALL_EXPR of a call to a builtin function.
7671 VALUE is the value which will be raised to a power. */
7673 static tree
7674 fold_builtin_exponent (tree fndecl, tree arglist,
7675 const REAL_VALUE_TYPE *value)
7677 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7679 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7680 tree arg = TREE_VALUE (arglist);
7682 /* Optimize exp*(0.0) = 1.0. */
7683 if (real_zerop (arg))
7684 return build_real (type, dconst1);
7686 /* Optimize expN(1.0) = N. */
7687 if (real_onep (arg))
7689 REAL_VALUE_TYPE cst;
7691 real_convert (&cst, TYPE_MODE (type), value);
7692 return build_real (type, cst);
7695 /* Attempt to evaluate expN(integer) at compile-time. */
7696 if (flag_unsafe_math_optimizations
7697 && TREE_CODE (arg) == REAL_CST
7698 && ! TREE_CONSTANT_OVERFLOW (arg))
7700 REAL_VALUE_TYPE cint;
7701 REAL_VALUE_TYPE c;
7702 HOST_WIDE_INT n;
7704 c = TREE_REAL_CST (arg);
7705 n = real_to_integer (&c);
7706 real_from_integer (&cint, VOIDmode, n,
7707 n < 0 ? -1 : 0, 0);
7708 if (real_identical (&c, &cint))
7710 REAL_VALUE_TYPE x;
7712 real_powi (&x, TYPE_MODE (type), value, n);
7713 return build_real (type, x);
7717 /* Optimize expN(logN(x)) = x. */
7718 if (flag_unsafe_math_optimizations)
7720 const enum built_in_function fcode = builtin_mathfn_code (arg);
7722 if ((value == &dconste
7723 && (fcode == BUILT_IN_LOG
7724 || fcode == BUILT_IN_LOGF
7725 || fcode == BUILT_IN_LOGL))
7726 || (value == &dconst2
7727 && (fcode == BUILT_IN_LOG2
7728 || fcode == BUILT_IN_LOG2F
7729 || fcode == BUILT_IN_LOG2L))
7730 || (value == &dconst10
7731 && (fcode == BUILT_IN_LOG10
7732 || fcode == BUILT_IN_LOG10F
7733 || fcode == BUILT_IN_LOG10L)))
7734 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7738 return 0;
7741 /* Fold function call to builtin memcpy. Return
7742 NULL_TREE if no simplification can be made. */
7744 static tree
7745 fold_builtin_memcpy (tree fndecl, tree arglist)
7747 tree dest, src, len;
7749 if (!validate_arglist (arglist,
7750 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7751 return 0;
7753 dest = TREE_VALUE (arglist);
7754 src = TREE_VALUE (TREE_CHAIN (arglist));
7755 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7757 /* If the LEN parameter is zero, return DEST. */
7758 if (integer_zerop (len))
7759 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7761 /* If SRC and DEST are the same (and not volatile), return DEST. */
7762 if (operand_equal_p (src, dest, 0))
7763 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7765 return 0;
7768 /* Fold function call to builtin mempcpy. Return
7769 NULL_TREE if no simplification can be made. */
7771 static tree
7772 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7774 if (validate_arglist (arglist,
7775 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7777 tree dest = TREE_VALUE (arglist);
7778 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7779 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7781 /* If the LEN parameter is zero, return DEST. */
7782 if (integer_zerop (len))
7783 return omit_one_operand (type, dest, src);
7785 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7786 if (operand_equal_p (src, dest, 0))
7788 if (endp == 0)
7789 return omit_one_operand (type, dest, len);
7791 if (endp == 2)
7792 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7793 ssize_int (1));
7795 len = fold_convert (TREE_TYPE (dest), len);
7796 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7797 return fold_convert (type, len);
7800 return 0;
7803 /* Fold function call to builtin memmove. Return
7804 NULL_TREE if no simplification can be made. */
7806 static tree
7807 fold_builtin_memmove (tree arglist, tree type)
7809 tree dest, src, len;
7811 if (!validate_arglist (arglist,
7812 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7813 return 0;
7815 dest = TREE_VALUE (arglist);
7816 src = TREE_VALUE (TREE_CHAIN (arglist));
7817 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7819 /* If the LEN parameter is zero, return DEST. */
7820 if (integer_zerop (len))
7821 return omit_one_operand (type, dest, src);
7823 /* If SRC and DEST are the same (and not volatile), return DEST. */
7824 if (operand_equal_p (src, dest, 0))
7825 return omit_one_operand (type, dest, len);
7827 return 0;
7830 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7831 the length of the string to be copied. Return NULL_TREE if no
7832 simplification can be made. */
7834 tree
7835 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7837 tree dest, src, fn;
7839 if (!validate_arglist (arglist,
7840 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7841 return 0;
7843 dest = TREE_VALUE (arglist);
7844 src = TREE_VALUE (TREE_CHAIN (arglist));
7846 /* If SRC and DEST are the same (and not volatile), return DEST. */
7847 if (operand_equal_p (src, dest, 0))
7848 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7850 if (optimize_size)
7851 return 0;
7853 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7854 if (!fn)
7855 return 0;
7857 if (!len)
7859 len = c_strlen (src, 1);
7860 if (! len || TREE_SIDE_EFFECTS (len))
7861 return 0;
7864 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7865 arglist = build_tree_list (NULL_TREE, len);
7866 arglist = tree_cons (NULL_TREE, src, arglist);
7867 arglist = tree_cons (NULL_TREE, dest, arglist);
7868 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7869 build_function_call_expr (fn, arglist));
7872 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7873 the length of the source string. Return NULL_TREE if no simplification
7874 can be made. */
7876 tree
7877 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7879 tree dest, src, len, fn;
7881 if (!validate_arglist (arglist,
7882 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7883 return 0;
7885 dest = TREE_VALUE (arglist);
7886 src = TREE_VALUE (TREE_CHAIN (arglist));
7887 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7889 /* If the LEN parameter is zero, return DEST. */
7890 if (integer_zerop (len))
7891 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7893 /* We can't compare slen with len as constants below if len is not a
7894 constant. */
7895 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7896 return 0;
7898 if (!slen)
7899 slen = c_strlen (src, 1);
7901 /* Now, we must be passed a constant src ptr parameter. */
7902 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7903 return 0;
7905 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7907 /* We do not support simplification of this case, though we do
7908 support it when expanding trees into RTL. */
7909 /* FIXME: generate a call to __builtin_memset. */
7910 if (tree_int_cst_lt (slen, len))
7911 return 0;
7913 /* OK transform into builtin memcpy. */
7914 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7915 if (!fn)
7916 return 0;
7917 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7918 build_function_call_expr (fn, arglist));
7921 /* Fold function call to builtin memcmp. Return
7922 NULL_TREE if no simplification can be made. */
7924 static tree
7925 fold_builtin_memcmp (tree arglist)
7927 tree arg1, arg2, len;
7928 const char *p1, *p2;
7930 if (!validate_arglist (arglist,
7931 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7932 return 0;
7934 arg1 = TREE_VALUE (arglist);
7935 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7936 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7938 /* If the LEN parameter is zero, return zero. */
7939 if (integer_zerop (len))
7940 return omit_two_operands (integer_type_node, integer_zero_node,
7941 arg1, arg2);
7943 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7944 if (operand_equal_p (arg1, arg2, 0))
7945 return omit_one_operand (integer_type_node, integer_zero_node, len);
7947 p1 = c_getstr (arg1);
7948 p2 = c_getstr (arg2);
7950 /* If all arguments are constant, and the value of len is not greater
7951 than the lengths of arg1 and arg2, evaluate at compile-time. */
7952 if (host_integerp (len, 1) && p1 && p2
7953 && compare_tree_int (len, strlen (p1) + 1) <= 0
7954 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7956 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7958 if (r > 0)
7959 return integer_one_node;
7960 else if (r < 0)
7961 return integer_minus_one_node;
7962 else
7963 return integer_zero_node;
7966 /* If len parameter is one, return an expression corresponding to
7967 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7968 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7970 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7971 tree cst_uchar_ptr_node
7972 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7974 tree ind1 = fold_convert (integer_type_node,
7975 build1 (INDIRECT_REF, cst_uchar_node,
7976 fold_convert (cst_uchar_ptr_node,
7977 arg1)));
7978 tree ind2 = fold_convert (integer_type_node,
7979 build1 (INDIRECT_REF, cst_uchar_node,
7980 fold_convert (cst_uchar_ptr_node,
7981 arg2)));
7982 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7985 return 0;
7988 /* Fold function call to builtin strcmp. Return
7989 NULL_TREE if no simplification can be made. */
7991 static tree
7992 fold_builtin_strcmp (tree arglist)
7994 tree arg1, arg2;
7995 const char *p1, *p2;
7997 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7998 return 0;
8000 arg1 = TREE_VALUE (arglist);
8001 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8003 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8004 if (operand_equal_p (arg1, arg2, 0))
8005 return integer_zero_node;
8007 p1 = c_getstr (arg1);
8008 p2 = c_getstr (arg2);
8010 if (p1 && p2)
8012 const int i = strcmp (p1, p2);
8013 if (i < 0)
8014 return integer_minus_one_node;
8015 else if (i > 0)
8016 return integer_one_node;
8017 else
8018 return integer_zero_node;
8021 /* If the second arg is "", return *(const unsigned char*)arg1. */
8022 if (p2 && *p2 == '\0')
8024 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8025 tree cst_uchar_ptr_node
8026 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8028 return fold_convert (integer_type_node,
8029 build1 (INDIRECT_REF, cst_uchar_node,
8030 fold_convert (cst_uchar_ptr_node,
8031 arg1)));
8034 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8035 if (p1 && *p1 == '\0')
8037 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8038 tree cst_uchar_ptr_node
8039 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8041 tree temp = fold_convert (integer_type_node,
8042 build1 (INDIRECT_REF, cst_uchar_node,
8043 fold_convert (cst_uchar_ptr_node,
8044 arg2)));
8045 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8048 return 0;
8051 /* Fold function call to builtin strncmp. Return
8052 NULL_TREE if no simplification can be made. */
8054 static tree
8055 fold_builtin_strncmp (tree arglist)
8057 tree arg1, arg2, len;
8058 const char *p1, *p2;
8060 if (!validate_arglist (arglist,
8061 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8062 return 0;
8064 arg1 = TREE_VALUE (arglist);
8065 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8066 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8068 /* If the LEN parameter is zero, return zero. */
8069 if (integer_zerop (len))
8070 return omit_two_operands (integer_type_node, integer_zero_node,
8071 arg1, arg2);
8073 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8074 if (operand_equal_p (arg1, arg2, 0))
8075 return omit_one_operand (integer_type_node, integer_zero_node, len);
8077 p1 = c_getstr (arg1);
8078 p2 = c_getstr (arg2);
8080 if (host_integerp (len, 1) && p1 && p2)
8082 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8083 if (i > 0)
8084 return integer_one_node;
8085 else if (i < 0)
8086 return integer_minus_one_node;
8087 else
8088 return integer_zero_node;
8091 /* If the second arg is "", and the length is greater than zero,
8092 return *(const unsigned char*)arg1. */
8093 if (p2 && *p2 == '\0'
8094 && TREE_CODE (len) == INTEGER_CST
8095 && tree_int_cst_sgn (len) == 1)
8097 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8098 tree cst_uchar_ptr_node
8099 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8101 return fold_convert (integer_type_node,
8102 build1 (INDIRECT_REF, cst_uchar_node,
8103 fold_convert (cst_uchar_ptr_node,
8104 arg1)));
8107 /* If the first arg is "", and the length is greater than zero,
8108 return -*(const unsigned char*)arg2. */
8109 if (p1 && *p1 == '\0'
8110 && TREE_CODE (len) == INTEGER_CST
8111 && tree_int_cst_sgn (len) == 1)
8113 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8114 tree cst_uchar_ptr_node
8115 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8117 tree temp = fold_convert (integer_type_node,
8118 build1 (INDIRECT_REF, cst_uchar_node,
8119 fold_convert (cst_uchar_ptr_node,
8120 arg2)));
8121 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8124 /* If len parameter is one, return an expression corresponding to
8125 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8126 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8128 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8129 tree cst_uchar_ptr_node
8130 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8132 tree ind1 = fold_convert (integer_type_node,
8133 build1 (INDIRECT_REF, cst_uchar_node,
8134 fold_convert (cst_uchar_ptr_node,
8135 arg1)));
8136 tree ind2 = fold_convert (integer_type_node,
8137 build1 (INDIRECT_REF, cst_uchar_node,
8138 fold_convert (cst_uchar_ptr_node,
8139 arg2)));
8140 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8143 return 0;
8146 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8147 NULL_TREE if no simplification can be made. */
8149 static tree
8150 fold_builtin_signbit (tree fndecl, tree arglist)
8152 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8153 tree arg, temp;
8155 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8156 return NULL_TREE;
8158 arg = TREE_VALUE (arglist);
8160 /* If ARG is a compile-time constant, determine the result. */
8161 if (TREE_CODE (arg) == REAL_CST
8162 && !TREE_CONSTANT_OVERFLOW (arg))
8164 REAL_VALUE_TYPE c;
8166 c = TREE_REAL_CST (arg);
8167 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8168 return fold_convert (type, temp);
8171 /* If ARG is non-negative, the result is always zero. */
8172 if (tree_expr_nonnegative_p (arg))
8173 return omit_one_operand (type, integer_zero_node, arg);
8175 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8176 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8177 return fold_build2 (LT_EXPR, type, arg,
8178 build_real (TREE_TYPE (arg), dconst0));
8180 return NULL_TREE;
8183 /* Fold function call to builtin copysign, copysignf or copysignl.
8184 Return NULL_TREE if no simplification can be made. */
8186 static tree
8187 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8189 tree arg1, arg2, tem;
8191 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8192 return NULL_TREE;
8194 arg1 = TREE_VALUE (arglist);
8195 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8197 /* copysign(X,X) is X. */
8198 if (operand_equal_p (arg1, arg2, 0))
8199 return fold_convert (type, arg1);
8201 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8202 if (TREE_CODE (arg1) == REAL_CST
8203 && TREE_CODE (arg2) == REAL_CST
8204 && !TREE_CONSTANT_OVERFLOW (arg1)
8205 && !TREE_CONSTANT_OVERFLOW (arg2))
8207 REAL_VALUE_TYPE c1, c2;
8209 c1 = TREE_REAL_CST (arg1);
8210 c2 = TREE_REAL_CST (arg2);
8211 real_copysign (&c1, &c2);
8212 return build_real (type, c1);
8213 c1.sign = c2.sign;
8216 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8217 Remember to evaluate Y for side-effects. */
8218 if (tree_expr_nonnegative_p (arg2))
8219 return omit_one_operand (type,
8220 fold_build1 (ABS_EXPR, type, arg1),
8221 arg2);
8223 /* Strip sign changing operations for the first argument. */
8224 tem = fold_strip_sign_ops (arg1);
8225 if (tem)
8227 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8228 return build_function_call_expr (fndecl, arglist);
8231 return NULL_TREE;
8234 /* Fold a call to builtin isascii. */
8236 static tree
8237 fold_builtin_isascii (tree arglist)
8239 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8240 return 0;
8241 else
8243 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8244 tree arg = TREE_VALUE (arglist);
8246 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8247 build_int_cst (NULL_TREE,
8248 ~ (unsigned HOST_WIDE_INT) 0x7f));
8249 arg = fold_build2 (EQ_EXPR, integer_type_node,
8250 arg, integer_zero_node);
8252 if (in_gimple_form && !TREE_CONSTANT (arg))
8253 return NULL_TREE;
8254 else
8255 return arg;
8259 /* Fold a call to builtin toascii. */
8261 static tree
8262 fold_builtin_toascii (tree arglist)
8264 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8265 return 0;
8266 else
8268 /* Transform toascii(c) -> (c & 0x7f). */
8269 tree arg = TREE_VALUE (arglist);
8271 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8272 build_int_cst (NULL_TREE, 0x7f));
8276 /* Fold a call to builtin isdigit. */
8278 static tree
8279 fold_builtin_isdigit (tree arglist)
8281 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8282 return 0;
8283 else
8285 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8286 /* According to the C standard, isdigit is unaffected by locale.
8287 However, it definitely is affected by the target character set. */
8288 tree arg;
8289 unsigned HOST_WIDE_INT target_digit0
8290 = lang_hooks.to_target_charset ('0');
8292 if (target_digit0 == 0)
8293 return NULL_TREE;
8295 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8296 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8297 build_int_cst (unsigned_type_node, target_digit0));
8298 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8299 build_int_cst (unsigned_type_node, 9));
8300 if (in_gimple_form && !TREE_CONSTANT (arg))
8301 return NULL_TREE;
8302 else
8303 return arg;
8307 /* Fold a call to fabs, fabsf or fabsl. */
8309 static tree
8310 fold_builtin_fabs (tree arglist, tree type)
8312 tree arg;
8314 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8315 return 0;
8317 arg = TREE_VALUE (arglist);
8318 arg = fold_convert (type, arg);
8319 if (TREE_CODE (arg) == REAL_CST)
8320 return fold_abs_const (arg, type);
8321 return fold_build1 (ABS_EXPR, type, arg);
8324 /* Fold a call to abs, labs, llabs or imaxabs. */
8326 static tree
8327 fold_builtin_abs (tree arglist, tree type)
8329 tree arg;
8331 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8332 return 0;
8334 arg = TREE_VALUE (arglist);
8335 arg = fold_convert (type, arg);
8336 if (TREE_CODE (arg) == INTEGER_CST)
8337 return fold_abs_const (arg, type);
8338 return fold_build1 (ABS_EXPR, type, arg);
8341 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8342 EXP is the CALL_EXPR for the call. */
8344 static tree
8345 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8347 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8348 tree arg;
8349 REAL_VALUE_TYPE r;
8351 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8353 /* Check that we have exactly one argument. */
8354 if (arglist == 0)
8356 error ("too few arguments to function %qs",
8357 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8358 return error_mark_node;
8360 else if (TREE_CHAIN (arglist) != 0)
8362 error ("too many arguments to function %qs",
8363 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8364 return error_mark_node;
8366 else
8368 error ("non-floating-point argument to function %qs",
8369 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8370 return error_mark_node;
8374 arg = TREE_VALUE (arglist);
8375 switch (builtin_index)
8377 case BUILT_IN_ISINF:
8378 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8379 return omit_one_operand (type, integer_zero_node, arg);
8381 if (TREE_CODE (arg) == REAL_CST)
8383 r = TREE_REAL_CST (arg);
8384 if (real_isinf (&r))
8385 return real_compare (GT_EXPR, &r, &dconst0)
8386 ? integer_one_node : integer_minus_one_node;
8387 else
8388 return integer_zero_node;
8391 return NULL_TREE;
8393 case BUILT_IN_FINITE:
8394 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8395 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8396 return omit_one_operand (type, integer_zero_node, arg);
8398 if (TREE_CODE (arg) == REAL_CST)
8400 r = TREE_REAL_CST (arg);
8401 return real_isinf (&r) || real_isnan (&r)
8402 ? integer_zero_node : integer_one_node;
8405 return NULL_TREE;
8407 case BUILT_IN_ISNAN:
8408 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8409 return omit_one_operand (type, integer_zero_node, arg);
8411 if (TREE_CODE (arg) == REAL_CST)
8413 r = TREE_REAL_CST (arg);
8414 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8417 arg = builtin_save_expr (arg);
8418 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8420 default:
8421 gcc_unreachable ();
8425 /* Fold a call to an unordered comparison function such as
8426 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8427 being called and ARGLIST is the argument list for the call.
8428 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8429 the opposite of the desired result. UNORDERED_CODE is used
8430 for modes that can hold NaNs and ORDERED_CODE is used for
8431 the rest. */
8433 static tree
8434 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8435 enum tree_code unordered_code,
8436 enum tree_code ordered_code)
8438 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8439 enum tree_code code;
8440 tree arg0, arg1;
8441 tree type0, type1;
8442 enum tree_code code0, code1;
8443 tree cmp_type = NULL_TREE;
8445 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8447 /* Check that we have exactly two arguments. */
8448 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8450 error ("too few arguments to function %qs",
8451 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8452 return error_mark_node;
8454 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8456 error ("too many arguments to function %qs",
8457 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8458 return error_mark_node;
8462 arg0 = TREE_VALUE (arglist);
8463 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8465 type0 = TREE_TYPE (arg0);
8466 type1 = TREE_TYPE (arg1);
8468 code0 = TREE_CODE (type0);
8469 code1 = TREE_CODE (type1);
8471 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8472 /* Choose the wider of two real types. */
8473 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8474 ? type0 : type1;
8475 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8476 cmp_type = type0;
8477 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8478 cmp_type = type1;
8479 else
8481 error ("non-floating-point argument to function %qs",
8482 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8483 return error_mark_node;
8486 arg0 = fold_convert (cmp_type, arg0);
8487 arg1 = fold_convert (cmp_type, arg1);
8489 if (unordered_code == UNORDERED_EXPR)
8491 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8492 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8493 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8496 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8497 : ordered_code;
8498 return fold_build1 (TRUTH_NOT_EXPR, type,
8499 fold_build2 (code, type, arg0, arg1));
8502 /* Used by constant folding to simplify calls to builtin functions. EXP is
8503 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8504 result of the function call is ignored. This function returns NULL_TREE
8505 if no simplification was possible. */
8507 static tree
8508 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8510 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8511 enum built_in_function fcode;
8513 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8514 return targetm.fold_builtin (fndecl, arglist, ignore);
8516 fcode = DECL_FUNCTION_CODE (fndecl);
8517 switch (fcode)
8519 case BUILT_IN_FPUTS:
8520 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8522 case BUILT_IN_FPUTS_UNLOCKED:
8523 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8525 case BUILT_IN_STRSTR:
8526 return fold_builtin_strstr (arglist, type);
8528 case BUILT_IN_STRCAT:
8529 return fold_builtin_strcat (arglist);
8531 case BUILT_IN_STRNCAT:
8532 return fold_builtin_strncat (arglist);
8534 case BUILT_IN_STRSPN:
8535 return fold_builtin_strspn (arglist);
8537 case BUILT_IN_STRCSPN:
8538 return fold_builtin_strcspn (arglist);
8540 case BUILT_IN_STRCHR:
8541 case BUILT_IN_INDEX:
8542 return fold_builtin_strchr (arglist, type);
8544 case BUILT_IN_STRRCHR:
8545 case BUILT_IN_RINDEX:
8546 return fold_builtin_strrchr (arglist, type);
8548 case BUILT_IN_STRCPY:
8549 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8551 case BUILT_IN_STRNCPY:
8552 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8554 case BUILT_IN_STRCMP:
8555 return fold_builtin_strcmp (arglist);
8557 case BUILT_IN_STRNCMP:
8558 return fold_builtin_strncmp (arglist);
8560 case BUILT_IN_STRPBRK:
8561 return fold_builtin_strpbrk (arglist, type);
8563 case BUILT_IN_BCMP:
8564 case BUILT_IN_MEMCMP:
8565 return fold_builtin_memcmp (arglist);
8567 case BUILT_IN_SPRINTF:
8568 return fold_builtin_sprintf (arglist, ignore);
8570 case BUILT_IN_CONSTANT_P:
8572 tree val;
8574 val = fold_builtin_constant_p (arglist);
8575 /* Gimplification will pull the CALL_EXPR for the builtin out of
8576 an if condition. When not optimizing, we'll not CSE it back.
8577 To avoid link error types of regressions, return false now. */
8578 if (!val && !optimize)
8579 val = integer_zero_node;
8581 return val;
8584 case BUILT_IN_EXPECT:
8585 return fold_builtin_expect (arglist);
8587 case BUILT_IN_CLASSIFY_TYPE:
8588 return fold_builtin_classify_type (arglist);
8590 case BUILT_IN_STRLEN:
8591 return fold_builtin_strlen (arglist);
8593 CASE_FLT_FN (BUILT_IN_FABS):
8594 return fold_builtin_fabs (arglist, type);
8596 case BUILT_IN_ABS:
8597 case BUILT_IN_LABS:
8598 case BUILT_IN_LLABS:
8599 case BUILT_IN_IMAXABS:
8600 return fold_builtin_abs (arglist, type);
8602 CASE_FLT_FN (BUILT_IN_CONJ):
8603 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8604 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8605 break;
8607 CASE_FLT_FN (BUILT_IN_CREAL):
8608 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8609 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8610 TREE_VALUE (arglist)));
8611 break;
8613 CASE_FLT_FN (BUILT_IN_CIMAG):
8614 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8615 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8616 TREE_VALUE (arglist)));
8617 break;
8619 CASE_FLT_FN (BUILT_IN_CABS):
8620 return fold_builtin_cabs (arglist, type);
8622 CASE_FLT_FN (BUILT_IN_SQRT):
8623 return fold_builtin_sqrt (arglist, type);
8625 CASE_FLT_FN (BUILT_IN_CBRT):
8626 return fold_builtin_cbrt (arglist, type);
8628 CASE_FLT_FN (BUILT_IN_SIN):
8629 return fold_builtin_sin (arglist);
8631 CASE_FLT_FN (BUILT_IN_COS):
8632 return fold_builtin_cos (arglist, type, fndecl);
8634 CASE_FLT_FN (BUILT_IN_EXP):
8635 return fold_builtin_exponent (fndecl, arglist, &dconste);
8637 CASE_FLT_FN (BUILT_IN_EXP2):
8638 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8640 CASE_FLT_FN (BUILT_IN_EXP10):
8641 CASE_FLT_FN (BUILT_IN_POW10):
8642 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8644 CASE_FLT_FN (BUILT_IN_LOG):
8645 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8647 CASE_FLT_FN (BUILT_IN_LOG2):
8648 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8650 CASE_FLT_FN (BUILT_IN_LOG10):
8651 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8653 CASE_FLT_FN (BUILT_IN_TAN):
8654 return fold_builtin_tan (arglist);
8656 CASE_FLT_FN (BUILT_IN_ATAN):
8657 return fold_builtin_atan (arglist, type);
8659 CASE_FLT_FN (BUILT_IN_POW):
8660 return fold_builtin_pow (fndecl, arglist, type);
8662 CASE_FLT_FN (BUILT_IN_POWI):
8663 return fold_builtin_powi (fndecl, arglist, type);
8665 CASE_FLT_FN (BUILT_IN_INF):
8666 case BUILT_IN_INFD32:
8667 case BUILT_IN_INFD64:
8668 case BUILT_IN_INFD128:
8669 return fold_builtin_inf (type, true);
8671 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8672 return fold_builtin_inf (type, false);
8674 CASE_FLT_FN (BUILT_IN_NAN):
8675 case BUILT_IN_NAND32:
8676 case BUILT_IN_NAND64:
8677 case BUILT_IN_NAND128:
8678 return fold_builtin_nan (arglist, type, true);
8680 CASE_FLT_FN (BUILT_IN_NANS):
8681 return fold_builtin_nan (arglist, type, false);
8683 CASE_FLT_FN (BUILT_IN_FLOOR):
8684 return fold_builtin_floor (fndecl, arglist);
8686 CASE_FLT_FN (BUILT_IN_CEIL):
8687 return fold_builtin_ceil (fndecl, arglist);
8689 CASE_FLT_FN (BUILT_IN_TRUNC):
8690 return fold_builtin_trunc (fndecl, arglist);
8692 CASE_FLT_FN (BUILT_IN_ROUND):
8693 return fold_builtin_round (fndecl, arglist);
8695 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8696 CASE_FLT_FN (BUILT_IN_RINT):
8697 return fold_trunc_transparent_mathfn (fndecl, arglist);
8699 CASE_FLT_FN (BUILT_IN_LCEIL):
8700 CASE_FLT_FN (BUILT_IN_LLCEIL):
8701 CASE_FLT_FN (BUILT_IN_LFLOOR):
8702 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8703 CASE_FLT_FN (BUILT_IN_LROUND):
8704 CASE_FLT_FN (BUILT_IN_LLROUND):
8705 return fold_builtin_int_roundingfn (fndecl, arglist);
8707 CASE_FLT_FN (BUILT_IN_LRINT):
8708 CASE_FLT_FN (BUILT_IN_LLRINT):
8709 return fold_fixed_mathfn (fndecl, arglist);
8711 CASE_INT_FN (BUILT_IN_FFS):
8712 CASE_INT_FN (BUILT_IN_CLZ):
8713 CASE_INT_FN (BUILT_IN_CTZ):
8714 CASE_INT_FN (BUILT_IN_POPCOUNT):
8715 CASE_INT_FN (BUILT_IN_PARITY):
8716 return fold_builtin_bitop (fndecl, arglist);
8718 case BUILT_IN_MEMCPY:
8719 return fold_builtin_memcpy (fndecl, arglist);
8721 case BUILT_IN_MEMPCPY:
8722 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8724 case BUILT_IN_MEMMOVE:
8725 return fold_builtin_memmove (arglist, type);
8727 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8728 return fold_builtin_signbit (fndecl, arglist);
8730 case BUILT_IN_ISASCII:
8731 return fold_builtin_isascii (arglist);
8733 case BUILT_IN_TOASCII:
8734 return fold_builtin_toascii (arglist);
8736 case BUILT_IN_ISDIGIT:
8737 return fold_builtin_isdigit (arglist);
8739 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8740 return fold_builtin_copysign (fndecl, arglist, type);
8742 CASE_FLT_FN (BUILT_IN_FINITE):
8743 case BUILT_IN_FINITED32:
8744 case BUILT_IN_FINITED64:
8745 case BUILT_IN_FINITED128:
8746 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8748 CASE_FLT_FN (BUILT_IN_ISINF):
8749 case BUILT_IN_ISINFD32:
8750 case BUILT_IN_ISINFD64:
8751 case BUILT_IN_ISINFD128:
8752 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8754 CASE_FLT_FN (BUILT_IN_ISNAN):
8755 case BUILT_IN_ISNAND32:
8756 case BUILT_IN_ISNAND64:
8757 case BUILT_IN_ISNAND128:
8758 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8760 case BUILT_IN_ISGREATER:
8761 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8762 case BUILT_IN_ISGREATEREQUAL:
8763 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8764 case BUILT_IN_ISLESS:
8765 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8766 case BUILT_IN_ISLESSEQUAL:
8767 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8768 case BUILT_IN_ISLESSGREATER:
8769 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8770 case BUILT_IN_ISUNORDERED:
8771 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8772 NOP_EXPR);
8774 /* We do the folding for va_start in the expander. */
8775 case BUILT_IN_VA_START:
8776 break;
8778 case BUILT_IN_OBJECT_SIZE:
8779 return fold_builtin_object_size (arglist);
8780 case BUILT_IN_MEMCPY_CHK:
8781 case BUILT_IN_MEMPCPY_CHK:
8782 case BUILT_IN_MEMMOVE_CHK:
8783 case BUILT_IN_MEMSET_CHK:
8784 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8785 DECL_FUNCTION_CODE (fndecl));
8786 case BUILT_IN_STRCPY_CHK:
8787 case BUILT_IN_STPCPY_CHK:
8788 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8789 DECL_FUNCTION_CODE (fndecl));
8790 case BUILT_IN_STRNCPY_CHK:
8791 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8792 case BUILT_IN_STRCAT_CHK:
8793 return fold_builtin_strcat_chk (fndecl, arglist);
8794 case BUILT_IN_STRNCAT_CHK:
8795 return fold_builtin_strncat_chk (fndecl, arglist);
8796 case BUILT_IN_SPRINTF_CHK:
8797 case BUILT_IN_VSPRINTF_CHK:
8798 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8799 case BUILT_IN_SNPRINTF_CHK:
8800 case BUILT_IN_VSNPRINTF_CHK:
8801 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8802 DECL_FUNCTION_CODE (fndecl));
8804 case BUILT_IN_PRINTF:
8805 case BUILT_IN_PRINTF_UNLOCKED:
8806 case BUILT_IN_VPRINTF:
8807 case BUILT_IN_PRINTF_CHK:
8808 case BUILT_IN_VPRINTF_CHK:
8809 return fold_builtin_printf (fndecl, arglist, ignore,
8810 DECL_FUNCTION_CODE (fndecl));
8812 case BUILT_IN_FPRINTF:
8813 case BUILT_IN_FPRINTF_UNLOCKED:
8814 case BUILT_IN_VFPRINTF:
8815 case BUILT_IN_FPRINTF_CHK:
8816 case BUILT_IN_VFPRINTF_CHK:
8817 return fold_builtin_fprintf (fndecl, arglist, ignore,
8818 DECL_FUNCTION_CODE (fndecl));
8820 default:
8821 break;
8824 return 0;
8827 /* A wrapper function for builtin folding that prevents warnings for
8828 "statement without effect" and the like, caused by removing the
8829 call node earlier than the warning is generated. */
8831 tree
8832 fold_builtin (tree fndecl, tree arglist, bool ignore)
8834 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8835 if (exp)
8837 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8838 TREE_NO_WARNING (exp) = 1;
8841 return exp;
8844 /* Conveniently construct a function call expression. */
8846 tree
8847 build_function_call_expr (tree fn, tree arglist)
8849 tree call_expr;
8851 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8852 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8853 call_expr, arglist, NULL_TREE);
8856 /* This function validates the types of a function call argument list
8857 represented as a tree chain of parameters against a specified list
8858 of tree_codes. If the last specifier is a 0, that represents an
8859 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8861 static int
8862 validate_arglist (tree arglist, ...)
8864 enum tree_code code;
8865 int res = 0;
8866 va_list ap;
8868 va_start (ap, arglist);
8872 code = va_arg (ap, enum tree_code);
8873 switch (code)
8875 case 0:
8876 /* This signifies an ellipses, any further arguments are all ok. */
8877 res = 1;
8878 goto end;
8879 case VOID_TYPE:
8880 /* This signifies an endlink, if no arguments remain, return
8881 true, otherwise return false. */
8882 res = arglist == 0;
8883 goto end;
8884 default:
8885 /* If no parameters remain or the parameter's code does not
8886 match the specified code, return false. Otherwise continue
8887 checking any remaining arguments. */
8888 if (arglist == 0)
8889 goto end;
8890 if (code == POINTER_TYPE)
8892 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8893 goto end;
8895 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8896 goto end;
8897 break;
8899 arglist = TREE_CHAIN (arglist);
8901 while (1);
8903 /* We need gotos here since we can only have one VA_CLOSE in a
8904 function. */
8905 end: ;
8906 va_end (ap);
8908 return res;
8911 /* Default target-specific builtin expander that does nothing. */
8914 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8915 rtx target ATTRIBUTE_UNUSED,
8916 rtx subtarget ATTRIBUTE_UNUSED,
8917 enum machine_mode mode ATTRIBUTE_UNUSED,
8918 int ignore ATTRIBUTE_UNUSED)
8920 return NULL_RTX;
8923 /* Default target-specific library builtin expander that does nothing. */
8926 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
8927 rtx target ATTRIBUTE_UNUSED,
8928 rtx subtarget ATTRIBUTE_UNUSED,
8929 enum machine_mode mode ATTRIBUTE_UNUSED,
8930 int ignore ATTRIBUTE_UNUSED)
8932 return NULL_RTX;
8935 /* Returns true is EXP represents data that would potentially reside
8936 in a readonly section. */
8938 static bool
8939 readonly_data_expr (tree exp)
8941 STRIP_NOPS (exp);
8943 if (TREE_CODE (exp) != ADDR_EXPR)
8944 return false;
8946 exp = get_base_address (TREE_OPERAND (exp, 0));
8947 if (!exp)
8948 return false;
8950 /* Make sure we call decl_readonly_section only for trees it
8951 can handle (since it returns true for everything it doesn't
8952 understand). */
8953 if (TREE_CODE (exp) == STRING_CST
8954 || TREE_CODE (exp) == CONSTRUCTOR
8955 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8956 return decl_readonly_section (exp, 0);
8957 else
8958 return false;
8961 /* Simplify a call to the strstr builtin.
8963 Return 0 if no simplification was possible, otherwise return the
8964 simplified form of the call as a tree.
8966 The simplified form may be a constant or other expression which
8967 computes the same value, but in a more efficient manner (including
8968 calls to other builtin functions).
8970 The call may contain arguments which need to be evaluated, but
8971 which are not useful to determine the result of the call. In
8972 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8973 COMPOUND_EXPR will be an argument which must be evaluated.
8974 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8975 COMPOUND_EXPR in the chain will contain the tree for the simplified
8976 form of the builtin function call. */
8978 static tree
8979 fold_builtin_strstr (tree arglist, tree type)
8981 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8982 return 0;
8983 else
8985 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8986 tree fn;
8987 const char *p1, *p2;
8989 p2 = c_getstr (s2);
8990 if (p2 == NULL)
8991 return 0;
8993 p1 = c_getstr (s1);
8994 if (p1 != NULL)
8996 const char *r = strstr (p1, p2);
8997 tree tem;
8999 if (r == NULL)
9000 return build_int_cst (TREE_TYPE (s1), 0);
9002 /* Return an offset into the constant string argument. */
9003 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9004 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9005 return fold_convert (type, tem);
9008 /* The argument is const char *, and the result is char *, so we need
9009 a type conversion here to avoid a warning. */
9010 if (p2[0] == '\0')
9011 return fold_convert (type, s1);
9013 if (p2[1] != '\0')
9014 return 0;
9016 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9017 if (!fn)
9018 return 0;
9020 /* New argument list transforming strstr(s1, s2) to
9021 strchr(s1, s2[0]). */
9022 arglist = build_tree_list (NULL_TREE,
9023 build_int_cst (NULL_TREE, p2[0]));
9024 arglist = tree_cons (NULL_TREE, s1, arglist);
9025 return build_function_call_expr (fn, arglist);
9029 /* Simplify a call to the strchr builtin.
9031 Return 0 if no simplification was possible, otherwise return the
9032 simplified form of the call as a tree.
9034 The simplified form may be a constant or other expression which
9035 computes the same value, but in a more efficient manner (including
9036 calls to other builtin functions).
9038 The call may contain arguments which need to be evaluated, but
9039 which are not useful to determine the result of the call. In
9040 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9041 COMPOUND_EXPR will be an argument which must be evaluated.
9042 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9043 COMPOUND_EXPR in the chain will contain the tree for the simplified
9044 form of the builtin function call. */
9046 static tree
9047 fold_builtin_strchr (tree arglist, tree type)
9049 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9050 return 0;
9051 else
9053 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9054 const char *p1;
9056 if (TREE_CODE (s2) != INTEGER_CST)
9057 return 0;
9059 p1 = c_getstr (s1);
9060 if (p1 != NULL)
9062 char c;
9063 const char *r;
9064 tree tem;
9066 if (target_char_cast (s2, &c))
9067 return 0;
9069 r = strchr (p1, c);
9071 if (r == NULL)
9072 return build_int_cst (TREE_TYPE (s1), 0);
9074 /* Return an offset into the constant string argument. */
9075 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9076 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9077 return fold_convert (type, tem);
9079 return 0;
9083 /* Simplify a call to the strrchr builtin.
9085 Return 0 if no simplification was possible, otherwise return the
9086 simplified form of the call as a tree.
9088 The simplified form may be a constant or other expression which
9089 computes the same value, but in a more efficient manner (including
9090 calls to other builtin functions).
9092 The call may contain arguments which need to be evaluated, but
9093 which are not useful to determine the result of the call. In
9094 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9095 COMPOUND_EXPR will be an argument which must be evaluated.
9096 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9097 COMPOUND_EXPR in the chain will contain the tree for the simplified
9098 form of the builtin function call. */
9100 static tree
9101 fold_builtin_strrchr (tree arglist, tree type)
9103 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9104 return 0;
9105 else
9107 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9108 tree fn;
9109 const char *p1;
9111 if (TREE_CODE (s2) != INTEGER_CST)
9112 return 0;
9114 p1 = c_getstr (s1);
9115 if (p1 != NULL)
9117 char c;
9118 const char *r;
9119 tree tem;
9121 if (target_char_cast (s2, &c))
9122 return 0;
9124 r = strrchr (p1, c);
9126 if (r == NULL)
9127 return build_int_cst (TREE_TYPE (s1), 0);
9129 /* Return an offset into the constant string argument. */
9130 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9131 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9132 return fold_convert (type, tem);
9135 if (! integer_zerop (s2))
9136 return 0;
9138 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9139 if (!fn)
9140 return 0;
9142 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9143 return build_function_call_expr (fn, arglist);
9147 /* Simplify a call to the strpbrk builtin.
9149 Return 0 if no simplification was possible, otherwise return the
9150 simplified form of the call as a tree.
9152 The simplified form may be a constant or other expression which
9153 computes the same value, but in a more efficient manner (including
9154 calls to other builtin functions).
9156 The call may contain arguments which need to be evaluated, but
9157 which are not useful to determine the result of the call. In
9158 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9159 COMPOUND_EXPR will be an argument which must be evaluated.
9160 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9161 COMPOUND_EXPR in the chain will contain the tree for the simplified
9162 form of the builtin function call. */
9164 static tree
9165 fold_builtin_strpbrk (tree arglist, tree type)
9167 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9168 return 0;
9169 else
9171 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9172 tree fn;
9173 const char *p1, *p2;
9175 p2 = c_getstr (s2);
9176 if (p2 == NULL)
9177 return 0;
9179 p1 = c_getstr (s1);
9180 if (p1 != NULL)
9182 const char *r = strpbrk (p1, p2);
9183 tree tem;
9185 if (r == NULL)
9186 return build_int_cst (TREE_TYPE (s1), 0);
9188 /* Return an offset into the constant string argument. */
9189 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9190 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9191 return fold_convert (type, tem);
9194 if (p2[0] == '\0')
9195 /* strpbrk(x, "") == NULL.
9196 Evaluate and ignore s1 in case it had side-effects. */
9197 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9199 if (p2[1] != '\0')
9200 return 0; /* Really call strpbrk. */
9202 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9203 if (!fn)
9204 return 0;
9206 /* New argument list transforming strpbrk(s1, s2) to
9207 strchr(s1, s2[0]). */
9208 arglist = build_tree_list (NULL_TREE,
9209 build_int_cst (NULL_TREE, p2[0]));
9210 arglist = tree_cons (NULL_TREE, s1, arglist);
9211 return build_function_call_expr (fn, arglist);
9215 /* Simplify a call to the strcat builtin.
9217 Return 0 if no simplification was possible, otherwise return the
9218 simplified form of the call as a tree.
9220 The simplified form may be a constant or other expression which
9221 computes the same value, but in a more efficient manner (including
9222 calls to other builtin functions).
9224 The call may contain arguments which need to be evaluated, but
9225 which are not useful to determine the result of the call. In
9226 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9227 COMPOUND_EXPR will be an argument which must be evaluated.
9228 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9229 COMPOUND_EXPR in the chain will contain the tree for the simplified
9230 form of the builtin function call. */
9232 static tree
9233 fold_builtin_strcat (tree arglist)
9235 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9236 return 0;
9237 else
9239 tree dst = TREE_VALUE (arglist),
9240 src = TREE_VALUE (TREE_CHAIN (arglist));
9241 const char *p = c_getstr (src);
9243 /* If the string length is zero, return the dst parameter. */
9244 if (p && *p == '\0')
9245 return dst;
9247 return 0;
9251 /* Simplify a call to the strncat builtin.
9253 Return 0 if no simplification was possible, otherwise return the
9254 simplified form of the call as a tree.
9256 The simplified form may be a constant or other expression which
9257 computes the same value, but in a more efficient manner (including
9258 calls to other builtin functions).
9260 The call may contain arguments which need to be evaluated, but
9261 which are not useful to determine the result of the call. In
9262 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9263 COMPOUND_EXPR will be an argument which must be evaluated.
9264 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9265 COMPOUND_EXPR in the chain will contain the tree for the simplified
9266 form of the builtin function call. */
9268 static tree
9269 fold_builtin_strncat (tree arglist)
9271 if (!validate_arglist (arglist,
9272 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9273 return 0;
9274 else
9276 tree dst = TREE_VALUE (arglist);
9277 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9278 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9279 const char *p = c_getstr (src);
9281 /* If the requested length is zero, or the src parameter string
9282 length is zero, return the dst parameter. */
9283 if (integer_zerop (len) || (p && *p == '\0'))
9284 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9286 /* If the requested len is greater than or equal to the string
9287 length, call strcat. */
9288 if (TREE_CODE (len) == INTEGER_CST && p
9289 && compare_tree_int (len, strlen (p)) >= 0)
9291 tree newarglist
9292 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9293 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9295 /* If the replacement _DECL isn't initialized, don't do the
9296 transformation. */
9297 if (!fn)
9298 return 0;
9300 return build_function_call_expr (fn, newarglist);
9302 return 0;
9306 /* Simplify a call to the strspn builtin.
9308 Return 0 if no simplification was possible, otherwise return the
9309 simplified form of the call as a tree.
9311 The simplified form may be a constant or other expression which
9312 computes the same value, but in a more efficient manner (including
9313 calls to other builtin functions).
9315 The call may contain arguments which need to be evaluated, but
9316 which are not useful to determine the result of the call. In
9317 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9318 COMPOUND_EXPR will be an argument which must be evaluated.
9319 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9320 COMPOUND_EXPR in the chain will contain the tree for the simplified
9321 form of the builtin function call. */
9323 static tree
9324 fold_builtin_strspn (tree arglist)
9326 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9327 return 0;
9328 else
9330 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9331 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9333 /* If both arguments are constants, evaluate at compile-time. */
9334 if (p1 && p2)
9336 const size_t r = strspn (p1, p2);
9337 return size_int (r);
9340 /* If either argument is "", return 0. */
9341 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9342 /* Evaluate and ignore both arguments in case either one has
9343 side-effects. */
9344 return omit_two_operands (integer_type_node, integer_zero_node,
9345 s1, s2);
9346 return 0;
9350 /* Simplify a call to the strcspn builtin.
9352 Return 0 if no simplification was possible, otherwise return the
9353 simplified form of the call as a tree.
9355 The simplified form may be a constant or other expression which
9356 computes the same value, but in a more efficient manner (including
9357 calls to other builtin functions).
9359 The call may contain arguments which need to be evaluated, but
9360 which are not useful to determine the result of the call. In
9361 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9362 COMPOUND_EXPR will be an argument which must be evaluated.
9363 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9364 COMPOUND_EXPR in the chain will contain the tree for the simplified
9365 form of the builtin function call. */
9367 static tree
9368 fold_builtin_strcspn (tree arglist)
9370 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9371 return 0;
9372 else
9374 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9375 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9377 /* If both arguments are constants, evaluate at compile-time. */
9378 if (p1 && p2)
9380 const size_t r = strcspn (p1, p2);
9381 return size_int (r);
9384 /* If the first argument is "", return 0. */
9385 if (p1 && *p1 == '\0')
9387 /* Evaluate and ignore argument s2 in case it has
9388 side-effects. */
9389 return omit_one_operand (integer_type_node,
9390 integer_zero_node, s2);
9393 /* If the second argument is "", return __builtin_strlen(s1). */
9394 if (p2 && *p2 == '\0')
9396 tree newarglist = build_tree_list (NULL_TREE, s1),
9397 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9399 /* If the replacement _DECL isn't initialized, don't do the
9400 transformation. */
9401 if (!fn)
9402 return 0;
9404 return build_function_call_expr (fn, newarglist);
9406 return 0;
9410 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9411 by the builtin will be ignored. UNLOCKED is true is true if this
9412 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9413 the known length of the string. Return NULL_TREE if no simplification
9414 was possible. */
9416 tree
9417 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9419 tree fn;
9420 /* If we're using an unlocked function, assume the other unlocked
9421 functions exist explicitly. */
9422 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9423 : implicit_built_in_decls[BUILT_IN_FPUTC];
9424 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9425 : implicit_built_in_decls[BUILT_IN_FWRITE];
9427 /* If the return value is used, don't do the transformation. */
9428 if (!ignore)
9429 return 0;
9431 /* Verify the arguments in the original call. */
9432 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9433 return 0;
9435 if (! len)
9436 len = c_strlen (TREE_VALUE (arglist), 0);
9438 /* Get the length of the string passed to fputs. If the length
9439 can't be determined, punt. */
9440 if (!len
9441 || TREE_CODE (len) != INTEGER_CST)
9442 return 0;
9444 switch (compare_tree_int (len, 1))
9446 case -1: /* length is 0, delete the call entirely . */
9447 return omit_one_operand (integer_type_node, integer_zero_node,
9448 TREE_VALUE (TREE_CHAIN (arglist)));
9450 case 0: /* length is 1, call fputc. */
9452 const char *p = c_getstr (TREE_VALUE (arglist));
9454 if (p != NULL)
9456 /* New argument list transforming fputs(string, stream) to
9457 fputc(string[0], stream). */
9458 arglist = build_tree_list (NULL_TREE,
9459 TREE_VALUE (TREE_CHAIN (arglist)));
9460 arglist = tree_cons (NULL_TREE,
9461 build_int_cst (NULL_TREE, p[0]),
9462 arglist);
9463 fn = fn_fputc;
9464 break;
9467 /* FALLTHROUGH */
9468 case 1: /* length is greater than 1, call fwrite. */
9470 tree string_arg;
9472 /* If optimizing for size keep fputs. */
9473 if (optimize_size)
9474 return 0;
9475 string_arg = TREE_VALUE (arglist);
9476 /* New argument list transforming fputs(string, stream) to
9477 fwrite(string, 1, len, stream). */
9478 arglist = build_tree_list (NULL_TREE,
9479 TREE_VALUE (TREE_CHAIN (arglist)));
9480 arglist = tree_cons (NULL_TREE, len, arglist);
9481 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9482 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9483 fn = fn_fwrite;
9484 break;
9486 default:
9487 gcc_unreachable ();
9490 /* If the replacement _DECL isn't initialized, don't do the
9491 transformation. */
9492 if (!fn)
9493 return 0;
9495 /* These optimizations are only performed when the result is ignored,
9496 hence there's no need to cast the result to integer_type_node. */
9497 return build_function_call_expr (fn, arglist);
9500 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9501 produced. False otherwise. This is done so that we don't output the error
9502 or warning twice or three times. */
9503 bool
9504 fold_builtin_next_arg (tree arglist)
9506 tree fntype = TREE_TYPE (current_function_decl);
9508 if (TYPE_ARG_TYPES (fntype) == 0
9509 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9510 == void_type_node))
9512 error ("%<va_start%> used in function with fixed args");
9513 return true;
9515 else if (!arglist)
9517 /* Evidently an out of date version of <stdarg.h>; can't validate
9518 va_start's second argument, but can still work as intended. */
9519 warning (0, "%<__builtin_next_arg%> called without an argument");
9520 return true;
9522 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9523 when we checked the arguments and if needed issued a warning. */
9524 else if (!TREE_CHAIN (arglist)
9525 || !integer_zerop (TREE_VALUE (arglist))
9526 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9527 || TREE_CHAIN (TREE_CHAIN (arglist)))
9529 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9530 tree arg = TREE_VALUE (arglist);
9532 if (TREE_CHAIN (arglist))
9534 error ("%<va_start%> used with too many arguments");
9535 return true;
9538 /* Strip off all nops for the sake of the comparison. This
9539 is not quite the same as STRIP_NOPS. It does more.
9540 We must also strip off INDIRECT_EXPR for C++ reference
9541 parameters. */
9542 while (TREE_CODE (arg) == NOP_EXPR
9543 || TREE_CODE (arg) == CONVERT_EXPR
9544 || TREE_CODE (arg) == NON_LVALUE_EXPR
9545 || TREE_CODE (arg) == INDIRECT_REF)
9546 arg = TREE_OPERAND (arg, 0);
9547 if (arg != last_parm)
9549 /* FIXME: Sometimes with the tree optimizers we can get the
9550 not the last argument even though the user used the last
9551 argument. We just warn and set the arg to be the last
9552 argument so that we will get wrong-code because of
9553 it. */
9554 warning (0, "second parameter of %<va_start%> not last named argument");
9556 /* We want to verify the second parameter just once before the tree
9557 optimizers are run and then avoid keeping it in the tree,
9558 as otherwise we could warn even for correct code like:
9559 void foo (int i, ...)
9560 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9561 TREE_VALUE (arglist) = integer_zero_node;
9562 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9564 return false;
9568 /* Simplify a call to the sprintf builtin.
9570 Return 0 if no simplification was possible, otherwise return the
9571 simplified form of the call as a tree. If IGNORED is true, it means that
9572 the caller does not use the returned value of the function. */
9574 static tree
9575 fold_builtin_sprintf (tree arglist, int ignored)
9577 tree call, retval, dest, fmt;
9578 const char *fmt_str = NULL;
9580 /* Verify the required arguments in the original call. We deal with two
9581 types of sprintf() calls: 'sprintf (str, fmt)' and
9582 'sprintf (dest, "%s", orig)'. */
9583 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9584 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9585 VOID_TYPE))
9586 return NULL_TREE;
9588 /* Get the destination string and the format specifier. */
9589 dest = TREE_VALUE (arglist);
9590 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9592 /* Check whether the format is a literal string constant. */
9593 fmt_str = c_getstr (fmt);
9594 if (fmt_str == NULL)
9595 return NULL_TREE;
9597 call = NULL_TREE;
9598 retval = NULL_TREE;
9600 if (!init_target_chars())
9601 return 0;
9603 /* If the format doesn't contain % args or %%, use strcpy. */
9604 if (strchr (fmt_str, target_percent) == NULL)
9606 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9608 if (!fn)
9609 return NULL_TREE;
9611 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9612 'format' is known to contain no % formats. */
9613 arglist = build_tree_list (NULL_TREE, fmt);
9614 arglist = tree_cons (NULL_TREE, dest, arglist);
9615 call = build_function_call_expr (fn, arglist);
9616 if (!ignored)
9617 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9620 /* If the format is "%s", use strcpy if the result isn't used. */
9621 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9623 tree fn, orig;
9624 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9626 if (!fn)
9627 return NULL_TREE;
9629 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9630 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9631 arglist = build_tree_list (NULL_TREE, orig);
9632 arglist = tree_cons (NULL_TREE, dest, arglist);
9633 if (!ignored)
9635 retval = c_strlen (orig, 1);
9636 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9637 return NULL_TREE;
9639 call = build_function_call_expr (fn, arglist);
9642 if (call && retval)
9644 retval = convert
9645 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9646 retval);
9647 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9649 else
9650 return call;
9653 /* Expand a call to __builtin_object_size. */
9656 expand_builtin_object_size (tree exp)
9658 tree ost;
9659 int object_size_type;
9660 tree fndecl = get_callee_fndecl (exp);
9661 tree arglist = TREE_OPERAND (exp, 1);
9662 location_t locus = EXPR_LOCATION (exp);
9664 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9666 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9667 &locus, fndecl);
9668 expand_builtin_trap ();
9669 return const0_rtx;
9672 ost = TREE_VALUE (TREE_CHAIN (arglist));
9673 STRIP_NOPS (ost);
9675 if (TREE_CODE (ost) != INTEGER_CST
9676 || tree_int_cst_sgn (ost) < 0
9677 || compare_tree_int (ost, 3) > 0)
9679 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9680 &locus, fndecl);
9681 expand_builtin_trap ();
9682 return const0_rtx;
9685 object_size_type = tree_low_cst (ost, 0);
9687 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9690 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9691 FCODE is the BUILT_IN_* to use.
9692 Return 0 if we failed; the caller should emit a normal call,
9693 otherwise try to get the result in TARGET, if convenient (and in
9694 mode MODE if that's convenient). */
9696 static rtx
9697 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9698 enum built_in_function fcode)
9700 tree arglist = TREE_OPERAND (exp, 1);
9701 tree dest, src, len, size;
9703 if (!validate_arglist (arglist,
9704 POINTER_TYPE,
9705 fcode == BUILT_IN_MEMSET_CHK
9706 ? INTEGER_TYPE : POINTER_TYPE,
9707 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9708 return 0;
9710 dest = TREE_VALUE (arglist);
9711 src = TREE_VALUE (TREE_CHAIN (arglist));
9712 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9713 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9715 if (! host_integerp (size, 1))
9716 return 0;
9718 if (host_integerp (len, 1) || integer_all_onesp (size))
9720 tree fn;
9722 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9724 location_t locus = EXPR_LOCATION (exp);
9725 warning (0, "%Hcall to %D will always overflow destination buffer",
9726 &locus, get_callee_fndecl (exp));
9727 return 0;
9730 arglist = build_tree_list (NULL_TREE, len);
9731 arglist = tree_cons (NULL_TREE, src, arglist);
9732 arglist = tree_cons (NULL_TREE, dest, arglist);
9734 fn = NULL_TREE;
9735 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9736 mem{cpy,pcpy,move,set} is available. */
9737 switch (fcode)
9739 case BUILT_IN_MEMCPY_CHK:
9740 fn = built_in_decls[BUILT_IN_MEMCPY];
9741 break;
9742 case BUILT_IN_MEMPCPY_CHK:
9743 fn = built_in_decls[BUILT_IN_MEMPCPY];
9744 break;
9745 case BUILT_IN_MEMMOVE_CHK:
9746 fn = built_in_decls[BUILT_IN_MEMMOVE];
9747 break;
9748 case BUILT_IN_MEMSET_CHK:
9749 fn = built_in_decls[BUILT_IN_MEMSET];
9750 break;
9751 default:
9752 break;
9755 if (! fn)
9756 return 0;
9758 fn = build_function_call_expr (fn, arglist);
9759 if (TREE_CODE (fn) == CALL_EXPR)
9760 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9761 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9763 else if (fcode == BUILT_IN_MEMSET_CHK)
9764 return 0;
9765 else
9767 unsigned int dest_align
9768 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9770 /* If DEST is not a pointer type, call the normal function. */
9771 if (dest_align == 0)
9772 return 0;
9774 /* If SRC and DEST are the same (and not volatile), do nothing. */
9775 if (operand_equal_p (src, dest, 0))
9777 tree expr;
9779 if (fcode != BUILT_IN_MEMPCPY_CHK)
9781 /* Evaluate and ignore LEN in case it has side-effects. */
9782 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9783 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9786 len = fold_convert (TREE_TYPE (dest), len);
9787 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9788 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9791 /* __memmove_chk special case. */
9792 if (fcode == BUILT_IN_MEMMOVE_CHK)
9794 unsigned int src_align
9795 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9797 if (src_align == 0)
9798 return 0;
9800 /* If src is categorized for a readonly section we can use
9801 normal __memcpy_chk. */
9802 if (readonly_data_expr (src))
9804 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9805 if (!fn)
9806 return 0;
9807 fn = build_function_call_expr (fn, arglist);
9808 if (TREE_CODE (fn) == CALL_EXPR)
9809 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9810 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9813 return 0;
9817 /* Emit warning if a buffer overflow is detected at compile time. */
9819 static void
9820 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9822 int arg_mask, is_strlen = 0;
9823 tree arglist = TREE_OPERAND (exp, 1), a;
9824 tree len, size;
9825 location_t locus;
9827 switch (fcode)
9829 case BUILT_IN_STRCPY_CHK:
9830 case BUILT_IN_STPCPY_CHK:
9831 /* For __strcat_chk the warning will be emitted only if overflowing
9832 by at least strlen (dest) + 1 bytes. */
9833 case BUILT_IN_STRCAT_CHK:
9834 arg_mask = 6;
9835 is_strlen = 1;
9836 break;
9837 case BUILT_IN_STRNCPY_CHK:
9838 arg_mask = 12;
9839 break;
9840 case BUILT_IN_SNPRINTF_CHK:
9841 case BUILT_IN_VSNPRINTF_CHK:
9842 arg_mask = 10;
9843 break;
9844 default:
9845 gcc_unreachable ();
9848 len = NULL_TREE;
9849 size = NULL_TREE;
9850 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9851 if (arg_mask & 1)
9853 if (len)
9854 size = a;
9855 else
9856 len = a;
9859 if (!len || !size)
9860 return;
9862 len = TREE_VALUE (len);
9863 size = TREE_VALUE (size);
9865 if (! host_integerp (size, 1) || integer_all_onesp (size))
9866 return;
9868 if (is_strlen)
9870 len = c_strlen (len, 1);
9871 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9872 return;
9874 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9875 return;
9877 locus = EXPR_LOCATION (exp);
9878 warning (0, "%Hcall to %D will always overflow destination buffer",
9879 &locus, get_callee_fndecl (exp));
9882 /* Emit warning if a buffer overflow is detected at compile time
9883 in __sprintf_chk/__vsprintf_chk calls. */
9885 static void
9886 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9888 tree arglist = TREE_OPERAND (exp, 1);
9889 tree dest, size, len, fmt, flag;
9890 const char *fmt_str;
9892 /* Verify the required arguments in the original call. */
9893 if (! arglist)
9894 return;
9895 dest = TREE_VALUE (arglist);
9896 arglist = TREE_CHAIN (arglist);
9897 if (! arglist)
9898 return;
9899 flag = TREE_VALUE (arglist);
9900 arglist = TREE_CHAIN (arglist);
9901 if (! arglist)
9902 return;
9903 size = TREE_VALUE (arglist);
9904 arglist = TREE_CHAIN (arglist);
9905 if (! arglist)
9906 return;
9907 fmt = TREE_VALUE (arglist);
9908 arglist = TREE_CHAIN (arglist);
9910 if (! host_integerp (size, 1) || integer_all_onesp (size))
9911 return;
9913 /* Check whether the format is a literal string constant. */
9914 fmt_str = c_getstr (fmt);
9915 if (fmt_str == NULL)
9916 return;
9918 if (!init_target_chars())
9919 return;
9921 /* If the format doesn't contain % args or %%, we know its size. */
9922 if (strchr (fmt_str, target_percent) == 0)
9923 len = build_int_cstu (size_type_node, strlen (fmt_str));
9924 /* If the format is "%s" and first ... argument is a string literal,
9925 we know it too. */
9926 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9928 tree arg;
9930 if (! arglist)
9931 return;
9932 arg = TREE_VALUE (arglist);
9933 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9934 return;
9936 len = c_strlen (arg, 1);
9937 if (!len || ! host_integerp (len, 1))
9938 return;
9940 else
9941 return;
9943 if (! tree_int_cst_lt (len, size))
9945 location_t locus = EXPR_LOCATION (exp);
9946 warning (0, "%Hcall to %D will always overflow destination buffer",
9947 &locus, get_callee_fndecl (exp));
9951 /* Fold a call to __builtin_object_size, if possible. */
9953 tree
9954 fold_builtin_object_size (tree arglist)
9956 tree ptr, ost, ret = 0;
9957 int object_size_type;
9959 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9960 return 0;
9962 ptr = TREE_VALUE (arglist);
9963 ost = TREE_VALUE (TREE_CHAIN (arglist));
9964 STRIP_NOPS (ost);
9966 if (TREE_CODE (ost) != INTEGER_CST
9967 || tree_int_cst_sgn (ost) < 0
9968 || compare_tree_int (ost, 3) > 0)
9969 return 0;
9971 object_size_type = tree_low_cst (ost, 0);
9973 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9974 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9975 and (size_t) 0 for types 2 and 3. */
9976 if (TREE_SIDE_EFFECTS (ptr))
9977 return fold_convert (size_type_node,
9978 object_size_type < 2
9979 ? integer_minus_one_node : integer_zero_node);
9981 if (TREE_CODE (ptr) == ADDR_EXPR)
9982 ret = build_int_cstu (size_type_node,
9983 compute_builtin_object_size (ptr, object_size_type));
9985 else if (TREE_CODE (ptr) == SSA_NAME)
9987 unsigned HOST_WIDE_INT bytes;
9989 /* If object size is not known yet, delay folding until
9990 later. Maybe subsequent passes will help determining
9991 it. */
9992 bytes = compute_builtin_object_size (ptr, object_size_type);
9993 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
9994 ? -1 : 0))
9995 ret = build_int_cstu (size_type_node, bytes);
9998 if (ret)
10000 ret = force_fit_type (ret, -1, false, false);
10001 if (TREE_CONSTANT_OVERFLOW (ret))
10002 ret = 0;
10005 return ret;
10008 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10009 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10010 code of the builtin. If MAXLEN is not NULL, it is maximum length
10011 passed as third argument. */
10013 tree
10014 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10015 enum built_in_function fcode)
10017 tree dest, src, len, size, fn;
10019 if (!validate_arglist (arglist,
10020 POINTER_TYPE,
10021 fcode == BUILT_IN_MEMSET_CHK
10022 ? INTEGER_TYPE : POINTER_TYPE,
10023 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10024 return 0;
10026 dest = TREE_VALUE (arglist);
10027 /* Actually val for __memset_chk, but it doesn't matter. */
10028 src = TREE_VALUE (TREE_CHAIN (arglist));
10029 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10030 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10032 /* If SRC and DEST are the same (and not volatile), return DEST
10033 (resp. DEST+LEN for __mempcpy_chk). */
10034 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10036 if (fcode != BUILT_IN_MEMPCPY_CHK)
10037 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10038 else
10040 tree temp = fold_convert (TREE_TYPE (dest), len);
10041 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10042 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10046 if (! host_integerp (size, 1))
10047 return 0;
10049 if (! integer_all_onesp (size))
10051 if (! host_integerp (len, 1))
10053 /* If LEN is not constant, try MAXLEN too.
10054 For MAXLEN only allow optimizing into non-_ocs function
10055 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10056 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10058 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10060 /* (void) __mempcpy_chk () can be optimized into
10061 (void) __memcpy_chk (). */
10062 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10063 if (!fn)
10064 return 0;
10066 return build_function_call_expr (fn, arglist);
10068 return 0;
10071 else
10072 maxlen = len;
10074 if (tree_int_cst_lt (size, maxlen))
10075 return 0;
10078 arglist = build_tree_list (NULL_TREE, len);
10079 arglist = tree_cons (NULL_TREE, src, arglist);
10080 arglist = tree_cons (NULL_TREE, dest, arglist);
10082 fn = NULL_TREE;
10083 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10084 mem{cpy,pcpy,move,set} is available. */
10085 switch (fcode)
10087 case BUILT_IN_MEMCPY_CHK:
10088 fn = built_in_decls[BUILT_IN_MEMCPY];
10089 break;
10090 case BUILT_IN_MEMPCPY_CHK:
10091 fn = built_in_decls[BUILT_IN_MEMPCPY];
10092 break;
10093 case BUILT_IN_MEMMOVE_CHK:
10094 fn = built_in_decls[BUILT_IN_MEMMOVE];
10095 break;
10096 case BUILT_IN_MEMSET_CHK:
10097 fn = built_in_decls[BUILT_IN_MEMSET];
10098 break;
10099 default:
10100 break;
10103 if (!fn)
10104 return 0;
10106 return build_function_call_expr (fn, arglist);
10109 /* Fold a call to the __st[rp]cpy_chk builtin.
10110 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10111 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10112 strings passed as second argument. */
10114 tree
10115 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10116 enum built_in_function fcode)
10118 tree dest, src, size, len, fn;
10120 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10121 VOID_TYPE))
10122 return 0;
10124 dest = TREE_VALUE (arglist);
10125 src = TREE_VALUE (TREE_CHAIN (arglist));
10126 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10128 /* If SRC and DEST are the same (and not volatile), return DEST. */
10129 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10130 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10132 if (! host_integerp (size, 1))
10133 return 0;
10135 if (! integer_all_onesp (size))
10137 len = c_strlen (src, 1);
10138 if (! len || ! host_integerp (len, 1))
10140 /* If LEN is not constant, try MAXLEN too.
10141 For MAXLEN only allow optimizing into non-_ocs function
10142 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10143 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10145 if (fcode == BUILT_IN_STPCPY_CHK)
10147 if (! ignore)
10148 return 0;
10150 /* If return value of __stpcpy_chk is ignored,
10151 optimize into __strcpy_chk. */
10152 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10153 if (!fn)
10154 return 0;
10156 return build_function_call_expr (fn, arglist);
10159 if (! len || TREE_SIDE_EFFECTS (len))
10160 return 0;
10162 /* If c_strlen returned something, but not a constant,
10163 transform __strcpy_chk into __memcpy_chk. */
10164 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10165 if (!fn)
10166 return 0;
10168 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10169 arglist = build_tree_list (NULL_TREE, size);
10170 arglist = tree_cons (NULL_TREE, len, arglist);
10171 arglist = tree_cons (NULL_TREE, src, arglist);
10172 arglist = tree_cons (NULL_TREE, dest, arglist);
10173 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10174 build_function_call_expr (fn, arglist));
10177 else
10178 maxlen = len;
10180 if (! tree_int_cst_lt (maxlen, size))
10181 return 0;
10184 arglist = build_tree_list (NULL_TREE, src);
10185 arglist = tree_cons (NULL_TREE, dest, arglist);
10187 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10188 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10189 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10190 if (!fn)
10191 return 0;
10193 return build_function_call_expr (fn, arglist);
10196 /* Fold a call to the __strncpy_chk builtin.
10197 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10199 tree
10200 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10202 tree dest, src, size, len, fn;
10204 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10205 INTEGER_TYPE, VOID_TYPE))
10206 return 0;
10208 dest = TREE_VALUE (arglist);
10209 src = TREE_VALUE (TREE_CHAIN (arglist));
10210 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10211 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10213 if (! host_integerp (size, 1))
10214 return 0;
10216 if (! integer_all_onesp (size))
10218 if (! host_integerp (len, 1))
10220 /* If LEN is not constant, try MAXLEN too.
10221 For MAXLEN only allow optimizing into non-_ocs function
10222 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10223 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10224 return 0;
10226 else
10227 maxlen = len;
10229 if (tree_int_cst_lt (size, maxlen))
10230 return 0;
10233 arglist = build_tree_list (NULL_TREE, len);
10234 arglist = tree_cons (NULL_TREE, src, arglist);
10235 arglist = tree_cons (NULL_TREE, dest, arglist);
10237 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10238 fn = built_in_decls[BUILT_IN_STRNCPY];
10239 if (!fn)
10240 return 0;
10242 return build_function_call_expr (fn, arglist);
10245 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10247 static tree
10248 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10250 tree dest, src, size, fn;
10251 const char *p;
10253 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10254 VOID_TYPE))
10255 return 0;
10257 dest = TREE_VALUE (arglist);
10258 src = TREE_VALUE (TREE_CHAIN (arglist));
10259 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10261 p = c_getstr (src);
10262 /* If the SRC parameter is "", return DEST. */
10263 if (p && *p == '\0')
10264 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10266 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10267 return 0;
10269 arglist = build_tree_list (NULL_TREE, src);
10270 arglist = tree_cons (NULL_TREE, dest, arglist);
10272 /* If __builtin_strcat_chk is used, assume strcat is available. */
10273 fn = built_in_decls[BUILT_IN_STRCAT];
10274 if (!fn)
10275 return 0;
10277 return build_function_call_expr (fn, arglist);
10280 /* Fold a call to the __strncat_chk builtin EXP. */
10282 static tree
10283 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10285 tree dest, src, size, len, fn;
10286 const char *p;
10288 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10289 INTEGER_TYPE, VOID_TYPE))
10290 return 0;
10292 dest = TREE_VALUE (arglist);
10293 src = TREE_VALUE (TREE_CHAIN (arglist));
10294 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10295 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10297 p = c_getstr (src);
10298 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10299 if (p && *p == '\0')
10300 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10301 else if (integer_zerop (len))
10302 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10304 if (! host_integerp (size, 1))
10305 return 0;
10307 if (! integer_all_onesp (size))
10309 tree src_len = c_strlen (src, 1);
10310 if (src_len
10311 && host_integerp (src_len, 1)
10312 && host_integerp (len, 1)
10313 && ! tree_int_cst_lt (len, src_len))
10315 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10316 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10317 if (!fn)
10318 return 0;
10320 arglist = build_tree_list (NULL_TREE, size);
10321 arglist = tree_cons (NULL_TREE, src, arglist);
10322 arglist = tree_cons (NULL_TREE, dest, arglist);
10323 return build_function_call_expr (fn, arglist);
10325 return 0;
10328 arglist = build_tree_list (NULL_TREE, len);
10329 arglist = tree_cons (NULL_TREE, src, arglist);
10330 arglist = tree_cons (NULL_TREE, dest, arglist);
10332 /* If __builtin_strncat_chk is used, assume strncat is available. */
10333 fn = built_in_decls[BUILT_IN_STRNCAT];
10334 if (!fn)
10335 return 0;
10337 return build_function_call_expr (fn, arglist);
10340 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10341 a normal call should be emitted rather than expanding the function
10342 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10344 static tree
10345 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10347 tree dest, size, len, fn, fmt, flag;
10348 const char *fmt_str;
10350 /* Verify the required arguments in the original call. */
10351 if (! arglist)
10352 return 0;
10353 dest = TREE_VALUE (arglist);
10354 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10355 return 0;
10356 arglist = TREE_CHAIN (arglist);
10357 if (! arglist)
10358 return 0;
10359 flag = TREE_VALUE (arglist);
10360 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10361 return 0;
10362 arglist = TREE_CHAIN (arglist);
10363 if (! arglist)
10364 return 0;
10365 size = TREE_VALUE (arglist);
10366 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10367 return 0;
10368 arglist = TREE_CHAIN (arglist);
10369 if (! arglist)
10370 return 0;
10371 fmt = TREE_VALUE (arglist);
10372 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10373 return 0;
10374 arglist = TREE_CHAIN (arglist);
10376 if (! host_integerp (size, 1))
10377 return 0;
10379 len = NULL_TREE;
10381 if (!init_target_chars())
10382 return 0;
10384 /* Check whether the format is a literal string constant. */
10385 fmt_str = c_getstr (fmt);
10386 if (fmt_str != NULL)
10388 /* If the format doesn't contain % args or %%, we know the size. */
10389 if (strchr (fmt_str, target_percent) == 0)
10391 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10392 len = build_int_cstu (size_type_node, strlen (fmt_str));
10394 /* If the format is "%s" and first ... argument is a string literal,
10395 we know the size too. */
10396 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10398 tree arg;
10400 if (arglist && !TREE_CHAIN (arglist))
10402 arg = TREE_VALUE (arglist);
10403 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10405 len = c_strlen (arg, 1);
10406 if (! len || ! host_integerp (len, 1))
10407 len = NULL_TREE;
10413 if (! integer_all_onesp (size))
10415 if (! len || ! tree_int_cst_lt (len, size))
10416 return 0;
10419 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10420 or if format doesn't contain % chars or is "%s". */
10421 if (! integer_zerop (flag))
10423 if (fmt_str == NULL)
10424 return 0;
10425 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10426 return 0;
10429 arglist = tree_cons (NULL_TREE, fmt, arglist);
10430 arglist = tree_cons (NULL_TREE, dest, arglist);
10432 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10433 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10434 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10435 if (!fn)
10436 return 0;
10438 return build_function_call_expr (fn, arglist);
10441 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10442 a normal call should be emitted rather than expanding the function
10443 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10444 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10445 passed as second argument. */
10447 tree
10448 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10449 enum built_in_function fcode)
10451 tree dest, size, len, fn, fmt, flag;
10452 const char *fmt_str;
10454 /* Verify the required arguments in the original call. */
10455 if (! arglist)
10456 return 0;
10457 dest = TREE_VALUE (arglist);
10458 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10459 return 0;
10460 arglist = TREE_CHAIN (arglist);
10461 if (! arglist)
10462 return 0;
10463 len = TREE_VALUE (arglist);
10464 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10465 return 0;
10466 arglist = TREE_CHAIN (arglist);
10467 if (! arglist)
10468 return 0;
10469 flag = TREE_VALUE (arglist);
10470 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10471 return 0;
10472 arglist = TREE_CHAIN (arglist);
10473 if (! arglist)
10474 return 0;
10475 size = TREE_VALUE (arglist);
10476 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10477 return 0;
10478 arglist = TREE_CHAIN (arglist);
10479 if (! arglist)
10480 return 0;
10481 fmt = TREE_VALUE (arglist);
10482 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10483 return 0;
10484 arglist = TREE_CHAIN (arglist);
10486 if (! host_integerp (size, 1))
10487 return 0;
10489 if (! integer_all_onesp (size))
10491 if (! host_integerp (len, 1))
10493 /* If LEN is not constant, try MAXLEN too.
10494 For MAXLEN only allow optimizing into non-_ocs function
10495 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10496 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10497 return 0;
10499 else
10500 maxlen = len;
10502 if (tree_int_cst_lt (size, maxlen))
10503 return 0;
10506 if (!init_target_chars())
10507 return 0;
10509 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10510 or if format doesn't contain % chars or is "%s". */
10511 if (! integer_zerop (flag))
10513 fmt_str = c_getstr (fmt);
10514 if (fmt_str == NULL)
10515 return 0;
10516 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10517 return 0;
10520 arglist = tree_cons (NULL_TREE, fmt, arglist);
10521 arglist = tree_cons (NULL_TREE, len, arglist);
10522 arglist = tree_cons (NULL_TREE, dest, arglist);
10524 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10525 available. */
10526 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10527 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10528 if (!fn)
10529 return 0;
10531 return build_function_call_expr (fn, arglist);
10534 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10536 Return 0 if no simplification was possible, otherwise return the
10537 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10538 code of the function to be simplified. */
10540 static tree
10541 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10542 enum built_in_function fcode)
10544 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10545 const char *fmt_str = NULL;
10547 /* If the return value is used, don't do the transformation. */
10548 if (! ignore)
10549 return 0;
10551 /* Verify the required arguments in the original call. */
10552 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10554 tree flag;
10556 if (! arglist)
10557 return 0;
10558 flag = TREE_VALUE (arglist);
10559 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10560 || TREE_SIDE_EFFECTS (flag))
10561 return 0;
10562 arglist = TREE_CHAIN (arglist);
10565 if (! arglist)
10566 return 0;
10567 fmt = TREE_VALUE (arglist);
10568 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10569 return 0;
10570 arglist = TREE_CHAIN (arglist);
10572 /* Check whether the format is a literal string constant. */
10573 fmt_str = c_getstr (fmt);
10574 if (fmt_str == NULL)
10575 return NULL_TREE;
10577 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10579 /* If we're using an unlocked function, assume the other
10580 unlocked functions exist explicitly. */
10581 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10582 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10584 else
10586 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10587 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10590 if (!init_target_chars())
10591 return 0;
10593 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10595 const char *str;
10597 if (strcmp (fmt_str, target_percent_s) == 0)
10599 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10600 return 0;
10602 if (! arglist
10603 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10604 || TREE_CHAIN (arglist))
10605 return 0;
10607 str = c_getstr (TREE_VALUE (arglist));
10608 if (str == NULL)
10609 return 0;
10611 else
10613 /* The format specifier doesn't contain any '%' characters. */
10614 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10615 && arglist)
10616 return 0;
10617 str = fmt_str;
10620 /* If the string was "", printf does nothing. */
10621 if (str[0] == '\0')
10622 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10624 /* If the string has length of 1, call putchar. */
10625 if (str[1] == '\0')
10627 /* Given printf("c"), (where c is any one character,)
10628 convert "c"[0] to an int and pass that to the replacement
10629 function. */
10630 arg = build_int_cst (NULL_TREE, str[0]);
10631 arglist = build_tree_list (NULL_TREE, arg);
10632 fn = fn_putchar;
10634 else
10636 /* If the string was "string\n", call puts("string"). */
10637 size_t len = strlen (str);
10638 if ((unsigned char)str[len - 1] == target_newline)
10640 /* Create a NUL-terminated string that's one char shorter
10641 than the original, stripping off the trailing '\n'. */
10642 char *newstr = alloca (len);
10643 memcpy (newstr, str, len - 1);
10644 newstr[len - 1] = 0;
10646 arg = build_string_literal (len, newstr);
10647 arglist = build_tree_list (NULL_TREE, arg);
10648 fn = fn_puts;
10650 else
10651 /* We'd like to arrange to call fputs(string,stdout) here,
10652 but we need stdout and don't have a way to get it yet. */
10653 return 0;
10657 /* The other optimizations can be done only on the non-va_list variants. */
10658 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10659 return 0;
10661 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10662 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10664 if (! arglist
10665 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10666 || TREE_CHAIN (arglist))
10667 return 0;
10668 fn = fn_puts;
10671 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10672 else if (strcmp (fmt_str, target_percent_c) == 0)
10674 if (! arglist
10675 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10676 || TREE_CHAIN (arglist))
10677 return 0;
10678 fn = fn_putchar;
10681 if (!fn)
10682 return 0;
10684 call = build_function_call_expr (fn, arglist);
10685 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10688 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10690 Return 0 if no simplification was possible, otherwise return the
10691 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10692 code of the function to be simplified. */
10694 static tree
10695 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10696 enum built_in_function fcode)
10698 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10699 const char *fmt_str = NULL;
10701 /* If the return value is used, don't do the transformation. */
10702 if (! ignore)
10703 return 0;
10705 /* Verify the required arguments in the original call. */
10706 if (! arglist)
10707 return 0;
10708 fp = TREE_VALUE (arglist);
10709 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10710 return 0;
10711 arglist = TREE_CHAIN (arglist);
10713 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10715 tree flag;
10717 if (! arglist)
10718 return 0;
10719 flag = TREE_VALUE (arglist);
10720 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10721 || TREE_SIDE_EFFECTS (flag))
10722 return 0;
10723 arglist = TREE_CHAIN (arglist);
10726 if (! arglist)
10727 return 0;
10728 fmt = TREE_VALUE (arglist);
10729 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10730 return 0;
10731 arglist = TREE_CHAIN (arglist);
10733 /* Check whether the format is a literal string constant. */
10734 fmt_str = c_getstr (fmt);
10735 if (fmt_str == NULL)
10736 return NULL_TREE;
10738 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10740 /* If we're using an unlocked function, assume the other
10741 unlocked functions exist explicitly. */
10742 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10743 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10745 else
10747 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10748 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10751 if (!init_target_chars())
10752 return 0;
10754 /* If the format doesn't contain % args or %%, use strcpy. */
10755 if (strchr (fmt_str, target_percent) == NULL)
10757 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10758 && arglist)
10759 return 0;
10761 /* If the format specifier was "", fprintf does nothing. */
10762 if (fmt_str[0] == '\0')
10764 /* If FP has side-effects, just wait until gimplification is
10765 done. */
10766 if (TREE_SIDE_EFFECTS (fp))
10767 return 0;
10769 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10772 /* When "string" doesn't contain %, replace all cases of
10773 fprintf (fp, string) with fputs (string, fp). The fputs
10774 builtin will take care of special cases like length == 1. */
10775 arglist = build_tree_list (NULL_TREE, fp);
10776 arglist = tree_cons (NULL_TREE, fmt, arglist);
10777 fn = fn_fputs;
10780 /* The other optimizations can be done only on the non-va_list variants. */
10781 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10782 return 0;
10784 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10785 else if (strcmp (fmt_str, target_percent_s) == 0)
10787 if (! arglist
10788 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10789 || TREE_CHAIN (arglist))
10790 return 0;
10791 arg = TREE_VALUE (arglist);
10792 arglist = build_tree_list (NULL_TREE, fp);
10793 arglist = tree_cons (NULL_TREE, arg, arglist);
10794 fn = fn_fputs;
10797 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10798 else if (strcmp (fmt_str, target_percent_c) == 0)
10800 if (! arglist
10801 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10802 || TREE_CHAIN (arglist))
10803 return 0;
10804 arg = TREE_VALUE (arglist);
10805 arglist = build_tree_list (NULL_TREE, fp);
10806 arglist = tree_cons (NULL_TREE, arg, arglist);
10807 fn = fn_fputc;
10810 if (!fn)
10811 return 0;
10813 call = build_function_call_expr (fn, arglist);
10814 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10817 /* Initialize format string characters in the target charset. */
10819 static bool
10820 init_target_chars (void)
10822 static bool init;
10823 if (!init)
10825 target_newline = lang_hooks.to_target_charset ('\n');
10826 target_percent = lang_hooks.to_target_charset ('%');
10827 target_c = lang_hooks.to_target_charset ('c');
10828 target_s = lang_hooks.to_target_charset ('s');
10829 if (target_newline == 0 || target_percent == 0 || target_c == 0
10830 || target_s == 0)
10831 return false;
10833 target_percent_c[0] = target_percent;
10834 target_percent_c[1] = target_c;
10835 target_percent_c[2] = '\0';
10837 target_percent_s[0] = target_percent;
10838 target_percent_s[1] = target_s;
10839 target_percent_s[2] = '\0';
10841 target_percent_s_newline[0] = target_percent;
10842 target_percent_s_newline[1] = target_s;
10843 target_percent_s_newline[2] = target_newline;
10844 target_percent_s_newline[3] = '\0';
10846 init = true;
10848 return true;