* compress.c (write_data): Mark 'ze' as unused.
[official-gcc.git] / gcc / builtins.c
blob2f7b23a49e8c25ca96d47dc8949ec0a8fbd26405
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 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 tree build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx result_vector (int, rtx);
84 #endif
85 static rtx expand_builtin_setjmp (tree, rtx);
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
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_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
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_expr (t_label, NULL_RTX, VOIDmode, 0);
846 r_label = convert_memory_address (Pmode, r_label);
847 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
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_expr (arg1, NULL_RTX, VOIDmode, 0);
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_expr (arg2, NULL_RTX, VOIDmode, 0);
994 /* Argument 2 must be 0, 1, 2, or 3. */
995 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
997 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
998 op2 = const0_rtx;
1001 #ifdef HAVE_prefetch
1002 if (HAVE_prefetch)
1004 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1005 (op0,
1006 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1007 || (GET_MODE (op0) != Pmode))
1009 op0 = convert_memory_address (Pmode, op0);
1010 op0 = force_reg (Pmode, op0);
1012 emit_insn (gen_prefetch (op0, op1, op2));
1014 #endif
1016 /* Don't do anything with direct references to volatile memory, but
1017 generate code to handle other side effects. */
1018 if (!MEM_P (op0) && side_effects_p (op0))
1019 emit_insn (op0);
1022 /* Get a MEM rtx for expression EXP which is the address of an operand
1023 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1024 the maximum length of the block of memory that might be accessed or
1025 NULL if unknown. */
1027 static rtx
1028 get_memory_rtx (tree exp, tree len)
1030 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1031 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1033 /* Get an expression we can use to find the attributes to assign to MEM.
1034 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1035 we can. First remove any nops. */
1036 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1037 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1038 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1039 exp = TREE_OPERAND (exp, 0);
1041 if (TREE_CODE (exp) == ADDR_EXPR)
1042 exp = TREE_OPERAND (exp, 0);
1043 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1044 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1045 else
1046 exp = NULL;
1048 /* Honor attributes derived from exp, except for the alias set
1049 (as builtin stringops may alias with anything) and the size
1050 (as stringops may access multiple array elements). */
1051 if (exp)
1053 set_mem_attributes (mem, exp, 0);
1055 /* Allow the string and memory builtins to overflow from one
1056 field into another, see http://gcc.gnu.org/PR23561.
1057 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1058 memory accessed by the string or memory builtin will fit
1059 within the field. */
1060 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1062 tree mem_expr = MEM_EXPR (mem);
1063 HOST_WIDE_INT offset = -1, length = -1;
1064 tree inner = exp;
1066 while (TREE_CODE (inner) == ARRAY_REF
1067 || TREE_CODE (inner) == NOP_EXPR
1068 || TREE_CODE (inner) == CONVERT_EXPR
1069 || TREE_CODE (inner) == NON_LVALUE_EXPR
1070 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1071 || TREE_CODE (inner) == SAVE_EXPR)
1072 inner = TREE_OPERAND (inner, 0);
1074 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1076 if (MEM_OFFSET (mem)
1077 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1078 offset = INTVAL (MEM_OFFSET (mem));
1080 if (offset >= 0 && len && host_integerp (len, 0))
1081 length = tree_low_cst (len, 0);
1083 while (TREE_CODE (inner) == COMPONENT_REF)
1085 tree field = TREE_OPERAND (inner, 1);
1086 gcc_assert (! DECL_BIT_FIELD (field));
1087 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1088 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1090 if (length >= 0
1091 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1092 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1094 HOST_WIDE_INT size
1095 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1096 /* If we can prove the memory starting at XEXP (mem, 0)
1097 and ending at XEXP (mem, 0) + LENGTH will fit into
1098 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1099 if (offset <= size
1100 && length <= size
1101 && offset + length <= size)
1102 break;
1105 if (offset >= 0
1106 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1107 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1108 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1109 / BITS_PER_UNIT;
1110 else
1112 offset = -1;
1113 length = -1;
1116 mem_expr = TREE_OPERAND (mem_expr, 0);
1117 inner = TREE_OPERAND (inner, 0);
1120 if (mem_expr == NULL)
1121 offset = -1;
1122 if (mem_expr != MEM_EXPR (mem))
1124 set_mem_expr (mem, mem_expr);
1125 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1128 set_mem_alias_set (mem, 0);
1129 set_mem_size (mem, NULL_RTX);
1132 return mem;
1135 /* Built-in functions to perform an untyped call and return. */
1137 /* For each register that may be used for calling a function, this
1138 gives a mode used to copy the register's value. VOIDmode indicates
1139 the register is not used for calling a function. If the machine
1140 has register windows, this gives only the outbound registers.
1141 INCOMING_REGNO gives the corresponding inbound register. */
1142 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1144 /* For each register that may be used for returning values, this gives
1145 a mode used to copy the register's value. VOIDmode indicates the
1146 register is not used for returning values. If the machine has
1147 register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1151 /* For each register that may be used for calling a function, this
1152 gives the offset of that register into the block returned by
1153 __builtin_apply_args. 0 indicates that the register is not
1154 used for calling a function. */
1155 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1157 /* Return the size required for the block returned by __builtin_apply_args,
1158 and initialize apply_args_mode. */
1160 static int
1161 apply_args_size (void)
1163 static int size = -1;
1164 int align;
1165 unsigned int regno;
1166 enum machine_mode mode;
1168 /* The values computed by this function never change. */
1169 if (size < 0)
1171 /* The first value is the incoming arg-pointer. */
1172 size = GET_MODE_SIZE (Pmode);
1174 /* The second value is the structure value address unless this is
1175 passed as an "invisible" first argument. */
1176 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1177 size += GET_MODE_SIZE (Pmode);
1179 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1180 if (FUNCTION_ARG_REGNO_P (regno))
1182 mode = reg_raw_mode[regno];
1184 gcc_assert (mode != VOIDmode);
1186 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1187 if (size % align != 0)
1188 size = CEIL (size, align) * align;
1189 apply_args_reg_offset[regno] = size;
1190 size += GET_MODE_SIZE (mode);
1191 apply_args_mode[regno] = mode;
1193 else
1195 apply_args_mode[regno] = VOIDmode;
1196 apply_args_reg_offset[regno] = 0;
1199 return size;
1202 /* Return the size required for the block returned by __builtin_apply,
1203 and initialize apply_result_mode. */
1205 static int
1206 apply_result_size (void)
1208 static int size = -1;
1209 int align, regno;
1210 enum machine_mode mode;
1212 /* The values computed by this function never change. */
1213 if (size < 0)
1215 size = 0;
1217 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1218 if (FUNCTION_VALUE_REGNO_P (regno))
1220 mode = reg_raw_mode[regno];
1222 gcc_assert (mode != VOIDmode);
1224 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1225 if (size % align != 0)
1226 size = CEIL (size, align) * align;
1227 size += GET_MODE_SIZE (mode);
1228 apply_result_mode[regno] = mode;
1230 else
1231 apply_result_mode[regno] = VOIDmode;
1233 /* Allow targets that use untyped_call and untyped_return to override
1234 the size so that machine-specific information can be stored here. */
1235 #ifdef APPLY_RESULT_SIZE
1236 size = APPLY_RESULT_SIZE;
1237 #endif
1239 return size;
1242 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1243 /* Create a vector describing the result block RESULT. If SAVEP is true,
1244 the result block is used to save the values; otherwise it is used to
1245 restore the values. */
1247 static rtx
1248 result_vector (int savep, rtx result)
1250 int regno, size, align, nelts;
1251 enum machine_mode mode;
1252 rtx reg, mem;
1253 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1255 size = nelts = 0;
1256 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1257 if ((mode = apply_result_mode[regno]) != VOIDmode)
1259 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1260 if (size % align != 0)
1261 size = CEIL (size, align) * align;
1262 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1263 mem = adjust_address (result, mode, size);
1264 savevec[nelts++] = (savep
1265 ? gen_rtx_SET (VOIDmode, mem, reg)
1266 : gen_rtx_SET (VOIDmode, reg, mem));
1267 size += GET_MODE_SIZE (mode);
1269 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1271 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1273 /* Save the state required to perform an untyped call with the same
1274 arguments as were passed to the current function. */
1276 static rtx
1277 expand_builtin_apply_args_1 (void)
1279 rtx registers, tem;
1280 int size, align, regno;
1281 enum machine_mode mode;
1282 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1284 /* Create a block where the arg-pointer, structure value address,
1285 and argument registers can be saved. */
1286 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1288 /* Walk past the arg-pointer and structure value address. */
1289 size = GET_MODE_SIZE (Pmode);
1290 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1291 size += GET_MODE_SIZE (Pmode);
1293 /* Save each register used in calling a function to the block. */
1294 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1295 if ((mode = apply_args_mode[regno]) != VOIDmode)
1297 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1298 if (size % align != 0)
1299 size = CEIL (size, align) * align;
1301 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1303 emit_move_insn (adjust_address (registers, mode, size), tem);
1304 size += GET_MODE_SIZE (mode);
1307 /* Save the arg pointer to the block. */
1308 tem = copy_to_reg (virtual_incoming_args_rtx);
1309 #ifdef STACK_GROWS_DOWNWARD
1310 /* We need the pointer as the caller actually passed them to us, not
1311 as we might have pretended they were passed. Make sure it's a valid
1312 operand, as emit_move_insn isn't expected to handle a PLUS. */
1314 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1315 NULL_RTX);
1316 #endif
1317 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1319 size = GET_MODE_SIZE (Pmode);
1321 /* Save the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 if (struct_incoming_value)
1325 emit_move_insn (adjust_address (registers, Pmode, size),
1326 copy_to_reg (struct_incoming_value));
1327 size += GET_MODE_SIZE (Pmode);
1330 /* Return the address of the block. */
1331 return copy_addr_to_reg (XEXP (registers, 0));
1334 /* __builtin_apply_args returns block of memory allocated on
1335 the stack into which is stored the arg pointer, structure
1336 value address, static chain, and all the registers that might
1337 possibly be used in performing a function call. The code is
1338 moved to the start of the function so the incoming values are
1339 saved. */
1341 static rtx
1342 expand_builtin_apply_args (void)
1344 /* Don't do __builtin_apply_args more than once in a function.
1345 Save the result of the first call and reuse it. */
1346 if (apply_args_value != 0)
1347 return apply_args_value;
1349 /* When this function is called, it means that registers must be
1350 saved on entry to this function. So we migrate the
1351 call to the first insn of this function. */
1352 rtx temp;
1353 rtx seq;
1355 start_sequence ();
1356 temp = expand_builtin_apply_args_1 ();
1357 seq = get_insns ();
1358 end_sequence ();
1360 apply_args_value = temp;
1362 /* Put the insns after the NOTE that starts the function.
1363 If this is inside a start_sequence, make the outer-level insn
1364 chain current, so the code is placed at the start of the
1365 function. */
1366 push_topmost_sequence ();
1367 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1368 pop_topmost_sequence ();
1369 return temp;
1373 /* Perform an untyped call and save the state required to perform an
1374 untyped return of whatever value was returned by the given function. */
1376 static rtx
1377 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1379 int size, align, regno;
1380 enum machine_mode mode;
1381 rtx incoming_args, result, reg, dest, src, call_insn;
1382 rtx old_stack_level = 0;
1383 rtx call_fusage = 0;
1384 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1386 arguments = convert_memory_address (Pmode, arguments);
1388 /* Create a block where the return registers can be saved. */
1389 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1391 /* Fetch the arg pointer from the ARGUMENTS block. */
1392 incoming_args = gen_reg_rtx (Pmode);
1393 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1394 #ifndef STACK_GROWS_DOWNWARD
1395 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1396 incoming_args, 0, OPTAB_LIB_WIDEN);
1397 #endif
1399 /* Push a new argument block and copy the arguments. Do not allow
1400 the (potential) memcpy call below to interfere with our stack
1401 manipulations. */
1402 do_pending_stack_adjust ();
1403 NO_DEFER_POP;
1405 /* Save the stack with nonlocal if available. */
1406 #ifdef HAVE_save_stack_nonlocal
1407 if (HAVE_save_stack_nonlocal)
1408 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1409 else
1410 #endif
1411 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1413 /* Allocate a block of memory onto the stack and copy the memory
1414 arguments to the outgoing arguments address. */
1415 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1416 dest = virtual_outgoing_args_rtx;
1417 #ifndef STACK_GROWS_DOWNWARD
1418 if (GET_CODE (argsize) == CONST_INT)
1419 dest = plus_constant (dest, -INTVAL (argsize));
1420 else
1421 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1422 #endif
1423 dest = gen_rtx_MEM (BLKmode, dest);
1424 set_mem_align (dest, PARM_BOUNDARY);
1425 src = gen_rtx_MEM (BLKmode, incoming_args);
1426 set_mem_align (src, PARM_BOUNDARY);
1427 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1429 /* Refer to the argument block. */
1430 apply_args_size ();
1431 arguments = gen_rtx_MEM (BLKmode, arguments);
1432 set_mem_align (arguments, PARM_BOUNDARY);
1434 /* Walk past the arg-pointer and structure value address. */
1435 size = GET_MODE_SIZE (Pmode);
1436 if (struct_value)
1437 size += GET_MODE_SIZE (Pmode);
1439 /* Restore each of the registers previously saved. Make USE insns
1440 for each of these registers for use in making the call. */
1441 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1442 if ((mode = apply_args_mode[regno]) != VOIDmode)
1444 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1445 if (size % align != 0)
1446 size = CEIL (size, align) * align;
1447 reg = gen_rtx_REG (mode, regno);
1448 emit_move_insn (reg, adjust_address (arguments, mode, size));
1449 use_reg (&call_fusage, reg);
1450 size += GET_MODE_SIZE (mode);
1453 /* Restore the structure value address unless this is passed as an
1454 "invisible" first argument. */
1455 size = GET_MODE_SIZE (Pmode);
1456 if (struct_value)
1458 rtx value = gen_reg_rtx (Pmode);
1459 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1460 emit_move_insn (struct_value, value);
1461 if (REG_P (struct_value))
1462 use_reg (&call_fusage, struct_value);
1463 size += GET_MODE_SIZE (Pmode);
1466 /* All arguments and registers used for the call are set up by now! */
1467 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1469 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1470 and we don't want to load it into a register as an optimization,
1471 because prepare_call_address already did it if it should be done. */
1472 if (GET_CODE (function) != SYMBOL_REF)
1473 function = memory_address (FUNCTION_MODE, function);
1475 /* Generate the actual call instruction and save the return value. */
1476 #ifdef HAVE_untyped_call
1477 if (HAVE_untyped_call)
1478 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1479 result, result_vector (1, result)));
1480 else
1481 #endif
1482 #ifdef HAVE_call_value
1483 if (HAVE_call_value)
1485 rtx valreg = 0;
1487 /* Locate the unique return register. It is not possible to
1488 express a call that sets more than one return register using
1489 call_value; use untyped_call for that. In fact, untyped_call
1490 only needs to save the return registers in the given block. */
1491 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1492 if ((mode = apply_result_mode[regno]) != VOIDmode)
1494 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1496 valreg = gen_rtx_REG (mode, regno);
1499 emit_call_insn (GEN_CALL_VALUE (valreg,
1500 gen_rtx_MEM (FUNCTION_MODE, function),
1501 const0_rtx, NULL_RTX, const0_rtx));
1503 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1505 else
1506 #endif
1507 gcc_unreachable ();
1509 /* Find the CALL insn we just emitted, and attach the register usage
1510 information. */
1511 call_insn = last_call_insn ();
1512 add_function_usage_to (call_insn, call_fusage);
1514 /* Restore the stack. */
1515 #ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal)
1517 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1518 else
1519 #endif
1520 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1522 OK_DEFER_POP;
1524 /* Return the address of the result block. */
1525 result = copy_addr_to_reg (XEXP (result, 0));
1526 return convert_memory_address (ptr_mode, result);
1529 /* Perform an untyped return. */
1531 static void
1532 expand_builtin_return (rtx result)
1534 int size, align, regno;
1535 enum machine_mode mode;
1536 rtx reg;
1537 rtx call_fusage = 0;
1539 result = convert_memory_address (Pmode, result);
1541 apply_result_size ();
1542 result = gen_rtx_MEM (BLKmode, result);
1544 #ifdef HAVE_untyped_return
1545 if (HAVE_untyped_return)
1547 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1548 emit_barrier ();
1549 return;
1551 #endif
1553 /* Restore the return value and note that each value is used. */
1554 size = 0;
1555 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1556 if ((mode = apply_result_mode[regno]) != VOIDmode)
1558 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1559 if (size % align != 0)
1560 size = CEIL (size, align) * align;
1561 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1562 emit_move_insn (reg, adjust_address (result, mode, size));
1564 push_to_sequence (call_fusage);
1565 emit_insn (gen_rtx_USE (VOIDmode, reg));
1566 call_fusage = get_insns ();
1567 end_sequence ();
1568 size += GET_MODE_SIZE (mode);
1571 /* Put the USE insns before the return. */
1572 emit_insn (call_fusage);
1574 /* Return whatever values was restored by jumping directly to the end
1575 of the function. */
1576 expand_naked_return ();
1579 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1581 static enum type_class
1582 type_to_class (tree type)
1584 switch (TREE_CODE (type))
1586 case VOID_TYPE: return void_type_class;
1587 case INTEGER_TYPE: return integer_type_class;
1588 case CHAR_TYPE: return char_type_class;
1589 case ENUMERAL_TYPE: return enumeral_type_class;
1590 case BOOLEAN_TYPE: return boolean_type_class;
1591 case POINTER_TYPE: return pointer_type_class;
1592 case REFERENCE_TYPE: return reference_type_class;
1593 case OFFSET_TYPE: return offset_type_class;
1594 case REAL_TYPE: return real_type_class;
1595 case COMPLEX_TYPE: return complex_type_class;
1596 case FUNCTION_TYPE: return function_type_class;
1597 case METHOD_TYPE: return method_type_class;
1598 case RECORD_TYPE: return record_type_class;
1599 case UNION_TYPE:
1600 case QUAL_UNION_TYPE: return union_type_class;
1601 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1602 ? string_type_class : array_type_class);
1603 case LANG_TYPE: return lang_type_class;
1604 default: return no_type_class;
1608 /* Expand a call to __builtin_classify_type with arguments found in
1609 ARGLIST. */
1611 static rtx
1612 expand_builtin_classify_type (tree arglist)
1614 if (arglist != 0)
1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1616 return GEN_INT (no_type_class);
1619 /* This helper macro, meant to be used in mathfn_built_in below,
1620 determines which among a set of three builtin math functions is
1621 appropriate for a given type mode. The `F' and `L' cases are
1622 automatically generated from the `double' case. */
1623 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626 fcodel = BUILT_IN_MATHFN##L ; break;
1628 /* Return mathematic function equivalent to FN but operating directly
1629 on TYPE, if available. If we can't do the conversion, return zero. */
1630 tree
1631 mathfn_built_in (tree type, enum built_in_function fn)
1633 enum built_in_function fcode, fcodef, fcodel;
1635 switch (fn)
1637 CASE_MATHFN (BUILT_IN_ACOS)
1638 CASE_MATHFN (BUILT_IN_ACOSH)
1639 CASE_MATHFN (BUILT_IN_ASIN)
1640 CASE_MATHFN (BUILT_IN_ASINH)
1641 CASE_MATHFN (BUILT_IN_ATAN)
1642 CASE_MATHFN (BUILT_IN_ATAN2)
1643 CASE_MATHFN (BUILT_IN_ATANH)
1644 CASE_MATHFN (BUILT_IN_CBRT)
1645 CASE_MATHFN (BUILT_IN_CEIL)
1646 CASE_MATHFN (BUILT_IN_COPYSIGN)
1647 CASE_MATHFN (BUILT_IN_COS)
1648 CASE_MATHFN (BUILT_IN_COSH)
1649 CASE_MATHFN (BUILT_IN_DREM)
1650 CASE_MATHFN (BUILT_IN_ERF)
1651 CASE_MATHFN (BUILT_IN_ERFC)
1652 CASE_MATHFN (BUILT_IN_EXP)
1653 CASE_MATHFN (BUILT_IN_EXP10)
1654 CASE_MATHFN (BUILT_IN_EXP2)
1655 CASE_MATHFN (BUILT_IN_EXPM1)
1656 CASE_MATHFN (BUILT_IN_FABS)
1657 CASE_MATHFN (BUILT_IN_FDIM)
1658 CASE_MATHFN (BUILT_IN_FLOOR)
1659 CASE_MATHFN (BUILT_IN_FMA)
1660 CASE_MATHFN (BUILT_IN_FMAX)
1661 CASE_MATHFN (BUILT_IN_FMIN)
1662 CASE_MATHFN (BUILT_IN_FMOD)
1663 CASE_MATHFN (BUILT_IN_FREXP)
1664 CASE_MATHFN (BUILT_IN_GAMMA)
1665 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1666 CASE_MATHFN (BUILT_IN_HYPOT)
1667 CASE_MATHFN (BUILT_IN_ILOGB)
1668 CASE_MATHFN (BUILT_IN_INF)
1669 CASE_MATHFN (BUILT_IN_J0)
1670 CASE_MATHFN (BUILT_IN_J1)
1671 CASE_MATHFN (BUILT_IN_JN)
1672 CASE_MATHFN (BUILT_IN_LCEIL)
1673 CASE_MATHFN (BUILT_IN_LDEXP)
1674 CASE_MATHFN (BUILT_IN_LFLOOR)
1675 CASE_MATHFN (BUILT_IN_LGAMMA)
1676 CASE_MATHFN (BUILT_IN_LLCEIL)
1677 CASE_MATHFN (BUILT_IN_LLFLOOR)
1678 CASE_MATHFN (BUILT_IN_LLRINT)
1679 CASE_MATHFN (BUILT_IN_LLROUND)
1680 CASE_MATHFN (BUILT_IN_LOG)
1681 CASE_MATHFN (BUILT_IN_LOG10)
1682 CASE_MATHFN (BUILT_IN_LOG1P)
1683 CASE_MATHFN (BUILT_IN_LOG2)
1684 CASE_MATHFN (BUILT_IN_LOGB)
1685 CASE_MATHFN (BUILT_IN_LRINT)
1686 CASE_MATHFN (BUILT_IN_LROUND)
1687 CASE_MATHFN (BUILT_IN_MODF)
1688 CASE_MATHFN (BUILT_IN_NAN)
1689 CASE_MATHFN (BUILT_IN_NANS)
1690 CASE_MATHFN (BUILT_IN_NEARBYINT)
1691 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1693 CASE_MATHFN (BUILT_IN_POW)
1694 CASE_MATHFN (BUILT_IN_POWI)
1695 CASE_MATHFN (BUILT_IN_POW10)
1696 CASE_MATHFN (BUILT_IN_REMAINDER)
1697 CASE_MATHFN (BUILT_IN_REMQUO)
1698 CASE_MATHFN (BUILT_IN_RINT)
1699 CASE_MATHFN (BUILT_IN_ROUND)
1700 CASE_MATHFN (BUILT_IN_SCALB)
1701 CASE_MATHFN (BUILT_IN_SCALBLN)
1702 CASE_MATHFN (BUILT_IN_SCALBN)
1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1704 CASE_MATHFN (BUILT_IN_SIN)
1705 CASE_MATHFN (BUILT_IN_SINCOS)
1706 CASE_MATHFN (BUILT_IN_SINH)
1707 CASE_MATHFN (BUILT_IN_SQRT)
1708 CASE_MATHFN (BUILT_IN_TAN)
1709 CASE_MATHFN (BUILT_IN_TANH)
1710 CASE_MATHFN (BUILT_IN_TGAMMA)
1711 CASE_MATHFN (BUILT_IN_TRUNC)
1712 CASE_MATHFN (BUILT_IN_Y0)
1713 CASE_MATHFN (BUILT_IN_Y1)
1714 CASE_MATHFN (BUILT_IN_YN)
1716 default:
1717 return 0;
1720 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1721 return implicit_built_in_decls[fcode];
1722 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1723 return implicit_built_in_decls[fcodef];
1724 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1725 return implicit_built_in_decls[fcodel];
1726 else
1727 return 0;
1730 /* If errno must be maintained, expand the RTL to check if the result,
1731 TARGET, of a built-in function call, EXP, is NaN, and if so set
1732 errno to EDOM. */
1734 static void
1735 expand_errno_check (tree exp, rtx target)
1737 rtx lab = gen_label_rtx ();
1739 /* Test the result; if it is NaN, set errno=EDOM because
1740 the argument was not in the domain. */
1741 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1742 0, lab);
1744 #ifdef TARGET_EDOM
1745 /* If this built-in doesn't throw an exception, set errno directly. */
1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1748 #ifdef GEN_ERRNO_RTX
1749 rtx errno_rtx = GEN_ERRNO_RTX;
1750 #else
1751 rtx errno_rtx
1752 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1753 #endif
1754 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1755 emit_label (lab);
1756 return;
1758 #endif
1760 /* We can't set errno=EDOM directly; let the library call do it.
1761 Pop the arguments right away in case the call gets deleted. */
1762 NO_DEFER_POP;
1763 expand_call (exp, target, 0);
1764 OK_DEFER_POP;
1765 emit_label (lab);
1769 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770 Return 0 if a normal call should be emitted rather than expanding the
1771 function in-line. EXP is the expression that is a call to the builtin
1772 function; if convenient, the result should be placed in TARGET.
1773 SUBTARGET may be used as the target for computing one of EXP's operands. */
1775 static rtx
1776 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1778 optab builtin_optab;
1779 rtx op0, insns, before_call;
1780 tree fndecl = get_callee_fndecl (exp);
1781 tree arglist = TREE_OPERAND (exp, 1);
1782 enum machine_mode mode;
1783 bool errno_set = false;
1784 tree arg, narg;
1786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1787 return 0;
1789 arg = TREE_VALUE (arglist);
1791 switch (DECL_FUNCTION_CODE (fndecl))
1793 case BUILT_IN_SQRT:
1794 case BUILT_IN_SQRTF:
1795 case BUILT_IN_SQRTL:
1796 errno_set = ! tree_expr_nonnegative_p (arg);
1797 builtin_optab = sqrt_optab;
1798 break;
1799 case BUILT_IN_EXP:
1800 case BUILT_IN_EXPF:
1801 case BUILT_IN_EXPL:
1802 errno_set = true; builtin_optab = exp_optab; break;
1803 case BUILT_IN_EXP10:
1804 case BUILT_IN_EXP10F:
1805 case BUILT_IN_EXP10L:
1806 case BUILT_IN_POW10:
1807 case BUILT_IN_POW10F:
1808 case BUILT_IN_POW10L:
1809 errno_set = true; builtin_optab = exp10_optab; break;
1810 case BUILT_IN_EXP2:
1811 case BUILT_IN_EXP2F:
1812 case BUILT_IN_EXP2L:
1813 errno_set = true; builtin_optab = exp2_optab; break;
1814 case BUILT_IN_EXPM1:
1815 case BUILT_IN_EXPM1F:
1816 case BUILT_IN_EXPM1L:
1817 errno_set = true; builtin_optab = expm1_optab; break;
1818 case BUILT_IN_LOGB:
1819 case BUILT_IN_LOGBF:
1820 case BUILT_IN_LOGBL:
1821 errno_set = true; builtin_optab = logb_optab; break;
1822 case BUILT_IN_ILOGB:
1823 case BUILT_IN_ILOGBF:
1824 case BUILT_IN_ILOGBL:
1825 errno_set = true; builtin_optab = ilogb_optab; break;
1826 case BUILT_IN_LOG:
1827 case BUILT_IN_LOGF:
1828 case BUILT_IN_LOGL:
1829 errno_set = true; builtin_optab = log_optab; break;
1830 case BUILT_IN_LOG10:
1831 case BUILT_IN_LOG10F:
1832 case BUILT_IN_LOG10L:
1833 errno_set = true; builtin_optab = log10_optab; break;
1834 case BUILT_IN_LOG2:
1835 case BUILT_IN_LOG2F:
1836 case BUILT_IN_LOG2L:
1837 errno_set = true; builtin_optab = log2_optab; break;
1838 case BUILT_IN_LOG1P:
1839 case BUILT_IN_LOG1PF:
1840 case BUILT_IN_LOG1PL:
1841 errno_set = true; builtin_optab = log1p_optab; break;
1842 case BUILT_IN_ASIN:
1843 case BUILT_IN_ASINF:
1844 case BUILT_IN_ASINL:
1845 builtin_optab = asin_optab; break;
1846 case BUILT_IN_ACOS:
1847 case BUILT_IN_ACOSF:
1848 case BUILT_IN_ACOSL:
1849 builtin_optab = acos_optab; break;
1850 case BUILT_IN_TAN:
1851 case BUILT_IN_TANF:
1852 case BUILT_IN_TANL:
1853 builtin_optab = tan_optab; break;
1854 case BUILT_IN_ATAN:
1855 case BUILT_IN_ATANF:
1856 case BUILT_IN_ATANL:
1857 builtin_optab = atan_optab; break;
1858 case BUILT_IN_FLOOR:
1859 case BUILT_IN_FLOORF:
1860 case BUILT_IN_FLOORL:
1861 builtin_optab = floor_optab; break;
1862 case BUILT_IN_CEIL:
1863 case BUILT_IN_CEILF:
1864 case BUILT_IN_CEILL:
1865 builtin_optab = ceil_optab; break;
1866 case BUILT_IN_TRUNC:
1867 case BUILT_IN_TRUNCF:
1868 case BUILT_IN_TRUNCL:
1869 builtin_optab = btrunc_optab; break;
1870 case BUILT_IN_ROUND:
1871 case BUILT_IN_ROUNDF:
1872 case BUILT_IN_ROUNDL:
1873 builtin_optab = round_optab; break;
1874 case BUILT_IN_NEARBYINT:
1875 case BUILT_IN_NEARBYINTF:
1876 case BUILT_IN_NEARBYINTL:
1877 builtin_optab = nearbyint_optab; break;
1878 case BUILT_IN_RINT:
1879 case BUILT_IN_RINTF:
1880 case BUILT_IN_RINTL:
1881 builtin_optab = rint_optab; break;
1882 case BUILT_IN_LRINT:
1883 case BUILT_IN_LRINTF:
1884 case BUILT_IN_LRINTL:
1885 case BUILT_IN_LLRINT:
1886 case BUILT_IN_LLRINTF:
1887 case BUILT_IN_LLRINTL:
1888 builtin_optab = lrint_optab; break;
1889 default:
1890 gcc_unreachable ();
1893 /* Make a suitable register to place result in. */
1894 mode = TYPE_MODE (TREE_TYPE (exp));
1896 if (! flag_errno_math || ! HONOR_NANS (mode))
1897 errno_set = false;
1899 /* Before working hard, check whether the instruction is available. */
1900 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1902 target = gen_reg_rtx (mode);
1904 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1905 need to expand the argument again. This way, we will not perform
1906 side-effects more the once. */
1907 narg = builtin_save_expr (arg);
1908 if (narg != arg)
1910 arg = narg;
1911 arglist = build_tree_list (NULL_TREE, arg);
1912 exp = build_function_call_expr (fndecl, arglist);
1915 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1917 start_sequence ();
1919 /* Compute into TARGET.
1920 Set TARGET to wherever the result comes back. */
1921 target = expand_unop (mode, builtin_optab, op0, target, 0);
1923 if (target != 0)
1925 if (errno_set)
1926 expand_errno_check (exp, target);
1928 /* Output the entire sequence. */
1929 insns = get_insns ();
1930 end_sequence ();
1931 emit_insn (insns);
1932 return target;
1935 /* If we were unable to expand via the builtin, stop the sequence
1936 (without outputting the insns) and call to the library function
1937 with the stabilized argument list. */
1938 end_sequence ();
1941 before_call = get_last_insn ();
1943 target = expand_call (exp, target, target == const0_rtx);
1945 /* If this is a sqrt operation and we don't care about errno, try to
1946 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1947 This allows the semantics of the libcall to be visible to the RTL
1948 optimizers. */
1949 if (builtin_optab == sqrt_optab && !errno_set)
1951 /* Search backwards through the insns emitted by expand_call looking
1952 for the instruction with the REG_RETVAL note. */
1953 rtx last = get_last_insn ();
1954 while (last != before_call)
1956 if (find_reg_note (last, REG_RETVAL, NULL))
1958 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1959 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1960 two elements, i.e. symbol_ref(sqrt) and the operand. */
1961 if (note
1962 && GET_CODE (note) == EXPR_LIST
1963 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1964 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1965 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1967 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1968 /* Check operand is a register with expected mode. */
1969 if (operand
1970 && REG_P (operand)
1971 && GET_MODE (operand) == mode)
1973 /* Replace the REG_EQUAL note with a SQRT rtx. */
1974 rtx equiv = gen_rtx_SQRT (mode, operand);
1975 set_unique_reg_note (last, REG_EQUAL, equiv);
1978 break;
1980 last = PREV_INSN (last);
1984 return target;
1987 /* Expand a call to the builtin binary math functions (pow and atan2).
1988 Return 0 if a normal call should be emitted rather than expanding the
1989 function in-line. EXP is the expression that is a call to the builtin
1990 function; if convenient, the result should be placed in TARGET.
1991 SUBTARGET may be used as the target for computing one of EXP's
1992 operands. */
1994 static rtx
1995 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1997 optab builtin_optab;
1998 rtx op0, op1, insns;
1999 int op1_type = REAL_TYPE;
2000 tree fndecl = get_callee_fndecl (exp);
2001 tree arglist = TREE_OPERAND (exp, 1);
2002 tree arg0, arg1, temp, narg;
2003 enum machine_mode mode;
2004 bool errno_set = true;
2005 bool stable = true;
2007 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2008 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2009 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2010 op1_type = INTEGER_TYPE;
2012 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2013 return 0;
2015 arg0 = TREE_VALUE (arglist);
2016 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2018 switch (DECL_FUNCTION_CODE (fndecl))
2020 case BUILT_IN_POW:
2021 case BUILT_IN_POWF:
2022 case BUILT_IN_POWL:
2023 builtin_optab = pow_optab; break;
2024 case BUILT_IN_ATAN2:
2025 case BUILT_IN_ATAN2F:
2026 case BUILT_IN_ATAN2L:
2027 builtin_optab = atan2_optab; break;
2028 case BUILT_IN_LDEXP:
2029 case BUILT_IN_LDEXPF:
2030 case BUILT_IN_LDEXPL:
2031 builtin_optab = ldexp_optab; break;
2032 case BUILT_IN_FMOD:
2033 case BUILT_IN_FMODF:
2034 case BUILT_IN_FMODL:
2035 builtin_optab = fmod_optab; break;
2036 case BUILT_IN_DREM:
2037 case BUILT_IN_DREMF:
2038 case BUILT_IN_DREML:
2039 builtin_optab = drem_optab; break;
2040 default:
2041 gcc_unreachable ();
2044 /* Make a suitable register to place result in. */
2045 mode = TYPE_MODE (TREE_TYPE (exp));
2047 /* Before working hard, check whether the instruction is available. */
2048 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2049 return 0;
2051 target = gen_reg_rtx (mode);
2053 if (! flag_errno_math || ! HONOR_NANS (mode))
2054 errno_set = false;
2056 /* Always stabilize the argument list. */
2057 narg = builtin_save_expr (arg1);
2058 if (narg != arg1)
2060 arg1 = narg;
2061 temp = build_tree_list (NULL_TREE, narg);
2062 stable = false;
2064 else
2065 temp = TREE_CHAIN (arglist);
2067 narg = builtin_save_expr (arg0);
2068 if (narg != arg0)
2070 arg0 = narg;
2071 arglist = tree_cons (NULL_TREE, narg, temp);
2072 stable = false;
2074 else if (! stable)
2075 arglist = tree_cons (NULL_TREE, arg0, temp);
2077 if (! stable)
2078 exp = build_function_call_expr (fndecl, arglist);
2080 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2081 op1 = expand_expr (arg1, 0, VOIDmode, 0);
2083 start_sequence ();
2085 /* Compute into TARGET.
2086 Set TARGET to wherever the result comes back. */
2087 target = expand_binop (mode, builtin_optab, op0, op1,
2088 target, 0, OPTAB_DIRECT);
2090 /* If we were unable to expand via the builtin, stop the sequence
2091 (without outputting the insns) and call to the library function
2092 with the stabilized argument list. */
2093 if (target == 0)
2095 end_sequence ();
2096 return expand_call (exp, target, target == const0_rtx);
2099 if (errno_set)
2100 expand_errno_check (exp, target);
2102 /* Output the entire sequence. */
2103 insns = get_insns ();
2104 end_sequence ();
2105 emit_insn (insns);
2107 return target;
2110 /* Expand a call to the builtin sin and cos math functions.
2111 Return 0 if a normal call should be emitted rather than expanding the
2112 function in-line. EXP is the expression that is a call to the builtin
2113 function; if convenient, the result should be placed in TARGET.
2114 SUBTARGET may be used as the target for computing one of EXP's
2115 operands. */
2117 static rtx
2118 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2120 optab builtin_optab;
2121 rtx op0, insns;
2122 tree fndecl = get_callee_fndecl (exp);
2123 tree arglist = TREE_OPERAND (exp, 1);
2124 enum machine_mode mode;
2125 bool errno_set = false;
2126 tree arg, narg;
2128 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2129 return 0;
2131 arg = TREE_VALUE (arglist);
2133 switch (DECL_FUNCTION_CODE (fndecl))
2135 case BUILT_IN_SIN:
2136 case BUILT_IN_SINF:
2137 case BUILT_IN_SINL:
2138 case BUILT_IN_COS:
2139 case BUILT_IN_COSF:
2140 case BUILT_IN_COSL:
2141 builtin_optab = sincos_optab; break;
2142 default:
2143 gcc_unreachable ();
2146 /* Make a suitable register to place result in. */
2147 mode = TYPE_MODE (TREE_TYPE (exp));
2149 if (! flag_errno_math || ! HONOR_NANS (mode))
2150 errno_set = false;
2152 /* Check if sincos insn is available, otherwise fallback
2153 to sin or cos insn. */
2154 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2155 switch (DECL_FUNCTION_CODE (fndecl))
2157 case BUILT_IN_SIN:
2158 case BUILT_IN_SINF:
2159 case BUILT_IN_SINL:
2160 builtin_optab = sin_optab; break;
2161 case BUILT_IN_COS:
2162 case BUILT_IN_COSF:
2163 case BUILT_IN_COSL:
2164 builtin_optab = cos_optab; break;
2165 default:
2166 gcc_unreachable ();
2170 /* Before working hard, check whether the instruction is available. */
2171 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2173 target = gen_reg_rtx (mode);
2175 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2176 need to expand the argument again. This way, we will not perform
2177 side-effects more the once. */
2178 narg = save_expr (arg);
2179 if (narg != arg)
2181 arg = narg;
2182 arglist = build_tree_list (NULL_TREE, arg);
2183 exp = build_function_call_expr (fndecl, arglist);
2186 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2188 start_sequence ();
2190 /* Compute into TARGET.
2191 Set TARGET to wherever the result comes back. */
2192 if (builtin_optab == sincos_optab)
2194 int result;
2196 switch (DECL_FUNCTION_CODE (fndecl))
2198 case BUILT_IN_SIN:
2199 case BUILT_IN_SINF:
2200 case BUILT_IN_SINL:
2201 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2202 break;
2203 case BUILT_IN_COS:
2204 case BUILT_IN_COSF:
2205 case BUILT_IN_COSL:
2206 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2207 break;
2208 default:
2209 gcc_unreachable ();
2211 gcc_assert (result);
2213 else
2215 target = expand_unop (mode, builtin_optab, op0, target, 0);
2218 if (target != 0)
2220 if (errno_set)
2221 expand_errno_check (exp, target);
2223 /* Output the entire sequence. */
2224 insns = get_insns ();
2225 end_sequence ();
2226 emit_insn (insns);
2227 return target;
2230 /* If we were unable to expand via the builtin, stop the sequence
2231 (without outputting the insns) and call to the library function
2232 with the stabilized argument list. */
2233 end_sequence ();
2236 target = expand_call (exp, target, target == const0_rtx);
2238 return target;
2241 /* Expand a call to one of the builtin rounding functions (lfloor).
2242 If expanding via optab fails, lower expression to (int)(floor(x)).
2243 EXP is the expression that is a call to the builtin function;
2244 if convenient, the result should be placed in TARGET. SUBTARGET may
2245 be used as the target for computing one of EXP's operands. */
2247 static rtx
2248 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2250 optab builtin_optab;
2251 rtx op0, insns, tmp;
2252 tree fndecl = get_callee_fndecl (exp);
2253 tree arglist = TREE_OPERAND (exp, 1);
2254 enum built_in_function fallback_fn;
2255 tree fallback_fndecl;
2256 enum machine_mode mode;
2257 tree arg, narg;
2259 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2260 gcc_unreachable ();
2262 arg = TREE_VALUE (arglist);
2264 switch (DECL_FUNCTION_CODE (fndecl))
2266 case BUILT_IN_LCEIL:
2267 case BUILT_IN_LCEILF:
2268 case BUILT_IN_LCEILL:
2269 case BUILT_IN_LLCEIL:
2270 case BUILT_IN_LLCEILF:
2271 case BUILT_IN_LLCEILL:
2272 builtin_optab = lceil_optab;
2273 fallback_fn = BUILT_IN_CEIL;
2274 break;
2276 case BUILT_IN_LFLOOR:
2277 case BUILT_IN_LFLOORF:
2278 case BUILT_IN_LFLOORL:
2279 case BUILT_IN_LLFLOOR:
2280 case BUILT_IN_LLFLOORF:
2281 case BUILT_IN_LLFLOORL:
2282 builtin_optab = lfloor_optab;
2283 fallback_fn = BUILT_IN_FLOOR;
2284 break;
2286 default:
2287 gcc_unreachable ();
2290 /* Make a suitable register to place result in. */
2291 mode = TYPE_MODE (TREE_TYPE (exp));
2293 /* Before working hard, check whether the instruction is available. */
2294 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2296 target = gen_reg_rtx (mode);
2298 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2299 need to expand the argument again. This way, we will not perform
2300 side-effects more the once. */
2301 narg = builtin_save_expr (arg);
2302 if (narg != arg)
2304 arg = narg;
2305 arglist = build_tree_list (NULL_TREE, arg);
2306 exp = build_function_call_expr (fndecl, arglist);
2309 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2311 start_sequence ();
2313 /* Compute into TARGET.
2314 Set TARGET to wherever the result comes back. */
2315 target = expand_unop (mode, builtin_optab, op0, target, 0);
2317 if (target != 0)
2319 /* Output the entire sequence. */
2320 insns = get_insns ();
2321 end_sequence ();
2322 emit_insn (insns);
2323 return target;
2326 /* If we were unable to expand via the builtin, stop the sequence
2327 (without outputting the insns). */
2328 end_sequence ();
2331 /* Fall back to floating point rounding optab. */
2332 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2333 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2334 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2335 gcc_assert (fallback_fndecl != NULL_TREE);
2336 exp = build_function_call_expr (fallback_fndecl, arglist);
2338 tmp = expand_builtin_mathfn (exp, NULL_RTX, NULL_RTX);
2340 /* Truncate the result of floating point optab to integer
2341 via expand_fix (). */
2342 target = gen_reg_rtx (mode);
2343 expand_fix (target, tmp, 0);
2345 return target;
2348 /* To evaluate powi(x,n), the floating point value x raised to the
2349 constant integer exponent n, we use a hybrid algorithm that
2350 combines the "window method" with look-up tables. For an
2351 introduction to exponentiation algorithms and "addition chains",
2352 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2353 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2354 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2355 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2357 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2358 multiplications to inline before calling the system library's pow
2359 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2360 so this default never requires calling pow, powf or powl. */
2362 #ifndef POWI_MAX_MULTS
2363 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2364 #endif
2366 /* The size of the "optimal power tree" lookup table. All
2367 exponents less than this value are simply looked up in the
2368 powi_table below. This threshold is also used to size the
2369 cache of pseudo registers that hold intermediate results. */
2370 #define POWI_TABLE_SIZE 256
2372 /* The size, in bits of the window, used in the "window method"
2373 exponentiation algorithm. This is equivalent to a radix of
2374 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2375 #define POWI_WINDOW_SIZE 3
2377 /* The following table is an efficient representation of an
2378 "optimal power tree". For each value, i, the corresponding
2379 value, j, in the table states than an optimal evaluation
2380 sequence for calculating pow(x,i) can be found by evaluating
2381 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2382 100 integers is given in Knuth's "Seminumerical algorithms". */
2384 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2386 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2387 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2388 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2389 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2390 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2391 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2392 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2393 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2394 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2395 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2396 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2397 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2398 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2399 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2400 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2401 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2402 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2403 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2404 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2405 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2406 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2407 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2408 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2409 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2410 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2411 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2412 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2413 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2414 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2415 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2416 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2417 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2421 /* Return the number of multiplications required to calculate
2422 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2423 subroutine of powi_cost. CACHE is an array indicating
2424 which exponents have already been calculated. */
2426 static int
2427 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2429 /* If we've already calculated this exponent, then this evaluation
2430 doesn't require any additional multiplications. */
2431 if (cache[n])
2432 return 0;
2434 cache[n] = true;
2435 return powi_lookup_cost (n - powi_table[n], cache)
2436 + powi_lookup_cost (powi_table[n], cache) + 1;
2439 /* Return the number of multiplications required to calculate
2440 powi(x,n) for an arbitrary x, given the exponent N. This
2441 function needs to be kept in sync with expand_powi below. */
2443 static int
2444 powi_cost (HOST_WIDE_INT n)
2446 bool cache[POWI_TABLE_SIZE];
2447 unsigned HOST_WIDE_INT digit;
2448 unsigned HOST_WIDE_INT val;
2449 int result;
2451 if (n == 0)
2452 return 0;
2454 /* Ignore the reciprocal when calculating the cost. */
2455 val = (n < 0) ? -n : n;
2457 /* Initialize the exponent cache. */
2458 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2459 cache[1] = true;
2461 result = 0;
2463 while (val >= POWI_TABLE_SIZE)
2465 if (val & 1)
2467 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2468 result += powi_lookup_cost (digit, cache)
2469 + POWI_WINDOW_SIZE + 1;
2470 val >>= POWI_WINDOW_SIZE;
2472 else
2474 val >>= 1;
2475 result++;
2479 return result + powi_lookup_cost (val, cache);
2482 /* Recursive subroutine of expand_powi. This function takes the array,
2483 CACHE, of already calculated exponents and an exponent N and returns
2484 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2486 static rtx
2487 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2489 unsigned HOST_WIDE_INT digit;
2490 rtx target, result;
2491 rtx op0, op1;
2493 if (n < POWI_TABLE_SIZE)
2495 if (cache[n])
2496 return cache[n];
2498 target = gen_reg_rtx (mode);
2499 cache[n] = target;
2501 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2502 op1 = expand_powi_1 (mode, powi_table[n], cache);
2504 else if (n & 1)
2506 target = gen_reg_rtx (mode);
2507 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2508 op0 = expand_powi_1 (mode, n - digit, cache);
2509 op1 = expand_powi_1 (mode, digit, cache);
2511 else
2513 target = gen_reg_rtx (mode);
2514 op0 = expand_powi_1 (mode, n >> 1, cache);
2515 op1 = op0;
2518 result = expand_mult (mode, op0, op1, target, 0);
2519 if (result != target)
2520 emit_move_insn (target, result);
2521 return target;
2524 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2525 floating point operand in mode MODE, and N is the exponent. This
2526 function needs to be kept in sync with powi_cost above. */
2528 static rtx
2529 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2531 unsigned HOST_WIDE_INT val;
2532 rtx cache[POWI_TABLE_SIZE];
2533 rtx result;
2535 if (n == 0)
2536 return CONST1_RTX (mode);
2538 val = (n < 0) ? -n : n;
2540 memset (cache, 0, sizeof (cache));
2541 cache[1] = x;
2543 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2545 /* If the original exponent was negative, reciprocate the result. */
2546 if (n < 0)
2547 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2548 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2550 return result;
2553 /* Expand a call to the pow built-in mathematical function. Return 0 if
2554 a normal call should be emitted rather than expanding the function
2555 in-line. EXP is the expression that is a call to the builtin
2556 function; if convenient, the result should be placed in TARGET. */
2558 static rtx
2559 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2561 tree arglist = TREE_OPERAND (exp, 1);
2562 tree arg0, arg1;
2564 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2565 return 0;
2567 arg0 = TREE_VALUE (arglist);
2568 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2570 if (TREE_CODE (arg1) == REAL_CST
2571 && ! TREE_CONSTANT_OVERFLOW (arg1))
2573 REAL_VALUE_TYPE cint;
2574 REAL_VALUE_TYPE c;
2575 HOST_WIDE_INT n;
2577 c = TREE_REAL_CST (arg1);
2578 n = real_to_integer (&c);
2579 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2580 if (real_identical (&c, &cint))
2582 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2583 Otherwise, check the number of multiplications required.
2584 Note that pow never sets errno for an integer exponent. */
2585 if ((n >= -1 && n <= 2)
2586 || (flag_unsafe_math_optimizations
2587 && ! optimize_size
2588 && powi_cost (n) <= POWI_MAX_MULTS))
2590 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2591 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2592 op = force_reg (mode, op);
2593 return expand_powi (op, mode, n);
2598 if (! flag_unsafe_math_optimizations)
2599 return NULL_RTX;
2600 return expand_builtin_mathfn_2 (exp, target, subtarget);
2603 /* Expand a call to the powi built-in mathematical function. Return 0 if
2604 a normal call should be emitted rather than expanding the function
2605 in-line. EXP is the expression that is a call to the builtin
2606 function; if convenient, the result should be placed in TARGET. */
2608 static rtx
2609 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2611 tree arglist = TREE_OPERAND (exp, 1);
2612 tree arg0, arg1;
2613 rtx op0, op1;
2614 enum machine_mode mode;
2615 enum machine_mode mode2;
2617 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2618 return 0;
2620 arg0 = TREE_VALUE (arglist);
2621 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2622 mode = TYPE_MODE (TREE_TYPE (exp));
2624 /* Handle constant power. */
2626 if (TREE_CODE (arg1) == INTEGER_CST
2627 && ! TREE_CONSTANT_OVERFLOW (arg1))
2629 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2631 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2632 Otherwise, check the number of multiplications required. */
2633 if ((TREE_INT_CST_HIGH (arg1) == 0
2634 || TREE_INT_CST_HIGH (arg1) == -1)
2635 && ((n >= -1 && n <= 2)
2636 || (! optimize_size
2637 && powi_cost (n) <= POWI_MAX_MULTS)))
2639 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2640 op0 = force_reg (mode, op0);
2641 return expand_powi (op0, mode, n);
2645 /* Emit a libcall to libgcc. */
2647 /* Mode of the 2nd argument must match that of an int. */
2648 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2650 if (target == NULL_RTX)
2651 target = gen_reg_rtx (mode);
2653 op0 = expand_expr (arg0, subtarget, mode, 0);
2654 if (GET_MODE (op0) != mode)
2655 op0 = convert_to_mode (mode, op0, 0);
2656 op1 = expand_expr (arg1, 0, mode2, 0);
2657 if (GET_MODE (op1) != mode2)
2658 op1 = convert_to_mode (mode2, op1, 0);
2660 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2661 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2662 op0, mode, op1, mode2);
2664 return target;
2667 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2668 if we failed the caller should emit a normal call, otherwise
2669 try to get the result in TARGET, if convenient. */
2671 static rtx
2672 expand_builtin_strlen (tree arglist, rtx target,
2673 enum machine_mode target_mode)
2675 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2676 return 0;
2677 else
2679 rtx pat;
2680 tree len, src = TREE_VALUE (arglist);
2681 rtx result, src_reg, char_rtx, before_strlen;
2682 enum machine_mode insn_mode = target_mode, char_mode;
2683 enum insn_code icode = CODE_FOR_nothing;
2684 int align;
2686 /* If the length can be computed at compile-time, return it. */
2687 len = c_strlen (src, 0);
2688 if (len)
2689 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2691 /* If the length can be computed at compile-time and is constant
2692 integer, but there are side-effects in src, evaluate
2693 src for side-effects, then return len.
2694 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2695 can be optimized into: i++; x = 3; */
2696 len = c_strlen (src, 1);
2697 if (len && TREE_CODE (len) == INTEGER_CST)
2699 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2700 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2703 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2705 /* If SRC is not a pointer type, don't do this operation inline. */
2706 if (align == 0)
2707 return 0;
2709 /* Bail out if we can't compute strlen in the right mode. */
2710 while (insn_mode != VOIDmode)
2712 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2713 if (icode != CODE_FOR_nothing)
2714 break;
2716 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2718 if (insn_mode == VOIDmode)
2719 return 0;
2721 /* Make a place to write the result of the instruction. */
2722 result = target;
2723 if (! (result != 0
2724 && REG_P (result)
2725 && GET_MODE (result) == insn_mode
2726 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2727 result = gen_reg_rtx (insn_mode);
2729 /* Make a place to hold the source address. We will not expand
2730 the actual source until we are sure that the expansion will
2731 not fail -- there are trees that cannot be expanded twice. */
2732 src_reg = gen_reg_rtx (Pmode);
2734 /* Mark the beginning of the strlen sequence so we can emit the
2735 source operand later. */
2736 before_strlen = get_last_insn ();
2738 char_rtx = const0_rtx;
2739 char_mode = insn_data[(int) icode].operand[2].mode;
2740 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2741 char_mode))
2742 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2744 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2745 char_rtx, GEN_INT (align));
2746 if (! pat)
2747 return 0;
2748 emit_insn (pat);
2750 /* Now that we are assured of success, expand the source. */
2751 start_sequence ();
2752 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2753 if (pat != src_reg)
2754 emit_move_insn (src_reg, pat);
2755 pat = get_insns ();
2756 end_sequence ();
2758 if (before_strlen)
2759 emit_insn_after (pat, before_strlen);
2760 else
2761 emit_insn_before (pat, get_insns ());
2763 /* Return the value in the proper mode for this function. */
2764 if (GET_MODE (result) == target_mode)
2765 target = result;
2766 else if (target != 0)
2767 convert_move (target, result, 0);
2768 else
2769 target = convert_to_mode (target_mode, result, 0);
2771 return target;
2775 /* Expand a call to the strstr builtin. Return 0 if we failed the
2776 caller should emit a normal call, otherwise try to get the result
2777 in TARGET, if convenient (and in mode MODE if that's convenient). */
2779 static rtx
2780 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2782 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2784 tree result = fold_builtin_strstr (arglist, type);
2785 if (result)
2786 return expand_expr (result, target, mode, EXPAND_NORMAL);
2788 return 0;
2791 /* Expand a call to the strchr builtin. Return 0 if we failed the
2792 caller should emit a normal call, otherwise try to get the result
2793 in TARGET, if convenient (and in mode MODE if that's convenient). */
2795 static rtx
2796 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2798 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2800 tree result = fold_builtin_strchr (arglist, type);
2801 if (result)
2802 return expand_expr (result, target, mode, EXPAND_NORMAL);
2804 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2806 return 0;
2809 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2810 caller should emit a normal call, otherwise try to get the result
2811 in TARGET, if convenient (and in mode MODE if that's convenient). */
2813 static rtx
2814 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2816 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2818 tree result = fold_builtin_strrchr (arglist, type);
2819 if (result)
2820 return expand_expr (result, target, mode, EXPAND_NORMAL);
2822 return 0;
2825 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2826 caller should emit a normal call, otherwise try to get the result
2827 in TARGET, if convenient (and in mode MODE if that's convenient). */
2829 static rtx
2830 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2832 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2834 tree result = fold_builtin_strpbrk (arglist, type);
2835 if (result)
2836 return expand_expr (result, target, mode, EXPAND_NORMAL);
2838 return 0;
2841 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2842 bytes from constant string DATA + OFFSET and return it as target
2843 constant. */
2845 static rtx
2846 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2847 enum machine_mode mode)
2849 const char *str = (const char *) data;
2851 gcc_assert (offset >= 0
2852 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2853 <= strlen (str) + 1));
2855 return c_readstr (str + offset, mode);
2858 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2859 Return 0 if we failed, the caller should emit a normal call,
2860 otherwise try to get the result in TARGET, if convenient (and in
2861 mode MODE if that's convenient). */
2862 static rtx
2863 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2865 tree fndecl = get_callee_fndecl (exp);
2866 tree arglist = TREE_OPERAND (exp, 1);
2867 if (!validate_arglist (arglist,
2868 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2869 return 0;
2870 else
2872 tree dest = TREE_VALUE (arglist);
2873 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2874 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2875 const char *src_str;
2876 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2877 unsigned int dest_align
2878 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2879 rtx dest_mem, src_mem, dest_addr, len_rtx;
2880 tree result = fold_builtin_memcpy (fndecl, arglist);
2882 if (result)
2883 return expand_expr (result, target, mode, EXPAND_NORMAL);
2885 /* If DEST is not a pointer type, call the normal function. */
2886 if (dest_align == 0)
2887 return 0;
2889 /* If either SRC is not a pointer type, don't do this
2890 operation in-line. */
2891 if (src_align == 0)
2892 return 0;
2894 dest_mem = get_memory_rtx (dest, len);
2895 set_mem_align (dest_mem, dest_align);
2896 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2897 src_str = c_getstr (src);
2899 /* If SRC is a string constant and block move would be done
2900 by pieces, we can avoid loading the string from memory
2901 and only stored the computed constants. */
2902 if (src_str
2903 && GET_CODE (len_rtx) == CONST_INT
2904 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2905 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2906 (void *) src_str, dest_align))
2908 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2909 builtin_memcpy_read_str,
2910 (void *) src_str, dest_align, 0);
2911 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2912 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2913 return dest_mem;
2916 src_mem = get_memory_rtx (src, len);
2917 set_mem_align (src_mem, src_align);
2919 /* Copy word part most expediently. */
2920 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2921 CALL_EXPR_TAILCALL (exp)
2922 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2924 if (dest_addr == 0)
2926 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2927 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2929 return dest_addr;
2933 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2934 Return 0 if we failed; the caller should emit a normal call,
2935 otherwise try to get the result in TARGET, if convenient (and in
2936 mode MODE if that's convenient). If ENDP is 0 return the
2937 destination pointer, if ENDP is 1 return the end pointer ala
2938 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2939 stpcpy. */
2941 static rtx
2942 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2943 int endp)
2945 if (!validate_arglist (arglist,
2946 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2947 return 0;
2948 /* If return value is ignored, transform mempcpy into memcpy. */
2949 else if (target == const0_rtx)
2951 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2953 if (!fn)
2954 return 0;
2956 return expand_expr (build_function_call_expr (fn, arglist),
2957 target, mode, EXPAND_NORMAL);
2959 else
2961 tree dest = TREE_VALUE (arglist);
2962 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2963 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2964 const char *src_str;
2965 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2966 unsigned int dest_align
2967 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2968 rtx dest_mem, src_mem, len_rtx;
2969 tree result = fold_builtin_mempcpy (arglist, type, endp);
2971 if (result)
2972 return expand_expr (result, target, mode, EXPAND_NORMAL);
2974 /* If either SRC or DEST is not a pointer type, don't do this
2975 operation in-line. */
2976 if (dest_align == 0 || src_align == 0)
2977 return 0;
2979 /* If LEN is not constant, call the normal function. */
2980 if (! host_integerp (len, 1))
2981 return 0;
2983 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2984 src_str = c_getstr (src);
2986 /* If SRC is a string constant and block move would be done
2987 by pieces, we can avoid loading the string from memory
2988 and only stored the computed constants. */
2989 if (src_str
2990 && GET_CODE (len_rtx) == CONST_INT
2991 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2992 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2993 (void *) src_str, dest_align))
2995 dest_mem = get_memory_rtx (dest, len);
2996 set_mem_align (dest_mem, dest_align);
2997 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2998 builtin_memcpy_read_str,
2999 (void *) src_str, dest_align, endp);
3000 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3001 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3002 return dest_mem;
3005 if (GET_CODE (len_rtx) == CONST_INT
3006 && can_move_by_pieces (INTVAL (len_rtx),
3007 MIN (dest_align, src_align)))
3009 dest_mem = get_memory_rtx (dest, len);
3010 set_mem_align (dest_mem, dest_align);
3011 src_mem = get_memory_rtx (src, len);
3012 set_mem_align (src_mem, src_align);
3013 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3014 MIN (dest_align, src_align), endp);
3015 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3016 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3017 return dest_mem;
3020 return 0;
3024 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3025 if we failed; the caller should emit a normal call. */
3027 static rtx
3028 expand_builtin_memmove (tree arglist, tree type, rtx target,
3029 enum machine_mode mode, tree orig_exp)
3031 if (!validate_arglist (arglist,
3032 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3033 return 0;
3034 else
3036 tree dest = TREE_VALUE (arglist);
3037 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3038 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3040 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3041 unsigned int dest_align
3042 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3043 tree result = fold_builtin_memmove (arglist, type);
3045 if (result)
3046 return expand_expr (result, target, mode, EXPAND_NORMAL);
3048 /* If DEST is not a pointer type, call the normal function. */
3049 if (dest_align == 0)
3050 return 0;
3052 /* If either SRC is not a pointer type, don't do this
3053 operation in-line. */
3054 if (src_align == 0)
3055 return 0;
3057 /* If src is categorized for a readonly section we can use
3058 normal memcpy. */
3059 if (readonly_data_expr (src))
3061 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3062 if (!fn)
3063 return 0;
3064 fn = build_function_call_expr (fn, arglist);
3065 if (TREE_CODE (fn) == CALL_EXPR)
3066 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3067 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3070 /* If length is 1 and we can expand memcpy call inline,
3071 it is ok to use memcpy as well. */
3072 if (integer_onep (len))
3074 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3075 /*endp=*/0);
3076 if (ret)
3077 return ret;
3080 /* Otherwise, call the normal function. */
3081 return 0;
3085 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3086 if we failed the caller should emit a normal call. */
3088 static rtx
3089 expand_builtin_bcopy (tree exp)
3091 tree arglist = TREE_OPERAND (exp, 1);
3092 tree type = TREE_TYPE (exp);
3093 tree src, dest, size, newarglist;
3095 if (!validate_arglist (arglist,
3096 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3097 return NULL_RTX;
3099 src = TREE_VALUE (arglist);
3100 dest = TREE_VALUE (TREE_CHAIN (arglist));
3101 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3103 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3104 memmove(ptr y, ptr x, size_t z). This is done this way
3105 so that if it isn't expanded inline, we fallback to
3106 calling bcopy instead of memmove. */
3108 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3109 newarglist = tree_cons (NULL_TREE, src, newarglist);
3110 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3112 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3115 #ifndef HAVE_movstr
3116 # define HAVE_movstr 0
3117 # define CODE_FOR_movstr CODE_FOR_nothing
3118 #endif
3120 /* Expand into a movstr instruction, if one is available. Return 0 if
3121 we failed, the caller should emit a normal call, otherwise try to
3122 get the result in TARGET, if convenient. If ENDP is 0 return the
3123 destination pointer, if ENDP is 1 return the end pointer ala
3124 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3125 stpcpy. */
3127 static rtx
3128 expand_movstr (tree dest, tree src, rtx target, int endp)
3130 rtx end;
3131 rtx dest_mem;
3132 rtx src_mem;
3133 rtx insn;
3134 const struct insn_data * data;
3136 if (!HAVE_movstr)
3137 return 0;
3139 dest_mem = get_memory_rtx (dest, NULL);
3140 src_mem = get_memory_rtx (src, NULL);
3141 if (!endp)
3143 target = force_reg (Pmode, XEXP (dest_mem, 0));
3144 dest_mem = replace_equiv_address (dest_mem, target);
3145 end = gen_reg_rtx (Pmode);
3147 else
3149 if (target == 0 || target == const0_rtx)
3151 end = gen_reg_rtx (Pmode);
3152 if (target == 0)
3153 target = end;
3155 else
3156 end = target;
3159 data = insn_data + CODE_FOR_movstr;
3161 if (data->operand[0].mode != VOIDmode)
3162 end = gen_lowpart (data->operand[0].mode, end);
3164 insn = data->genfun (end, dest_mem, src_mem);
3166 gcc_assert (insn);
3168 emit_insn (insn);
3170 /* movstr is supposed to set end to the address of the NUL
3171 terminator. If the caller requested a mempcpy-like return value,
3172 adjust it. */
3173 if (endp == 1 && target != const0_rtx)
3175 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3176 emit_move_insn (target, force_operand (tem, NULL_RTX));
3179 return target;
3182 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3183 if we failed the caller should emit a normal call, otherwise try to get
3184 the result in TARGET, if convenient (and in mode MODE if that's
3185 convenient). */
3187 static rtx
3188 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3190 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3192 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3193 if (result)
3194 return expand_expr (result, target, mode, EXPAND_NORMAL);
3196 return expand_movstr (TREE_VALUE (arglist),
3197 TREE_VALUE (TREE_CHAIN (arglist)),
3198 target, /*endp=*/0);
3200 return 0;
3203 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3204 Return 0 if we failed the caller should emit a normal call,
3205 otherwise try to get the result in TARGET, if convenient (and in
3206 mode MODE if that's convenient). */
3208 static rtx
3209 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3211 tree arglist = TREE_OPERAND (exp, 1);
3212 /* If return value is ignored, transform stpcpy into strcpy. */
3213 if (target == const0_rtx)
3215 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3216 if (!fn)
3217 return 0;
3219 return expand_expr (build_function_call_expr (fn, arglist),
3220 target, mode, EXPAND_NORMAL);
3223 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3224 return 0;
3225 else
3227 tree dst, src, len, lenp1;
3228 tree narglist;
3229 rtx ret;
3231 /* Ensure we get an actual string whose length can be evaluated at
3232 compile-time, not an expression containing a string. This is
3233 because the latter will potentially produce pessimized code
3234 when used to produce the return value. */
3235 src = TREE_VALUE (TREE_CHAIN (arglist));
3236 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3237 return expand_movstr (TREE_VALUE (arglist),
3238 TREE_VALUE (TREE_CHAIN (arglist)),
3239 target, /*endp=*/2);
3241 dst = TREE_VALUE (arglist);
3242 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3243 narglist = build_tree_list (NULL_TREE, lenp1);
3244 narglist = tree_cons (NULL_TREE, src, narglist);
3245 narglist = tree_cons (NULL_TREE, dst, narglist);
3246 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3247 target, mode, /*endp=*/2);
3249 if (ret)
3250 return ret;
3252 if (TREE_CODE (len) == INTEGER_CST)
3254 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3256 if (GET_CODE (len_rtx) == CONST_INT)
3258 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3259 arglist, target, mode);
3261 if (ret)
3263 if (! target)
3265 if (mode != VOIDmode)
3266 target = gen_reg_rtx (mode);
3267 else
3268 target = gen_reg_rtx (GET_MODE (ret));
3270 if (GET_MODE (target) != GET_MODE (ret))
3271 ret = gen_lowpart (GET_MODE (target), ret);
3273 ret = plus_constant (ret, INTVAL (len_rtx));
3274 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3275 gcc_assert (ret);
3277 return target;
3282 return expand_movstr (TREE_VALUE (arglist),
3283 TREE_VALUE (TREE_CHAIN (arglist)),
3284 target, /*endp=*/2);
3288 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3289 bytes from constant string DATA + OFFSET and return it as target
3290 constant. */
3292 static rtx
3293 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3294 enum machine_mode mode)
3296 const char *str = (const char *) data;
3298 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3299 return const0_rtx;
3301 return c_readstr (str + offset, mode);
3304 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3305 if we failed the caller should emit a normal call. */
3307 static rtx
3308 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3310 tree fndecl = get_callee_fndecl (exp);
3311 tree arglist = TREE_OPERAND (exp, 1);
3312 if (validate_arglist (arglist,
3313 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3315 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3316 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3317 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3319 if (result)
3320 return expand_expr (result, target, mode, EXPAND_NORMAL);
3322 /* We must be passed a constant len and src parameter. */
3323 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3324 return 0;
3326 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3328 /* We're required to pad with trailing zeros if the requested
3329 len is greater than strlen(s2)+1. In that case try to
3330 use store_by_pieces, if it fails, punt. */
3331 if (tree_int_cst_lt (slen, len))
3333 tree dest = TREE_VALUE (arglist);
3334 unsigned int dest_align
3335 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3336 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3337 rtx dest_mem;
3339 if (!p || dest_align == 0 || !host_integerp (len, 1)
3340 || !can_store_by_pieces (tree_low_cst (len, 1),
3341 builtin_strncpy_read_str,
3342 (void *) p, dest_align))
3343 return 0;
3345 dest_mem = get_memory_rtx (dest, len);
3346 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3347 builtin_strncpy_read_str,
3348 (void *) p, dest_align, 0);
3349 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3350 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3351 return dest_mem;
3354 return 0;
3357 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3358 bytes from constant string DATA + OFFSET and return it as target
3359 constant. */
3361 static rtx
3362 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3363 enum machine_mode mode)
3365 const char *c = (const char *) data;
3366 char *p = alloca (GET_MODE_SIZE (mode));
3368 memset (p, *c, GET_MODE_SIZE (mode));
3370 return c_readstr (p, mode);
3373 /* Callback routine for store_by_pieces. Return the RTL of a register
3374 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3375 char value given in the RTL register data. For example, if mode is
3376 4 bytes wide, return the RTL for 0x01010101*data. */
3378 static rtx
3379 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3380 enum machine_mode mode)
3382 rtx target, coeff;
3383 size_t size;
3384 char *p;
3386 size = GET_MODE_SIZE (mode);
3387 if (size == 1)
3388 return (rtx) data;
3390 p = alloca (size);
3391 memset (p, 1, size);
3392 coeff = c_readstr (p, mode);
3394 target = convert_to_mode (mode, (rtx) data, 1);
3395 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3396 return force_reg (mode, target);
3399 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3400 if we failed the caller should emit a normal call, otherwise try to get
3401 the result in TARGET, if convenient (and in mode MODE if that's
3402 convenient). */
3404 static rtx
3405 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3406 tree orig_exp)
3408 if (!validate_arglist (arglist,
3409 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3410 return 0;
3411 else
3413 tree dest = TREE_VALUE (arglist);
3414 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3415 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3416 char c;
3418 unsigned int dest_align
3419 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3420 rtx dest_mem, dest_addr, len_rtx;
3422 /* If DEST is not a pointer type, don't do this
3423 operation in-line. */
3424 if (dest_align == 0)
3425 return 0;
3427 /* If the LEN parameter is zero, return DEST. */
3428 if (integer_zerop (len))
3430 /* Evaluate and ignore VAL in case it has side-effects. */
3431 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3432 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3435 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3436 dest_mem = get_memory_rtx (dest, len);
3438 if (TREE_CODE (val) != INTEGER_CST)
3440 rtx val_rtx;
3442 val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3443 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3445 /* Assume that we can memset by pieces if we can store the
3446 * the coefficients by pieces (in the required modes).
3447 * We can't pass builtin_memset_gen_str as that emits RTL. */
3448 c = 1;
3449 if (host_integerp (len, 1)
3450 && !(optimize_size && tree_low_cst (len, 1) > 1)
3451 && can_store_by_pieces (tree_low_cst (len, 1),
3452 builtin_memset_read_str, &c, dest_align))
3454 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3455 val_rtx);
3456 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3457 builtin_memset_gen_str, val_rtx, dest_align, 0);
3459 else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
3460 dest_align))
3461 return 0;
3463 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3464 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3465 return dest_mem;
3468 if (target_char_cast (val, &c))
3469 return 0;
3471 if (c)
3473 if (host_integerp (len, 1)
3474 && !(optimize_size && tree_low_cst (len, 1) > 1)
3475 && can_store_by_pieces (tree_low_cst (len, 1),
3476 builtin_memset_read_str, &c, dest_align))
3477 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3478 builtin_memset_read_str, &c, dest_align, 0);
3479 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3480 dest_align))
3481 return 0;
3483 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3484 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3485 return dest_mem;
3488 set_mem_align (dest_mem, dest_align);
3489 dest_addr = clear_storage (dest_mem, len_rtx,
3490 CALL_EXPR_TAILCALL (orig_exp)
3491 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3493 if (dest_addr == 0)
3495 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3496 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3499 return dest_addr;
3503 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3504 if we failed the caller should emit a normal call. */
3506 static rtx
3507 expand_builtin_bzero (tree exp)
3509 tree arglist = TREE_OPERAND (exp, 1);
3510 tree dest, size, newarglist;
3512 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3513 return NULL_RTX;
3515 dest = TREE_VALUE (arglist);
3516 size = TREE_VALUE (TREE_CHAIN (arglist));
3518 /* New argument list transforming bzero(ptr x, int y) to
3519 memset(ptr x, int 0, size_t y). This is done this way
3520 so that if it isn't expanded inline, we fallback to
3521 calling bzero instead of memset. */
3523 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3524 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3525 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3527 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3530 /* Expand expression EXP, which is a call to the memcmp built-in function.
3531 ARGLIST is the argument list for this call. Return 0 if we failed and the
3532 caller should emit a normal call, otherwise try to get the result in
3533 TARGET, if convenient (and in mode MODE, if that's convenient). */
3535 static rtx
3536 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3537 enum machine_mode mode)
3539 if (!validate_arglist (arglist,
3540 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3541 return 0;
3542 else
3544 tree result = fold_builtin_memcmp (arglist);
3545 if (result)
3546 return expand_expr (result, target, mode, EXPAND_NORMAL);
3549 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3551 tree arg1 = TREE_VALUE (arglist);
3552 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3553 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3554 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3555 rtx result;
3556 rtx insn;
3558 int arg1_align
3559 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3560 int arg2_align
3561 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3562 enum machine_mode insn_mode;
3564 #ifdef HAVE_cmpmemsi
3565 if (HAVE_cmpmemsi)
3566 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3567 else
3568 #endif
3569 #ifdef HAVE_cmpstrnsi
3570 if (HAVE_cmpstrnsi)
3571 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3572 else
3573 #endif
3574 return 0;
3576 /* If we don't have POINTER_TYPE, call the function. */
3577 if (arg1_align == 0 || arg2_align == 0)
3578 return 0;
3580 /* Make a place to write the result of the instruction. */
3581 result = target;
3582 if (! (result != 0
3583 && REG_P (result) && GET_MODE (result) == insn_mode
3584 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3585 result = gen_reg_rtx (insn_mode);
3587 arg1_rtx = get_memory_rtx (arg1, len);
3588 arg2_rtx = get_memory_rtx (arg2, len);
3589 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3591 /* Set MEM_SIZE as appropriate. */
3592 if (GET_CODE (arg3_rtx) == CONST_INT)
3594 set_mem_size (arg1_rtx, arg3_rtx);
3595 set_mem_size (arg2_rtx, arg3_rtx);
3598 #ifdef HAVE_cmpmemsi
3599 if (HAVE_cmpmemsi)
3600 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3601 GEN_INT (MIN (arg1_align, arg2_align)));
3602 else
3603 #endif
3604 #ifdef HAVE_cmpstrnsi
3605 if (HAVE_cmpstrnsi)
3606 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3607 GEN_INT (MIN (arg1_align, arg2_align)));
3608 else
3609 #endif
3610 gcc_unreachable ();
3612 if (insn)
3613 emit_insn (insn);
3614 else
3615 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3616 TYPE_MODE (integer_type_node), 3,
3617 XEXP (arg1_rtx, 0), Pmode,
3618 XEXP (arg2_rtx, 0), Pmode,
3619 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3620 TYPE_UNSIGNED (sizetype)),
3621 TYPE_MODE (sizetype));
3623 /* Return the value in the proper mode for this function. */
3624 mode = TYPE_MODE (TREE_TYPE (exp));
3625 if (GET_MODE (result) == mode)
3626 return result;
3627 else if (target != 0)
3629 convert_move (target, result, 0);
3630 return target;
3632 else
3633 return convert_to_mode (mode, result, 0);
3635 #endif
3637 return 0;
3640 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3641 if we failed the caller should emit a normal call, otherwise try to get
3642 the result in TARGET, if convenient. */
3644 static rtx
3645 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3647 tree arglist = TREE_OPERAND (exp, 1);
3649 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3650 return 0;
3651 else
3653 tree result = fold_builtin_strcmp (arglist);
3654 if (result)
3655 return expand_expr (result, target, mode, EXPAND_NORMAL);
3658 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3659 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3660 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3662 rtx arg1_rtx, arg2_rtx;
3663 rtx result, insn = NULL_RTX;
3664 tree fndecl, fn;
3666 tree arg1 = TREE_VALUE (arglist);
3667 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3668 int arg1_align
3669 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3670 int arg2_align
3671 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3673 /* If we don't have POINTER_TYPE, call the function. */
3674 if (arg1_align == 0 || arg2_align == 0)
3675 return 0;
3677 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3678 arg1 = builtin_save_expr (arg1);
3679 arg2 = builtin_save_expr (arg2);
3681 arg1_rtx = get_memory_rtx (arg1, NULL);
3682 arg2_rtx = get_memory_rtx (arg2, NULL);
3684 #ifdef HAVE_cmpstrsi
3685 /* Try to call cmpstrsi. */
3686 if (HAVE_cmpstrsi)
3688 enum machine_mode insn_mode
3689 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3691 /* Make a place to write the result of the instruction. */
3692 result = target;
3693 if (! (result != 0
3694 && REG_P (result) && GET_MODE (result) == insn_mode
3695 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3696 result = gen_reg_rtx (insn_mode);
3698 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3699 GEN_INT (MIN (arg1_align, arg2_align)));
3701 #endif
3702 #if HAVE_cmpstrnsi
3703 /* Try to determine at least one length and call cmpstrnsi. */
3704 if (!insn && HAVE_cmpstrnsi)
3706 tree len;
3707 rtx arg3_rtx;
3709 enum machine_mode insn_mode
3710 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3711 tree len1 = c_strlen (arg1, 1);
3712 tree len2 = c_strlen (arg2, 1);
3714 if (len1)
3715 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3716 if (len2)
3717 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3719 /* If we don't have a constant length for the first, use the length
3720 of the second, if we know it. We don't require a constant for
3721 this case; some cost analysis could be done if both are available
3722 but neither is constant. For now, assume they're equally cheap,
3723 unless one has side effects. If both strings have constant lengths,
3724 use the smaller. */
3726 if (!len1)
3727 len = len2;
3728 else if (!len2)
3729 len = len1;
3730 else if (TREE_SIDE_EFFECTS (len1))
3731 len = len2;
3732 else if (TREE_SIDE_EFFECTS (len2))
3733 len = len1;
3734 else if (TREE_CODE (len1) != INTEGER_CST)
3735 len = len2;
3736 else if (TREE_CODE (len2) != INTEGER_CST)
3737 len = len1;
3738 else if (tree_int_cst_lt (len1, len2))
3739 len = len1;
3740 else
3741 len = len2;
3743 /* If both arguments have side effects, we cannot optimize. */
3744 if (!len || TREE_SIDE_EFFECTS (len))
3745 return 0;
3747 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3748 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3750 /* Make a place to write the result of the instruction. */
3751 result = target;
3752 if (! (result != 0
3753 && REG_P (result) && GET_MODE (result) == insn_mode
3754 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3755 result = gen_reg_rtx (insn_mode);
3757 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3758 GEN_INT (MIN (arg1_align, arg2_align)));
3760 #endif
3762 if (insn)
3764 emit_insn (insn);
3766 /* Return the value in the proper mode for this function. */
3767 mode = TYPE_MODE (TREE_TYPE (exp));
3768 if (GET_MODE (result) == mode)
3769 return result;
3770 if (target == 0)
3771 return convert_to_mode (mode, result, 0);
3772 convert_move (target, result, 0);
3773 return target;
3776 /* Expand the library call ourselves using a stabilized argument
3777 list to avoid re-evaluating the function's arguments twice. */
3778 arglist = build_tree_list (NULL_TREE, arg2);
3779 arglist = tree_cons (NULL_TREE, arg1, arglist);
3780 fndecl = get_callee_fndecl (exp);
3781 fn = build_function_call_expr (fndecl, arglist);
3782 if (TREE_CODE (fn) == CALL_EXPR)
3783 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3784 return expand_call (fn, target, target == const0_rtx);
3786 #endif
3787 return 0;
3790 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3791 if we failed the caller should emit a normal call, otherwise try to get
3792 the result in TARGET, if convenient. */
3794 static rtx
3795 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3797 tree arglist = TREE_OPERAND (exp, 1);
3799 if (!validate_arglist (arglist,
3800 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3801 return 0;
3802 else
3804 tree result = fold_builtin_strncmp (arglist);
3805 if (result)
3806 return expand_expr (result, target, mode, EXPAND_NORMAL);
3809 /* If c_strlen can determine an expression for one of the string
3810 lengths, and it doesn't have side effects, then emit cmpstrnsi
3811 using length MIN(strlen(string)+1, arg3). */
3812 #ifdef HAVE_cmpstrnsi
3813 if (HAVE_cmpstrnsi)
3815 tree arg1 = TREE_VALUE (arglist);
3816 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3817 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3818 tree len, len1, len2;
3819 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3820 rtx result, insn;
3821 tree fndecl, fn;
3823 int arg1_align
3824 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3825 int arg2_align
3826 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3827 enum machine_mode insn_mode
3828 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3830 len1 = c_strlen (arg1, 1);
3831 len2 = c_strlen (arg2, 1);
3833 if (len1)
3834 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3835 if (len2)
3836 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3838 /* If we don't have a constant length for the first, use the length
3839 of the second, if we know it. We don't require a constant for
3840 this case; some cost analysis could be done if both are available
3841 but neither is constant. For now, assume they're equally cheap,
3842 unless one has side effects. If both strings have constant lengths,
3843 use the smaller. */
3845 if (!len1)
3846 len = len2;
3847 else if (!len2)
3848 len = len1;
3849 else if (TREE_SIDE_EFFECTS (len1))
3850 len = len2;
3851 else if (TREE_SIDE_EFFECTS (len2))
3852 len = len1;
3853 else if (TREE_CODE (len1) != INTEGER_CST)
3854 len = len2;
3855 else if (TREE_CODE (len2) != INTEGER_CST)
3856 len = len1;
3857 else if (tree_int_cst_lt (len1, len2))
3858 len = len1;
3859 else
3860 len = len2;
3862 /* If both arguments have side effects, we cannot optimize. */
3863 if (!len || TREE_SIDE_EFFECTS (len))
3864 return 0;
3866 /* The actual new length parameter is MIN(len,arg3). */
3867 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3868 fold_convert (TREE_TYPE (len), arg3));
3870 /* If we don't have POINTER_TYPE, call the function. */
3871 if (arg1_align == 0 || arg2_align == 0)
3872 return 0;
3874 /* Make a place to write the result of the instruction. */
3875 result = target;
3876 if (! (result != 0
3877 && REG_P (result) && GET_MODE (result) == insn_mode
3878 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3879 result = gen_reg_rtx (insn_mode);
3881 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3882 arg1 = builtin_save_expr (arg1);
3883 arg2 = builtin_save_expr (arg2);
3884 len = builtin_save_expr (len);
3886 arg1_rtx = get_memory_rtx (arg1, len);
3887 arg2_rtx = get_memory_rtx (arg2, len);
3888 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3889 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3890 GEN_INT (MIN (arg1_align, arg2_align)));
3891 if (insn)
3893 emit_insn (insn);
3895 /* Return the value in the proper mode for this function. */
3896 mode = TYPE_MODE (TREE_TYPE (exp));
3897 if (GET_MODE (result) == mode)
3898 return result;
3899 if (target == 0)
3900 return convert_to_mode (mode, result, 0);
3901 convert_move (target, result, 0);
3902 return target;
3905 /* Expand the library call ourselves using a stabilized argument
3906 list to avoid re-evaluating the function's arguments twice. */
3907 arglist = build_tree_list (NULL_TREE, len);
3908 arglist = tree_cons (NULL_TREE, arg2, arglist);
3909 arglist = tree_cons (NULL_TREE, arg1, arglist);
3910 fndecl = get_callee_fndecl (exp);
3911 fn = build_function_call_expr (fndecl, arglist);
3912 if (TREE_CODE (fn) == CALL_EXPR)
3913 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3914 return expand_call (fn, target, target == const0_rtx);
3916 #endif
3917 return 0;
3920 /* Expand expression EXP, which is a call to the strcat builtin.
3921 Return 0 if we failed the caller should emit a normal call,
3922 otherwise try to get the result in TARGET, if convenient. */
3924 static rtx
3925 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3927 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3928 return 0;
3929 else
3931 tree dst = TREE_VALUE (arglist),
3932 src = TREE_VALUE (TREE_CHAIN (arglist));
3933 const char *p = c_getstr (src);
3935 /* If the string length is zero, return the dst parameter. */
3936 if (p && *p == '\0')
3937 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3939 if (!optimize_size)
3941 /* See if we can store by pieces into (dst + strlen(dst)). */
3942 tree newsrc, newdst,
3943 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3944 rtx insns;
3946 /* Stabilize the argument list. */
3947 newsrc = builtin_save_expr (src);
3948 if (newsrc != src)
3949 arglist = build_tree_list (NULL_TREE, newsrc);
3950 else
3951 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3953 dst = builtin_save_expr (dst);
3955 start_sequence ();
3957 /* Create strlen (dst). */
3958 newdst =
3959 build_function_call_expr (strlen_fn,
3960 build_tree_list (NULL_TREE, dst));
3961 /* Create (dst + (cast) strlen (dst)). */
3962 newdst = fold_convert (TREE_TYPE (dst), newdst);
3963 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3965 newdst = builtin_save_expr (newdst);
3966 arglist = tree_cons (NULL_TREE, newdst, arglist);
3968 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3970 end_sequence (); /* Stop sequence. */
3971 return 0;
3974 /* Output the entire sequence. */
3975 insns = get_insns ();
3976 end_sequence ();
3977 emit_insn (insns);
3979 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3982 return 0;
3986 /* Expand expression EXP, which is a call to the strncat builtin.
3987 Return 0 if we failed the caller should emit a normal call,
3988 otherwise try to get the result in TARGET, if convenient. */
3990 static rtx
3991 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3993 if (validate_arglist (arglist,
3994 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3996 tree result = fold_builtin_strncat (arglist);
3997 if (result)
3998 return expand_expr (result, target, mode, EXPAND_NORMAL);
4000 return 0;
4003 /* Expand expression EXP, which is a call to the strspn builtin.
4004 Return 0 if we failed the caller should emit a normal call,
4005 otherwise try to get the result in TARGET, if convenient. */
4007 static rtx
4008 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4010 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4012 tree result = fold_builtin_strspn (arglist);
4013 if (result)
4014 return expand_expr (result, target, mode, EXPAND_NORMAL);
4016 return 0;
4019 /* Expand expression EXP, which is a call to the strcspn builtin.
4020 Return 0 if we failed the caller should emit a normal call,
4021 otherwise try to get the result in TARGET, if convenient. */
4023 static rtx
4024 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4026 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4028 tree result = fold_builtin_strcspn (arglist);
4029 if (result)
4030 return expand_expr (result, target, mode, EXPAND_NORMAL);
4032 return 0;
4035 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4036 if that's convenient. */
4039 expand_builtin_saveregs (void)
4041 rtx val, seq;
4043 /* Don't do __builtin_saveregs more than once in a function.
4044 Save the result of the first call and reuse it. */
4045 if (saveregs_value != 0)
4046 return saveregs_value;
4048 /* When this function is called, it means that registers must be
4049 saved on entry to this function. So we migrate the call to the
4050 first insn of this function. */
4052 start_sequence ();
4054 /* Do whatever the machine needs done in this case. */
4055 val = targetm.calls.expand_builtin_saveregs ();
4057 seq = get_insns ();
4058 end_sequence ();
4060 saveregs_value = val;
4062 /* Put the insns after the NOTE that starts the function. If this
4063 is inside a start_sequence, make the outer-level insn chain current, so
4064 the code is placed at the start of the function. */
4065 push_topmost_sequence ();
4066 emit_insn_after (seq, entry_of_function ());
4067 pop_topmost_sequence ();
4069 return val;
4072 /* __builtin_args_info (N) returns word N of the arg space info
4073 for the current function. The number and meanings of words
4074 is controlled by the definition of CUMULATIVE_ARGS. */
4076 static rtx
4077 expand_builtin_args_info (tree arglist)
4079 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4080 int *word_ptr = (int *) &current_function_args_info;
4082 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4084 if (arglist != 0)
4086 if (!host_integerp (TREE_VALUE (arglist), 0))
4087 error ("argument of %<__builtin_args_info%> must be constant");
4088 else
4090 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4092 if (wordnum < 0 || wordnum >= nwords)
4093 error ("argument of %<__builtin_args_info%> out of range");
4094 else
4095 return GEN_INT (word_ptr[wordnum]);
4098 else
4099 error ("missing argument in %<__builtin_args_info%>");
4101 return const0_rtx;
4104 /* Expand a call to __builtin_next_arg. */
4106 static rtx
4107 expand_builtin_next_arg (void)
4109 /* Checking arguments is already done in fold_builtin_next_arg
4110 that must be called before this function. */
4111 return expand_binop (Pmode, add_optab,
4112 current_function_internal_arg_pointer,
4113 current_function_arg_offset_rtx,
4114 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4117 /* Make it easier for the backends by protecting the valist argument
4118 from multiple evaluations. */
4120 static tree
4121 stabilize_va_list (tree valist, int needs_lvalue)
4123 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4125 if (TREE_SIDE_EFFECTS (valist))
4126 valist = save_expr (valist);
4128 /* For this case, the backends will be expecting a pointer to
4129 TREE_TYPE (va_list_type_node), but it's possible we've
4130 actually been given an array (an actual va_list_type_node).
4131 So fix it. */
4132 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4134 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4135 valist = build_fold_addr_expr_with_type (valist, p1);
4138 else
4140 tree pt;
4142 if (! needs_lvalue)
4144 if (! TREE_SIDE_EFFECTS (valist))
4145 return valist;
4147 pt = build_pointer_type (va_list_type_node);
4148 valist = fold_build1 (ADDR_EXPR, pt, valist);
4149 TREE_SIDE_EFFECTS (valist) = 1;
4152 if (TREE_SIDE_EFFECTS (valist))
4153 valist = save_expr (valist);
4154 valist = build_fold_indirect_ref (valist);
4157 return valist;
4160 /* The "standard" definition of va_list is void*. */
4162 tree
4163 std_build_builtin_va_list (void)
4165 return ptr_type_node;
4168 /* The "standard" implementation of va_start: just assign `nextarg' to
4169 the variable. */
4171 void
4172 std_expand_builtin_va_start (tree valist, rtx nextarg)
4174 tree t;
4176 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4177 make_tree (ptr_type_node, nextarg));
4178 TREE_SIDE_EFFECTS (t) = 1;
4180 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4183 /* Expand ARGLIST, from a call to __builtin_va_start. */
4185 static rtx
4186 expand_builtin_va_start (tree arglist)
4188 rtx nextarg;
4189 tree chain, valist;
4191 chain = TREE_CHAIN (arglist);
4193 if (!chain)
4195 error ("too few arguments to function %<va_start%>");
4196 return const0_rtx;
4199 if (fold_builtin_next_arg (chain))
4200 return const0_rtx;
4202 nextarg = expand_builtin_next_arg ();
4203 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4205 #ifdef EXPAND_BUILTIN_VA_START
4206 EXPAND_BUILTIN_VA_START (valist, nextarg);
4207 #else
4208 std_expand_builtin_va_start (valist, nextarg);
4209 #endif
4211 return const0_rtx;
4214 /* The "standard" implementation of va_arg: read the value from the
4215 current (padded) address and increment by the (padded) size. */
4217 tree
4218 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4220 tree addr, t, type_size, rounded_size, valist_tmp;
4221 unsigned HOST_WIDE_INT align, boundary;
4222 bool indirect;
4224 #ifdef ARGS_GROW_DOWNWARD
4225 /* All of the alignment and movement below is for args-grow-up machines.
4226 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4227 implement their own specialized gimplify_va_arg_expr routines. */
4228 gcc_unreachable ();
4229 #endif
4231 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4232 if (indirect)
4233 type = build_pointer_type (type);
4235 align = PARM_BOUNDARY / BITS_PER_UNIT;
4236 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4238 /* Hoist the valist value into a temporary for the moment. */
4239 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4241 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4242 requires greater alignment, we must perform dynamic alignment. */
4243 if (boundary > align)
4245 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4246 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4247 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4248 gimplify_and_add (t, pre_p);
4250 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4251 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4252 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4253 gimplify_and_add (t, pre_p);
4255 else
4256 boundary = align;
4258 /* If the actual alignment is less than the alignment of the type,
4259 adjust the type accordingly so that we don't assume strict alignment
4260 when deferencing the pointer. */
4261 boundary *= BITS_PER_UNIT;
4262 if (boundary < TYPE_ALIGN (type))
4264 type = build_variant_type_copy (type);
4265 TYPE_ALIGN (type) = boundary;
4268 /* Compute the rounded size of the type. */
4269 type_size = size_in_bytes (type);
4270 rounded_size = round_up (type_size, align);
4272 /* Reduce rounded_size so it's sharable with the postqueue. */
4273 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4275 /* Get AP. */
4276 addr = valist_tmp;
4277 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4279 /* Small args are padded downward. */
4280 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4281 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4282 size_binop (MINUS_EXPR, rounded_size, type_size));
4283 t = fold_convert (TREE_TYPE (addr), t);
4284 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4287 /* Compute new value for AP. */
4288 t = fold_convert (TREE_TYPE (valist), rounded_size);
4289 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4290 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4291 gimplify_and_add (t, pre_p);
4293 addr = fold_convert (build_pointer_type (type), addr);
4295 if (indirect)
4296 addr = build_va_arg_indirect_ref (addr);
4298 return build_va_arg_indirect_ref (addr);
4301 /* Build an indirect-ref expression over the given TREE, which represents a
4302 piece of a va_arg() expansion. */
4303 tree
4304 build_va_arg_indirect_ref (tree addr)
4306 addr = build_fold_indirect_ref (addr);
4308 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4309 mf_mark (addr);
4311 return addr;
4314 /* Return a dummy expression of type TYPE in order to keep going after an
4315 error. */
4317 static tree
4318 dummy_object (tree type)
4320 tree t = convert (build_pointer_type (type), null_pointer_node);
4321 return build1 (INDIRECT_REF, type, t);
4324 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4325 builtin function, but a very special sort of operator. */
4327 enum gimplify_status
4328 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4330 tree promoted_type, want_va_type, have_va_type;
4331 tree valist = TREE_OPERAND (*expr_p, 0);
4332 tree type = TREE_TYPE (*expr_p);
4333 tree t;
4335 /* Verify that valist is of the proper type. */
4336 want_va_type = va_list_type_node;
4337 have_va_type = TREE_TYPE (valist);
4339 if (have_va_type == error_mark_node)
4340 return GS_ERROR;
4342 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4344 /* If va_list is an array type, the argument may have decayed
4345 to a pointer type, e.g. by being passed to another function.
4346 In that case, unwrap both types so that we can compare the
4347 underlying records. */
4348 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4349 || POINTER_TYPE_P (have_va_type))
4351 want_va_type = TREE_TYPE (want_va_type);
4352 have_va_type = TREE_TYPE (have_va_type);
4356 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4358 error ("first argument to %<va_arg%> not of type %<va_list%>");
4359 return GS_ERROR;
4362 /* Generate a diagnostic for requesting data of a type that cannot
4363 be passed through `...' due to type promotion at the call site. */
4364 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4365 != type)
4367 static bool gave_help;
4369 /* Unfortunately, this is merely undefined, rather than a constraint
4370 violation, so we cannot make this an error. If this call is never
4371 executed, the program is still strictly conforming. */
4372 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4373 type, promoted_type);
4374 if (! gave_help)
4376 gave_help = true;
4377 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4378 promoted_type, type);
4381 /* We can, however, treat "undefined" any way we please.
4382 Call abort to encourage the user to fix the program. */
4383 inform ("if this code is reached, the program will abort");
4384 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4385 NULL);
4386 append_to_statement_list (t, pre_p);
4388 /* This is dead code, but go ahead and finish so that the
4389 mode of the result comes out right. */
4390 *expr_p = dummy_object (type);
4391 return GS_ALL_DONE;
4393 else
4395 /* Make it easier for the backends by protecting the valist argument
4396 from multiple evaluations. */
4397 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4399 /* For this case, the backends will be expecting a pointer to
4400 TREE_TYPE (va_list_type_node), but it's possible we've
4401 actually been given an array (an actual va_list_type_node).
4402 So fix it. */
4403 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4405 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4406 valist = build_fold_addr_expr_with_type (valist, p1);
4408 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4410 else
4411 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4413 if (!targetm.gimplify_va_arg_expr)
4414 /* FIXME:Once most targets are converted we should merely
4415 assert this is non-null. */
4416 return GS_ALL_DONE;
4418 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4419 return GS_OK;
4423 /* Expand ARGLIST, from a call to __builtin_va_end. */
4425 static rtx
4426 expand_builtin_va_end (tree arglist)
4428 tree valist = TREE_VALUE (arglist);
4430 /* Evaluate for side effects, if needed. I hate macros that don't
4431 do that. */
4432 if (TREE_SIDE_EFFECTS (valist))
4433 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4435 return const0_rtx;
4438 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4439 builtin rather than just as an assignment in stdarg.h because of the
4440 nastiness of array-type va_list types. */
4442 static rtx
4443 expand_builtin_va_copy (tree arglist)
4445 tree dst, src, t;
4447 dst = TREE_VALUE (arglist);
4448 src = TREE_VALUE (TREE_CHAIN (arglist));
4450 dst = stabilize_va_list (dst, 1);
4451 src = stabilize_va_list (src, 0);
4453 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4455 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4456 TREE_SIDE_EFFECTS (t) = 1;
4457 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4459 else
4461 rtx dstb, srcb, size;
4463 /* Evaluate to pointers. */
4464 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4465 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4466 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4467 VOIDmode, EXPAND_NORMAL);
4469 dstb = convert_memory_address (Pmode, dstb);
4470 srcb = convert_memory_address (Pmode, srcb);
4472 /* "Dereference" to BLKmode memories. */
4473 dstb = gen_rtx_MEM (BLKmode, dstb);
4474 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4475 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4476 srcb = gen_rtx_MEM (BLKmode, srcb);
4477 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4478 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4480 /* Copy. */
4481 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4484 return const0_rtx;
4487 /* Expand a call to one of the builtin functions __builtin_frame_address or
4488 __builtin_return_address. */
4490 static rtx
4491 expand_builtin_frame_address (tree fndecl, tree arglist)
4493 /* The argument must be a nonnegative integer constant.
4494 It counts the number of frames to scan up the stack.
4495 The value is the return address saved in that frame. */
4496 if (arglist == 0)
4497 /* Warning about missing arg was already issued. */
4498 return const0_rtx;
4499 else if (! host_integerp (TREE_VALUE (arglist), 1))
4501 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4502 error ("invalid argument to %<__builtin_frame_address%>");
4503 else
4504 error ("invalid argument to %<__builtin_return_address%>");
4505 return const0_rtx;
4507 else
4509 rtx tem
4510 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4511 tree_low_cst (TREE_VALUE (arglist), 1));
4513 /* Some ports cannot access arbitrary stack frames. */
4514 if (tem == NULL)
4516 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4517 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4518 else
4519 warning (0, "unsupported argument to %<__builtin_return_address%>");
4520 return const0_rtx;
4523 /* For __builtin_frame_address, return what we've got. */
4524 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4525 return tem;
4527 if (!REG_P (tem)
4528 && ! CONSTANT_P (tem))
4529 tem = copy_to_mode_reg (Pmode, tem);
4530 return tem;
4534 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4535 we failed and the caller should emit a normal call, otherwise try to get
4536 the result in TARGET, if convenient. */
4538 static rtx
4539 expand_builtin_alloca (tree arglist, rtx target)
4541 rtx op0;
4542 rtx result;
4544 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4545 should always expand to function calls. These can be intercepted
4546 in libmudflap. */
4547 if (flag_mudflap)
4548 return 0;
4550 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4551 return 0;
4553 /* Compute the argument. */
4554 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4556 /* Allocate the desired space. */
4557 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4558 result = convert_memory_address (ptr_mode, result);
4560 return result;
4563 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4564 Return 0 if a normal call should be emitted rather than expanding the
4565 function in-line. If convenient, the result should be placed in TARGET.
4566 SUBTARGET may be used as the target for computing one of EXP's operands. */
4568 static rtx
4569 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4570 rtx subtarget, optab op_optab)
4572 rtx op0;
4573 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4574 return 0;
4576 /* Compute the argument. */
4577 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4578 /* Compute op, into TARGET if possible.
4579 Set TARGET to wherever the result comes back. */
4580 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4581 op_optab, op0, target, 1);
4582 gcc_assert (target);
4584 return convert_to_mode (target_mode, target, 0);
4587 /* If the string passed to fputs is a constant and is one character
4588 long, we attempt to transform this call into __builtin_fputc(). */
4590 static rtx
4591 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4593 /* Verify the arguments in the original call. */
4594 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4596 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4597 unlocked, NULL_TREE);
4598 if (result)
4599 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4601 return 0;
4604 /* Expand a call to __builtin_expect. We return our argument and emit a
4605 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4606 a non-jump context. */
4608 static rtx
4609 expand_builtin_expect (tree arglist, rtx target)
4611 tree exp, c;
4612 rtx note, rtx_c;
4614 if (arglist == NULL_TREE
4615 || TREE_CHAIN (arglist) == NULL_TREE)
4616 return const0_rtx;
4617 exp = TREE_VALUE (arglist);
4618 c = TREE_VALUE (TREE_CHAIN (arglist));
4620 if (TREE_CODE (c) != INTEGER_CST)
4622 error ("second argument to %<__builtin_expect%> must be a constant");
4623 c = integer_zero_node;
4626 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4628 /* Don't bother with expected value notes for integral constants. */
4629 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4631 /* We do need to force this into a register so that we can be
4632 moderately sure to be able to correctly interpret the branch
4633 condition later. */
4634 target = force_reg (GET_MODE (target), target);
4636 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4638 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4639 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4642 return target;
4645 /* Like expand_builtin_expect, except do this in a jump context. This is
4646 called from do_jump if the conditional is a __builtin_expect. Return either
4647 a list of insns to emit the jump or NULL if we cannot optimize
4648 __builtin_expect. We need to optimize this at jump time so that machines
4649 like the PowerPC don't turn the test into a SCC operation, and then jump
4650 based on the test being 0/1. */
4653 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4655 tree arglist = TREE_OPERAND (exp, 1);
4656 tree arg0 = TREE_VALUE (arglist);
4657 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4658 rtx ret = NULL_RTX;
4660 /* Only handle __builtin_expect (test, 0) and
4661 __builtin_expect (test, 1). */
4662 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4663 && (integer_zerop (arg1) || integer_onep (arg1)))
4665 rtx insn, drop_through_label, temp;
4667 /* Expand the jump insns. */
4668 start_sequence ();
4669 do_jump (arg0, if_false_label, if_true_label);
4670 ret = get_insns ();
4672 drop_through_label = get_last_insn ();
4673 if (drop_through_label && NOTE_P (drop_through_label))
4674 drop_through_label = prev_nonnote_insn (drop_through_label);
4675 if (drop_through_label && !LABEL_P (drop_through_label))
4676 drop_through_label = NULL_RTX;
4677 end_sequence ();
4679 if (! if_true_label)
4680 if_true_label = drop_through_label;
4681 if (! if_false_label)
4682 if_false_label = drop_through_label;
4684 /* Go through and add the expect's to each of the conditional jumps. */
4685 insn = ret;
4686 while (insn != NULL_RTX)
4688 rtx next = NEXT_INSN (insn);
4690 if (JUMP_P (insn) && any_condjump_p (insn))
4692 rtx ifelse = SET_SRC (pc_set (insn));
4693 rtx then_dest = XEXP (ifelse, 1);
4694 rtx else_dest = XEXP (ifelse, 2);
4695 int taken = -1;
4697 /* First check if we recognize any of the labels. */
4698 if (GET_CODE (then_dest) == LABEL_REF
4699 && XEXP (then_dest, 0) == if_true_label)
4700 taken = 1;
4701 else if (GET_CODE (then_dest) == LABEL_REF
4702 && XEXP (then_dest, 0) == if_false_label)
4703 taken = 0;
4704 else if (GET_CODE (else_dest) == LABEL_REF
4705 && XEXP (else_dest, 0) == if_false_label)
4706 taken = 1;
4707 else if (GET_CODE (else_dest) == LABEL_REF
4708 && XEXP (else_dest, 0) == if_true_label)
4709 taken = 0;
4710 /* Otherwise check where we drop through. */
4711 else if (else_dest == pc_rtx)
4713 if (next && NOTE_P (next))
4714 next = next_nonnote_insn (next);
4716 if (next && JUMP_P (next)
4717 && any_uncondjump_p (next))
4718 temp = XEXP (SET_SRC (pc_set (next)), 0);
4719 else
4720 temp = next;
4722 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4723 else that can't possibly match either target label. */
4724 if (temp == if_false_label)
4725 taken = 1;
4726 else if (temp == if_true_label)
4727 taken = 0;
4729 else if (then_dest == pc_rtx)
4731 if (next && NOTE_P (next))
4732 next = next_nonnote_insn (next);
4734 if (next && JUMP_P (next)
4735 && any_uncondjump_p (next))
4736 temp = XEXP (SET_SRC (pc_set (next)), 0);
4737 else
4738 temp = next;
4740 if (temp == if_false_label)
4741 taken = 0;
4742 else if (temp == if_true_label)
4743 taken = 1;
4746 if (taken != -1)
4748 /* If the test is expected to fail, reverse the
4749 probabilities. */
4750 if (integer_zerop (arg1))
4751 taken = 1 - taken;
4752 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4756 insn = next;
4760 return ret;
4763 void
4764 expand_builtin_trap (void)
4766 #ifdef HAVE_trap
4767 if (HAVE_trap)
4768 emit_insn (gen_trap ());
4769 else
4770 #endif
4771 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4772 emit_barrier ();
4775 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4776 Return 0 if a normal call should be emitted rather than expanding
4777 the function inline. If convenient, the result should be placed
4778 in TARGET. SUBTARGET may be used as the target for computing
4779 the operand. */
4781 static rtx
4782 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4784 enum machine_mode mode;
4785 tree arg;
4786 rtx op0;
4788 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4789 return 0;
4791 arg = TREE_VALUE (arglist);
4792 mode = TYPE_MODE (TREE_TYPE (arg));
4793 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4794 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4797 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4798 Return NULL is a normal call should be emitted rather than expanding the
4799 function inline. If convenient, the result should be placed in TARGET.
4800 SUBTARGET may be used as the target for computing the operand. */
4802 static rtx
4803 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4805 rtx op0, op1;
4806 tree arg;
4808 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4809 return 0;
4811 arg = TREE_VALUE (arglist);
4812 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4814 arg = TREE_VALUE (TREE_CHAIN (arglist));
4815 op1 = expand_expr (arg, NULL, VOIDmode, 0);
4817 return expand_copysign (op0, op1, target);
4820 /* Create a new constant string literal and return a char* pointer to it.
4821 The STRING_CST value is the LEN characters at STR. */
4822 static tree
4823 build_string_literal (int len, const char *str)
4825 tree t, elem, index, type;
4827 t = build_string (len, str);
4828 elem = build_type_variant (char_type_node, 1, 0);
4829 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4830 type = build_array_type (elem, index);
4831 TREE_TYPE (t) = type;
4832 TREE_CONSTANT (t) = 1;
4833 TREE_INVARIANT (t) = 1;
4834 TREE_READONLY (t) = 1;
4835 TREE_STATIC (t) = 1;
4837 type = build_pointer_type (type);
4838 t = build1 (ADDR_EXPR, type, t);
4840 type = build_pointer_type (elem);
4841 t = build1 (NOP_EXPR, type, t);
4842 return t;
4845 /* Expand EXP, a call to printf or printf_unlocked.
4846 Return 0 if a normal call should be emitted rather than transforming
4847 the function inline. If convenient, the result should be placed in
4848 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4849 call. */
4850 static rtx
4851 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4852 bool unlocked)
4854 tree arglist = TREE_OPERAND (exp, 1);
4855 /* If we're using an unlocked function, assume the other unlocked
4856 functions exist explicitly. */
4857 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4858 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4859 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4860 : implicit_built_in_decls[BUILT_IN_PUTS];
4861 const char *fmt_str;
4862 tree fn, fmt, arg;
4864 /* If the return value is used, don't do the transformation. */
4865 if (target != const0_rtx)
4866 return 0;
4868 /* Verify the required arguments in the original call. */
4869 if (! arglist)
4870 return 0;
4871 fmt = TREE_VALUE (arglist);
4872 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4873 return 0;
4874 arglist = TREE_CHAIN (arglist);
4876 /* Check whether the format is a literal string constant. */
4877 fmt_str = c_getstr (fmt);
4878 if (fmt_str == NULL)
4879 return 0;
4881 if (!init_target_chars())
4882 return 0;
4884 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4885 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4887 if (! arglist
4888 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4889 || TREE_CHAIN (arglist))
4890 return 0;
4891 fn = fn_puts;
4893 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4894 else if (strcmp (fmt_str, target_percent_c) == 0)
4896 if (! arglist
4897 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4898 || TREE_CHAIN (arglist))
4899 return 0;
4900 fn = fn_putchar;
4902 else
4904 /* We can't handle anything else with % args or %% ... yet. */
4905 if (strchr (fmt_str, target_percent))
4906 return 0;
4908 if (arglist)
4909 return 0;
4911 /* If the format specifier was "", printf does nothing. */
4912 if (fmt_str[0] == '\0')
4913 return const0_rtx;
4914 /* If the format specifier has length of 1, call putchar. */
4915 if (fmt_str[1] == '\0')
4917 /* Given printf("c"), (where c is any one character,)
4918 convert "c"[0] to an int and pass that to the replacement
4919 function. */
4920 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4921 arglist = build_tree_list (NULL_TREE, arg);
4922 fn = fn_putchar;
4924 else
4926 /* If the format specifier was "string\n", call puts("string"). */
4927 size_t len = strlen (fmt_str);
4928 if ((unsigned char)fmt_str[len - 1] == target_newline)
4930 /* Create a NUL-terminated string that's one char shorter
4931 than the original, stripping off the trailing '\n'. */
4932 char *newstr = alloca (len);
4933 memcpy (newstr, fmt_str, len - 1);
4934 newstr[len - 1] = 0;
4936 arg = build_string_literal (len, newstr);
4937 arglist = build_tree_list (NULL_TREE, arg);
4938 fn = fn_puts;
4940 else
4941 /* We'd like to arrange to call fputs(string,stdout) here,
4942 but we need stdout and don't have a way to get it yet. */
4943 return 0;
4947 if (!fn)
4948 return 0;
4949 fn = build_function_call_expr (fn, arglist);
4950 if (TREE_CODE (fn) == CALL_EXPR)
4951 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4952 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4955 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4956 Return 0 if a normal call should be emitted rather than transforming
4957 the function inline. If convenient, the result should be placed in
4958 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4959 call. */
4960 static rtx
4961 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4962 bool unlocked)
4964 tree arglist = TREE_OPERAND (exp, 1);
4965 /* If we're using an unlocked function, assume the other unlocked
4966 functions exist explicitly. */
4967 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4968 : implicit_built_in_decls[BUILT_IN_FPUTC];
4969 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4970 : implicit_built_in_decls[BUILT_IN_FPUTS];
4971 const char *fmt_str;
4972 tree fn, fmt, fp, arg;
4974 /* If the return value is used, don't do the transformation. */
4975 if (target != const0_rtx)
4976 return 0;
4978 /* Verify the required arguments in the original call. */
4979 if (! arglist)
4980 return 0;
4981 fp = TREE_VALUE (arglist);
4982 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4983 return 0;
4984 arglist = TREE_CHAIN (arglist);
4985 if (! arglist)
4986 return 0;
4987 fmt = TREE_VALUE (arglist);
4988 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4989 return 0;
4990 arglist = TREE_CHAIN (arglist);
4992 /* Check whether the format is a literal string constant. */
4993 fmt_str = c_getstr (fmt);
4994 if (fmt_str == NULL)
4995 return 0;
4997 if (!init_target_chars())
4998 return 0;
5000 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5001 if (strcmp (fmt_str, target_percent_s) == 0)
5003 if (! arglist
5004 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5005 || TREE_CHAIN (arglist))
5006 return 0;
5007 arg = TREE_VALUE (arglist);
5008 arglist = build_tree_list (NULL_TREE, fp);
5009 arglist = tree_cons (NULL_TREE, arg, arglist);
5010 fn = fn_fputs;
5012 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5013 else if (strcmp (fmt_str, target_percent_c) == 0)
5015 if (! arglist
5016 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5017 || TREE_CHAIN (arglist))
5018 return 0;
5019 arg = TREE_VALUE (arglist);
5020 arglist = build_tree_list (NULL_TREE, fp);
5021 arglist = tree_cons (NULL_TREE, arg, arglist);
5022 fn = fn_fputc;
5024 else
5026 /* We can't handle anything else with % args or %% ... yet. */
5027 if (strchr (fmt_str, target_percent))
5028 return 0;
5030 if (arglist)
5031 return 0;
5033 /* If the format specifier was "", fprintf does nothing. */
5034 if (fmt_str[0] == '\0')
5036 /* Evaluate and ignore FILE* argument for side-effects. */
5037 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5038 return const0_rtx;
5041 /* When "string" doesn't contain %, replace all cases of
5042 fprintf(stream,string) with fputs(string,stream). The fputs
5043 builtin will take care of special cases like length == 1. */
5044 arglist = build_tree_list (NULL_TREE, fp);
5045 arglist = tree_cons (NULL_TREE, fmt, arglist);
5046 fn = fn_fputs;
5049 if (!fn)
5050 return 0;
5051 fn = build_function_call_expr (fn, arglist);
5052 if (TREE_CODE (fn) == CALL_EXPR)
5053 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5054 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5057 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5058 a normal call should be emitted rather than expanding the function
5059 inline. If convenient, the result should be placed in TARGET with
5060 mode MODE. */
5062 static rtx
5063 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5065 tree orig_arglist, dest, fmt;
5066 const char *fmt_str;
5068 orig_arglist = arglist;
5070 /* Verify the required arguments in the original call. */
5071 if (! arglist)
5072 return 0;
5073 dest = TREE_VALUE (arglist);
5074 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5075 return 0;
5076 arglist = TREE_CHAIN (arglist);
5077 if (! arglist)
5078 return 0;
5079 fmt = TREE_VALUE (arglist);
5080 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5081 return 0;
5082 arglist = TREE_CHAIN (arglist);
5084 /* Check whether the format is a literal string constant. */
5085 fmt_str = c_getstr (fmt);
5086 if (fmt_str == NULL)
5087 return 0;
5089 if (!init_target_chars())
5090 return 0;
5092 /* If the format doesn't contain % args or %%, use strcpy. */
5093 if (strchr (fmt_str, target_percent) == 0)
5095 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5096 tree exp;
5098 if (arglist || ! fn)
5099 return 0;
5100 expand_expr (build_function_call_expr (fn, orig_arglist),
5101 const0_rtx, VOIDmode, EXPAND_NORMAL);
5102 if (target == const0_rtx)
5103 return const0_rtx;
5104 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5105 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5107 /* If the format is "%s", use strcpy if the result isn't used. */
5108 else if (strcmp (fmt_str, target_percent_s) == 0)
5110 tree fn, arg, len;
5111 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5113 if (! fn)
5114 return 0;
5116 if (! arglist || TREE_CHAIN (arglist))
5117 return 0;
5118 arg = TREE_VALUE (arglist);
5119 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5120 return 0;
5122 if (target != const0_rtx)
5124 len = c_strlen (arg, 1);
5125 if (! len || TREE_CODE (len) != INTEGER_CST)
5126 return 0;
5128 else
5129 len = NULL_TREE;
5131 arglist = build_tree_list (NULL_TREE, arg);
5132 arglist = tree_cons (NULL_TREE, dest, arglist);
5133 expand_expr (build_function_call_expr (fn, arglist),
5134 const0_rtx, VOIDmode, EXPAND_NORMAL);
5136 if (target == const0_rtx)
5137 return const0_rtx;
5138 return expand_expr (len, target, mode, EXPAND_NORMAL);
5141 return 0;
5144 /* Expand a call to either the entry or exit function profiler. */
5146 static rtx
5147 expand_builtin_profile_func (bool exitp)
5149 rtx this, which;
5151 this = DECL_RTL (current_function_decl);
5152 gcc_assert (MEM_P (this));
5153 this = XEXP (this, 0);
5155 if (exitp)
5156 which = profile_function_exit_libfunc;
5157 else
5158 which = profile_function_entry_libfunc;
5160 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5161 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5163 Pmode);
5165 return const0_rtx;
5168 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5170 static rtx
5171 round_trampoline_addr (rtx tramp)
5173 rtx temp, addend, mask;
5175 /* If we don't need too much alignment, we'll have been guaranteed
5176 proper alignment by get_trampoline_type. */
5177 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5178 return tramp;
5180 /* Round address up to desired boundary. */
5181 temp = gen_reg_rtx (Pmode);
5182 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5183 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5185 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5186 temp, 0, OPTAB_LIB_WIDEN);
5187 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5188 temp, 0, OPTAB_LIB_WIDEN);
5190 return tramp;
5193 static rtx
5194 expand_builtin_init_trampoline (tree arglist)
5196 tree t_tramp, t_func, t_chain;
5197 rtx r_tramp, r_func, r_chain;
5198 #ifdef TRAMPOLINE_TEMPLATE
5199 rtx blktramp;
5200 #endif
5202 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5203 POINTER_TYPE, VOID_TYPE))
5204 return NULL_RTX;
5206 t_tramp = TREE_VALUE (arglist);
5207 arglist = TREE_CHAIN (arglist);
5208 t_func = TREE_VALUE (arglist);
5209 arglist = TREE_CHAIN (arglist);
5210 t_chain = TREE_VALUE (arglist);
5212 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5213 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5214 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5216 /* Generate insns to initialize the trampoline. */
5217 r_tramp = round_trampoline_addr (r_tramp);
5218 #ifdef TRAMPOLINE_TEMPLATE
5219 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5220 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5221 emit_block_move (blktramp, assemble_trampoline_template (),
5222 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5223 #endif
5224 trampolines_created = 1;
5225 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5227 return const0_rtx;
5230 static rtx
5231 expand_builtin_adjust_trampoline (tree arglist)
5233 rtx tramp;
5235 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5236 return NULL_RTX;
5238 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5239 tramp = round_trampoline_addr (tramp);
5240 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5241 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5242 #endif
5244 return tramp;
5247 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5248 Return NULL_RTX if a normal call should be emitted rather than expanding
5249 the function in-line. EXP is the expression that is a call to the builtin
5250 function; if convenient, the result should be placed in TARGET. */
5252 static rtx
5253 expand_builtin_signbit (tree exp, rtx target)
5255 const struct real_format *fmt;
5256 enum machine_mode fmode, imode, rmode;
5257 HOST_WIDE_INT hi, lo;
5258 tree arg, arglist;
5259 int word, bitpos;
5260 rtx temp;
5262 arglist = TREE_OPERAND (exp, 1);
5263 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5264 return 0;
5266 arg = TREE_VALUE (arglist);
5267 fmode = TYPE_MODE (TREE_TYPE (arg));
5268 rmode = TYPE_MODE (TREE_TYPE (exp));
5269 fmt = REAL_MODE_FORMAT (fmode);
5271 /* For floating point formats without a sign bit, implement signbit
5272 as "ARG < 0.0". */
5273 bitpos = fmt->signbit_ro;
5274 if (bitpos < 0)
5276 /* But we can't do this if the format supports signed zero. */
5277 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5278 return 0;
5280 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5281 build_real (TREE_TYPE (arg), dconst0));
5282 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5285 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5286 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5288 imode = int_mode_for_mode (fmode);
5289 if (imode == BLKmode)
5290 return 0;
5291 temp = gen_lowpart (imode, temp);
5293 else
5295 imode = word_mode;
5296 /* Handle targets with different FP word orders. */
5297 if (FLOAT_WORDS_BIG_ENDIAN)
5298 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5299 else
5300 word = bitpos / BITS_PER_WORD;
5301 temp = operand_subword_force (temp, word, fmode);
5302 bitpos = bitpos % BITS_PER_WORD;
5305 /* Force the intermediate word_mode (or narrower) result into a
5306 register. This avoids attempting to create paradoxical SUBREGs
5307 of floating point modes below. */
5308 temp = force_reg (imode, temp);
5310 /* If the bitpos is within the "result mode" lowpart, the operation
5311 can be implement with a single bitwise AND. Otherwise, we need
5312 a right shift and an AND. */
5314 if (bitpos < GET_MODE_BITSIZE (rmode))
5316 if (bitpos < HOST_BITS_PER_WIDE_INT)
5318 hi = 0;
5319 lo = (HOST_WIDE_INT) 1 << bitpos;
5321 else
5323 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5324 lo = 0;
5327 if (imode != rmode)
5328 temp = gen_lowpart (rmode, temp);
5329 temp = expand_binop (rmode, and_optab, temp,
5330 immed_double_const (lo, hi, rmode),
5331 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5333 else
5335 /* Perform a logical right shift to place the signbit in the least
5336 significant bit, then truncate the result to the desired mode
5337 and mask just this bit. */
5338 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5339 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5340 temp = gen_lowpart (rmode, temp);
5341 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5342 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5345 return temp;
5348 /* Expand fork or exec calls. TARGET is the desired target of the
5349 call. ARGLIST is the list of arguments of the call. FN is the
5350 identificator of the actual function. IGNORE is nonzero if the
5351 value is to be ignored. */
5353 static rtx
5354 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5356 tree id, decl;
5357 tree call;
5359 /* If we are not profiling, just call the function. */
5360 if (!profile_arc_flag)
5361 return NULL_RTX;
5363 /* Otherwise call the wrapper. This should be equivalent for the rest of
5364 compiler, so the code does not diverge, and the wrapper may run the
5365 code necessary for keeping the profiling sane. */
5367 switch (DECL_FUNCTION_CODE (fn))
5369 case BUILT_IN_FORK:
5370 id = get_identifier ("__gcov_fork");
5371 break;
5373 case BUILT_IN_EXECL:
5374 id = get_identifier ("__gcov_execl");
5375 break;
5377 case BUILT_IN_EXECV:
5378 id = get_identifier ("__gcov_execv");
5379 break;
5381 case BUILT_IN_EXECLP:
5382 id = get_identifier ("__gcov_execlp");
5383 break;
5385 case BUILT_IN_EXECLE:
5386 id = get_identifier ("__gcov_execle");
5387 break;
5389 case BUILT_IN_EXECVP:
5390 id = get_identifier ("__gcov_execvp");
5391 break;
5393 case BUILT_IN_EXECVE:
5394 id = get_identifier ("__gcov_execve");
5395 break;
5397 default:
5398 gcc_unreachable ();
5401 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5402 DECL_EXTERNAL (decl) = 1;
5403 TREE_PUBLIC (decl) = 1;
5404 DECL_ARTIFICIAL (decl) = 1;
5405 TREE_NOTHROW (decl) = 1;
5406 call = build_function_call_expr (decl, arglist);
5408 return expand_call (call, target, ignore);
5412 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5413 the pointer in these functions is void*, the tree optimizers may remove
5414 casts. The mode computed in expand_builtin isn't reliable either, due
5415 to __sync_bool_compare_and_swap.
5417 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5418 group of builtins. This gives us log2 of the mode size. */
5420 static inline enum machine_mode
5421 get_builtin_sync_mode (int fcode_diff)
5423 /* The size is not negotiable, so ask not to get BLKmode in return
5424 if the target indicates that a smaller size would be better. */
5425 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5428 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5429 ARGLIST is the operands list to the function. CODE is the rtx code
5430 that corresponds to the arithmetic or logical operation from the name;
5431 an exception here is that NOT actually means NAND. TARGET is an optional
5432 place for us to store the results; AFTER is true if this is the
5433 fetch_and_xxx form. IGNORE is true if we don't actually care about
5434 the result of the operation at all. */
5436 static rtx
5437 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5438 enum rtx_code code, bool after,
5439 rtx target, bool ignore)
5441 rtx addr, val, mem;
5443 /* Expand the operands. */
5444 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5446 arglist = TREE_CHAIN (arglist);
5447 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5449 /* Note that we explicitly do not want any alias information for this
5450 memory, so that we kill all other live memories. Otherwise we don't
5451 satisfy the full barrier semantics of the intrinsic. */
5452 mem = validize_mem (gen_rtx_MEM (mode, addr));
5453 MEM_VOLATILE_P (mem) = 1;
5455 if (ignore)
5456 return expand_sync_operation (mem, val, code);
5457 else
5458 return expand_sync_fetch_operation (mem, val, code, after, target);
5461 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5462 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5463 true if this is the boolean form. TARGET is a place for us to store the
5464 results; this is NOT optional if IS_BOOL is true. */
5466 static rtx
5467 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5468 bool is_bool, rtx target)
5470 rtx addr, old_val, new_val, mem;
5472 /* Expand the operands. */
5473 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5475 arglist = TREE_CHAIN (arglist);
5476 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5478 arglist = TREE_CHAIN (arglist);
5479 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5481 /* Note that we explicitly do not want any alias information for this
5482 memory, so that we kill all other live memories. Otherwise we don't
5483 satisfy the full barrier semantics of the intrinsic. */
5484 mem = validize_mem (gen_rtx_MEM (mode, addr));
5485 MEM_VOLATILE_P (mem) = 1;
5487 if (is_bool)
5488 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5489 else
5490 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5493 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5494 general form is actually an atomic exchange, and some targets only
5495 support a reduced form with the second argument being a constant 1.
5496 ARGLIST is the operands list to the function; TARGET is an optional
5497 place for us to store the results. */
5499 static rtx
5500 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5501 rtx target)
5503 rtx addr, val, mem;
5505 /* Expand the operands. */
5506 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5508 arglist = TREE_CHAIN (arglist);
5509 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5511 /* Note that we explicitly do not want any alias information for this
5512 memory, so that we kill all other live memories. Otherwise we don't
5513 satisfy the barrier semantics of the intrinsic. */
5514 mem = validize_mem (gen_rtx_MEM (mode, addr));
5515 MEM_VOLATILE_P (mem) = 1;
5517 return expand_sync_lock_test_and_set (mem, val, target);
5520 /* Expand the __sync_synchronize intrinsic. */
5522 static void
5523 expand_builtin_synchronize (void)
5525 tree x;
5527 #ifdef HAVE_memory_barrier
5528 if (HAVE_memory_barrier)
5530 emit_insn (gen_memory_barrier ());
5531 return;
5533 #endif
5535 /* If no explicit memory barrier instruction is available, create an
5536 empty asm stmt with a memory clobber. */
5537 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5538 tree_cons (NULL, build_string (6, "memory"), NULL));
5539 ASM_VOLATILE_P (x) = 1;
5540 expand_asm_expr (x);
5543 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5544 to the function. */
5546 static void
5547 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5549 enum insn_code icode;
5550 rtx addr, mem, insn;
5551 rtx val = const0_rtx;
5553 /* Expand the operands. */
5554 addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5556 /* Note that we explicitly do not want any alias information for this
5557 memory, so that we kill all other live memories. Otherwise we don't
5558 satisfy the barrier semantics of the intrinsic. */
5559 mem = validize_mem (gen_rtx_MEM (mode, addr));
5560 MEM_VOLATILE_P (mem) = 1;
5562 /* If there is an explicit operation in the md file, use it. */
5563 icode = sync_lock_release[mode];
5564 if (icode != CODE_FOR_nothing)
5566 if (!insn_data[icode].operand[1].predicate (val, mode))
5567 val = force_reg (mode, val);
5569 insn = GEN_FCN (icode) (mem, val);
5570 if (insn)
5572 emit_insn (insn);
5573 return;
5577 /* Otherwise we can implement this operation by emitting a barrier
5578 followed by a store of zero. */
5579 expand_builtin_synchronize ();
5580 emit_move_insn (mem, val);
5583 /* Expand an expression EXP that calls a built-in function,
5584 with result going to TARGET if that's convenient
5585 (and in mode MODE if that's convenient).
5586 SUBTARGET may be used as the target for computing one of EXP's operands.
5587 IGNORE is nonzero if the value is to be ignored. */
5590 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5591 int ignore)
5593 tree fndecl = get_callee_fndecl (exp);
5594 tree arglist = TREE_OPERAND (exp, 1);
5595 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5596 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5598 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5599 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5601 /* When not optimizing, generate calls to library functions for a certain
5602 set of builtins. */
5603 if (!optimize
5604 && !called_as_built_in (fndecl)
5605 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5606 && fcode != BUILT_IN_ALLOCA)
5607 return expand_call (exp, target, ignore);
5609 /* The built-in function expanders test for target == const0_rtx
5610 to determine whether the function's result will be ignored. */
5611 if (ignore)
5612 target = const0_rtx;
5614 /* If the result of a pure or const built-in function is ignored, and
5615 none of its arguments are volatile, we can avoid expanding the
5616 built-in call and just evaluate the arguments for side-effects. */
5617 if (target == const0_rtx
5618 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5620 bool volatilep = false;
5621 tree arg;
5623 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5624 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5626 volatilep = true;
5627 break;
5630 if (! volatilep)
5632 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5633 expand_expr (TREE_VALUE (arg), const0_rtx,
5634 VOIDmode, EXPAND_NORMAL);
5635 return const0_rtx;
5639 switch (fcode)
5641 case BUILT_IN_FABS:
5642 case BUILT_IN_FABSF:
5643 case BUILT_IN_FABSL:
5644 target = expand_builtin_fabs (arglist, target, subtarget);
5645 if (target)
5646 return target;
5647 break;
5649 case BUILT_IN_COPYSIGN:
5650 case BUILT_IN_COPYSIGNF:
5651 case BUILT_IN_COPYSIGNL:
5652 target = expand_builtin_copysign (arglist, target, subtarget);
5653 if (target)
5654 return target;
5655 break;
5657 /* Just do a normal library call if we were unable to fold
5658 the values. */
5659 case BUILT_IN_CABS:
5660 case BUILT_IN_CABSF:
5661 case BUILT_IN_CABSL:
5662 break;
5664 case BUILT_IN_EXP:
5665 case BUILT_IN_EXPF:
5666 case BUILT_IN_EXPL:
5667 case BUILT_IN_EXP10:
5668 case BUILT_IN_EXP10F:
5669 case BUILT_IN_EXP10L:
5670 case BUILT_IN_POW10:
5671 case BUILT_IN_POW10F:
5672 case BUILT_IN_POW10L:
5673 case BUILT_IN_EXP2:
5674 case BUILT_IN_EXP2F:
5675 case BUILT_IN_EXP2L:
5676 case BUILT_IN_EXPM1:
5677 case BUILT_IN_EXPM1F:
5678 case BUILT_IN_EXPM1L:
5679 case BUILT_IN_LOGB:
5680 case BUILT_IN_LOGBF:
5681 case BUILT_IN_LOGBL:
5682 case BUILT_IN_ILOGB:
5683 case BUILT_IN_ILOGBF:
5684 case BUILT_IN_ILOGBL:
5685 case BUILT_IN_LOG:
5686 case BUILT_IN_LOGF:
5687 case BUILT_IN_LOGL:
5688 case BUILT_IN_LOG10:
5689 case BUILT_IN_LOG10F:
5690 case BUILT_IN_LOG10L:
5691 case BUILT_IN_LOG2:
5692 case BUILT_IN_LOG2F:
5693 case BUILT_IN_LOG2L:
5694 case BUILT_IN_LOG1P:
5695 case BUILT_IN_LOG1PF:
5696 case BUILT_IN_LOG1PL:
5697 case BUILT_IN_TAN:
5698 case BUILT_IN_TANF:
5699 case BUILT_IN_TANL:
5700 case BUILT_IN_ASIN:
5701 case BUILT_IN_ASINF:
5702 case BUILT_IN_ASINL:
5703 case BUILT_IN_ACOS:
5704 case BUILT_IN_ACOSF:
5705 case BUILT_IN_ACOSL:
5706 case BUILT_IN_ATAN:
5707 case BUILT_IN_ATANF:
5708 case BUILT_IN_ATANL:
5709 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5710 because of possible accuracy problems. */
5711 if (! flag_unsafe_math_optimizations)
5712 break;
5713 case BUILT_IN_SQRT:
5714 case BUILT_IN_SQRTF:
5715 case BUILT_IN_SQRTL:
5716 case BUILT_IN_FLOOR:
5717 case BUILT_IN_FLOORF:
5718 case BUILT_IN_FLOORL:
5719 case BUILT_IN_CEIL:
5720 case BUILT_IN_CEILF:
5721 case BUILT_IN_CEILL:
5722 case BUILT_IN_TRUNC:
5723 case BUILT_IN_TRUNCF:
5724 case BUILT_IN_TRUNCL:
5725 case BUILT_IN_ROUND:
5726 case BUILT_IN_ROUNDF:
5727 case BUILT_IN_ROUNDL:
5728 case BUILT_IN_NEARBYINT:
5729 case BUILT_IN_NEARBYINTF:
5730 case BUILT_IN_NEARBYINTL:
5731 case BUILT_IN_RINT:
5732 case BUILT_IN_RINTF:
5733 case BUILT_IN_RINTL:
5734 case BUILT_IN_LRINT:
5735 case BUILT_IN_LRINTF:
5736 case BUILT_IN_LRINTL:
5737 case BUILT_IN_LLRINT:
5738 case BUILT_IN_LLRINTF:
5739 case BUILT_IN_LLRINTL:
5740 target = expand_builtin_mathfn (exp, target, subtarget);
5741 if (target)
5742 return target;
5743 break;
5745 case BUILT_IN_LCEIL:
5746 case BUILT_IN_LCEILF:
5747 case BUILT_IN_LCEILL:
5748 case BUILT_IN_LLCEIL:
5749 case BUILT_IN_LLCEILF:
5750 case BUILT_IN_LLCEILL:
5751 case BUILT_IN_LFLOOR:
5752 case BUILT_IN_LFLOORF:
5753 case BUILT_IN_LFLOORL:
5754 case BUILT_IN_LLFLOOR:
5755 case BUILT_IN_LLFLOORF:
5756 case BUILT_IN_LLFLOORL:
5757 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5758 if (target)
5759 return target;
5760 break;
5762 case BUILT_IN_POW:
5763 case BUILT_IN_POWF:
5764 case BUILT_IN_POWL:
5765 target = expand_builtin_pow (exp, target, subtarget);
5766 if (target)
5767 return target;
5768 break;
5770 case BUILT_IN_POWI:
5771 case BUILT_IN_POWIF:
5772 case BUILT_IN_POWIL:
5773 target = expand_builtin_powi (exp, target, subtarget);
5774 if (target)
5775 return target;
5776 break;
5778 case BUILT_IN_ATAN2:
5779 case BUILT_IN_ATAN2F:
5780 case BUILT_IN_ATAN2L:
5781 case BUILT_IN_LDEXP:
5782 case BUILT_IN_LDEXPF:
5783 case BUILT_IN_LDEXPL:
5784 case BUILT_IN_FMOD:
5785 case BUILT_IN_FMODF:
5786 case BUILT_IN_FMODL:
5787 case BUILT_IN_DREM:
5788 case BUILT_IN_DREMF:
5789 case BUILT_IN_DREML:
5790 if (! flag_unsafe_math_optimizations)
5791 break;
5792 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5793 if (target)
5794 return target;
5795 break;
5797 case BUILT_IN_SIN:
5798 case BUILT_IN_SINF:
5799 case BUILT_IN_SINL:
5800 case BUILT_IN_COS:
5801 case BUILT_IN_COSF:
5802 case BUILT_IN_COSL:
5803 if (! flag_unsafe_math_optimizations)
5804 break;
5805 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5806 if (target)
5807 return target;
5808 break;
5810 case BUILT_IN_APPLY_ARGS:
5811 return expand_builtin_apply_args ();
5813 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5814 FUNCTION with a copy of the parameters described by
5815 ARGUMENTS, and ARGSIZE. It returns a block of memory
5816 allocated on the stack into which is stored all the registers
5817 that might possibly be used for returning the result of a
5818 function. ARGUMENTS is the value returned by
5819 __builtin_apply_args. ARGSIZE is the number of bytes of
5820 arguments that must be copied. ??? How should this value be
5821 computed? We'll also need a safe worst case value for varargs
5822 functions. */
5823 case BUILT_IN_APPLY:
5824 if (!validate_arglist (arglist, POINTER_TYPE,
5825 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5826 && !validate_arglist (arglist, REFERENCE_TYPE,
5827 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5828 return const0_rtx;
5829 else
5831 int i;
5832 tree t;
5833 rtx ops[3];
5835 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5836 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5838 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5841 /* __builtin_return (RESULT) causes the function to return the
5842 value described by RESULT. RESULT is address of the block of
5843 memory returned by __builtin_apply. */
5844 case BUILT_IN_RETURN:
5845 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5846 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5847 NULL_RTX, VOIDmode, 0));
5848 return const0_rtx;
5850 case BUILT_IN_SAVEREGS:
5851 return expand_builtin_saveregs ();
5853 case BUILT_IN_ARGS_INFO:
5854 return expand_builtin_args_info (arglist);
5856 /* Return the address of the first anonymous stack arg. */
5857 case BUILT_IN_NEXT_ARG:
5858 if (fold_builtin_next_arg (arglist))
5859 return const0_rtx;
5860 return expand_builtin_next_arg ();
5862 case BUILT_IN_CLASSIFY_TYPE:
5863 return expand_builtin_classify_type (arglist);
5865 case BUILT_IN_CONSTANT_P:
5866 return const0_rtx;
5868 case BUILT_IN_FRAME_ADDRESS:
5869 case BUILT_IN_RETURN_ADDRESS:
5870 return expand_builtin_frame_address (fndecl, arglist);
5872 /* Returns the address of the area where the structure is returned.
5873 0 otherwise. */
5874 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5875 if (arglist != 0
5876 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5877 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5878 return const0_rtx;
5879 else
5880 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5882 case BUILT_IN_ALLOCA:
5883 target = expand_builtin_alloca (arglist, target);
5884 if (target)
5885 return target;
5886 break;
5888 case BUILT_IN_STACK_SAVE:
5889 return expand_stack_save ();
5891 case BUILT_IN_STACK_RESTORE:
5892 expand_stack_restore (TREE_VALUE (arglist));
5893 return const0_rtx;
5895 case BUILT_IN_FFS:
5896 case BUILT_IN_FFSL:
5897 case BUILT_IN_FFSLL:
5898 case BUILT_IN_FFSIMAX:
5899 target = expand_builtin_unop (target_mode, arglist, target,
5900 subtarget, ffs_optab);
5901 if (target)
5902 return target;
5903 break;
5905 case BUILT_IN_CLZ:
5906 case BUILT_IN_CLZL:
5907 case BUILT_IN_CLZLL:
5908 case BUILT_IN_CLZIMAX:
5909 target = expand_builtin_unop (target_mode, arglist, target,
5910 subtarget, clz_optab);
5911 if (target)
5912 return target;
5913 break;
5915 case BUILT_IN_CTZ:
5916 case BUILT_IN_CTZL:
5917 case BUILT_IN_CTZLL:
5918 case BUILT_IN_CTZIMAX:
5919 target = expand_builtin_unop (target_mode, arglist, target,
5920 subtarget, ctz_optab);
5921 if (target)
5922 return target;
5923 break;
5925 case BUILT_IN_POPCOUNT:
5926 case BUILT_IN_POPCOUNTL:
5927 case BUILT_IN_POPCOUNTLL:
5928 case BUILT_IN_POPCOUNTIMAX:
5929 target = expand_builtin_unop (target_mode, arglist, target,
5930 subtarget, popcount_optab);
5931 if (target)
5932 return target;
5933 break;
5935 case BUILT_IN_PARITY:
5936 case BUILT_IN_PARITYL:
5937 case BUILT_IN_PARITYLL:
5938 case BUILT_IN_PARITYIMAX:
5939 target = expand_builtin_unop (target_mode, arglist, target,
5940 subtarget, parity_optab);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_STRLEN:
5946 target = expand_builtin_strlen (arglist, target, target_mode);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_STRCPY:
5952 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_STRNCPY:
5958 target = expand_builtin_strncpy (exp, target, mode);
5959 if (target)
5960 return target;
5961 break;
5963 case BUILT_IN_STPCPY:
5964 target = expand_builtin_stpcpy (exp, target, mode);
5965 if (target)
5966 return target;
5967 break;
5969 case BUILT_IN_STRCAT:
5970 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5971 if (target)
5972 return target;
5973 break;
5975 case BUILT_IN_STRNCAT:
5976 target = expand_builtin_strncat (arglist, target, mode);
5977 if (target)
5978 return target;
5979 break;
5981 case BUILT_IN_STRSPN:
5982 target = expand_builtin_strspn (arglist, target, mode);
5983 if (target)
5984 return target;
5985 break;
5987 case BUILT_IN_STRCSPN:
5988 target = expand_builtin_strcspn (arglist, target, mode);
5989 if (target)
5990 return target;
5991 break;
5993 case BUILT_IN_STRSTR:
5994 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5995 if (target)
5996 return target;
5997 break;
5999 case BUILT_IN_STRPBRK:
6000 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6001 if (target)
6002 return target;
6003 break;
6005 case BUILT_IN_INDEX:
6006 case BUILT_IN_STRCHR:
6007 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6008 if (target)
6009 return target;
6010 break;
6012 case BUILT_IN_RINDEX:
6013 case BUILT_IN_STRRCHR:
6014 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6015 if (target)
6016 return target;
6017 break;
6019 case BUILT_IN_MEMCPY:
6020 target = expand_builtin_memcpy (exp, target, mode);
6021 if (target)
6022 return target;
6023 break;
6025 case BUILT_IN_MEMPCPY:
6026 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6027 if (target)
6028 return target;
6029 break;
6031 case BUILT_IN_MEMMOVE:
6032 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6033 mode, exp);
6034 if (target)
6035 return target;
6036 break;
6038 case BUILT_IN_BCOPY:
6039 target = expand_builtin_bcopy (exp);
6040 if (target)
6041 return target;
6042 break;
6044 case BUILT_IN_MEMSET:
6045 target = expand_builtin_memset (arglist, target, mode, exp);
6046 if (target)
6047 return target;
6048 break;
6050 case BUILT_IN_BZERO:
6051 target = expand_builtin_bzero (exp);
6052 if (target)
6053 return target;
6054 break;
6056 case BUILT_IN_STRCMP:
6057 target = expand_builtin_strcmp (exp, target, mode);
6058 if (target)
6059 return target;
6060 break;
6062 case BUILT_IN_STRNCMP:
6063 target = expand_builtin_strncmp (exp, target, mode);
6064 if (target)
6065 return target;
6066 break;
6068 case BUILT_IN_BCMP:
6069 case BUILT_IN_MEMCMP:
6070 target = expand_builtin_memcmp (exp, arglist, target, mode);
6071 if (target)
6072 return target;
6073 break;
6075 case BUILT_IN_SETJMP:
6076 target = expand_builtin_setjmp (arglist, target);
6077 if (target)
6078 return target;
6079 break;
6081 /* __builtin_longjmp is passed a pointer to an array of five words.
6082 It's similar to the C library longjmp function but works with
6083 __builtin_setjmp above. */
6084 case BUILT_IN_LONGJMP:
6085 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6086 break;
6087 else
6089 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6090 VOIDmode, 0);
6091 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6092 NULL_RTX, VOIDmode, 0);
6094 if (value != const1_rtx)
6096 error ("%<__builtin_longjmp%> second argument must be 1");
6097 return const0_rtx;
6100 expand_builtin_longjmp (buf_addr, value);
6101 return const0_rtx;
6104 case BUILT_IN_NONLOCAL_GOTO:
6105 target = expand_builtin_nonlocal_goto (arglist);
6106 if (target)
6107 return target;
6108 break;
6110 /* This updates the setjmp buffer that is its argument with the value
6111 of the current stack pointer. */
6112 case BUILT_IN_UPDATE_SETJMP_BUF:
6113 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6115 rtx buf_addr
6116 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6118 expand_builtin_update_setjmp_buf (buf_addr);
6119 return const0_rtx;
6121 break;
6123 case BUILT_IN_TRAP:
6124 expand_builtin_trap ();
6125 return const0_rtx;
6127 case BUILT_IN_PRINTF:
6128 target = expand_builtin_printf (exp, target, mode, false);
6129 if (target)
6130 return target;
6131 break;
6133 case BUILT_IN_PRINTF_UNLOCKED:
6134 target = expand_builtin_printf (exp, target, mode, true);
6135 if (target)
6136 return target;
6137 break;
6139 case BUILT_IN_FPUTS:
6140 target = expand_builtin_fputs (arglist, target, false);
6141 if (target)
6142 return target;
6143 break;
6144 case BUILT_IN_FPUTS_UNLOCKED:
6145 target = expand_builtin_fputs (arglist, target, true);
6146 if (target)
6147 return target;
6148 break;
6150 case BUILT_IN_FPRINTF:
6151 target = expand_builtin_fprintf (exp, target, mode, false);
6152 if (target)
6153 return target;
6154 break;
6156 case BUILT_IN_FPRINTF_UNLOCKED:
6157 target = expand_builtin_fprintf (exp, target, mode, true);
6158 if (target)
6159 return target;
6160 break;
6162 case BUILT_IN_SPRINTF:
6163 target = expand_builtin_sprintf (arglist, target, mode);
6164 if (target)
6165 return target;
6166 break;
6168 case BUILT_IN_SIGNBIT:
6169 case BUILT_IN_SIGNBITF:
6170 case BUILT_IN_SIGNBITL:
6171 target = expand_builtin_signbit (exp, target);
6172 if (target)
6173 return target;
6174 break;
6176 /* Various hooks for the DWARF 2 __throw routine. */
6177 case BUILT_IN_UNWIND_INIT:
6178 expand_builtin_unwind_init ();
6179 return const0_rtx;
6180 case BUILT_IN_DWARF_CFA:
6181 return virtual_cfa_rtx;
6182 #ifdef DWARF2_UNWIND_INFO
6183 case BUILT_IN_DWARF_SP_COLUMN:
6184 return expand_builtin_dwarf_sp_column ();
6185 case BUILT_IN_INIT_DWARF_REG_SIZES:
6186 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6187 return const0_rtx;
6188 #endif
6189 case BUILT_IN_FROB_RETURN_ADDR:
6190 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6191 case BUILT_IN_EXTRACT_RETURN_ADDR:
6192 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6193 case BUILT_IN_EH_RETURN:
6194 expand_builtin_eh_return (TREE_VALUE (arglist),
6195 TREE_VALUE (TREE_CHAIN (arglist)));
6196 return const0_rtx;
6197 #ifdef EH_RETURN_DATA_REGNO
6198 case BUILT_IN_EH_RETURN_DATA_REGNO:
6199 return expand_builtin_eh_return_data_regno (arglist);
6200 #endif
6201 case BUILT_IN_EXTEND_POINTER:
6202 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6204 case BUILT_IN_VA_START:
6205 case BUILT_IN_STDARG_START:
6206 return expand_builtin_va_start (arglist);
6207 case BUILT_IN_VA_END:
6208 return expand_builtin_va_end (arglist);
6209 case BUILT_IN_VA_COPY:
6210 return expand_builtin_va_copy (arglist);
6211 case BUILT_IN_EXPECT:
6212 return expand_builtin_expect (arglist, target);
6213 case BUILT_IN_PREFETCH:
6214 expand_builtin_prefetch (arglist);
6215 return const0_rtx;
6217 case BUILT_IN_PROFILE_FUNC_ENTER:
6218 return expand_builtin_profile_func (false);
6219 case BUILT_IN_PROFILE_FUNC_EXIT:
6220 return expand_builtin_profile_func (true);
6222 case BUILT_IN_INIT_TRAMPOLINE:
6223 return expand_builtin_init_trampoline (arglist);
6224 case BUILT_IN_ADJUST_TRAMPOLINE:
6225 return expand_builtin_adjust_trampoline (arglist);
6227 case BUILT_IN_FORK:
6228 case BUILT_IN_EXECL:
6229 case BUILT_IN_EXECV:
6230 case BUILT_IN_EXECLP:
6231 case BUILT_IN_EXECLE:
6232 case BUILT_IN_EXECVP:
6233 case BUILT_IN_EXECVE:
6234 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6235 if (target)
6236 return target;
6237 break;
6239 case BUILT_IN_FETCH_AND_ADD_1:
6240 case BUILT_IN_FETCH_AND_ADD_2:
6241 case BUILT_IN_FETCH_AND_ADD_4:
6242 case BUILT_IN_FETCH_AND_ADD_8:
6243 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6244 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6245 false, target, ignore);
6246 if (target)
6247 return target;
6248 break;
6250 case BUILT_IN_FETCH_AND_SUB_1:
6251 case BUILT_IN_FETCH_AND_SUB_2:
6252 case BUILT_IN_FETCH_AND_SUB_4:
6253 case BUILT_IN_FETCH_AND_SUB_8:
6254 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6255 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6256 false, target, ignore);
6257 if (target)
6258 return target;
6259 break;
6261 case BUILT_IN_FETCH_AND_OR_1:
6262 case BUILT_IN_FETCH_AND_OR_2:
6263 case BUILT_IN_FETCH_AND_OR_4:
6264 case BUILT_IN_FETCH_AND_OR_8:
6265 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6266 target = expand_builtin_sync_operation (mode, arglist, IOR,
6267 false, target, ignore);
6268 if (target)
6269 return target;
6270 break;
6272 case BUILT_IN_FETCH_AND_AND_1:
6273 case BUILT_IN_FETCH_AND_AND_2:
6274 case BUILT_IN_FETCH_AND_AND_4:
6275 case BUILT_IN_FETCH_AND_AND_8:
6276 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6277 target = expand_builtin_sync_operation (mode, arglist, AND,
6278 false, target, ignore);
6279 if (target)
6280 return target;
6281 break;
6283 case BUILT_IN_FETCH_AND_XOR_1:
6284 case BUILT_IN_FETCH_AND_XOR_2:
6285 case BUILT_IN_FETCH_AND_XOR_4:
6286 case BUILT_IN_FETCH_AND_XOR_8:
6287 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6288 target = expand_builtin_sync_operation (mode, arglist, XOR,
6289 false, target, ignore);
6290 if (target)
6291 return target;
6292 break;
6294 case BUILT_IN_FETCH_AND_NAND_1:
6295 case BUILT_IN_FETCH_AND_NAND_2:
6296 case BUILT_IN_FETCH_AND_NAND_4:
6297 case BUILT_IN_FETCH_AND_NAND_8:
6298 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6299 target = expand_builtin_sync_operation (mode, arglist, NOT,
6300 false, target, ignore);
6301 if (target)
6302 return target;
6303 break;
6305 case BUILT_IN_ADD_AND_FETCH_1:
6306 case BUILT_IN_ADD_AND_FETCH_2:
6307 case BUILT_IN_ADD_AND_FETCH_4:
6308 case BUILT_IN_ADD_AND_FETCH_8:
6309 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6310 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6311 true, target, ignore);
6312 if (target)
6313 return target;
6314 break;
6316 case BUILT_IN_SUB_AND_FETCH_1:
6317 case BUILT_IN_SUB_AND_FETCH_2:
6318 case BUILT_IN_SUB_AND_FETCH_4:
6319 case BUILT_IN_SUB_AND_FETCH_8:
6320 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6321 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6322 true, target, ignore);
6323 if (target)
6324 return target;
6325 break;
6327 case BUILT_IN_OR_AND_FETCH_1:
6328 case BUILT_IN_OR_AND_FETCH_2:
6329 case BUILT_IN_OR_AND_FETCH_4:
6330 case BUILT_IN_OR_AND_FETCH_8:
6331 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6332 target = expand_builtin_sync_operation (mode, arglist, IOR,
6333 true, target, ignore);
6334 if (target)
6335 return target;
6336 break;
6338 case BUILT_IN_AND_AND_FETCH_1:
6339 case BUILT_IN_AND_AND_FETCH_2:
6340 case BUILT_IN_AND_AND_FETCH_4:
6341 case BUILT_IN_AND_AND_FETCH_8:
6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6343 target = expand_builtin_sync_operation (mode, arglist, AND,
6344 true, target, ignore);
6345 if (target)
6346 return target;
6347 break;
6349 case BUILT_IN_XOR_AND_FETCH_1:
6350 case BUILT_IN_XOR_AND_FETCH_2:
6351 case BUILT_IN_XOR_AND_FETCH_4:
6352 case BUILT_IN_XOR_AND_FETCH_8:
6353 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6354 target = expand_builtin_sync_operation (mode, arglist, XOR,
6355 true, target, ignore);
6356 if (target)
6357 return target;
6358 break;
6360 case BUILT_IN_NAND_AND_FETCH_1:
6361 case BUILT_IN_NAND_AND_FETCH_2:
6362 case BUILT_IN_NAND_AND_FETCH_4:
6363 case BUILT_IN_NAND_AND_FETCH_8:
6364 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6365 target = expand_builtin_sync_operation (mode, arglist, NOT,
6366 true, target, ignore);
6367 if (target)
6368 return target;
6369 break;
6371 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6372 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6373 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6374 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6375 if (mode == VOIDmode)
6376 mode = TYPE_MODE (boolean_type_node);
6377 if (!target || !register_operand (target, mode))
6378 target = gen_reg_rtx (mode);
6380 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6381 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6382 if (target)
6383 return target;
6384 break;
6386 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6387 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6388 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6389 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6390 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6391 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6392 if (target)
6393 return target;
6394 break;
6396 case BUILT_IN_LOCK_TEST_AND_SET_1:
6397 case BUILT_IN_LOCK_TEST_AND_SET_2:
6398 case BUILT_IN_LOCK_TEST_AND_SET_4:
6399 case BUILT_IN_LOCK_TEST_AND_SET_8:
6400 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6401 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6402 if (target)
6403 return target;
6404 break;
6406 case BUILT_IN_LOCK_RELEASE_1:
6407 case BUILT_IN_LOCK_RELEASE_2:
6408 case BUILT_IN_LOCK_RELEASE_4:
6409 case BUILT_IN_LOCK_RELEASE_8:
6410 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6411 expand_builtin_lock_release (mode, arglist);
6412 return const0_rtx;
6414 case BUILT_IN_SYNCHRONIZE:
6415 expand_builtin_synchronize ();
6416 return const0_rtx;
6418 case BUILT_IN_OBJECT_SIZE:
6419 return expand_builtin_object_size (exp);
6421 case BUILT_IN_MEMCPY_CHK:
6422 case BUILT_IN_MEMPCPY_CHK:
6423 case BUILT_IN_MEMMOVE_CHK:
6424 case BUILT_IN_MEMSET_CHK:
6425 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6426 if (target)
6427 return target;
6428 break;
6430 case BUILT_IN_STRCPY_CHK:
6431 case BUILT_IN_STPCPY_CHK:
6432 case BUILT_IN_STRNCPY_CHK:
6433 case BUILT_IN_STRCAT_CHK:
6434 case BUILT_IN_SNPRINTF_CHK:
6435 case BUILT_IN_VSNPRINTF_CHK:
6436 maybe_emit_chk_warning (exp, fcode);
6437 break;
6439 case BUILT_IN_SPRINTF_CHK:
6440 case BUILT_IN_VSPRINTF_CHK:
6441 maybe_emit_sprintf_chk_warning (exp, fcode);
6442 break;
6444 default: /* just do library call, if unknown builtin */
6445 break;
6448 /* The switch statement above can drop through to cause the function
6449 to be called normally. */
6450 return expand_call (exp, target, ignore);
6453 /* Determine whether a tree node represents a call to a built-in
6454 function. If the tree T is a call to a built-in function with
6455 the right number of arguments of the appropriate types, return
6456 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6457 Otherwise the return value is END_BUILTINS. */
6459 enum built_in_function
6460 builtin_mathfn_code (tree t)
6462 tree fndecl, arglist, parmlist;
6463 tree argtype, parmtype;
6465 if (TREE_CODE (t) != CALL_EXPR
6466 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6467 return END_BUILTINS;
6469 fndecl = get_callee_fndecl (t);
6470 if (fndecl == NULL_TREE
6471 || TREE_CODE (fndecl) != FUNCTION_DECL
6472 || ! DECL_BUILT_IN (fndecl)
6473 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6474 return END_BUILTINS;
6476 arglist = TREE_OPERAND (t, 1);
6477 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6478 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6480 /* If a function doesn't take a variable number of arguments,
6481 the last element in the list will have type `void'. */
6482 parmtype = TREE_VALUE (parmlist);
6483 if (VOID_TYPE_P (parmtype))
6485 if (arglist)
6486 return END_BUILTINS;
6487 return DECL_FUNCTION_CODE (fndecl);
6490 if (! arglist)
6491 return END_BUILTINS;
6493 argtype = TREE_TYPE (TREE_VALUE (arglist));
6495 if (SCALAR_FLOAT_TYPE_P (parmtype))
6497 if (! SCALAR_FLOAT_TYPE_P (argtype))
6498 return END_BUILTINS;
6500 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6502 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6503 return END_BUILTINS;
6505 else if (POINTER_TYPE_P (parmtype))
6507 if (! POINTER_TYPE_P (argtype))
6508 return END_BUILTINS;
6510 else if (INTEGRAL_TYPE_P (parmtype))
6512 if (! INTEGRAL_TYPE_P (argtype))
6513 return END_BUILTINS;
6515 else
6516 return END_BUILTINS;
6518 arglist = TREE_CHAIN (arglist);
6521 /* Variable-length argument list. */
6522 return DECL_FUNCTION_CODE (fndecl);
6525 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6526 constant. ARGLIST is the argument list of the call. */
6528 static tree
6529 fold_builtin_constant_p (tree arglist)
6531 if (arglist == 0)
6532 return 0;
6534 arglist = TREE_VALUE (arglist);
6536 /* We return 1 for a numeric type that's known to be a constant
6537 value at compile-time or for an aggregate type that's a
6538 literal constant. */
6539 STRIP_NOPS (arglist);
6541 /* If we know this is a constant, emit the constant of one. */
6542 if (CONSTANT_CLASS_P (arglist)
6543 || (TREE_CODE (arglist) == CONSTRUCTOR
6544 && TREE_CONSTANT (arglist)))
6545 return integer_one_node;
6546 if (TREE_CODE (arglist) == ADDR_EXPR)
6548 tree op = TREE_OPERAND (arglist, 0);
6549 if (TREE_CODE (op) == STRING_CST
6550 || (TREE_CODE (op) == ARRAY_REF
6551 && integer_zerop (TREE_OPERAND (op, 1))
6552 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6553 return integer_one_node;
6556 /* If this expression has side effects, show we don't know it to be a
6557 constant. Likewise if it's a pointer or aggregate type since in
6558 those case we only want literals, since those are only optimized
6559 when generating RTL, not later.
6560 And finally, if we are compiling an initializer, not code, we
6561 need to return a definite result now; there's not going to be any
6562 more optimization done. */
6563 if (TREE_SIDE_EFFECTS (arglist)
6564 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6565 || POINTER_TYPE_P (TREE_TYPE (arglist))
6566 || cfun == 0)
6567 return integer_zero_node;
6569 return 0;
6572 /* Fold a call to __builtin_expect, if we expect that a comparison against
6573 the argument will fold to a constant. In practice, this means a true
6574 constant or the address of a non-weak symbol. ARGLIST is the argument
6575 list of the call. */
6577 static tree
6578 fold_builtin_expect (tree arglist)
6580 tree arg, inner;
6582 if (arglist == 0)
6583 return 0;
6585 arg = TREE_VALUE (arglist);
6587 /* If the argument isn't invariant, then there's nothing we can do. */
6588 if (!TREE_INVARIANT (arg))
6589 return 0;
6591 /* If we're looking at an address of a weak decl, then do not fold. */
6592 inner = arg;
6593 STRIP_NOPS (inner);
6594 if (TREE_CODE (inner) == ADDR_EXPR)
6598 inner = TREE_OPERAND (inner, 0);
6600 while (TREE_CODE (inner) == COMPONENT_REF
6601 || TREE_CODE (inner) == ARRAY_REF);
6602 if (DECL_P (inner) && DECL_WEAK (inner))
6603 return 0;
6606 /* Otherwise, ARG already has the proper type for the return value. */
6607 return arg;
6610 /* Fold a call to __builtin_classify_type. */
6612 static tree
6613 fold_builtin_classify_type (tree arglist)
6615 if (arglist == 0)
6616 return build_int_cst (NULL_TREE, no_type_class);
6618 return build_int_cst (NULL_TREE,
6619 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6622 /* Fold a call to __builtin_strlen. */
6624 static tree
6625 fold_builtin_strlen (tree arglist)
6627 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6628 return NULL_TREE;
6629 else
6631 tree len = c_strlen (TREE_VALUE (arglist), 0);
6633 if (len)
6635 /* Convert from the internal "sizetype" type to "size_t". */
6636 if (size_type_node)
6637 len = fold_convert (size_type_node, len);
6638 return len;
6641 return NULL_TREE;
6645 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6647 static tree
6648 fold_builtin_inf (tree type, int warn)
6650 REAL_VALUE_TYPE real;
6652 /* __builtin_inff is intended to be usable to define INFINITY on all
6653 targets. If an infinity is not available, INFINITY expands "to a
6654 positive constant of type float that overflows at translation
6655 time", footnote "In this case, using INFINITY will violate the
6656 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6657 Thus we pedwarn to ensure this constraint violation is
6658 diagnosed. */
6659 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6660 pedwarn ("target format does not support infinity");
6662 real_inf (&real);
6663 return build_real (type, real);
6666 /* Fold a call to __builtin_nan or __builtin_nans. */
6668 static tree
6669 fold_builtin_nan (tree arglist, tree type, int quiet)
6671 REAL_VALUE_TYPE real;
6672 const char *str;
6674 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6675 return 0;
6676 str = c_getstr (TREE_VALUE (arglist));
6677 if (!str)
6678 return 0;
6680 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6681 return 0;
6683 return build_real (type, real);
6686 /* Return true if the floating point expression T has an integer value.
6687 We also allow +Inf, -Inf and NaN to be considered integer values. */
6689 static bool
6690 integer_valued_real_p (tree t)
6692 switch (TREE_CODE (t))
6694 case FLOAT_EXPR:
6695 return true;
6697 case ABS_EXPR:
6698 case SAVE_EXPR:
6699 case NON_LVALUE_EXPR:
6700 return integer_valued_real_p (TREE_OPERAND (t, 0));
6702 case COMPOUND_EXPR:
6703 case MODIFY_EXPR:
6704 case BIND_EXPR:
6705 return integer_valued_real_p (TREE_OPERAND (t, 1));
6707 case PLUS_EXPR:
6708 case MINUS_EXPR:
6709 case MULT_EXPR:
6710 case MIN_EXPR:
6711 case MAX_EXPR:
6712 return integer_valued_real_p (TREE_OPERAND (t, 0))
6713 && integer_valued_real_p (TREE_OPERAND (t, 1));
6715 case COND_EXPR:
6716 return integer_valued_real_p (TREE_OPERAND (t, 1))
6717 && integer_valued_real_p (TREE_OPERAND (t, 2));
6719 case REAL_CST:
6720 if (! TREE_CONSTANT_OVERFLOW (t))
6722 REAL_VALUE_TYPE c, cint;
6724 c = TREE_REAL_CST (t);
6725 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6726 return real_identical (&c, &cint);
6728 break;
6730 case NOP_EXPR:
6732 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6733 if (TREE_CODE (type) == INTEGER_TYPE)
6734 return true;
6735 if (TREE_CODE (type) == REAL_TYPE)
6736 return integer_valued_real_p (TREE_OPERAND (t, 0));
6737 break;
6740 case CALL_EXPR:
6741 switch (builtin_mathfn_code (t))
6743 case BUILT_IN_CEIL:
6744 case BUILT_IN_CEILF:
6745 case BUILT_IN_CEILL:
6746 case BUILT_IN_FLOOR:
6747 case BUILT_IN_FLOORF:
6748 case BUILT_IN_FLOORL:
6749 case BUILT_IN_NEARBYINT:
6750 case BUILT_IN_NEARBYINTF:
6751 case BUILT_IN_NEARBYINTL:
6752 case BUILT_IN_RINT:
6753 case BUILT_IN_RINTF:
6754 case BUILT_IN_RINTL:
6755 case BUILT_IN_ROUND:
6756 case BUILT_IN_ROUNDF:
6757 case BUILT_IN_ROUNDL:
6758 case BUILT_IN_TRUNC:
6759 case BUILT_IN_TRUNCF:
6760 case BUILT_IN_TRUNCL:
6761 return true;
6763 default:
6764 break;
6766 break;
6768 default:
6769 break;
6771 return false;
6774 /* EXP is assumed to be builtin call where truncation can be propagated
6775 across (for instance floor((double)f) == (double)floorf (f).
6776 Do the transformation. */
6778 static tree
6779 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6781 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6782 tree arg;
6784 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6785 return 0;
6787 arg = TREE_VALUE (arglist);
6788 /* Integer rounding functions are idempotent. */
6789 if (fcode == builtin_mathfn_code (arg))
6790 return arg;
6792 /* If argument is already integer valued, and we don't need to worry
6793 about setting errno, there's no need to perform rounding. */
6794 if (! flag_errno_math && integer_valued_real_p (arg))
6795 return arg;
6797 if (optimize)
6799 tree arg0 = strip_float_extensions (arg);
6800 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6801 tree newtype = TREE_TYPE (arg0);
6802 tree decl;
6804 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6805 && (decl = mathfn_built_in (newtype, fcode)))
6807 arglist =
6808 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6809 return fold_convert (ftype,
6810 build_function_call_expr (decl, arglist));
6813 return 0;
6816 /* EXP is assumed to be builtin call which can narrow the FP type of
6817 the argument, for instance lround((double)f) -> lroundf (f). */
6819 static tree
6820 fold_fixed_mathfn (tree fndecl, tree arglist)
6822 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6823 tree arg;
6825 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6826 return 0;
6828 arg = TREE_VALUE (arglist);
6830 /* If argument is already integer valued, and we don't need to worry
6831 about setting errno, there's no need to perform rounding. */
6832 if (! flag_errno_math && integer_valued_real_p (arg))
6833 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6835 if (optimize)
6837 tree ftype = TREE_TYPE (arg);
6838 tree arg0 = strip_float_extensions (arg);
6839 tree newtype = TREE_TYPE (arg0);
6840 tree decl;
6842 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6843 && (decl = mathfn_built_in (newtype, fcode)))
6845 arglist =
6846 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6847 return build_function_call_expr (decl, arglist);
6850 return 0;
6853 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6854 is the argument list and TYPE is the return type. Return
6855 NULL_TREE if no if no simplification can be made. */
6857 static tree
6858 fold_builtin_cabs (tree arglist, tree type)
6860 tree arg;
6862 if (!arglist || TREE_CHAIN (arglist))
6863 return NULL_TREE;
6865 arg = TREE_VALUE (arglist);
6866 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6867 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6868 return NULL_TREE;
6870 /* Evaluate cabs of a constant at compile-time. */
6871 if (flag_unsafe_math_optimizations
6872 && TREE_CODE (arg) == COMPLEX_CST
6873 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6874 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6875 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6876 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6878 REAL_VALUE_TYPE r, i;
6880 r = TREE_REAL_CST (TREE_REALPART (arg));
6881 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6883 real_arithmetic (&r, MULT_EXPR, &r, &r);
6884 real_arithmetic (&i, MULT_EXPR, &i, &i);
6885 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6886 if (real_sqrt (&r, TYPE_MODE (type), &r)
6887 || ! flag_trapping_math)
6888 return build_real (type, r);
6891 /* If either part is zero, cabs is fabs of the other. */
6892 if (TREE_CODE (arg) == COMPLEX_EXPR
6893 && real_zerop (TREE_OPERAND (arg, 0)))
6894 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6895 if (TREE_CODE (arg) == COMPLEX_EXPR
6896 && real_zerop (TREE_OPERAND (arg, 1)))
6897 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6899 /* Don't do this when optimizing for size. */
6900 if (flag_unsafe_math_optimizations
6901 && optimize && !optimize_size)
6903 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6905 if (sqrtfn != NULL_TREE)
6907 tree rpart, ipart, result, arglist;
6909 arg = builtin_save_expr (arg);
6911 rpart = fold_build1 (REALPART_EXPR, type, arg);
6912 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6914 rpart = builtin_save_expr (rpart);
6915 ipart = builtin_save_expr (ipart);
6917 result = fold_build2 (PLUS_EXPR, type,
6918 fold_build2 (MULT_EXPR, type,
6919 rpart, rpart),
6920 fold_build2 (MULT_EXPR, type,
6921 ipart, ipart));
6923 arglist = build_tree_list (NULL_TREE, result);
6924 return build_function_call_expr (sqrtfn, arglist);
6928 return NULL_TREE;
6931 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6932 NULL_TREE if no simplification can be made. */
6934 static tree
6935 fold_builtin_sqrt (tree arglist, tree type)
6938 enum built_in_function fcode;
6939 tree arg = TREE_VALUE (arglist);
6941 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6942 return NULL_TREE;
6944 /* Optimize sqrt of constant value. */
6945 if (TREE_CODE (arg) == REAL_CST
6946 && ! TREE_CONSTANT_OVERFLOW (arg))
6948 REAL_VALUE_TYPE r, x;
6950 x = TREE_REAL_CST (arg);
6951 if (real_sqrt (&r, TYPE_MODE (type), &x)
6952 || (!flag_trapping_math && !flag_errno_math))
6953 return build_real (type, r);
6956 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6957 fcode = builtin_mathfn_code (arg);
6958 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6960 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6961 arg = fold_build2 (MULT_EXPR, type,
6962 TREE_VALUE (TREE_OPERAND (arg, 1)),
6963 build_real (type, dconsthalf));
6964 arglist = build_tree_list (NULL_TREE, arg);
6965 return build_function_call_expr (expfn, arglist);
6968 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6969 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6971 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6973 if (powfn)
6975 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6976 tree tree_root;
6977 /* The inner root was either sqrt or cbrt. */
6978 REAL_VALUE_TYPE dconstroot =
6979 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6981 /* Adjust for the outer root. */
6982 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6983 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6984 tree_root = build_real (type, dconstroot);
6985 arglist = tree_cons (NULL_TREE, arg0,
6986 build_tree_list (NULL_TREE, tree_root));
6987 return build_function_call_expr (powfn, arglist);
6991 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6992 if (flag_unsafe_math_optimizations
6993 && (fcode == BUILT_IN_POW
6994 || fcode == BUILT_IN_POWF
6995 || fcode == BUILT_IN_POWL))
6997 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6998 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6999 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7000 tree narg1;
7001 if (!tree_expr_nonnegative_p (arg0))
7002 arg0 = build1 (ABS_EXPR, type, arg0);
7003 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7004 build_real (type, dconsthalf));
7005 arglist = tree_cons (NULL_TREE, arg0,
7006 build_tree_list (NULL_TREE, narg1));
7007 return build_function_call_expr (powfn, arglist);
7010 return NULL_TREE;
7013 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7014 NULL_TREE if no simplification can be made. */
7015 static tree
7016 fold_builtin_cbrt (tree arglist, tree type)
7018 tree arg = TREE_VALUE (arglist);
7019 const enum built_in_function fcode = builtin_mathfn_code (arg);
7021 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7022 return NULL_TREE;
7024 /* Optimize cbrt of constant value. */
7025 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7026 return arg;
7028 if (flag_unsafe_math_optimizations)
7030 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7031 if (BUILTIN_EXPONENT_P (fcode))
7033 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7034 const REAL_VALUE_TYPE third_trunc =
7035 real_value_truncate (TYPE_MODE (type), dconstthird);
7036 arg = fold_build2 (MULT_EXPR, type,
7037 TREE_VALUE (TREE_OPERAND (arg, 1)),
7038 build_real (type, third_trunc));
7039 arglist = build_tree_list (NULL_TREE, arg);
7040 return build_function_call_expr (expfn, arglist);
7043 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7044 if (BUILTIN_SQRT_P (fcode))
7046 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7048 if (powfn)
7050 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7051 tree tree_root;
7052 REAL_VALUE_TYPE dconstroot = dconstthird;
7054 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7055 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7056 tree_root = build_real (type, dconstroot);
7057 arglist = tree_cons (NULL_TREE, arg0,
7058 build_tree_list (NULL_TREE, tree_root));
7059 return build_function_call_expr (powfn, arglist);
7063 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7064 if (BUILTIN_CBRT_P (fcode))
7066 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7067 if (tree_expr_nonnegative_p (arg0))
7069 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7071 if (powfn)
7073 tree tree_root;
7074 REAL_VALUE_TYPE dconstroot;
7076 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7077 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7078 tree_root = build_real (type, dconstroot);
7079 arglist = tree_cons (NULL_TREE, arg0,
7080 build_tree_list (NULL_TREE, tree_root));
7081 return build_function_call_expr (powfn, arglist);
7086 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7087 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7088 || fcode == BUILT_IN_POWL)
7090 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7091 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7092 if (tree_expr_nonnegative_p (arg00))
7094 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7095 const REAL_VALUE_TYPE dconstroot
7096 = real_value_truncate (TYPE_MODE (type), dconstthird);
7097 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7098 build_real (type, dconstroot));
7099 arglist = tree_cons (NULL_TREE, arg00,
7100 build_tree_list (NULL_TREE, narg01));
7101 return build_function_call_expr (powfn, arglist);
7105 return NULL_TREE;
7108 /* Fold function call to builtin sin, sinf, or sinl. Return
7109 NULL_TREE if no simplification can be made. */
7110 static tree
7111 fold_builtin_sin (tree arglist)
7113 tree arg = TREE_VALUE (arglist);
7115 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7116 return NULL_TREE;
7118 /* Optimize sin (0.0) = 0.0. */
7119 if (real_zerop (arg))
7120 return arg;
7122 return NULL_TREE;
7125 /* Fold function call to builtin cos, cosf, or cosl. Return
7126 NULL_TREE if no simplification can be made. */
7127 static tree
7128 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7130 tree arg = TREE_VALUE (arglist);
7132 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7133 return NULL_TREE;
7135 /* Optimize cos (0.0) = 1.0. */
7136 if (real_zerop (arg))
7137 return build_real (type, dconst1);
7139 /* Optimize cos(-x) into cos (x). */
7140 if (TREE_CODE (arg) == NEGATE_EXPR)
7142 tree args = build_tree_list (NULL_TREE,
7143 TREE_OPERAND (arg, 0));
7144 return build_function_call_expr (fndecl, args);
7147 return NULL_TREE;
7150 /* Fold function call to builtin tan, tanf, or tanl. Return
7151 NULL_TREE if no simplification can be made. */
7152 static tree
7153 fold_builtin_tan (tree arglist)
7155 enum built_in_function fcode;
7156 tree arg = TREE_VALUE (arglist);
7158 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7159 return NULL_TREE;
7161 /* Optimize tan(0.0) = 0.0. */
7162 if (real_zerop (arg))
7163 return arg;
7165 /* Optimize tan(atan(x)) = x. */
7166 fcode = builtin_mathfn_code (arg);
7167 if (flag_unsafe_math_optimizations
7168 && (fcode == BUILT_IN_ATAN
7169 || fcode == BUILT_IN_ATANF
7170 || fcode == BUILT_IN_ATANL))
7171 return TREE_VALUE (TREE_OPERAND (arg, 1));
7173 return NULL_TREE;
7176 /* Fold function call to builtin atan, atanf, or atanl. Return
7177 NULL_TREE if no simplification can be made. */
7179 static tree
7180 fold_builtin_atan (tree arglist, tree type)
7183 tree arg = TREE_VALUE (arglist);
7185 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7186 return NULL_TREE;
7188 /* Optimize atan(0.0) = 0.0. */
7189 if (real_zerop (arg))
7190 return arg;
7192 /* Optimize atan(1.0) = pi/4. */
7193 if (real_onep (arg))
7195 REAL_VALUE_TYPE cst;
7197 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7198 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7199 return build_real (type, cst);
7202 return NULL_TREE;
7205 /* Fold function call to builtin trunc, truncf or truncl. Return
7206 NULL_TREE if no simplification can be made. */
7208 static tree
7209 fold_builtin_trunc (tree fndecl, tree arglist)
7211 tree arg;
7213 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7214 return 0;
7216 /* Optimize trunc of constant value. */
7217 arg = TREE_VALUE (arglist);
7218 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7220 REAL_VALUE_TYPE r, x;
7221 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7223 x = TREE_REAL_CST (arg);
7224 real_trunc (&r, TYPE_MODE (type), &x);
7225 return build_real (type, r);
7228 return fold_trunc_transparent_mathfn (fndecl, arglist);
7231 /* Fold function call to builtin floor, floorf or floorl. Return
7232 NULL_TREE if no simplification can be made. */
7234 static tree
7235 fold_builtin_floor (tree fndecl, tree arglist)
7237 tree arg;
7239 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7240 return 0;
7242 /* Optimize floor of constant value. */
7243 arg = TREE_VALUE (arglist);
7244 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7246 REAL_VALUE_TYPE x;
7248 x = TREE_REAL_CST (arg);
7249 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7251 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7252 REAL_VALUE_TYPE r;
7254 real_floor (&r, TYPE_MODE (type), &x);
7255 return build_real (type, r);
7259 return fold_trunc_transparent_mathfn (fndecl, arglist);
7262 /* Fold function call to builtin ceil, ceilf or ceill. Return
7263 NULL_TREE if no simplification can be made. */
7265 static tree
7266 fold_builtin_ceil (tree fndecl, tree arglist)
7268 tree arg;
7270 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7271 return 0;
7273 /* Optimize ceil of constant value. */
7274 arg = TREE_VALUE (arglist);
7275 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7277 REAL_VALUE_TYPE x;
7279 x = TREE_REAL_CST (arg);
7280 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7282 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7283 REAL_VALUE_TYPE r;
7285 real_ceil (&r, TYPE_MODE (type), &x);
7286 return build_real (type, r);
7290 return fold_trunc_transparent_mathfn (fndecl, arglist);
7293 /* Fold function call to builtin round, roundf or roundl. Return
7294 NULL_TREE if no simplification can be made. */
7296 static tree
7297 fold_builtin_round (tree fndecl, tree arglist)
7299 tree arg;
7301 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7302 return 0;
7304 /* Optimize round of constant value. */
7305 arg = TREE_VALUE (arglist);
7306 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7308 REAL_VALUE_TYPE x;
7310 x = TREE_REAL_CST (arg);
7311 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7313 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7314 REAL_VALUE_TYPE r;
7316 real_round (&r, TYPE_MODE (type), &x);
7317 return build_real (type, r);
7321 return fold_trunc_transparent_mathfn (fndecl, arglist);
7324 /* Fold function call to builtin lround, lroundf or lroundl (or the
7325 corresponding long long versions) and other rounding functions.
7326 Return NULL_TREE if no simplification can be made. */
7328 static tree
7329 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7331 tree arg;
7333 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7334 return 0;
7336 /* Optimize lround of constant value. */
7337 arg = TREE_VALUE (arglist);
7338 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7340 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7342 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7344 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7345 tree ftype = TREE_TYPE (arg), result;
7346 HOST_WIDE_INT hi, lo;
7347 REAL_VALUE_TYPE r;
7349 switch (DECL_FUNCTION_CODE (fndecl))
7351 case BUILT_IN_LFLOOR:
7352 case BUILT_IN_LFLOORF:
7353 case BUILT_IN_LFLOORL:
7354 case BUILT_IN_LLFLOOR:
7355 case BUILT_IN_LLFLOORF:
7356 case BUILT_IN_LLFLOORL:
7357 real_floor (&r, TYPE_MODE (ftype), &x);
7358 break;
7360 case BUILT_IN_LCEIL:
7361 case BUILT_IN_LCEILF:
7362 case BUILT_IN_LCEILL:
7363 case BUILT_IN_LLCEIL:
7364 case BUILT_IN_LLCEILF:
7365 case BUILT_IN_LLCEILL:
7366 real_ceil (&r, TYPE_MODE (ftype), &x);
7367 break;
7369 case BUILT_IN_LROUND:
7370 case BUILT_IN_LROUNDF:
7371 case BUILT_IN_LROUNDL:
7372 case BUILT_IN_LLROUND:
7373 case BUILT_IN_LLROUNDF:
7374 case BUILT_IN_LLROUNDL:
7375 real_round (&r, TYPE_MODE (ftype), &x);
7376 break;
7378 default:
7379 gcc_unreachable ();
7382 REAL_VALUE_TO_INT (&lo, &hi, r);
7383 result = build_int_cst_wide (NULL_TREE, lo, hi);
7384 if (int_fits_type_p (result, itype))
7385 return fold_convert (itype, result);
7389 return fold_fixed_mathfn (fndecl, arglist);
7392 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7393 and their long and long long variants (i.e. ffsl and ffsll).
7394 Return NULL_TREE if no simplification can be made. */
7396 static tree
7397 fold_builtin_bitop (tree fndecl, tree arglist)
7399 tree arg;
7401 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7402 return NULL_TREE;
7404 /* Optimize for constant argument. */
7405 arg = TREE_VALUE (arglist);
7406 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7408 HOST_WIDE_INT hi, width, result;
7409 unsigned HOST_WIDE_INT lo;
7410 tree type;
7412 type = TREE_TYPE (arg);
7413 width = TYPE_PRECISION (type);
7414 lo = TREE_INT_CST_LOW (arg);
7416 /* Clear all the bits that are beyond the type's precision. */
7417 if (width > HOST_BITS_PER_WIDE_INT)
7419 hi = TREE_INT_CST_HIGH (arg);
7420 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7421 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7423 else
7425 hi = 0;
7426 if (width < HOST_BITS_PER_WIDE_INT)
7427 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7430 switch (DECL_FUNCTION_CODE (fndecl))
7432 case BUILT_IN_FFS:
7433 case BUILT_IN_FFSL:
7434 case BUILT_IN_FFSLL:
7435 if (lo != 0)
7436 result = exact_log2 (lo & -lo) + 1;
7437 else if (hi != 0)
7438 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7439 else
7440 result = 0;
7441 break;
7443 case BUILT_IN_CLZ:
7444 case BUILT_IN_CLZL:
7445 case BUILT_IN_CLZLL:
7446 if (hi != 0)
7447 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7448 else if (lo != 0)
7449 result = width - floor_log2 (lo) - 1;
7450 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7451 result = width;
7452 break;
7454 case BUILT_IN_CTZ:
7455 case BUILT_IN_CTZL:
7456 case BUILT_IN_CTZLL:
7457 if (lo != 0)
7458 result = exact_log2 (lo & -lo);
7459 else if (hi != 0)
7460 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7461 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7462 result = width;
7463 break;
7465 case BUILT_IN_POPCOUNT:
7466 case BUILT_IN_POPCOUNTL:
7467 case BUILT_IN_POPCOUNTLL:
7468 result = 0;
7469 while (lo)
7470 result++, lo &= lo - 1;
7471 while (hi)
7472 result++, hi &= hi - 1;
7473 break;
7475 case BUILT_IN_PARITY:
7476 case BUILT_IN_PARITYL:
7477 case BUILT_IN_PARITYLL:
7478 result = 0;
7479 while (lo)
7480 result++, lo &= lo - 1;
7481 while (hi)
7482 result++, hi &= hi - 1;
7483 result &= 1;
7484 break;
7486 default:
7487 gcc_unreachable ();
7490 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7493 return NULL_TREE;
7496 /* Return true if EXPR is the real constant contained in VALUE. */
7498 static bool
7499 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7501 STRIP_NOPS (expr);
7503 return ((TREE_CODE (expr) == REAL_CST
7504 && ! TREE_CONSTANT_OVERFLOW (expr)
7505 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7506 || (TREE_CODE (expr) == COMPLEX_CST
7507 && real_dconstp (TREE_REALPART (expr), value)
7508 && real_zerop (TREE_IMAGPART (expr))));
7511 /* A subroutine of fold_builtin to fold the various logarithmic
7512 functions. EXP is the CALL_EXPR of a call to a builtin logN
7513 function. VALUE is the base of the logN function. */
7515 static tree
7516 fold_builtin_logarithm (tree fndecl, tree arglist,
7517 const REAL_VALUE_TYPE *value)
7519 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7521 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7522 tree arg = TREE_VALUE (arglist);
7523 const enum built_in_function fcode = builtin_mathfn_code (arg);
7525 /* Optimize logN(1.0) = 0.0. */
7526 if (real_onep (arg))
7527 return build_real (type, dconst0);
7529 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7530 exactly, then only do this if flag_unsafe_math_optimizations. */
7531 if (exact_real_truncate (TYPE_MODE (type), value)
7532 || flag_unsafe_math_optimizations)
7534 const REAL_VALUE_TYPE value_truncate =
7535 real_value_truncate (TYPE_MODE (type), *value);
7536 if (real_dconstp (arg, &value_truncate))
7537 return build_real (type, dconst1);
7540 /* Special case, optimize logN(expN(x)) = x. */
7541 if (flag_unsafe_math_optimizations
7542 && ((value == &dconste
7543 && (fcode == BUILT_IN_EXP
7544 || fcode == BUILT_IN_EXPF
7545 || fcode == BUILT_IN_EXPL))
7546 || (value == &dconst2
7547 && (fcode == BUILT_IN_EXP2
7548 || fcode == BUILT_IN_EXP2F
7549 || fcode == BUILT_IN_EXP2L))
7550 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7551 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7553 /* Optimize logN(func()) for various exponential functions. We
7554 want to determine the value "x" and the power "exponent" in
7555 order to transform logN(x**exponent) into exponent*logN(x). */
7556 if (flag_unsafe_math_optimizations)
7558 tree exponent = 0, x = 0;
7560 switch (fcode)
7562 case BUILT_IN_EXP:
7563 case BUILT_IN_EXPF:
7564 case BUILT_IN_EXPL:
7565 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7566 x = build_real (type,
7567 real_value_truncate (TYPE_MODE (type), dconste));
7568 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7569 break;
7570 case BUILT_IN_EXP2:
7571 case BUILT_IN_EXP2F:
7572 case BUILT_IN_EXP2L:
7573 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7574 x = build_real (type, dconst2);
7575 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7576 break;
7577 case BUILT_IN_EXP10:
7578 case BUILT_IN_EXP10F:
7579 case BUILT_IN_EXP10L:
7580 case BUILT_IN_POW10:
7581 case BUILT_IN_POW10F:
7582 case BUILT_IN_POW10L:
7583 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7584 x = build_real (type, dconst10);
7585 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7586 break;
7587 case BUILT_IN_SQRT:
7588 case BUILT_IN_SQRTF:
7589 case BUILT_IN_SQRTL:
7590 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7591 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7592 exponent = build_real (type, dconsthalf);
7593 break;
7594 case BUILT_IN_CBRT:
7595 case BUILT_IN_CBRTF:
7596 case BUILT_IN_CBRTL:
7597 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7598 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7599 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7600 dconstthird));
7601 break;
7602 case BUILT_IN_POW:
7603 case BUILT_IN_POWF:
7604 case BUILT_IN_POWL:
7605 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7606 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7607 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7608 break;
7609 default:
7610 break;
7613 /* Now perform the optimization. */
7614 if (x && exponent)
7616 tree logfn;
7617 arglist = build_tree_list (NULL_TREE, x);
7618 logfn = build_function_call_expr (fndecl, arglist);
7619 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7624 return 0;
7627 /* Fold a builtin function call to pow, powf, or powl. Return
7628 NULL_TREE if no simplification can be made. */
7629 static tree
7630 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7632 tree arg0 = TREE_VALUE (arglist);
7633 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7635 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7636 return NULL_TREE;
7638 /* Optimize pow(1.0,y) = 1.0. */
7639 if (real_onep (arg0))
7640 return omit_one_operand (type, build_real (type, dconst1), arg1);
7642 if (TREE_CODE (arg1) == REAL_CST
7643 && ! TREE_CONSTANT_OVERFLOW (arg1))
7645 REAL_VALUE_TYPE cint;
7646 REAL_VALUE_TYPE c;
7647 HOST_WIDE_INT n;
7649 c = TREE_REAL_CST (arg1);
7651 /* Optimize pow(x,0.0) = 1.0. */
7652 if (REAL_VALUES_EQUAL (c, dconst0))
7653 return omit_one_operand (type, build_real (type, dconst1),
7654 arg0);
7656 /* Optimize pow(x,1.0) = x. */
7657 if (REAL_VALUES_EQUAL (c, dconst1))
7658 return arg0;
7660 /* Optimize pow(x,-1.0) = 1.0/x. */
7661 if (REAL_VALUES_EQUAL (c, dconstm1))
7662 return fold_build2 (RDIV_EXPR, type,
7663 build_real (type, dconst1), arg0);
7665 /* Optimize pow(x,0.5) = sqrt(x). */
7666 if (flag_unsafe_math_optimizations
7667 && REAL_VALUES_EQUAL (c, dconsthalf))
7669 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7671 if (sqrtfn != NULL_TREE)
7673 tree arglist = build_tree_list (NULL_TREE, arg0);
7674 return build_function_call_expr (sqrtfn, arglist);
7678 /* Check for an integer exponent. */
7679 n = real_to_integer (&c);
7680 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7681 if (real_identical (&c, &cint))
7683 /* Attempt to evaluate pow at compile-time. */
7684 if (TREE_CODE (arg0) == REAL_CST
7685 && ! TREE_CONSTANT_OVERFLOW (arg0))
7687 REAL_VALUE_TYPE x;
7688 bool inexact;
7690 x = TREE_REAL_CST (arg0);
7691 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7692 if (flag_unsafe_math_optimizations || !inexact)
7693 return build_real (type, x);
7696 /* Strip sign ops from even integer powers. */
7697 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7699 tree narg0 = fold_strip_sign_ops (arg0);
7700 if (narg0)
7702 arglist = build_tree_list (NULL_TREE, arg1);
7703 arglist = tree_cons (NULL_TREE, narg0, arglist);
7704 return build_function_call_expr (fndecl, arglist);
7710 if (flag_unsafe_math_optimizations)
7712 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7714 /* Optimize pow(expN(x),y) = expN(x*y). */
7715 if (BUILTIN_EXPONENT_P (fcode))
7717 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7718 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7719 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7720 arglist = build_tree_list (NULL_TREE, arg);
7721 return build_function_call_expr (expfn, arglist);
7724 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7725 if (BUILTIN_SQRT_P (fcode))
7727 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7728 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7729 build_real (type, dconsthalf));
7731 arglist = tree_cons (NULL_TREE, narg0,
7732 build_tree_list (NULL_TREE, narg1));
7733 return build_function_call_expr (fndecl, arglist);
7736 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7737 if (BUILTIN_CBRT_P (fcode))
7739 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7740 if (tree_expr_nonnegative_p (arg))
7742 const REAL_VALUE_TYPE dconstroot
7743 = real_value_truncate (TYPE_MODE (type), dconstthird);
7744 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7745 build_real (type, dconstroot));
7746 arglist = tree_cons (NULL_TREE, arg,
7747 build_tree_list (NULL_TREE, narg1));
7748 return build_function_call_expr (fndecl, arglist);
7752 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7753 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7754 || fcode == BUILT_IN_POWL)
7756 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7757 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7758 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7759 arglist = tree_cons (NULL_TREE, arg00,
7760 build_tree_list (NULL_TREE, narg1));
7761 return build_function_call_expr (fndecl, arglist);
7765 return NULL_TREE;
7768 /* Fold a builtin function call to powi, powif, or powil. Return
7769 NULL_TREE if no simplification can be made. */
7770 static tree
7771 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7773 tree arg0 = TREE_VALUE (arglist);
7774 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7776 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7777 return NULL_TREE;
7779 /* Optimize pow(1.0,y) = 1.0. */
7780 if (real_onep (arg0))
7781 return omit_one_operand (type, build_real (type, dconst1), arg1);
7783 if (host_integerp (arg1, 0))
7785 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7787 /* Evaluate powi at compile-time. */
7788 if (TREE_CODE (arg0) == REAL_CST
7789 && ! TREE_CONSTANT_OVERFLOW (arg0))
7791 REAL_VALUE_TYPE x;
7792 x = TREE_REAL_CST (arg0);
7793 real_powi (&x, TYPE_MODE (type), &x, c);
7794 return build_real (type, x);
7797 /* Optimize pow(x,0) = 1.0. */
7798 if (c == 0)
7799 return omit_one_operand (type, build_real (type, dconst1),
7800 arg0);
7802 /* Optimize pow(x,1) = x. */
7803 if (c == 1)
7804 return arg0;
7806 /* Optimize pow(x,-1) = 1.0/x. */
7807 if (c == -1)
7808 return fold_build2 (RDIV_EXPR, type,
7809 build_real (type, dconst1), arg0);
7812 return NULL_TREE;
7815 /* A subroutine of fold_builtin to fold the various exponent
7816 functions. EXP is the CALL_EXPR of a call to a builtin function.
7817 VALUE is the value which will be raised to a power. */
7819 static tree
7820 fold_builtin_exponent (tree fndecl, tree arglist,
7821 const REAL_VALUE_TYPE *value)
7823 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7825 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7826 tree arg = TREE_VALUE (arglist);
7828 /* Optimize exp*(0.0) = 1.0. */
7829 if (real_zerop (arg))
7830 return build_real (type, dconst1);
7832 /* Optimize expN(1.0) = N. */
7833 if (real_onep (arg))
7835 REAL_VALUE_TYPE cst;
7837 real_convert (&cst, TYPE_MODE (type), value);
7838 return build_real (type, cst);
7841 /* Attempt to evaluate expN(integer) at compile-time. */
7842 if (flag_unsafe_math_optimizations
7843 && TREE_CODE (arg) == REAL_CST
7844 && ! TREE_CONSTANT_OVERFLOW (arg))
7846 REAL_VALUE_TYPE cint;
7847 REAL_VALUE_TYPE c;
7848 HOST_WIDE_INT n;
7850 c = TREE_REAL_CST (arg);
7851 n = real_to_integer (&c);
7852 real_from_integer (&cint, VOIDmode, n,
7853 n < 0 ? -1 : 0, 0);
7854 if (real_identical (&c, &cint))
7856 REAL_VALUE_TYPE x;
7858 real_powi (&x, TYPE_MODE (type), value, n);
7859 return build_real (type, x);
7863 /* Optimize expN(logN(x)) = x. */
7864 if (flag_unsafe_math_optimizations)
7866 const enum built_in_function fcode = builtin_mathfn_code (arg);
7868 if ((value == &dconste
7869 && (fcode == BUILT_IN_LOG
7870 || fcode == BUILT_IN_LOGF
7871 || fcode == BUILT_IN_LOGL))
7872 || (value == &dconst2
7873 && (fcode == BUILT_IN_LOG2
7874 || fcode == BUILT_IN_LOG2F
7875 || fcode == BUILT_IN_LOG2L))
7876 || (value == &dconst10
7877 && (fcode == BUILT_IN_LOG10
7878 || fcode == BUILT_IN_LOG10F
7879 || fcode == BUILT_IN_LOG10L)))
7880 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7884 return 0;
7887 /* Fold function call to builtin memcpy. Return
7888 NULL_TREE if no simplification can be made. */
7890 static tree
7891 fold_builtin_memcpy (tree fndecl, tree arglist)
7893 tree dest, src, len;
7895 if (!validate_arglist (arglist,
7896 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7897 return 0;
7899 dest = TREE_VALUE (arglist);
7900 src = TREE_VALUE (TREE_CHAIN (arglist));
7901 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7903 /* If the LEN parameter is zero, return DEST. */
7904 if (integer_zerop (len))
7905 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7907 /* If SRC and DEST are the same (and not volatile), return DEST. */
7908 if (operand_equal_p (src, dest, 0))
7909 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7911 return 0;
7914 /* Fold function call to builtin mempcpy. Return
7915 NULL_TREE if no simplification can be made. */
7917 static tree
7918 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7920 if (validate_arglist (arglist,
7921 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7923 tree dest = TREE_VALUE (arglist);
7924 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7925 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7927 /* If the LEN parameter is zero, return DEST. */
7928 if (integer_zerop (len))
7929 return omit_one_operand (type, dest, src);
7931 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7932 if (operand_equal_p (src, dest, 0))
7934 if (endp == 0)
7935 return omit_one_operand (type, dest, len);
7937 if (endp == 2)
7938 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7939 ssize_int (1));
7941 len = fold_convert (TREE_TYPE (dest), len);
7942 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7943 return fold_convert (type, len);
7946 return 0;
7949 /* Fold function call to builtin memmove. Return
7950 NULL_TREE if no simplification can be made. */
7952 static tree
7953 fold_builtin_memmove (tree arglist, tree type)
7955 tree dest, src, len;
7957 if (!validate_arglist (arglist,
7958 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7959 return 0;
7961 dest = TREE_VALUE (arglist);
7962 src = TREE_VALUE (TREE_CHAIN (arglist));
7963 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7965 /* If the LEN parameter is zero, return DEST. */
7966 if (integer_zerop (len))
7967 return omit_one_operand (type, dest, src);
7969 /* If SRC and DEST are the same (and not volatile), return DEST. */
7970 if (operand_equal_p (src, dest, 0))
7971 return omit_one_operand (type, dest, len);
7973 return 0;
7976 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7977 the length of the string to be copied. Return NULL_TREE if no
7978 simplification can be made. */
7980 tree
7981 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7983 tree dest, src, fn;
7985 if (!validate_arglist (arglist,
7986 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7987 return 0;
7989 dest = TREE_VALUE (arglist);
7990 src = TREE_VALUE (TREE_CHAIN (arglist));
7992 /* If SRC and DEST are the same (and not volatile), return DEST. */
7993 if (operand_equal_p (src, dest, 0))
7994 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7996 if (optimize_size)
7997 return 0;
7999 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8000 if (!fn)
8001 return 0;
8003 if (!len)
8005 len = c_strlen (src, 1);
8006 if (! len || TREE_SIDE_EFFECTS (len))
8007 return 0;
8010 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8011 arglist = build_tree_list (NULL_TREE, len);
8012 arglist = tree_cons (NULL_TREE, src, arglist);
8013 arglist = tree_cons (NULL_TREE, dest, arglist);
8014 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8015 build_function_call_expr (fn, arglist));
8018 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8019 the length of the source string. Return NULL_TREE if no simplification
8020 can be made. */
8022 tree
8023 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8025 tree dest, src, len, fn;
8027 if (!validate_arglist (arglist,
8028 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8029 return 0;
8031 dest = TREE_VALUE (arglist);
8032 src = TREE_VALUE (TREE_CHAIN (arglist));
8033 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8035 /* If the LEN parameter is zero, return DEST. */
8036 if (integer_zerop (len))
8037 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8039 /* We can't compare slen with len as constants below if len is not a
8040 constant. */
8041 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8042 return 0;
8044 if (!slen)
8045 slen = c_strlen (src, 1);
8047 /* Now, we must be passed a constant src ptr parameter. */
8048 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8049 return 0;
8051 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8053 /* We do not support simplification of this case, though we do
8054 support it when expanding trees into RTL. */
8055 /* FIXME: generate a call to __builtin_memset. */
8056 if (tree_int_cst_lt (slen, len))
8057 return 0;
8059 /* OK transform into builtin memcpy. */
8060 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8061 if (!fn)
8062 return 0;
8063 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8064 build_function_call_expr (fn, arglist));
8067 /* Fold function call to builtin memcmp. Return
8068 NULL_TREE if no simplification can be made. */
8070 static tree
8071 fold_builtin_memcmp (tree arglist)
8073 tree arg1, arg2, len;
8074 const char *p1, *p2;
8076 if (!validate_arglist (arglist,
8077 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8078 return 0;
8080 arg1 = TREE_VALUE (arglist);
8081 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8082 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8084 /* If the LEN parameter is zero, return zero. */
8085 if (integer_zerop (len))
8086 return omit_two_operands (integer_type_node, integer_zero_node,
8087 arg1, arg2);
8089 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8090 if (operand_equal_p (arg1, arg2, 0))
8091 return omit_one_operand (integer_type_node, integer_zero_node, len);
8093 p1 = c_getstr (arg1);
8094 p2 = c_getstr (arg2);
8096 /* If all arguments are constant, and the value of len is not greater
8097 than the lengths of arg1 and arg2, evaluate at compile-time. */
8098 if (host_integerp (len, 1) && p1 && p2
8099 && compare_tree_int (len, strlen (p1) + 1) <= 0
8100 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8102 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8104 if (r > 0)
8105 return integer_one_node;
8106 else if (r < 0)
8107 return integer_minus_one_node;
8108 else
8109 return integer_zero_node;
8112 /* If len parameter is one, return an expression corresponding to
8113 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8114 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8116 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8117 tree cst_uchar_ptr_node
8118 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8120 tree ind1 = fold_convert (integer_type_node,
8121 build1 (INDIRECT_REF, cst_uchar_node,
8122 fold_convert (cst_uchar_ptr_node,
8123 arg1)));
8124 tree ind2 = fold_convert (integer_type_node,
8125 build1 (INDIRECT_REF, cst_uchar_node,
8126 fold_convert (cst_uchar_ptr_node,
8127 arg2)));
8128 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8131 return 0;
8134 /* Fold function call to builtin strcmp. Return
8135 NULL_TREE if no simplification can be made. */
8137 static tree
8138 fold_builtin_strcmp (tree arglist)
8140 tree arg1, arg2;
8141 const char *p1, *p2;
8143 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8144 return 0;
8146 arg1 = TREE_VALUE (arglist);
8147 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8149 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8150 if (operand_equal_p (arg1, arg2, 0))
8151 return integer_zero_node;
8153 p1 = c_getstr (arg1);
8154 p2 = c_getstr (arg2);
8156 if (p1 && p2)
8158 const int i = strcmp (p1, p2);
8159 if (i < 0)
8160 return integer_minus_one_node;
8161 else if (i > 0)
8162 return integer_one_node;
8163 else
8164 return integer_zero_node;
8167 /* If the second arg is "", return *(const unsigned char*)arg1. */
8168 if (p2 && *p2 == '\0')
8170 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8171 tree cst_uchar_ptr_node
8172 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8174 return fold_convert (integer_type_node,
8175 build1 (INDIRECT_REF, cst_uchar_node,
8176 fold_convert (cst_uchar_ptr_node,
8177 arg1)));
8180 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8181 if (p1 && *p1 == '\0')
8183 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8184 tree cst_uchar_ptr_node
8185 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8187 tree temp = fold_convert (integer_type_node,
8188 build1 (INDIRECT_REF, cst_uchar_node,
8189 fold_convert (cst_uchar_ptr_node,
8190 arg2)));
8191 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8194 return 0;
8197 /* Fold function call to builtin strncmp. Return
8198 NULL_TREE if no simplification can be made. */
8200 static tree
8201 fold_builtin_strncmp (tree arglist)
8203 tree arg1, arg2, len;
8204 const char *p1, *p2;
8206 if (!validate_arglist (arglist,
8207 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8208 return 0;
8210 arg1 = TREE_VALUE (arglist);
8211 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8212 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8214 /* If the LEN parameter is zero, return zero. */
8215 if (integer_zerop (len))
8216 return omit_two_operands (integer_type_node, integer_zero_node,
8217 arg1, arg2);
8219 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8220 if (operand_equal_p (arg1, arg2, 0))
8221 return omit_one_operand (integer_type_node, integer_zero_node, len);
8223 p1 = c_getstr (arg1);
8224 p2 = c_getstr (arg2);
8226 if (host_integerp (len, 1) && p1 && p2)
8228 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8229 if (i > 0)
8230 return integer_one_node;
8231 else if (i < 0)
8232 return integer_minus_one_node;
8233 else
8234 return integer_zero_node;
8237 /* If the second arg is "", and the length is greater than zero,
8238 return *(const unsigned char*)arg1. */
8239 if (p2 && *p2 == '\0'
8240 && TREE_CODE (len) == INTEGER_CST
8241 && tree_int_cst_sgn (len) == 1)
8243 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8244 tree cst_uchar_ptr_node
8245 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8247 return fold_convert (integer_type_node,
8248 build1 (INDIRECT_REF, cst_uchar_node,
8249 fold_convert (cst_uchar_ptr_node,
8250 arg1)));
8253 /* If the first arg is "", and the length is greater than zero,
8254 return -*(const unsigned char*)arg2. */
8255 if (p1 && *p1 == '\0'
8256 && TREE_CODE (len) == INTEGER_CST
8257 && tree_int_cst_sgn (len) == 1)
8259 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8260 tree cst_uchar_ptr_node
8261 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8263 tree temp = fold_convert (integer_type_node,
8264 build1 (INDIRECT_REF, cst_uchar_node,
8265 fold_convert (cst_uchar_ptr_node,
8266 arg2)));
8267 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8270 /* If len parameter is one, return an expression corresponding to
8271 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8272 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8274 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8275 tree cst_uchar_ptr_node
8276 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8278 tree ind1 = fold_convert (integer_type_node,
8279 build1 (INDIRECT_REF, cst_uchar_node,
8280 fold_convert (cst_uchar_ptr_node,
8281 arg1)));
8282 tree ind2 = fold_convert (integer_type_node,
8283 build1 (INDIRECT_REF, cst_uchar_node,
8284 fold_convert (cst_uchar_ptr_node,
8285 arg2)));
8286 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8289 return 0;
8292 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8293 NULL_TREE if no simplification can be made. */
8295 static tree
8296 fold_builtin_signbit (tree fndecl, tree arglist)
8298 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8299 tree arg, temp;
8301 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8302 return NULL_TREE;
8304 arg = TREE_VALUE (arglist);
8306 /* If ARG is a compile-time constant, determine the result. */
8307 if (TREE_CODE (arg) == REAL_CST
8308 && !TREE_CONSTANT_OVERFLOW (arg))
8310 REAL_VALUE_TYPE c;
8312 c = TREE_REAL_CST (arg);
8313 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8314 return fold_convert (type, temp);
8317 /* If ARG is non-negative, the result is always zero. */
8318 if (tree_expr_nonnegative_p (arg))
8319 return omit_one_operand (type, integer_zero_node, arg);
8321 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8322 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8323 return fold_build2 (LT_EXPR, type, arg,
8324 build_real (TREE_TYPE (arg), dconst0));
8326 return NULL_TREE;
8329 /* Fold function call to builtin copysign, copysignf or copysignl.
8330 Return NULL_TREE if no simplification can be made. */
8332 static tree
8333 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8335 tree arg1, arg2, tem;
8337 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8338 return NULL_TREE;
8340 arg1 = TREE_VALUE (arglist);
8341 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8343 /* copysign(X,X) is X. */
8344 if (operand_equal_p (arg1, arg2, 0))
8345 return fold_convert (type, arg1);
8347 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8348 if (TREE_CODE (arg1) == REAL_CST
8349 && TREE_CODE (arg2) == REAL_CST
8350 && !TREE_CONSTANT_OVERFLOW (arg1)
8351 && !TREE_CONSTANT_OVERFLOW (arg2))
8353 REAL_VALUE_TYPE c1, c2;
8355 c1 = TREE_REAL_CST (arg1);
8356 c2 = TREE_REAL_CST (arg2);
8357 real_copysign (&c1, &c2);
8358 return build_real (type, c1);
8359 c1.sign = c2.sign;
8362 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8363 Remember to evaluate Y for side-effects. */
8364 if (tree_expr_nonnegative_p (arg2))
8365 return omit_one_operand (type,
8366 fold_build1 (ABS_EXPR, type, arg1),
8367 arg2);
8369 /* Strip sign changing operations for the first argument. */
8370 tem = fold_strip_sign_ops (arg1);
8371 if (tem)
8373 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8374 return build_function_call_expr (fndecl, arglist);
8377 return NULL_TREE;
8380 /* Fold a call to builtin isascii. */
8382 static tree
8383 fold_builtin_isascii (tree arglist)
8385 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8386 return 0;
8387 else
8389 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8390 tree arg = TREE_VALUE (arglist);
8392 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8393 build_int_cst (NULL_TREE,
8394 ~ (unsigned HOST_WIDE_INT) 0x7f));
8395 arg = fold_build2 (EQ_EXPR, integer_type_node,
8396 arg, integer_zero_node);
8398 if (in_gimple_form && !TREE_CONSTANT (arg))
8399 return NULL_TREE;
8400 else
8401 return arg;
8405 /* Fold a call to builtin toascii. */
8407 static tree
8408 fold_builtin_toascii (tree arglist)
8410 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8411 return 0;
8412 else
8414 /* Transform toascii(c) -> (c & 0x7f). */
8415 tree arg = TREE_VALUE (arglist);
8417 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8418 build_int_cst (NULL_TREE, 0x7f));
8422 /* Fold a call to builtin isdigit. */
8424 static tree
8425 fold_builtin_isdigit (tree arglist)
8427 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8428 return 0;
8429 else
8431 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8432 /* According to the C standard, isdigit is unaffected by locale.
8433 However, it definitely is affected by the target character set. */
8434 tree arg;
8435 unsigned HOST_WIDE_INT target_digit0
8436 = lang_hooks.to_target_charset ('0');
8438 if (target_digit0 == 0)
8439 return NULL_TREE;
8441 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8442 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8443 build_int_cst (unsigned_type_node, target_digit0));
8444 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8445 build_int_cst (unsigned_type_node, 9));
8446 if (in_gimple_form && !TREE_CONSTANT (arg))
8447 return NULL_TREE;
8448 else
8449 return arg;
8453 /* Fold a call to fabs, fabsf or fabsl. */
8455 static tree
8456 fold_builtin_fabs (tree arglist, tree type)
8458 tree arg;
8460 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8461 return 0;
8463 arg = TREE_VALUE (arglist);
8464 arg = fold_convert (type, arg);
8465 if (TREE_CODE (arg) == REAL_CST)
8466 return fold_abs_const (arg, type);
8467 return fold_build1 (ABS_EXPR, type, arg);
8470 /* Fold a call to abs, labs, llabs or imaxabs. */
8472 static tree
8473 fold_builtin_abs (tree arglist, tree type)
8475 tree arg;
8477 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8478 return 0;
8480 arg = TREE_VALUE (arglist);
8481 arg = fold_convert (type, arg);
8482 if (TREE_CODE (arg) == INTEGER_CST)
8483 return fold_abs_const (arg, type);
8484 return fold_build1 (ABS_EXPR, type, arg);
8487 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8488 EXP is the CALL_EXPR for the call. */
8490 static tree
8491 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8493 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8494 tree arg;
8495 REAL_VALUE_TYPE r;
8497 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8499 /* Check that we have exactly one argument. */
8500 if (arglist == 0)
8502 error ("too few arguments to function %qs",
8503 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8504 return error_mark_node;
8506 else if (TREE_CHAIN (arglist) != 0)
8508 error ("too many arguments to function %qs",
8509 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8510 return error_mark_node;
8512 else
8514 error ("non-floating-point argument to function %qs",
8515 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8516 return error_mark_node;
8520 arg = TREE_VALUE (arglist);
8521 switch (builtin_index)
8523 case BUILT_IN_ISINF:
8524 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8525 return omit_one_operand (type, integer_zero_node, arg);
8527 if (TREE_CODE (arg) == REAL_CST)
8529 r = TREE_REAL_CST (arg);
8530 if (real_isinf (&r))
8531 return real_compare (GT_EXPR, &r, &dconst0)
8532 ? integer_one_node : integer_minus_one_node;
8533 else
8534 return integer_zero_node;
8537 return NULL_TREE;
8539 case BUILT_IN_FINITE:
8540 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8541 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8542 return omit_one_operand (type, integer_zero_node, arg);
8544 if (TREE_CODE (arg) == REAL_CST)
8546 r = TREE_REAL_CST (arg);
8547 return real_isinf (&r) || real_isnan (&r)
8548 ? integer_zero_node : integer_one_node;
8551 return NULL_TREE;
8553 case BUILT_IN_ISNAN:
8554 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8555 return omit_one_operand (type, integer_zero_node, arg);
8557 if (TREE_CODE (arg) == REAL_CST)
8559 r = TREE_REAL_CST (arg);
8560 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8563 arg = builtin_save_expr (arg);
8564 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8566 default:
8567 gcc_unreachable ();
8571 /* Fold a call to an unordered comparison function such as
8572 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8573 being called and ARGLIST is the argument list for the call.
8574 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8575 the opposite of the desired result. UNORDERED_CODE is used
8576 for modes that can hold NaNs and ORDERED_CODE is used for
8577 the rest. */
8579 static tree
8580 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8581 enum tree_code unordered_code,
8582 enum tree_code ordered_code)
8584 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8585 enum tree_code code;
8586 tree arg0, arg1;
8587 tree type0, type1;
8588 enum tree_code code0, code1;
8589 tree cmp_type = NULL_TREE;
8591 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8593 /* Check that we have exactly two arguments. */
8594 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8596 error ("too few arguments to function %qs",
8597 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8598 return error_mark_node;
8600 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8602 error ("too many arguments to function %qs",
8603 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8604 return error_mark_node;
8608 arg0 = TREE_VALUE (arglist);
8609 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8611 type0 = TREE_TYPE (arg0);
8612 type1 = TREE_TYPE (arg1);
8614 code0 = TREE_CODE (type0);
8615 code1 = TREE_CODE (type1);
8617 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8618 /* Choose the wider of two real types. */
8619 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8620 ? type0 : type1;
8621 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8622 cmp_type = type0;
8623 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8624 cmp_type = type1;
8625 else
8627 error ("non-floating-point argument to function %qs",
8628 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8629 return error_mark_node;
8632 arg0 = fold_convert (cmp_type, arg0);
8633 arg1 = fold_convert (cmp_type, arg1);
8635 if (unordered_code == UNORDERED_EXPR)
8637 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8638 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8639 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8642 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8643 : ordered_code;
8644 return fold_build1 (TRUTH_NOT_EXPR, type,
8645 fold_build2 (code, type, arg0, arg1));
8648 /* Used by constant folding to simplify calls to builtin functions. EXP is
8649 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8650 result of the function call is ignored. This function returns NULL_TREE
8651 if no simplification was possible. */
8653 static tree
8654 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8656 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8657 enum built_in_function fcode;
8659 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8660 return targetm.fold_builtin (fndecl, arglist, ignore);
8662 fcode = DECL_FUNCTION_CODE (fndecl);
8663 switch (fcode)
8665 case BUILT_IN_FPUTS:
8666 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8668 case BUILT_IN_FPUTS_UNLOCKED:
8669 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8671 case BUILT_IN_STRSTR:
8672 return fold_builtin_strstr (arglist, type);
8674 case BUILT_IN_STRCAT:
8675 return fold_builtin_strcat (arglist);
8677 case BUILT_IN_STRNCAT:
8678 return fold_builtin_strncat (arglist);
8680 case BUILT_IN_STRSPN:
8681 return fold_builtin_strspn (arglist);
8683 case BUILT_IN_STRCSPN:
8684 return fold_builtin_strcspn (arglist);
8686 case BUILT_IN_STRCHR:
8687 case BUILT_IN_INDEX:
8688 return fold_builtin_strchr (arglist, type);
8690 case BUILT_IN_STRRCHR:
8691 case BUILT_IN_RINDEX:
8692 return fold_builtin_strrchr (arglist, type);
8694 case BUILT_IN_STRCPY:
8695 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8697 case BUILT_IN_STRNCPY:
8698 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8700 case BUILT_IN_STRCMP:
8701 return fold_builtin_strcmp (arglist);
8703 case BUILT_IN_STRNCMP:
8704 return fold_builtin_strncmp (arglist);
8706 case BUILT_IN_STRPBRK:
8707 return fold_builtin_strpbrk (arglist, type);
8709 case BUILT_IN_BCMP:
8710 case BUILT_IN_MEMCMP:
8711 return fold_builtin_memcmp (arglist);
8713 case BUILT_IN_SPRINTF:
8714 return fold_builtin_sprintf (arglist, ignore);
8716 case BUILT_IN_CONSTANT_P:
8718 tree val;
8720 val = fold_builtin_constant_p (arglist);
8721 /* Gimplification will pull the CALL_EXPR for the builtin out of
8722 an if condition. When not optimizing, we'll not CSE it back.
8723 To avoid link error types of regressions, return false now. */
8724 if (!val && !optimize)
8725 val = integer_zero_node;
8727 return val;
8730 case BUILT_IN_EXPECT:
8731 return fold_builtin_expect (arglist);
8733 case BUILT_IN_CLASSIFY_TYPE:
8734 return fold_builtin_classify_type (arglist);
8736 case BUILT_IN_STRLEN:
8737 return fold_builtin_strlen (arglist);
8739 case BUILT_IN_FABS:
8740 case BUILT_IN_FABSF:
8741 case BUILT_IN_FABSL:
8742 return fold_builtin_fabs (arglist, type);
8744 case BUILT_IN_ABS:
8745 case BUILT_IN_LABS:
8746 case BUILT_IN_LLABS:
8747 case BUILT_IN_IMAXABS:
8748 return fold_builtin_abs (arglist, type);
8750 case BUILT_IN_CONJ:
8751 case BUILT_IN_CONJF:
8752 case BUILT_IN_CONJL:
8753 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8754 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8755 break;
8757 case BUILT_IN_CREAL:
8758 case BUILT_IN_CREALF:
8759 case BUILT_IN_CREALL:
8760 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8761 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8762 TREE_VALUE (arglist)));
8763 break;
8765 case BUILT_IN_CIMAG:
8766 case BUILT_IN_CIMAGF:
8767 case BUILT_IN_CIMAGL:
8768 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8769 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8770 TREE_VALUE (arglist)));
8771 break;
8773 case BUILT_IN_CABS:
8774 case BUILT_IN_CABSF:
8775 case BUILT_IN_CABSL:
8776 return fold_builtin_cabs (arglist, type);
8778 case BUILT_IN_SQRT:
8779 case BUILT_IN_SQRTF:
8780 case BUILT_IN_SQRTL:
8781 return fold_builtin_sqrt (arglist, type);
8783 case BUILT_IN_CBRT:
8784 case BUILT_IN_CBRTF:
8785 case BUILT_IN_CBRTL:
8786 return fold_builtin_cbrt (arglist, type);
8788 case BUILT_IN_SIN:
8789 case BUILT_IN_SINF:
8790 case BUILT_IN_SINL:
8791 return fold_builtin_sin (arglist);
8793 case BUILT_IN_COS:
8794 case BUILT_IN_COSF:
8795 case BUILT_IN_COSL:
8796 return fold_builtin_cos (arglist, type, fndecl);
8798 case BUILT_IN_EXP:
8799 case BUILT_IN_EXPF:
8800 case BUILT_IN_EXPL:
8801 return fold_builtin_exponent (fndecl, arglist, &dconste);
8803 case BUILT_IN_EXP2:
8804 case BUILT_IN_EXP2F:
8805 case BUILT_IN_EXP2L:
8806 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8808 case BUILT_IN_EXP10:
8809 case BUILT_IN_EXP10F:
8810 case BUILT_IN_EXP10L:
8811 case BUILT_IN_POW10:
8812 case BUILT_IN_POW10F:
8813 case BUILT_IN_POW10L:
8814 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8816 case BUILT_IN_LOG:
8817 case BUILT_IN_LOGF:
8818 case BUILT_IN_LOGL:
8819 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8821 case BUILT_IN_LOG2:
8822 case BUILT_IN_LOG2F:
8823 case BUILT_IN_LOG2L:
8824 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8826 case BUILT_IN_LOG10:
8827 case BUILT_IN_LOG10F:
8828 case BUILT_IN_LOG10L:
8829 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8831 case BUILT_IN_TAN:
8832 case BUILT_IN_TANF:
8833 case BUILT_IN_TANL:
8834 return fold_builtin_tan (arglist);
8836 case BUILT_IN_ATAN:
8837 case BUILT_IN_ATANF:
8838 case BUILT_IN_ATANL:
8839 return fold_builtin_atan (arglist, type);
8841 case BUILT_IN_POW:
8842 case BUILT_IN_POWF:
8843 case BUILT_IN_POWL:
8844 return fold_builtin_pow (fndecl, arglist, type);
8846 case BUILT_IN_POWI:
8847 case BUILT_IN_POWIF:
8848 case BUILT_IN_POWIL:
8849 return fold_builtin_powi (fndecl, arglist, type);
8851 case BUILT_IN_INF:
8852 case BUILT_IN_INFF:
8853 case BUILT_IN_INFL:
8854 return fold_builtin_inf (type, true);
8856 case BUILT_IN_HUGE_VAL:
8857 case BUILT_IN_HUGE_VALF:
8858 case BUILT_IN_HUGE_VALL:
8859 return fold_builtin_inf (type, false);
8861 case BUILT_IN_NAN:
8862 case BUILT_IN_NANF:
8863 case BUILT_IN_NANL:
8864 return fold_builtin_nan (arglist, type, true);
8866 case BUILT_IN_NANS:
8867 case BUILT_IN_NANSF:
8868 case BUILT_IN_NANSL:
8869 return fold_builtin_nan (arglist, type, false);
8871 case BUILT_IN_FLOOR:
8872 case BUILT_IN_FLOORF:
8873 case BUILT_IN_FLOORL:
8874 return fold_builtin_floor (fndecl, arglist);
8876 case BUILT_IN_CEIL:
8877 case BUILT_IN_CEILF:
8878 case BUILT_IN_CEILL:
8879 return fold_builtin_ceil (fndecl, arglist);
8881 case BUILT_IN_TRUNC:
8882 case BUILT_IN_TRUNCF:
8883 case BUILT_IN_TRUNCL:
8884 return fold_builtin_trunc (fndecl, arglist);
8886 case BUILT_IN_ROUND:
8887 case BUILT_IN_ROUNDF:
8888 case BUILT_IN_ROUNDL:
8889 return fold_builtin_round (fndecl, arglist);
8891 case BUILT_IN_NEARBYINT:
8892 case BUILT_IN_NEARBYINTF:
8893 case BUILT_IN_NEARBYINTL:
8894 case BUILT_IN_RINT:
8895 case BUILT_IN_RINTF:
8896 case BUILT_IN_RINTL:
8897 return fold_trunc_transparent_mathfn (fndecl, arglist);
8899 case BUILT_IN_LCEIL:
8900 case BUILT_IN_LCEILF:
8901 case BUILT_IN_LCEILL:
8902 case BUILT_IN_LLCEIL:
8903 case BUILT_IN_LLCEILF:
8904 case BUILT_IN_LLCEILL:
8905 case BUILT_IN_LFLOOR:
8906 case BUILT_IN_LFLOORF:
8907 case BUILT_IN_LFLOORL:
8908 case BUILT_IN_LLFLOOR:
8909 case BUILT_IN_LLFLOORF:
8910 case BUILT_IN_LLFLOORL:
8911 case BUILT_IN_LROUND:
8912 case BUILT_IN_LROUNDF:
8913 case BUILT_IN_LROUNDL:
8914 case BUILT_IN_LLROUND:
8915 case BUILT_IN_LLROUNDF:
8916 case BUILT_IN_LLROUNDL:
8917 return fold_builtin_int_roundingfn (fndecl, arglist);
8919 case BUILT_IN_LRINT:
8920 case BUILT_IN_LRINTF:
8921 case BUILT_IN_LRINTL:
8922 case BUILT_IN_LLRINT:
8923 case BUILT_IN_LLRINTF:
8924 case BUILT_IN_LLRINTL:
8925 return fold_fixed_mathfn (fndecl, arglist);
8927 case BUILT_IN_FFS:
8928 case BUILT_IN_FFSL:
8929 case BUILT_IN_FFSLL:
8930 case BUILT_IN_CLZ:
8931 case BUILT_IN_CLZL:
8932 case BUILT_IN_CLZLL:
8933 case BUILT_IN_CTZ:
8934 case BUILT_IN_CTZL:
8935 case BUILT_IN_CTZLL:
8936 case BUILT_IN_POPCOUNT:
8937 case BUILT_IN_POPCOUNTL:
8938 case BUILT_IN_POPCOUNTLL:
8939 case BUILT_IN_PARITY:
8940 case BUILT_IN_PARITYL:
8941 case BUILT_IN_PARITYLL:
8942 return fold_builtin_bitop (fndecl, arglist);
8944 case BUILT_IN_MEMCPY:
8945 return fold_builtin_memcpy (fndecl, arglist);
8947 case BUILT_IN_MEMPCPY:
8948 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8950 case BUILT_IN_MEMMOVE:
8951 return fold_builtin_memmove (arglist, type);
8953 case BUILT_IN_SIGNBIT:
8954 case BUILT_IN_SIGNBITF:
8955 case BUILT_IN_SIGNBITL:
8956 return fold_builtin_signbit (fndecl, arglist);
8958 case BUILT_IN_ISASCII:
8959 return fold_builtin_isascii (arglist);
8961 case BUILT_IN_TOASCII:
8962 return fold_builtin_toascii (arglist);
8964 case BUILT_IN_ISDIGIT:
8965 return fold_builtin_isdigit (arglist);
8967 case BUILT_IN_COPYSIGN:
8968 case BUILT_IN_COPYSIGNF:
8969 case BUILT_IN_COPYSIGNL:
8970 return fold_builtin_copysign (fndecl, arglist, type);
8972 case BUILT_IN_FINITE:
8973 case BUILT_IN_FINITEF:
8974 case BUILT_IN_FINITEL:
8975 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8977 case BUILT_IN_ISINF:
8978 case BUILT_IN_ISINFF:
8979 case BUILT_IN_ISINFL:
8980 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8982 case BUILT_IN_ISNAN:
8983 case BUILT_IN_ISNANF:
8984 case BUILT_IN_ISNANL:
8985 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8987 case BUILT_IN_ISGREATER:
8988 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8989 case BUILT_IN_ISGREATEREQUAL:
8990 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8991 case BUILT_IN_ISLESS:
8992 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8993 case BUILT_IN_ISLESSEQUAL:
8994 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8995 case BUILT_IN_ISLESSGREATER:
8996 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8997 case BUILT_IN_ISUNORDERED:
8998 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8999 NOP_EXPR);
9001 /* We do the folding for va_start in the expander. */
9002 case BUILT_IN_VA_START:
9003 break;
9005 case BUILT_IN_OBJECT_SIZE:
9006 return fold_builtin_object_size (arglist);
9007 case BUILT_IN_MEMCPY_CHK:
9008 case BUILT_IN_MEMPCPY_CHK:
9009 case BUILT_IN_MEMMOVE_CHK:
9010 case BUILT_IN_MEMSET_CHK:
9011 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9012 DECL_FUNCTION_CODE (fndecl));
9013 case BUILT_IN_STRCPY_CHK:
9014 case BUILT_IN_STPCPY_CHK:
9015 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9016 DECL_FUNCTION_CODE (fndecl));
9017 case BUILT_IN_STRNCPY_CHK:
9018 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9019 case BUILT_IN_STRCAT_CHK:
9020 return fold_builtin_strcat_chk (fndecl, arglist);
9021 case BUILT_IN_STRNCAT_CHK:
9022 return fold_builtin_strncat_chk (fndecl, arglist);
9023 case BUILT_IN_SPRINTF_CHK:
9024 case BUILT_IN_VSPRINTF_CHK:
9025 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9026 case BUILT_IN_SNPRINTF_CHK:
9027 case BUILT_IN_VSNPRINTF_CHK:
9028 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9029 DECL_FUNCTION_CODE (fndecl));
9031 case BUILT_IN_PRINTF:
9032 case BUILT_IN_PRINTF_UNLOCKED:
9033 case BUILT_IN_VPRINTF:
9034 case BUILT_IN_PRINTF_CHK:
9035 case BUILT_IN_VPRINTF_CHK:
9036 return fold_builtin_printf (fndecl, arglist, ignore,
9037 DECL_FUNCTION_CODE (fndecl));
9039 case BUILT_IN_FPRINTF:
9040 case BUILT_IN_FPRINTF_UNLOCKED:
9041 case BUILT_IN_VFPRINTF:
9042 case BUILT_IN_FPRINTF_CHK:
9043 case BUILT_IN_VFPRINTF_CHK:
9044 return fold_builtin_fprintf (fndecl, arglist, ignore,
9045 DECL_FUNCTION_CODE (fndecl));
9047 default:
9048 break;
9051 return 0;
9054 /* A wrapper function for builtin folding that prevents warnings for
9055 "statement without effect" and the like, caused by removing the
9056 call node earlier than the warning is generated. */
9058 tree
9059 fold_builtin (tree fndecl, tree arglist, bool ignore)
9061 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9062 if (exp)
9064 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9065 TREE_NO_WARNING (exp) = 1;
9068 return exp;
9071 /* Conveniently construct a function call expression. */
9073 tree
9074 build_function_call_expr (tree fn, tree arglist)
9076 tree call_expr;
9078 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9079 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9080 call_expr, arglist, NULL_TREE);
9083 /* This function validates the types of a function call argument list
9084 represented as a tree chain of parameters against a specified list
9085 of tree_codes. If the last specifier is a 0, that represents an
9086 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9088 static int
9089 validate_arglist (tree arglist, ...)
9091 enum tree_code code;
9092 int res = 0;
9093 va_list ap;
9095 va_start (ap, arglist);
9099 code = va_arg (ap, enum tree_code);
9100 switch (code)
9102 case 0:
9103 /* This signifies an ellipses, any further arguments are all ok. */
9104 res = 1;
9105 goto end;
9106 case VOID_TYPE:
9107 /* This signifies an endlink, if no arguments remain, return
9108 true, otherwise return false. */
9109 res = arglist == 0;
9110 goto end;
9111 default:
9112 /* If no parameters remain or the parameter's code does not
9113 match the specified code, return false. Otherwise continue
9114 checking any remaining arguments. */
9115 if (arglist == 0)
9116 goto end;
9117 if (code == POINTER_TYPE)
9119 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9120 goto end;
9122 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9123 goto end;
9124 break;
9126 arglist = TREE_CHAIN (arglist);
9128 while (1);
9130 /* We need gotos here since we can only have one VA_CLOSE in a
9131 function. */
9132 end: ;
9133 va_end (ap);
9135 return res;
9138 /* Default target-specific builtin expander that does nothing. */
9141 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9142 rtx target ATTRIBUTE_UNUSED,
9143 rtx subtarget ATTRIBUTE_UNUSED,
9144 enum machine_mode mode ATTRIBUTE_UNUSED,
9145 int ignore ATTRIBUTE_UNUSED)
9147 return NULL_RTX;
9150 /* Returns true is EXP represents data that would potentially reside
9151 in a readonly section. */
9153 static bool
9154 readonly_data_expr (tree exp)
9156 STRIP_NOPS (exp);
9158 if (TREE_CODE (exp) != ADDR_EXPR)
9159 return false;
9161 exp = get_base_address (TREE_OPERAND (exp, 0));
9162 if (!exp)
9163 return false;
9165 /* Make sure we call decl_readonly_section only for trees it
9166 can handle (since it returns true for everything it doesn't
9167 understand). */
9168 if (TREE_CODE (exp) == STRING_CST
9169 || TREE_CODE (exp) == CONSTRUCTOR
9170 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9171 return decl_readonly_section (exp, 0);
9172 else
9173 return false;
9176 /* Simplify a call to the strstr builtin.
9178 Return 0 if no simplification was possible, otherwise return the
9179 simplified form of the call as a tree.
9181 The simplified form may be a constant or other expression which
9182 computes the same value, but in a more efficient manner (including
9183 calls to other builtin functions).
9185 The call may contain arguments which need to be evaluated, but
9186 which are not useful to determine the result of the call. In
9187 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9188 COMPOUND_EXPR will be an argument which must be evaluated.
9189 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9190 COMPOUND_EXPR in the chain will contain the tree for the simplified
9191 form of the builtin function call. */
9193 static tree
9194 fold_builtin_strstr (tree arglist, tree type)
9196 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9197 return 0;
9198 else
9200 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9201 tree fn;
9202 const char *p1, *p2;
9204 p2 = c_getstr (s2);
9205 if (p2 == NULL)
9206 return 0;
9208 p1 = c_getstr (s1);
9209 if (p1 != NULL)
9211 const char *r = strstr (p1, p2);
9212 tree tem;
9214 if (r == NULL)
9215 return build_int_cst (TREE_TYPE (s1), 0);
9217 /* Return an offset into the constant string argument. */
9218 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9219 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9220 return fold_convert (type, tem);
9223 /* The argument is const char *, and the result is char *, so we need
9224 a type conversion here to avoid a warning. */
9225 if (p2[0] == '\0')
9226 return fold_convert (type, s1);
9228 if (p2[1] != '\0')
9229 return 0;
9231 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9232 if (!fn)
9233 return 0;
9235 /* New argument list transforming strstr(s1, s2) to
9236 strchr(s1, s2[0]). */
9237 arglist = build_tree_list (NULL_TREE,
9238 build_int_cst (NULL_TREE, p2[0]));
9239 arglist = tree_cons (NULL_TREE, s1, arglist);
9240 return build_function_call_expr (fn, arglist);
9244 /* Simplify a call to the strchr builtin.
9246 Return 0 if no simplification was possible, otherwise return the
9247 simplified form of the call as a tree.
9249 The simplified form may be a constant or other expression which
9250 computes the same value, but in a more efficient manner (including
9251 calls to other builtin functions).
9253 The call may contain arguments which need to be evaluated, but
9254 which are not useful to determine the result of the call. In
9255 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9256 COMPOUND_EXPR will be an argument which must be evaluated.
9257 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9258 COMPOUND_EXPR in the chain will contain the tree for the simplified
9259 form of the builtin function call. */
9261 static tree
9262 fold_builtin_strchr (tree arglist, tree type)
9264 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9265 return 0;
9266 else
9268 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9269 const char *p1;
9271 if (TREE_CODE (s2) != INTEGER_CST)
9272 return 0;
9274 p1 = c_getstr (s1);
9275 if (p1 != NULL)
9277 char c;
9278 const char *r;
9279 tree tem;
9281 if (target_char_cast (s2, &c))
9282 return 0;
9284 r = strchr (p1, c);
9286 if (r == NULL)
9287 return build_int_cst (TREE_TYPE (s1), 0);
9289 /* Return an offset into the constant string argument. */
9290 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9291 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9292 return fold_convert (type, tem);
9294 return 0;
9298 /* Simplify a call to the strrchr builtin.
9300 Return 0 if no simplification was possible, otherwise return the
9301 simplified form of the call as a tree.
9303 The simplified form may be a constant or other expression which
9304 computes the same value, but in a more efficient manner (including
9305 calls to other builtin functions).
9307 The call may contain arguments which need to be evaluated, but
9308 which are not useful to determine the result of the call. In
9309 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9310 COMPOUND_EXPR will be an argument which must be evaluated.
9311 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9312 COMPOUND_EXPR in the chain will contain the tree for the simplified
9313 form of the builtin function call. */
9315 static tree
9316 fold_builtin_strrchr (tree arglist, tree type)
9318 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9319 return 0;
9320 else
9322 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9323 tree fn;
9324 const char *p1;
9326 if (TREE_CODE (s2) != INTEGER_CST)
9327 return 0;
9329 p1 = c_getstr (s1);
9330 if (p1 != NULL)
9332 char c;
9333 const char *r;
9334 tree tem;
9336 if (target_char_cast (s2, &c))
9337 return 0;
9339 r = strrchr (p1, c);
9341 if (r == NULL)
9342 return build_int_cst (TREE_TYPE (s1), 0);
9344 /* Return an offset into the constant string argument. */
9345 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9346 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9347 return fold_convert (type, tem);
9350 if (! integer_zerop (s2))
9351 return 0;
9353 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9354 if (!fn)
9355 return 0;
9357 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9358 return build_function_call_expr (fn, arglist);
9362 /* Simplify a call to the strpbrk builtin.
9364 Return 0 if no simplification was possible, otherwise return the
9365 simplified form of the call as a tree.
9367 The simplified form may be a constant or other expression which
9368 computes the same value, but in a more efficient manner (including
9369 calls to other builtin functions).
9371 The call may contain arguments which need to be evaluated, but
9372 which are not useful to determine the result of the call. In
9373 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9374 COMPOUND_EXPR will be an argument which must be evaluated.
9375 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9376 COMPOUND_EXPR in the chain will contain the tree for the simplified
9377 form of the builtin function call. */
9379 static tree
9380 fold_builtin_strpbrk (tree arglist, tree type)
9382 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9383 return 0;
9384 else
9386 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9387 tree fn;
9388 const char *p1, *p2;
9390 p2 = c_getstr (s2);
9391 if (p2 == NULL)
9392 return 0;
9394 p1 = c_getstr (s1);
9395 if (p1 != NULL)
9397 const char *r = strpbrk (p1, p2);
9398 tree tem;
9400 if (r == NULL)
9401 return build_int_cst (TREE_TYPE (s1), 0);
9403 /* Return an offset into the constant string argument. */
9404 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9405 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9406 return fold_convert (type, tem);
9409 if (p2[0] == '\0')
9410 /* strpbrk(x, "") == NULL.
9411 Evaluate and ignore s1 in case it had side-effects. */
9412 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9414 if (p2[1] != '\0')
9415 return 0; /* Really call strpbrk. */
9417 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9418 if (!fn)
9419 return 0;
9421 /* New argument list transforming strpbrk(s1, s2) to
9422 strchr(s1, s2[0]). */
9423 arglist = build_tree_list (NULL_TREE,
9424 build_int_cst (NULL_TREE, p2[0]));
9425 arglist = tree_cons (NULL_TREE, s1, arglist);
9426 return build_function_call_expr (fn, arglist);
9430 /* Simplify a call to the strcat builtin.
9432 Return 0 if no simplification was possible, otherwise return the
9433 simplified form of the call as a tree.
9435 The simplified form may be a constant or other expression which
9436 computes the same value, but in a more efficient manner (including
9437 calls to other builtin functions).
9439 The call may contain arguments which need to be evaluated, but
9440 which are not useful to determine the result of the call. In
9441 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9442 COMPOUND_EXPR will be an argument which must be evaluated.
9443 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9444 COMPOUND_EXPR in the chain will contain the tree for the simplified
9445 form of the builtin function call. */
9447 static tree
9448 fold_builtin_strcat (tree arglist)
9450 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9451 return 0;
9452 else
9454 tree dst = TREE_VALUE (arglist),
9455 src = TREE_VALUE (TREE_CHAIN (arglist));
9456 const char *p = c_getstr (src);
9458 /* If the string length is zero, return the dst parameter. */
9459 if (p && *p == '\0')
9460 return dst;
9462 return 0;
9466 /* Simplify a call to the strncat builtin.
9468 Return 0 if no simplification was possible, otherwise return the
9469 simplified form of the call as a tree.
9471 The simplified form may be a constant or other expression which
9472 computes the same value, but in a more efficient manner (including
9473 calls to other builtin functions).
9475 The call may contain arguments which need to be evaluated, but
9476 which are not useful to determine the result of the call. In
9477 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9478 COMPOUND_EXPR will be an argument which must be evaluated.
9479 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9480 COMPOUND_EXPR in the chain will contain the tree for the simplified
9481 form of the builtin function call. */
9483 static tree
9484 fold_builtin_strncat (tree arglist)
9486 if (!validate_arglist (arglist,
9487 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9488 return 0;
9489 else
9491 tree dst = TREE_VALUE (arglist);
9492 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9493 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9494 const char *p = c_getstr (src);
9496 /* If the requested length is zero, or the src parameter string
9497 length is zero, return the dst parameter. */
9498 if (integer_zerop (len) || (p && *p == '\0'))
9499 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9501 /* If the requested len is greater than or equal to the string
9502 length, call strcat. */
9503 if (TREE_CODE (len) == INTEGER_CST && p
9504 && compare_tree_int (len, strlen (p)) >= 0)
9506 tree newarglist
9507 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9508 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9510 /* If the replacement _DECL isn't initialized, don't do the
9511 transformation. */
9512 if (!fn)
9513 return 0;
9515 return build_function_call_expr (fn, newarglist);
9517 return 0;
9521 /* Simplify a call to the strspn builtin.
9523 Return 0 if no simplification was possible, otherwise return the
9524 simplified form of the call as a tree.
9526 The simplified form may be a constant or other expression which
9527 computes the same value, but in a more efficient manner (including
9528 calls to other builtin functions).
9530 The call may contain arguments which need to be evaluated, but
9531 which are not useful to determine the result of the call. In
9532 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9533 COMPOUND_EXPR will be an argument which must be evaluated.
9534 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9535 COMPOUND_EXPR in the chain will contain the tree for the simplified
9536 form of the builtin function call. */
9538 static tree
9539 fold_builtin_strspn (tree arglist)
9541 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9542 return 0;
9543 else
9545 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9546 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9548 /* If both arguments are constants, evaluate at compile-time. */
9549 if (p1 && p2)
9551 const size_t r = strspn (p1, p2);
9552 return size_int (r);
9555 /* If either argument is "", return 0. */
9556 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9557 /* Evaluate and ignore both arguments in case either one has
9558 side-effects. */
9559 return omit_two_operands (integer_type_node, integer_zero_node,
9560 s1, s2);
9561 return 0;
9565 /* Simplify a call to the strcspn builtin.
9567 Return 0 if no simplification was possible, otherwise return the
9568 simplified form of the call as a tree.
9570 The simplified form may be a constant or other expression which
9571 computes the same value, but in a more efficient manner (including
9572 calls to other builtin functions).
9574 The call may contain arguments which need to be evaluated, but
9575 which are not useful to determine the result of the call. In
9576 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9577 COMPOUND_EXPR will be an argument which must be evaluated.
9578 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9579 COMPOUND_EXPR in the chain will contain the tree for the simplified
9580 form of the builtin function call. */
9582 static tree
9583 fold_builtin_strcspn (tree arglist)
9585 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9586 return 0;
9587 else
9589 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9590 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9592 /* If both arguments are constants, evaluate at compile-time. */
9593 if (p1 && p2)
9595 const size_t r = strcspn (p1, p2);
9596 return size_int (r);
9599 /* If the first argument is "", return 0. */
9600 if (p1 && *p1 == '\0')
9602 /* Evaluate and ignore argument s2 in case it has
9603 side-effects. */
9604 return omit_one_operand (integer_type_node,
9605 integer_zero_node, s2);
9608 /* If the second argument is "", return __builtin_strlen(s1). */
9609 if (p2 && *p2 == '\0')
9611 tree newarglist = build_tree_list (NULL_TREE, s1),
9612 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9614 /* If the replacement _DECL isn't initialized, don't do the
9615 transformation. */
9616 if (!fn)
9617 return 0;
9619 return build_function_call_expr (fn, newarglist);
9621 return 0;
9625 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9626 by the builtin will be ignored. UNLOCKED is true is true if this
9627 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9628 the known length of the string. Return NULL_TREE if no simplification
9629 was possible. */
9631 tree
9632 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9634 tree fn;
9635 /* If we're using an unlocked function, assume the other unlocked
9636 functions exist explicitly. */
9637 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9638 : implicit_built_in_decls[BUILT_IN_FPUTC];
9639 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9640 : implicit_built_in_decls[BUILT_IN_FWRITE];
9642 /* If the return value is used, or the replacement _DECL isn't
9643 initialized, don't do the transformation. */
9644 if (!ignore || !fn_fputc || !fn_fwrite)
9645 return 0;
9647 /* Verify the arguments in the original call. */
9648 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9649 return 0;
9651 if (! len)
9652 len = c_strlen (TREE_VALUE (arglist), 0);
9654 /* Get the length of the string passed to fputs. If the length
9655 can't be determined, punt. */
9656 if (!len
9657 || TREE_CODE (len) != INTEGER_CST)
9658 return 0;
9660 switch (compare_tree_int (len, 1))
9662 case -1: /* length is 0, delete the call entirely . */
9663 return omit_one_operand (integer_type_node, integer_zero_node,
9664 TREE_VALUE (TREE_CHAIN (arglist)));
9666 case 0: /* length is 1, call fputc. */
9668 const char *p = c_getstr (TREE_VALUE (arglist));
9670 if (p != NULL)
9672 /* New argument list transforming fputs(string, stream) to
9673 fputc(string[0], stream). */
9674 arglist = build_tree_list (NULL_TREE,
9675 TREE_VALUE (TREE_CHAIN (arglist)));
9676 arglist = tree_cons (NULL_TREE,
9677 build_int_cst (NULL_TREE, p[0]),
9678 arglist);
9679 fn = fn_fputc;
9680 break;
9683 /* FALLTHROUGH */
9684 case 1: /* length is greater than 1, call fwrite. */
9686 tree string_arg;
9688 /* If optimizing for size keep fputs. */
9689 if (optimize_size)
9690 return 0;
9691 string_arg = TREE_VALUE (arglist);
9692 /* New argument list transforming fputs(string, stream) to
9693 fwrite(string, 1, len, stream). */
9694 arglist = build_tree_list (NULL_TREE,
9695 TREE_VALUE (TREE_CHAIN (arglist)));
9696 arglist = tree_cons (NULL_TREE, len, arglist);
9697 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9698 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9699 fn = fn_fwrite;
9700 break;
9702 default:
9703 gcc_unreachable ();
9706 /* These optimizations are only performed when the result is ignored,
9707 hence there's no need to cast the result to integer_type_node. */
9708 return build_function_call_expr (fn, arglist);
9711 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9712 produced. False otherwise. This is done so that we don't output the error
9713 or warning twice or three times. */
9714 bool
9715 fold_builtin_next_arg (tree arglist)
9717 tree fntype = TREE_TYPE (current_function_decl);
9719 if (TYPE_ARG_TYPES (fntype) == 0
9720 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9721 == void_type_node))
9723 error ("%<va_start%> used in function with fixed args");
9724 return true;
9726 else if (!arglist)
9728 /* Evidently an out of date version of <stdarg.h>; can't validate
9729 va_start's second argument, but can still work as intended. */
9730 warning (0, "%<__builtin_next_arg%> called without an argument");
9731 return true;
9733 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9734 when we checked the arguments and if needed issued a warning. */
9735 else if (!TREE_CHAIN (arglist)
9736 || !integer_zerop (TREE_VALUE (arglist))
9737 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9738 || TREE_CHAIN (TREE_CHAIN (arglist)))
9740 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9741 tree arg = TREE_VALUE (arglist);
9743 if (TREE_CHAIN (arglist))
9745 error ("%<va_start%> used with too many arguments");
9746 return true;
9749 /* Strip off all nops for the sake of the comparison. This
9750 is not quite the same as STRIP_NOPS. It does more.
9751 We must also strip off INDIRECT_EXPR for C++ reference
9752 parameters. */
9753 while (TREE_CODE (arg) == NOP_EXPR
9754 || TREE_CODE (arg) == CONVERT_EXPR
9755 || TREE_CODE (arg) == NON_LVALUE_EXPR
9756 || TREE_CODE (arg) == INDIRECT_REF)
9757 arg = TREE_OPERAND (arg, 0);
9758 if (arg != last_parm)
9760 /* FIXME: Sometimes with the tree optimizers we can get the
9761 not the last argument even though the user used the last
9762 argument. We just warn and set the arg to be the last
9763 argument so that we will get wrong-code because of
9764 it. */
9765 warning (0, "second parameter of %<va_start%> not last named argument");
9767 /* We want to verify the second parameter just once before the tree
9768 optimizers are run and then avoid keeping it in the tree,
9769 as otherwise we could warn even for correct code like:
9770 void foo (int i, ...)
9771 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9772 TREE_VALUE (arglist) = integer_zero_node;
9773 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9775 return false;
9779 /* Simplify a call to the sprintf builtin.
9781 Return 0 if no simplification was possible, otherwise return the
9782 simplified form of the call as a tree. If IGNORED is true, it means that
9783 the caller does not use the returned value of the function. */
9785 static tree
9786 fold_builtin_sprintf (tree arglist, int ignored)
9788 tree call, retval, dest, fmt;
9789 const char *fmt_str = NULL;
9791 /* Verify the required arguments in the original call. We deal with two
9792 types of sprintf() calls: 'sprintf (str, fmt)' and
9793 'sprintf (dest, "%s", orig)'. */
9794 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9795 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9796 VOID_TYPE))
9797 return NULL_TREE;
9799 /* Get the destination string and the format specifier. */
9800 dest = TREE_VALUE (arglist);
9801 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9803 /* Check whether the format is a literal string constant. */
9804 fmt_str = c_getstr (fmt);
9805 if (fmt_str == NULL)
9806 return NULL_TREE;
9808 call = NULL_TREE;
9809 retval = NULL_TREE;
9811 if (!init_target_chars())
9812 return 0;
9814 /* If the format doesn't contain % args or %%, use strcpy. */
9815 if (strchr (fmt_str, target_percent) == NULL)
9817 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9819 if (!fn)
9820 return NULL_TREE;
9822 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9823 'format' is known to contain no % formats. */
9824 arglist = build_tree_list (NULL_TREE, fmt);
9825 arglist = tree_cons (NULL_TREE, dest, arglist);
9826 call = build_function_call_expr (fn, arglist);
9827 if (!ignored)
9828 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9831 /* If the format is "%s", use strcpy if the result isn't used. */
9832 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9834 tree fn, orig;
9835 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9837 if (!fn)
9838 return NULL_TREE;
9840 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9841 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9842 arglist = build_tree_list (NULL_TREE, orig);
9843 arglist = tree_cons (NULL_TREE, dest, arglist);
9844 if (!ignored)
9846 retval = c_strlen (orig, 1);
9847 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9848 return NULL_TREE;
9850 call = build_function_call_expr (fn, arglist);
9853 if (call && retval)
9855 retval = convert
9856 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9857 retval);
9858 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9860 else
9861 return call;
9864 /* Expand a call to __builtin_object_size. */
9867 expand_builtin_object_size (tree exp)
9869 tree ost;
9870 int object_size_type;
9871 tree fndecl = get_callee_fndecl (exp);
9872 tree arglist = TREE_OPERAND (exp, 1);
9873 location_t locus = EXPR_LOCATION (exp);
9875 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9877 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9878 &locus, fndecl);
9879 expand_builtin_trap ();
9880 return const0_rtx;
9883 ost = TREE_VALUE (TREE_CHAIN (arglist));
9884 STRIP_NOPS (ost);
9886 if (TREE_CODE (ost) != INTEGER_CST
9887 || tree_int_cst_sgn (ost) < 0
9888 || compare_tree_int (ost, 3) > 0)
9890 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9891 &locus, fndecl);
9892 expand_builtin_trap ();
9893 return const0_rtx;
9896 object_size_type = tree_low_cst (ost, 0);
9898 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9901 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9902 FCODE is the BUILT_IN_* to use.
9903 Return 0 if we failed; the caller should emit a normal call,
9904 otherwise try to get the result in TARGET, if convenient (and in
9905 mode MODE if that's convenient). */
9907 static rtx
9908 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9909 enum built_in_function fcode)
9911 tree arglist = TREE_OPERAND (exp, 1);
9912 tree dest, src, len, size;
9914 if (!validate_arglist (arglist,
9915 POINTER_TYPE,
9916 fcode == BUILT_IN_MEMSET_CHK
9917 ? INTEGER_TYPE : POINTER_TYPE,
9918 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9919 return 0;
9921 dest = TREE_VALUE (arglist);
9922 src = TREE_VALUE (TREE_CHAIN (arglist));
9923 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9924 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9926 if (! host_integerp (size, 1))
9927 return 0;
9929 if (host_integerp (len, 1) || integer_all_onesp (size))
9931 tree fn;
9933 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9935 location_t locus = EXPR_LOCATION (exp);
9936 warning (0, "%Hcall to %D will always overflow destination buffer",
9937 &locus, get_callee_fndecl (exp));
9938 return 0;
9941 arglist = build_tree_list (NULL_TREE, len);
9942 arglist = tree_cons (NULL_TREE, src, arglist);
9943 arglist = tree_cons (NULL_TREE, dest, arglist);
9945 fn = NULL_TREE;
9946 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9947 mem{cpy,pcpy,move,set} is available. */
9948 switch (fcode)
9950 case BUILT_IN_MEMCPY_CHK:
9951 fn = built_in_decls[BUILT_IN_MEMCPY];
9952 break;
9953 case BUILT_IN_MEMPCPY_CHK:
9954 fn = built_in_decls[BUILT_IN_MEMPCPY];
9955 break;
9956 case BUILT_IN_MEMMOVE_CHK:
9957 fn = built_in_decls[BUILT_IN_MEMMOVE];
9958 break;
9959 case BUILT_IN_MEMSET_CHK:
9960 fn = built_in_decls[BUILT_IN_MEMSET];
9961 break;
9962 default:
9963 break;
9966 if (! fn)
9967 return 0;
9969 fn = build_function_call_expr (fn, arglist);
9970 if (TREE_CODE (fn) == CALL_EXPR)
9971 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9972 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9974 else if (fcode == BUILT_IN_MEMSET_CHK)
9975 return 0;
9976 else
9978 unsigned int dest_align
9979 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9981 /* If DEST is not a pointer type, call the normal function. */
9982 if (dest_align == 0)
9983 return 0;
9985 /* If SRC and DEST are the same (and not volatile), do nothing. */
9986 if (operand_equal_p (src, dest, 0))
9988 tree expr;
9990 if (fcode != BUILT_IN_MEMPCPY_CHK)
9992 /* Evaluate and ignore LEN in case it has side-effects. */
9993 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9994 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9997 len = fold_convert (TREE_TYPE (dest), len);
9998 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9999 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10002 /* __memmove_chk special case. */
10003 if (fcode == BUILT_IN_MEMMOVE_CHK)
10005 unsigned int src_align
10006 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10008 if (src_align == 0)
10009 return 0;
10011 /* If src is categorized for a readonly section we can use
10012 normal __memcpy_chk. */
10013 if (readonly_data_expr (src))
10015 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10016 if (!fn)
10017 return 0;
10018 fn = build_function_call_expr (fn, arglist);
10019 if (TREE_CODE (fn) == CALL_EXPR)
10020 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10021 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10024 return 0;
10028 /* Emit warning if a buffer overflow is detected at compile time. */
10030 static void
10031 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10033 int arg_mask, is_strlen = 0;
10034 tree arglist = TREE_OPERAND (exp, 1), a;
10035 tree len, size;
10036 location_t locus;
10038 switch (fcode)
10040 case BUILT_IN_STRCPY_CHK:
10041 case BUILT_IN_STPCPY_CHK:
10042 /* For __strcat_chk the warning will be emitted only if overflowing
10043 by at least strlen (dest) + 1 bytes. */
10044 case BUILT_IN_STRCAT_CHK:
10045 arg_mask = 6;
10046 is_strlen = 1;
10047 break;
10048 case BUILT_IN_STRNCPY_CHK:
10049 arg_mask = 12;
10050 break;
10051 case BUILT_IN_SNPRINTF_CHK:
10052 case BUILT_IN_VSNPRINTF_CHK:
10053 arg_mask = 10;
10054 break;
10055 default:
10056 gcc_unreachable ();
10059 len = NULL_TREE;
10060 size = NULL_TREE;
10061 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10062 if (arg_mask & 1)
10064 if (len)
10065 size = a;
10066 else
10067 len = a;
10070 if (!len || !size)
10071 return;
10073 len = TREE_VALUE (len);
10074 size = TREE_VALUE (size);
10076 if (! host_integerp (size, 1) || integer_all_onesp (size))
10077 return;
10079 if (is_strlen)
10081 len = c_strlen (len, 1);
10082 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10083 return;
10085 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10086 return;
10088 locus = EXPR_LOCATION (exp);
10089 warning (0, "%Hcall to %D will always overflow destination buffer",
10090 &locus, get_callee_fndecl (exp));
10093 /* Emit warning if a buffer overflow is detected at compile time
10094 in __sprintf_chk/__vsprintf_chk calls. */
10096 static void
10097 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10099 tree arglist = TREE_OPERAND (exp, 1);
10100 tree dest, size, len, fmt, flag;
10101 const char *fmt_str;
10103 /* Verify the required arguments in the original call. */
10104 if (! arglist)
10105 return;
10106 dest = TREE_VALUE (arglist);
10107 arglist = TREE_CHAIN (arglist);
10108 if (! arglist)
10109 return;
10110 flag = TREE_VALUE (arglist);
10111 arglist = TREE_CHAIN (arglist);
10112 if (! arglist)
10113 return;
10114 size = TREE_VALUE (arglist);
10115 arglist = TREE_CHAIN (arglist);
10116 if (! arglist)
10117 return;
10118 fmt = TREE_VALUE (arglist);
10119 arglist = TREE_CHAIN (arglist);
10121 if (! host_integerp (size, 1) || integer_all_onesp (size))
10122 return;
10124 /* Check whether the format is a literal string constant. */
10125 fmt_str = c_getstr (fmt);
10126 if (fmt_str == NULL)
10127 return;
10129 if (!init_target_chars())
10130 return;
10132 /* If the format doesn't contain % args or %%, we know its size. */
10133 if (strchr (fmt_str, target_percent) == 0)
10134 len = build_int_cstu (size_type_node, strlen (fmt_str));
10135 /* If the format is "%s" and first ... argument is a string literal,
10136 we know it too. */
10137 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10139 tree arg;
10141 if (! arglist)
10142 return;
10143 arg = TREE_VALUE (arglist);
10144 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10145 return;
10147 len = c_strlen (arg, 1);
10148 if (!len || ! host_integerp (len, 1))
10149 return;
10151 else
10152 return;
10154 if (! tree_int_cst_lt (len, size))
10156 location_t locus = EXPR_LOCATION (exp);
10157 warning (0, "%Hcall to %D will always overflow destination buffer",
10158 &locus, get_callee_fndecl (exp));
10162 /* Fold a call to __builtin_object_size, if possible. */
10164 tree
10165 fold_builtin_object_size (tree arglist)
10167 tree ptr, ost, ret = 0;
10168 int object_size_type;
10170 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10171 return 0;
10173 ptr = TREE_VALUE (arglist);
10174 ost = TREE_VALUE (TREE_CHAIN (arglist));
10175 STRIP_NOPS (ost);
10177 if (TREE_CODE (ost) != INTEGER_CST
10178 || tree_int_cst_sgn (ost) < 0
10179 || compare_tree_int (ost, 3) > 0)
10180 return 0;
10182 object_size_type = tree_low_cst (ost, 0);
10184 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10185 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10186 and (size_t) 0 for types 2 and 3. */
10187 if (TREE_SIDE_EFFECTS (ptr))
10188 return fold_convert (size_type_node,
10189 object_size_type < 2
10190 ? integer_minus_one_node : integer_zero_node);
10192 if (TREE_CODE (ptr) == ADDR_EXPR)
10193 ret = build_int_cstu (size_type_node,
10194 compute_builtin_object_size (ptr, object_size_type));
10196 else if (TREE_CODE (ptr) == SSA_NAME)
10198 unsigned HOST_WIDE_INT bytes;
10200 /* If object size is not known yet, delay folding until
10201 later. Maybe subsequent passes will help determining
10202 it. */
10203 bytes = compute_builtin_object_size (ptr, object_size_type);
10204 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10205 ? -1 : 0))
10206 ret = build_int_cstu (size_type_node, bytes);
10209 if (ret)
10211 ret = force_fit_type (ret, -1, false, false);
10212 if (TREE_CONSTANT_OVERFLOW (ret))
10213 ret = 0;
10216 return ret;
10219 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10220 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10221 code of the builtin. If MAXLEN is not NULL, it is maximum length
10222 passed as third argument. */
10224 tree
10225 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10226 enum built_in_function fcode)
10228 tree dest, src, len, size, fn;
10230 if (!validate_arglist (arglist,
10231 POINTER_TYPE,
10232 fcode == BUILT_IN_MEMSET_CHK
10233 ? INTEGER_TYPE : POINTER_TYPE,
10234 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10235 return 0;
10237 dest = TREE_VALUE (arglist);
10238 /* Actually val for __memset_chk, but it doesn't matter. */
10239 src = TREE_VALUE (TREE_CHAIN (arglist));
10240 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10241 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10243 /* If SRC and DEST are the same (and not volatile), return DEST
10244 (resp. DEST+LEN for __mempcpy_chk). */
10245 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10247 if (fcode != BUILT_IN_MEMPCPY_CHK)
10248 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10249 else
10251 tree temp = fold_convert (TREE_TYPE (dest), len);
10252 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10253 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10257 if (! host_integerp (size, 1))
10258 return 0;
10260 if (! integer_all_onesp (size))
10262 if (! host_integerp (len, 1))
10264 /* If LEN is not constant, try MAXLEN too.
10265 For MAXLEN only allow optimizing into non-_ocs function
10266 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10267 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10269 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10271 /* (void) __mempcpy_chk () can be optimized into
10272 (void) __memcpy_chk (). */
10273 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10274 if (!fn)
10275 return 0;
10277 return build_function_call_expr (fn, arglist);
10279 return 0;
10282 else
10283 maxlen = len;
10285 if (tree_int_cst_lt (size, maxlen))
10286 return 0;
10289 arglist = build_tree_list (NULL_TREE, len);
10290 arglist = tree_cons (NULL_TREE, src, arglist);
10291 arglist = tree_cons (NULL_TREE, dest, arglist);
10293 fn = NULL_TREE;
10294 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10295 mem{cpy,pcpy,move,set} is available. */
10296 switch (fcode)
10298 case BUILT_IN_MEMCPY_CHK:
10299 fn = built_in_decls[BUILT_IN_MEMCPY];
10300 break;
10301 case BUILT_IN_MEMPCPY_CHK:
10302 fn = built_in_decls[BUILT_IN_MEMPCPY];
10303 break;
10304 case BUILT_IN_MEMMOVE_CHK:
10305 fn = built_in_decls[BUILT_IN_MEMMOVE];
10306 break;
10307 case BUILT_IN_MEMSET_CHK:
10308 fn = built_in_decls[BUILT_IN_MEMSET];
10309 break;
10310 default:
10311 break;
10314 if (!fn)
10315 return 0;
10317 return build_function_call_expr (fn, arglist);
10320 /* Fold a call to the __st[rp]cpy_chk builtin.
10321 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10322 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10323 strings passed as second argument. */
10325 tree
10326 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10327 enum built_in_function fcode)
10329 tree dest, src, size, len, fn;
10331 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10332 VOID_TYPE))
10333 return 0;
10335 dest = TREE_VALUE (arglist);
10336 src = TREE_VALUE (TREE_CHAIN (arglist));
10337 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10339 /* If SRC and DEST are the same (and not volatile), return DEST. */
10340 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10341 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10343 if (! host_integerp (size, 1))
10344 return 0;
10346 if (! integer_all_onesp (size))
10348 len = c_strlen (src, 1);
10349 if (! len || ! host_integerp (len, 1))
10351 /* If LEN is not constant, try MAXLEN too.
10352 For MAXLEN only allow optimizing into non-_ocs function
10353 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10354 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10356 if (fcode == BUILT_IN_STPCPY_CHK)
10358 if (! ignore)
10359 return 0;
10361 /* If return value of __stpcpy_chk is ignored,
10362 optimize into __strcpy_chk. */
10363 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10364 if (!fn)
10365 return 0;
10367 return build_function_call_expr (fn, arglist);
10370 if (! len || TREE_SIDE_EFFECTS (len))
10371 return 0;
10373 /* If c_strlen returned something, but not a constant,
10374 transform __strcpy_chk into __memcpy_chk. */
10375 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10376 if (!fn)
10377 return 0;
10379 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10380 arglist = build_tree_list (NULL_TREE, size);
10381 arglist = tree_cons (NULL_TREE, len, arglist);
10382 arglist = tree_cons (NULL_TREE, src, arglist);
10383 arglist = tree_cons (NULL_TREE, dest, arglist);
10384 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10385 build_function_call_expr (fn, arglist));
10388 else
10389 maxlen = len;
10391 if (! tree_int_cst_lt (maxlen, size))
10392 return 0;
10395 arglist = build_tree_list (NULL_TREE, src);
10396 arglist = tree_cons (NULL_TREE, dest, arglist);
10398 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10399 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10400 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10401 if (!fn)
10402 return 0;
10404 return build_function_call_expr (fn, arglist);
10407 /* Fold a call to the __strncpy_chk builtin.
10408 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10410 tree
10411 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10413 tree dest, src, size, len, fn;
10415 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10416 INTEGER_TYPE, VOID_TYPE))
10417 return 0;
10419 dest = TREE_VALUE (arglist);
10420 src = TREE_VALUE (TREE_CHAIN (arglist));
10421 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10422 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10424 if (! host_integerp (size, 1))
10425 return 0;
10427 if (! integer_all_onesp (size))
10429 if (! host_integerp (len, 1))
10431 /* If LEN is not constant, try MAXLEN too.
10432 For MAXLEN only allow optimizing into non-_ocs function
10433 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10434 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10435 return 0;
10437 else
10438 maxlen = len;
10440 if (tree_int_cst_lt (size, maxlen))
10441 return 0;
10444 arglist = build_tree_list (NULL_TREE, len);
10445 arglist = tree_cons (NULL_TREE, src, arglist);
10446 arglist = tree_cons (NULL_TREE, dest, arglist);
10448 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10449 fn = built_in_decls[BUILT_IN_STRNCPY];
10450 if (!fn)
10451 return 0;
10453 return build_function_call_expr (fn, arglist);
10456 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10458 static tree
10459 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10461 tree dest, src, size, fn;
10462 const char *p;
10464 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10465 VOID_TYPE))
10466 return 0;
10468 dest = TREE_VALUE (arglist);
10469 src = TREE_VALUE (TREE_CHAIN (arglist));
10470 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10472 p = c_getstr (src);
10473 /* If the SRC parameter is "", return DEST. */
10474 if (p && *p == '\0')
10475 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10477 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10478 return 0;
10480 arglist = build_tree_list (NULL_TREE, src);
10481 arglist = tree_cons (NULL_TREE, dest, arglist);
10483 /* If __builtin_strcat_chk is used, assume strcat is available. */
10484 fn = built_in_decls[BUILT_IN_STRCAT];
10485 if (!fn)
10486 return 0;
10488 return build_function_call_expr (fn, arglist);
10491 /* Fold a call to the __strncat_chk builtin EXP. */
10493 static tree
10494 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10496 tree dest, src, size, len, fn;
10497 const char *p;
10499 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10500 INTEGER_TYPE, VOID_TYPE))
10501 return 0;
10503 dest = TREE_VALUE (arglist);
10504 src = TREE_VALUE (TREE_CHAIN (arglist));
10505 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10506 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10508 p = c_getstr (src);
10509 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10510 if (p && *p == '\0')
10511 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10512 else if (integer_zerop (len))
10513 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10515 if (! host_integerp (size, 1))
10516 return 0;
10518 if (! integer_all_onesp (size))
10520 tree src_len = c_strlen (src, 1);
10521 if (src_len
10522 && host_integerp (src_len, 1)
10523 && host_integerp (len, 1)
10524 && ! tree_int_cst_lt (len, src_len))
10526 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10527 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10528 if (!fn)
10529 return 0;
10531 arglist = build_tree_list (NULL_TREE, size);
10532 arglist = tree_cons (NULL_TREE, src, arglist);
10533 arglist = tree_cons (NULL_TREE, dest, arglist);
10534 return build_function_call_expr (fn, arglist);
10536 return 0;
10539 arglist = build_tree_list (NULL_TREE, len);
10540 arglist = tree_cons (NULL_TREE, src, arglist);
10541 arglist = tree_cons (NULL_TREE, dest, arglist);
10543 /* If __builtin_strncat_chk is used, assume strncat is available. */
10544 fn = built_in_decls[BUILT_IN_STRNCAT];
10545 if (!fn)
10546 return 0;
10548 return build_function_call_expr (fn, arglist);
10551 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10552 a normal call should be emitted rather than expanding the function
10553 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10555 static tree
10556 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10558 tree dest, size, len, fn, fmt, flag;
10559 const char *fmt_str;
10561 /* Verify the required arguments in the original call. */
10562 if (! arglist)
10563 return 0;
10564 dest = TREE_VALUE (arglist);
10565 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10566 return 0;
10567 arglist = TREE_CHAIN (arglist);
10568 if (! arglist)
10569 return 0;
10570 flag = TREE_VALUE (arglist);
10571 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10572 return 0;
10573 arglist = TREE_CHAIN (arglist);
10574 if (! arglist)
10575 return 0;
10576 size = TREE_VALUE (arglist);
10577 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10578 return 0;
10579 arglist = TREE_CHAIN (arglist);
10580 if (! arglist)
10581 return 0;
10582 fmt = TREE_VALUE (arglist);
10583 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10584 return 0;
10585 arglist = TREE_CHAIN (arglist);
10587 if (! host_integerp (size, 1))
10588 return 0;
10590 len = NULL_TREE;
10592 if (!init_target_chars())
10593 return 0;
10595 /* Check whether the format is a literal string constant. */
10596 fmt_str = c_getstr (fmt);
10597 if (fmt_str != NULL)
10599 /* If the format doesn't contain % args or %%, we know the size. */
10600 if (strchr (fmt_str, target_percent) == 0)
10602 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10603 len = build_int_cstu (size_type_node, strlen (fmt_str));
10605 /* If the format is "%s" and first ... argument is a string literal,
10606 we know the size too. */
10607 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10609 tree arg;
10611 if (arglist && !TREE_CHAIN (arglist))
10613 arg = TREE_VALUE (arglist);
10614 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10616 len = c_strlen (arg, 1);
10617 if (! len || ! host_integerp (len, 1))
10618 len = NULL_TREE;
10624 if (! integer_all_onesp (size))
10626 if (! len || ! tree_int_cst_lt (len, size))
10627 return 0;
10630 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10631 or if format doesn't contain % chars or is "%s". */
10632 if (! integer_zerop (flag))
10634 if (fmt_str == NULL)
10635 return 0;
10636 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10637 return 0;
10640 arglist = tree_cons (NULL_TREE, fmt, arglist);
10641 arglist = tree_cons (NULL_TREE, dest, arglist);
10643 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10644 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10645 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10646 if (!fn)
10647 return 0;
10649 return build_function_call_expr (fn, arglist);
10652 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10653 a normal call should be emitted rather than expanding the function
10654 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10655 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10656 passed as second argument. */
10658 tree
10659 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10660 enum built_in_function fcode)
10662 tree dest, size, len, fn, fmt, flag;
10663 const char *fmt_str;
10665 /* Verify the required arguments in the original call. */
10666 if (! arglist)
10667 return 0;
10668 dest = TREE_VALUE (arglist);
10669 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10670 return 0;
10671 arglist = TREE_CHAIN (arglist);
10672 if (! arglist)
10673 return 0;
10674 len = TREE_VALUE (arglist);
10675 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10676 return 0;
10677 arglist = TREE_CHAIN (arglist);
10678 if (! arglist)
10679 return 0;
10680 flag = TREE_VALUE (arglist);
10681 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10682 return 0;
10683 arglist = TREE_CHAIN (arglist);
10684 if (! arglist)
10685 return 0;
10686 size = TREE_VALUE (arglist);
10687 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10688 return 0;
10689 arglist = TREE_CHAIN (arglist);
10690 if (! arglist)
10691 return 0;
10692 fmt = TREE_VALUE (arglist);
10693 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10694 return 0;
10695 arglist = TREE_CHAIN (arglist);
10697 if (! host_integerp (size, 1))
10698 return 0;
10700 if (! integer_all_onesp (size))
10702 if (! host_integerp (len, 1))
10704 /* If LEN is not constant, try MAXLEN too.
10705 For MAXLEN only allow optimizing into non-_ocs function
10706 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10707 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10708 return 0;
10710 else
10711 maxlen = len;
10713 if (tree_int_cst_lt (size, maxlen))
10714 return 0;
10717 if (!init_target_chars())
10718 return 0;
10720 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10721 or if format doesn't contain % chars or is "%s". */
10722 if (! integer_zerop (flag))
10724 fmt_str = c_getstr (fmt);
10725 if (fmt_str == NULL)
10726 return 0;
10727 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10728 return 0;
10731 arglist = tree_cons (NULL_TREE, fmt, arglist);
10732 arglist = tree_cons (NULL_TREE, len, arglist);
10733 arglist = tree_cons (NULL_TREE, dest, arglist);
10735 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10736 available. */
10737 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10738 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10739 if (!fn)
10740 return 0;
10742 return build_function_call_expr (fn, arglist);
10745 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10747 Return 0 if no simplification was possible, otherwise return the
10748 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10749 code of the function to be simplified. */
10751 static tree
10752 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10753 enum built_in_function fcode)
10755 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10756 const char *fmt_str = NULL;
10758 /* If the return value is used, don't do the transformation. */
10759 if (! ignore)
10760 return 0;
10762 /* Verify the required arguments in the original call. */
10763 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10765 tree flag;
10767 if (! arglist)
10768 return 0;
10769 flag = TREE_VALUE (arglist);
10770 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10771 || TREE_SIDE_EFFECTS (flag))
10772 return 0;
10773 arglist = TREE_CHAIN (arglist);
10776 if (! arglist)
10777 return 0;
10778 fmt = TREE_VALUE (arglist);
10779 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10780 return 0;
10781 arglist = TREE_CHAIN (arglist);
10783 /* Check whether the format is a literal string constant. */
10784 fmt_str = c_getstr (fmt);
10785 if (fmt_str == NULL)
10786 return NULL_TREE;
10788 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10790 /* If we're using an unlocked function, assume the other
10791 unlocked functions exist explicitly. */
10792 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10793 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10795 else
10797 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10798 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10801 if (!init_target_chars())
10802 return 0;
10804 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10806 const char *str;
10808 if (strcmp (fmt_str, target_percent_s) == 0)
10810 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10811 return 0;
10813 if (! arglist
10814 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10815 || TREE_CHAIN (arglist))
10816 return 0;
10818 str = c_getstr (TREE_VALUE (arglist));
10819 if (str == NULL)
10820 return 0;
10822 else
10824 /* The format specifier doesn't contain any '%' characters. */
10825 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10826 && arglist)
10827 return 0;
10828 str = fmt_str;
10831 /* If the string was "", printf does nothing. */
10832 if (str[0] == '\0')
10833 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10835 /* If the string has length of 1, call putchar. */
10836 if (str[1] == '\0')
10838 /* Given printf("c"), (where c is any one character,)
10839 convert "c"[0] to an int and pass that to the replacement
10840 function. */
10841 arg = build_int_cst (NULL_TREE, str[0]);
10842 arglist = build_tree_list (NULL_TREE, arg);
10843 fn = fn_putchar;
10845 else
10847 /* If the string was "string\n", call puts("string"). */
10848 size_t len = strlen (str);
10849 if ((unsigned char)str[len - 1] == target_newline)
10851 /* Create a NUL-terminated string that's one char shorter
10852 than the original, stripping off the trailing '\n'. */
10853 char *newstr = alloca (len);
10854 memcpy (newstr, str, len - 1);
10855 newstr[len - 1] = 0;
10857 arg = build_string_literal (len, newstr);
10858 arglist = build_tree_list (NULL_TREE, arg);
10859 fn = fn_puts;
10861 else
10862 /* We'd like to arrange to call fputs(string,stdout) here,
10863 but we need stdout and don't have a way to get it yet. */
10864 return 0;
10868 /* The other optimizations can be done only on the non-va_list variants. */
10869 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10870 return 0;
10872 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10873 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10875 if (! arglist
10876 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10877 || TREE_CHAIN (arglist))
10878 return 0;
10879 fn = fn_puts;
10882 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10883 else if (strcmp (fmt_str, target_percent_c) == 0)
10885 if (! arglist
10886 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10887 || TREE_CHAIN (arglist))
10888 return 0;
10889 fn = fn_putchar;
10892 if (!fn)
10893 return 0;
10895 call = build_function_call_expr (fn, arglist);
10896 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10899 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10901 Return 0 if no simplification was possible, otherwise return the
10902 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10903 code of the function to be simplified. */
10905 static tree
10906 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10907 enum built_in_function fcode)
10909 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10910 const char *fmt_str = NULL;
10912 /* If the return value is used, don't do the transformation. */
10913 if (! ignore)
10914 return 0;
10916 /* Verify the required arguments in the original call. */
10917 if (! arglist)
10918 return 0;
10919 fp = TREE_VALUE (arglist);
10920 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10921 return 0;
10922 arglist = TREE_CHAIN (arglist);
10924 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10926 tree flag;
10928 if (! arglist)
10929 return 0;
10930 flag = TREE_VALUE (arglist);
10931 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10932 || TREE_SIDE_EFFECTS (flag))
10933 return 0;
10934 arglist = TREE_CHAIN (arglist);
10937 if (! arglist)
10938 return 0;
10939 fmt = TREE_VALUE (arglist);
10940 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10941 return 0;
10942 arglist = TREE_CHAIN (arglist);
10944 /* Check whether the format is a literal string constant. */
10945 fmt_str = c_getstr (fmt);
10946 if (fmt_str == NULL)
10947 return NULL_TREE;
10949 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10951 /* If we're using an unlocked function, assume the other
10952 unlocked functions exist explicitly. */
10953 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10954 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10956 else
10958 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10959 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10962 if (!init_target_chars())
10963 return 0;
10965 /* If the format doesn't contain % args or %%, use strcpy. */
10966 if (strchr (fmt_str, target_percent) == NULL)
10968 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10969 && arglist)
10970 return 0;
10972 /* If the format specifier was "", fprintf does nothing. */
10973 if (fmt_str[0] == '\0')
10975 /* If FP has side-effects, just wait until gimplification is
10976 done. */
10977 if (TREE_SIDE_EFFECTS (fp))
10978 return 0;
10980 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10983 /* When "string" doesn't contain %, replace all cases of
10984 fprintf (fp, string) with fputs (string, fp). The fputs
10985 builtin will take care of special cases like length == 1. */
10986 arglist = build_tree_list (NULL_TREE, fp);
10987 arglist = tree_cons (NULL_TREE, fmt, arglist);
10988 fn = fn_fputs;
10991 /* The other optimizations can be done only on the non-va_list variants. */
10992 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10993 return 0;
10995 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10996 else if (strcmp (fmt_str, target_percent_s) == 0)
10998 if (! arglist
10999 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11000 || TREE_CHAIN (arglist))
11001 return 0;
11002 arg = TREE_VALUE (arglist);
11003 arglist = build_tree_list (NULL_TREE, fp);
11004 arglist = tree_cons (NULL_TREE, arg, arglist);
11005 fn = fn_fputs;
11008 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11009 else if (strcmp (fmt_str, target_percent_c) == 0)
11011 if (! arglist
11012 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11013 || TREE_CHAIN (arglist))
11014 return 0;
11015 arg = TREE_VALUE (arglist);
11016 arglist = build_tree_list (NULL_TREE, fp);
11017 arglist = tree_cons (NULL_TREE, arg, arglist);
11018 fn = fn_fputc;
11021 if (!fn)
11022 return 0;
11024 call = build_function_call_expr (fn, arglist);
11025 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11028 /* Initialize format string characters in the target charset. */
11030 static bool
11031 init_target_chars (void)
11033 static bool init;
11034 if (!init)
11036 target_newline = lang_hooks.to_target_charset ('\n');
11037 target_percent = lang_hooks.to_target_charset ('%');
11038 target_c = lang_hooks.to_target_charset ('c');
11039 target_s = lang_hooks.to_target_charset ('s');
11040 if (target_newline == 0 || target_percent == 0 || target_c == 0
11041 || target_s == 0)
11042 return false;
11044 target_percent_c[0] = target_percent;
11045 target_percent_c[1] = target_c;
11046 target_percent_c[2] = '\0';
11048 target_percent_s[0] = target_percent;
11049 target_percent_s[1] = target_s;
11050 target_percent_s[2] = '\0';
11052 target_percent_s_newline[0] = target_percent;
11053 target_percent_s_newline[1] = target_s;
11054 target_percent_s_newline[2] = target_newline;
11055 target_percent_s_newline[3] = '\0';
11057 init = true;
11059 return true;