2006-08-06 Paolo Carlini <pcarlini@suse.de>
[official-gcc.git] / gcc / builtins.c
blob47c61cdb1332d376a092bf6f8aa2bd7aebd6bfc4
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_sin (tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_tan (tree);
156 static tree fold_builtin_atan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memcpy (tree, tree);
164 static tree fold_builtin_mempcpy (tree, tree, int);
165 static tree fold_builtin_memmove (tree, tree);
166 static tree fold_builtin_strchr (tree, tree);
167 static tree fold_builtin_memcmp (tree);
168 static tree fold_builtin_strcmp (tree);
169 static tree fold_builtin_strncmp (tree);
170 static tree fold_builtin_signbit (tree, tree);
171 static tree fold_builtin_copysign (tree, tree, tree);
172 static tree fold_builtin_isascii (tree);
173 static tree fold_builtin_toascii (tree);
174 static tree fold_builtin_isdigit (tree);
175 static tree fold_builtin_fabs (tree, tree);
176 static tree fold_builtin_abs (tree, tree);
177 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
178 enum tree_code);
179 static tree fold_builtin_1 (tree, tree, bool);
181 static tree fold_builtin_strpbrk (tree, tree);
182 static tree fold_builtin_strstr (tree, tree);
183 static tree fold_builtin_strrchr (tree, tree);
184 static tree fold_builtin_strcat (tree);
185 static tree fold_builtin_strncat (tree);
186 static tree fold_builtin_strspn (tree);
187 static tree fold_builtin_strcspn (tree);
188 static tree fold_builtin_sprintf (tree, int);
190 static rtx expand_builtin_object_size (tree);
191 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
192 enum built_in_function);
193 static void maybe_emit_chk_warning (tree, enum built_in_function);
194 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
195 static tree fold_builtin_object_size (tree);
196 static tree fold_builtin_strcat_chk (tree, tree);
197 static tree fold_builtin_strncat_chk (tree, tree);
198 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
199 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
200 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
201 static bool init_target_chars (void);
203 static unsigned HOST_WIDE_INT target_newline;
204 static unsigned HOST_WIDE_INT target_percent;
205 static unsigned HOST_WIDE_INT target_c;
206 static unsigned HOST_WIDE_INT target_s;
207 static char target_percent_c[3];
208 static char target_percent_s[3];
209 static char target_percent_s_newline[4];
211 /* Return true if NODE should be considered for inline expansion regardless
212 of the optimization level. This means whenever a function is invoked with
213 its "internal" name, which normally contains the prefix "__builtin". */
215 static bool called_as_built_in (tree node)
217 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
218 if (strncmp (name, "__builtin_", 10) == 0)
219 return true;
220 if (strncmp (name, "__sync_", 7) == 0)
221 return true;
222 return false;
225 /* Return the alignment in bits of EXP, a pointer valued expression.
226 But don't return more than MAX_ALIGN no matter what.
227 The alignment returned is, by default, the alignment of the thing that
228 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
230 Otherwise, look at the expression to see if we can do better, i.e., if the
231 expression is actually pointing at an object whose alignment is tighter. */
233 static int
234 get_pointer_alignment (tree exp, unsigned int max_align)
236 unsigned int align, inner;
238 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
239 return 0;
241 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
242 align = MIN (align, max_align);
244 while (1)
246 switch (TREE_CODE (exp))
248 case NOP_EXPR:
249 case CONVERT_EXPR:
250 case NON_LVALUE_EXPR:
251 exp = TREE_OPERAND (exp, 0);
252 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
253 return align;
255 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
256 align = MIN (inner, max_align);
257 break;
259 case PLUS_EXPR:
260 /* If sum of pointer + int, restrict our maximum alignment to that
261 imposed by the integer. If not, we can't do any better than
262 ALIGN. */
263 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
264 return align;
266 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
267 & (max_align / BITS_PER_UNIT - 1))
268 != 0)
269 max_align >>= 1;
271 exp = TREE_OPERAND (exp, 0);
272 break;
274 case ADDR_EXPR:
275 /* See what we are pointing at and look at its alignment. */
276 exp = TREE_OPERAND (exp, 0);
277 inner = max_align;
278 while (handled_component_p (exp))
280 /* Fields in a structure can be packed, honor DECL_ALIGN
281 of the FIELD_DECL. For all other references the conservative
282 alignment is the element type alignment. */
283 if (TREE_CODE (exp) == COMPONENT_REF)
284 inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
285 else
286 inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
287 exp = TREE_OPERAND (exp, 0);
289 if (TREE_CODE (exp) == FUNCTION_DECL)
290 align = FUNCTION_BOUNDARY;
291 else if (DECL_P (exp))
292 align = MIN (inner, DECL_ALIGN (exp));
293 #ifdef CONSTANT_ALIGNMENT
294 else if (CONSTANT_CLASS_P (exp))
295 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
296 #endif
297 else
298 align = MIN (align, inner);
299 return MIN (align, max_align);
301 default:
302 return align;
307 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
308 way, because it could contain a zero byte in the middle.
309 TREE_STRING_LENGTH is the size of the character array, not the string.
311 ONLY_VALUE should be nonzero if the result is not going to be emitted
312 into the instruction stream and zero if it is going to be expanded.
313 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
314 is returned, otherwise NULL, since
315 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
316 evaluate the side-effects.
318 The value returned is of type `ssizetype'.
320 Unfortunately, string_constant can't access the values of const char
321 arrays with initializers, so neither can we do so here. */
323 tree
324 c_strlen (tree src, int only_value)
326 tree offset_node;
327 HOST_WIDE_INT offset;
328 int max;
329 const char *ptr;
331 STRIP_NOPS (src);
332 if (TREE_CODE (src) == COND_EXPR
333 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
335 tree len1, len2;
337 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
338 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
339 if (tree_int_cst_equal (len1, len2))
340 return len1;
343 if (TREE_CODE (src) == COMPOUND_EXPR
344 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
345 return c_strlen (TREE_OPERAND (src, 1), only_value);
347 src = string_constant (src, &offset_node);
348 if (src == 0)
349 return 0;
351 max = TREE_STRING_LENGTH (src) - 1;
352 ptr = TREE_STRING_POINTER (src);
354 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
356 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
357 compute the offset to the following null if we don't know where to
358 start searching for it. */
359 int i;
361 for (i = 0; i < max; i++)
362 if (ptr[i] == 0)
363 return 0;
365 /* We don't know the starting offset, but we do know that the string
366 has no internal zero bytes. We can assume that the offset falls
367 within the bounds of the string; otherwise, the programmer deserves
368 what he gets. Subtract the offset from the length of the string,
369 and return that. This would perhaps not be valid if we were dealing
370 with named arrays in addition to literal string constants. */
372 return size_diffop (size_int (max), offset_node);
375 /* We have a known offset into the string. Start searching there for
376 a null character if we can represent it as a single HOST_WIDE_INT. */
377 if (offset_node == 0)
378 offset = 0;
379 else if (! host_integerp (offset_node, 0))
380 offset = -1;
381 else
382 offset = tree_low_cst (offset_node, 0);
384 /* If the offset is known to be out of bounds, warn, and call strlen at
385 runtime. */
386 if (offset < 0 || offset > max)
388 warning (0, "offset outside bounds of constant string");
389 return 0;
392 /* Use strlen to search for the first zero byte. Since any strings
393 constructed with build_string will have nulls appended, we win even
394 if we get handed something like (char[4])"abcd".
396 Since OFFSET is our starting index into the string, no further
397 calculation is needed. */
398 return ssize_int (strlen (ptr + offset));
401 /* Return a char pointer for a C string if it is a string constant
402 or sum of string constant and integer constant. */
404 static const char *
405 c_getstr (tree src)
407 tree offset_node;
409 src = string_constant (src, &offset_node);
410 if (src == 0)
411 return 0;
413 if (offset_node == 0)
414 return TREE_STRING_POINTER (src);
415 else if (!host_integerp (offset_node, 1)
416 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
417 return 0;
419 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
422 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
423 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
425 static rtx
426 c_readstr (const char *str, enum machine_mode mode)
428 HOST_WIDE_INT c[2];
429 HOST_WIDE_INT ch;
430 unsigned int i, j;
432 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
434 c[0] = 0;
435 c[1] = 0;
436 ch = 1;
437 for (i = 0; i < GET_MODE_SIZE (mode); i++)
439 j = i;
440 if (WORDS_BIG_ENDIAN)
441 j = GET_MODE_SIZE (mode) - i - 1;
442 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
443 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
444 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
445 j *= BITS_PER_UNIT;
446 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
448 if (ch)
449 ch = (unsigned char) str[i];
450 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
452 return immed_double_const (c[0], c[1], mode);
455 /* Cast a target constant CST to target CHAR and if that value fits into
456 host char type, return zero and put that value into variable pointed to by
457 P. */
459 static int
460 target_char_cast (tree cst, char *p)
462 unsigned HOST_WIDE_INT val, hostval;
464 if (!host_integerp (cst, 1)
465 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
466 return 1;
468 val = tree_low_cst (cst, 1);
469 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
470 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
472 hostval = val;
473 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
474 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
476 if (val != hostval)
477 return 1;
479 *p = hostval;
480 return 0;
483 /* Similar to save_expr, but assumes that arbitrary code is not executed
484 in between the multiple evaluations. In particular, we assume that a
485 non-addressable local variable will not be modified. */
487 static tree
488 builtin_save_expr (tree exp)
490 if (TREE_ADDRESSABLE (exp) == 0
491 && (TREE_CODE (exp) == PARM_DECL
492 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
493 return exp;
495 return save_expr (exp);
498 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
499 times to get the address of either a higher stack frame, or a return
500 address located within it (depending on FNDECL_CODE). */
502 static rtx
503 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
505 int i;
507 #ifdef INITIAL_FRAME_ADDRESS_RTX
508 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
509 #else
510 rtx tem;
512 /* For a zero count with __builtin_return_address, we don't care what
513 frame address we return, because target-specific definitions will
514 override us. Therefore frame pointer elimination is OK, and using
515 the soft frame pointer is OK.
517 For a non-zero count, or a zero count with __builtin_frame_address,
518 we require a stable offset from the current frame pointer to the
519 previous one, so we must use the hard frame pointer, and
520 we must disable frame pointer elimination. */
521 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
522 tem = frame_pointer_rtx;
523 else
525 tem = hard_frame_pointer_rtx;
527 /* Tell reload not to eliminate the frame pointer. */
528 current_function_accesses_prior_frames = 1;
530 #endif
532 /* Some machines need special handling before we can access
533 arbitrary frames. For example, on the sparc, we must first flush
534 all register windows to the stack. */
535 #ifdef SETUP_FRAME_ADDRESSES
536 if (count > 0)
537 SETUP_FRAME_ADDRESSES ();
538 #endif
540 /* On the sparc, the return address is not in the frame, it is in a
541 register. There is no way to access it off of the current frame
542 pointer, but it can be accessed off the previous frame pointer by
543 reading the value from the register window save area. */
544 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
545 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
546 count--;
547 #endif
549 /* Scan back COUNT frames to the specified frame. */
550 for (i = 0; i < count; i++)
552 /* Assume the dynamic chain pointer is in the word that the
553 frame address points to, unless otherwise specified. */
554 #ifdef DYNAMIC_CHAIN_ADDRESS
555 tem = DYNAMIC_CHAIN_ADDRESS (tem);
556 #endif
557 tem = memory_address (Pmode, tem);
558 tem = gen_frame_mem (Pmode, tem);
559 tem = copy_to_reg (tem);
562 /* For __builtin_frame_address, return what we've got. */
563 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
564 return tem;
566 /* For __builtin_return_address, Get the return address from that
567 frame. */
568 #ifdef RETURN_ADDR_RTX
569 tem = RETURN_ADDR_RTX (count, tem);
570 #else
571 tem = memory_address (Pmode,
572 plus_constant (tem, GET_MODE_SIZE (Pmode)));
573 tem = gen_frame_mem (Pmode, tem);
574 #endif
575 return tem;
578 /* Alias set used for setjmp buffer. */
579 static HOST_WIDE_INT setjmp_alias_set = -1;
581 /* Construct the leading half of a __builtin_setjmp call. Control will
582 return to RECEIVER_LABEL. This is used directly by sjlj exception
583 handling code. */
585 void
586 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
588 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
589 rtx stack_save;
590 rtx mem;
592 if (setjmp_alias_set == -1)
593 setjmp_alias_set = new_alias_set ();
595 buf_addr = convert_memory_address (Pmode, buf_addr);
597 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
599 /* We store the frame pointer and the address of receiver_label in
600 the buffer and use the rest of it for the stack save area, which
601 is machine-dependent. */
603 mem = gen_rtx_MEM (Pmode, buf_addr);
604 set_mem_alias_set (mem, setjmp_alias_set);
605 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
607 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
608 set_mem_alias_set (mem, setjmp_alias_set);
610 emit_move_insn (validize_mem (mem),
611 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
613 stack_save = gen_rtx_MEM (sa_mode,
614 plus_constant (buf_addr,
615 2 * GET_MODE_SIZE (Pmode)));
616 set_mem_alias_set (stack_save, setjmp_alias_set);
617 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
619 /* If there is further processing to do, do it. */
620 #ifdef HAVE_builtin_setjmp_setup
621 if (HAVE_builtin_setjmp_setup)
622 emit_insn (gen_builtin_setjmp_setup (buf_addr));
623 #endif
625 /* Tell optimize_save_area_alloca that extra work is going to
626 need to go on during alloca. */
627 current_function_calls_setjmp = 1;
629 /* Set this so all the registers get saved in our frame; we need to be
630 able to copy the saved values for any registers from frames we unwind. */
631 current_function_has_nonlocal_label = 1;
634 /* Construct the trailing part of a __builtin_setjmp call.
635 This is used directly by sjlj exception handling code. */
637 void
638 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
640 /* Clobber the FP when we get here, so we have to make sure it's
641 marked as used by this function. */
642 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
644 /* Mark the static chain as clobbered here so life information
645 doesn't get messed up for it. */
646 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
648 /* Now put in the code to restore the frame pointer, and argument
649 pointer, if needed. */
650 #ifdef HAVE_nonlocal_goto
651 if (! HAVE_nonlocal_goto)
652 #endif
653 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
655 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
656 if (fixed_regs[ARG_POINTER_REGNUM])
658 #ifdef ELIMINABLE_REGS
659 size_t i;
660 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
662 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
663 if (elim_regs[i].from == ARG_POINTER_REGNUM
664 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
665 break;
667 if (i == ARRAY_SIZE (elim_regs))
668 #endif
670 /* Now restore our arg pointer from the address at which it
671 was saved in our stack frame. */
672 emit_move_insn (virtual_incoming_args_rtx,
673 copy_to_reg (get_arg_pointer_save_area (cfun)));
676 #endif
678 #ifdef HAVE_builtin_setjmp_receiver
679 if (HAVE_builtin_setjmp_receiver)
680 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
681 else
682 #endif
683 #ifdef HAVE_nonlocal_goto_receiver
684 if (HAVE_nonlocal_goto_receiver)
685 emit_insn (gen_nonlocal_goto_receiver ());
686 else
687 #endif
688 { /* Nothing */ }
690 /* @@@ This is a kludge. Not all machine descriptions define a blockage
691 insn, but we must not allow the code we just generated to be reordered
692 by scheduling. Specifically, the update of the frame pointer must
693 happen immediately, not later. So emit an ASM_INPUT to act as blockage
694 insn. */
695 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
698 /* __builtin_setjmp is passed a pointer to an array of five words (not
699 all will be used on all machines). It operates similarly to the C
700 library function of the same name, but is more efficient. Much of
701 the code below (and for longjmp) is copied from the handling of
702 non-local gotos.
704 NOTE: This is intended for use by GNAT and the exception handling
705 scheme in the compiler and will only work in the method used by
706 them. */
708 static rtx
709 expand_builtin_setjmp (tree arglist, rtx target)
711 rtx buf_addr, next_lab, cont_lab;
713 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
714 return NULL_RTX;
716 if (target == 0 || !REG_P (target)
717 || REGNO (target) < FIRST_PSEUDO_REGISTER)
718 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
720 buf_addr = expand_normal (TREE_VALUE (arglist));
722 next_lab = gen_label_rtx ();
723 cont_lab = gen_label_rtx ();
725 expand_builtin_setjmp_setup (buf_addr, next_lab);
727 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
728 ensure that pending stack adjustments are flushed. */
729 emit_move_insn (target, const0_rtx);
730 emit_jump (cont_lab);
732 emit_label (next_lab);
734 expand_builtin_setjmp_receiver (next_lab);
736 /* Set TARGET to one. */
737 emit_move_insn (target, const1_rtx);
738 emit_label (cont_lab);
740 /* Tell flow about the strange goings on. Putting `next_lab' on
741 `nonlocal_goto_handler_labels' to indicates that function
742 calls may traverse the arc back to this label. */
744 current_function_has_nonlocal_label = 1;
745 nonlocal_goto_handler_labels
746 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
748 return target;
751 /* __builtin_longjmp is passed a pointer to an array of five words (not
752 all will be used on all machines). It operates similarly to the C
753 library function of the same name, but is more efficient. Much of
754 the code below is copied from the handling of non-local gotos.
756 NOTE: This is intended for use by GNAT and the exception handling
757 scheme in the compiler and will only work in the method used by
758 them. */
760 static void
761 expand_builtin_longjmp (rtx buf_addr, rtx value)
763 rtx fp, lab, stack, insn, last;
764 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
766 if (setjmp_alias_set == -1)
767 setjmp_alias_set = new_alias_set ();
769 buf_addr = convert_memory_address (Pmode, buf_addr);
771 buf_addr = force_reg (Pmode, buf_addr);
773 /* We used to store value in static_chain_rtx, but that fails if pointers
774 are smaller than integers. We instead require that the user must pass
775 a second argument of 1, because that is what builtin_setjmp will
776 return. This also makes EH slightly more efficient, since we are no
777 longer copying around a value that we don't care about. */
778 gcc_assert (value == const1_rtx);
780 last = get_last_insn ();
781 #ifdef HAVE_builtin_longjmp
782 if (HAVE_builtin_longjmp)
783 emit_insn (gen_builtin_longjmp (buf_addr));
784 else
785 #endif
787 fp = gen_rtx_MEM (Pmode, buf_addr);
788 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
789 GET_MODE_SIZE (Pmode)));
791 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
792 2 * GET_MODE_SIZE (Pmode)));
793 set_mem_alias_set (fp, setjmp_alias_set);
794 set_mem_alias_set (lab, setjmp_alias_set);
795 set_mem_alias_set (stack, setjmp_alias_set);
797 /* Pick up FP, label, and SP from the block and jump. This code is
798 from expand_goto in stmt.c; see there for detailed comments. */
799 #ifdef HAVE_nonlocal_goto
800 if (HAVE_nonlocal_goto)
801 /* We have to pass a value to the nonlocal_goto pattern that will
802 get copied into the static_chain pointer, but it does not matter
803 what that value is, because builtin_setjmp does not use it. */
804 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
805 else
806 #endif
808 lab = copy_to_reg (lab);
810 emit_insn (gen_rtx_CLOBBER (VOIDmode,
811 gen_rtx_MEM (BLKmode,
812 gen_rtx_SCRATCH (VOIDmode))));
813 emit_insn (gen_rtx_CLOBBER (VOIDmode,
814 gen_rtx_MEM (BLKmode,
815 hard_frame_pointer_rtx)));
817 emit_move_insn (hard_frame_pointer_rtx, fp);
818 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
820 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
821 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
822 emit_indirect_jump (lab);
826 /* Search backwards and mark the jump insn as a non-local goto.
827 Note that this precludes the use of __builtin_longjmp to a
828 __builtin_setjmp target in the same function. However, we've
829 already cautioned the user that these functions are for
830 internal exception handling use only. */
831 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
833 gcc_assert (insn != last);
835 if (JUMP_P (insn))
837 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
838 REG_NOTES (insn));
839 break;
841 else if (CALL_P (insn))
842 break;
846 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
847 and the address of the save area. */
849 static rtx
850 expand_builtin_nonlocal_goto (tree arglist)
852 tree t_label, t_save_area;
853 rtx r_label, r_save_area, r_fp, r_sp, insn;
855 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
856 return NULL_RTX;
858 t_label = TREE_VALUE (arglist);
859 arglist = TREE_CHAIN (arglist);
860 t_save_area = TREE_VALUE (arglist);
862 r_label = expand_normal (t_label);
863 r_label = convert_memory_address (Pmode, r_label);
864 r_save_area = expand_normal (t_save_area);
865 r_save_area = convert_memory_address (Pmode, r_save_area);
866 r_fp = gen_rtx_MEM (Pmode, r_save_area);
867 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
868 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
870 current_function_has_nonlocal_goto = 1;
872 #ifdef HAVE_nonlocal_goto
873 /* ??? We no longer need to pass the static chain value, afaik. */
874 if (HAVE_nonlocal_goto)
875 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
876 else
877 #endif
879 r_label = copy_to_reg (r_label);
881 emit_insn (gen_rtx_CLOBBER (VOIDmode,
882 gen_rtx_MEM (BLKmode,
883 gen_rtx_SCRATCH (VOIDmode))));
885 emit_insn (gen_rtx_CLOBBER (VOIDmode,
886 gen_rtx_MEM (BLKmode,
887 hard_frame_pointer_rtx)));
889 /* Restore frame pointer for containing function.
890 This sets the actual hard register used for the frame pointer
891 to the location of the function's incoming static chain info.
892 The non-local goto handler will then adjust it to contain the
893 proper value and reload the argument pointer, if needed. */
894 emit_move_insn (hard_frame_pointer_rtx, r_fp);
895 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
897 /* USE of hard_frame_pointer_rtx added for consistency;
898 not clear if really needed. */
899 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
900 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
901 emit_indirect_jump (r_label);
904 /* Search backwards to the jump insn and mark it as a
905 non-local goto. */
906 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
908 if (JUMP_P (insn))
910 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
911 const0_rtx, REG_NOTES (insn));
912 break;
914 else if (CALL_P (insn))
915 break;
918 return const0_rtx;
921 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
922 (not all will be used on all machines) that was passed to __builtin_setjmp.
923 It updates the stack pointer in that block to correspond to the current
924 stack pointer. */
926 static void
927 expand_builtin_update_setjmp_buf (rtx buf_addr)
929 enum machine_mode sa_mode = Pmode;
930 rtx stack_save;
933 #ifdef HAVE_save_stack_nonlocal
934 if (HAVE_save_stack_nonlocal)
935 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
936 #endif
937 #ifdef STACK_SAVEAREA_MODE
938 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
939 #endif
941 stack_save
942 = gen_rtx_MEM (sa_mode,
943 memory_address
944 (sa_mode,
945 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
947 #ifdef HAVE_setjmp
948 if (HAVE_setjmp)
949 emit_insn (gen_setjmp ());
950 #endif
952 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
955 /* Expand a call to __builtin_prefetch. For a target that does not support
956 data prefetch, evaluate the memory address argument in case it has side
957 effects. */
959 static void
960 expand_builtin_prefetch (tree arglist)
962 tree arg0, arg1, arg2;
963 rtx op0, op1, op2;
965 if (!validate_arglist (arglist, POINTER_TYPE, 0))
966 return;
968 arg0 = TREE_VALUE (arglist);
969 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
970 zero (read) and argument 2 (locality) defaults to 3 (high degree of
971 locality). */
972 if (TREE_CHAIN (arglist))
974 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
975 if (TREE_CHAIN (TREE_CHAIN (arglist)))
976 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
977 else
978 arg2 = build_int_cst (NULL_TREE, 3);
980 else
982 arg1 = integer_zero_node;
983 arg2 = build_int_cst (NULL_TREE, 3);
986 /* Argument 0 is an address. */
987 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
989 /* Argument 1 (read/write flag) must be a compile-time constant int. */
990 if (TREE_CODE (arg1) != INTEGER_CST)
992 error ("second argument to %<__builtin_prefetch%> must be a constant");
993 arg1 = integer_zero_node;
995 op1 = expand_normal (arg1);
996 /* Argument 1 must be either zero or one. */
997 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
999 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1000 " using zero");
1001 op1 = const0_rtx;
1004 /* Argument 2 (locality) must be a compile-time constant int. */
1005 if (TREE_CODE (arg2) != INTEGER_CST)
1007 error ("third argument to %<__builtin_prefetch%> must be a constant");
1008 arg2 = integer_zero_node;
1010 op2 = expand_normal (arg2);
1011 /* Argument 2 must be 0, 1, 2, or 3. */
1012 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1014 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1015 op2 = const0_rtx;
1018 #ifdef HAVE_prefetch
1019 if (HAVE_prefetch)
1021 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1022 (op0,
1023 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1024 || (GET_MODE (op0) != Pmode))
1026 op0 = convert_memory_address (Pmode, op0);
1027 op0 = force_reg (Pmode, op0);
1029 emit_insn (gen_prefetch (op0, op1, op2));
1031 #endif
1033 /* Don't do anything with direct references to volatile memory, but
1034 generate code to handle other side effects. */
1035 if (!MEM_P (op0) && side_effects_p (op0))
1036 emit_insn (op0);
1039 /* Get a MEM rtx for expression EXP which is the address of an operand
1040 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1041 the maximum length of the block of memory that might be accessed or
1042 NULL if unknown. */
1044 static rtx
1045 get_memory_rtx (tree exp, tree len)
1047 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1048 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1050 /* Get an expression we can use to find the attributes to assign to MEM.
1051 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1052 we can. First remove any nops. */
1053 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1054 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1055 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1056 exp = TREE_OPERAND (exp, 0);
1058 if (TREE_CODE (exp) == ADDR_EXPR)
1059 exp = TREE_OPERAND (exp, 0);
1060 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1061 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1062 else
1063 exp = NULL;
1065 /* Honor attributes derived from exp, except for the alias set
1066 (as builtin stringops may alias with anything) and the size
1067 (as stringops may access multiple array elements). */
1068 if (exp)
1070 set_mem_attributes (mem, exp, 0);
1072 /* Allow the string and memory builtins to overflow from one
1073 field into another, see http://gcc.gnu.org/PR23561.
1074 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1075 memory accessed by the string or memory builtin will fit
1076 within the field. */
1077 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1079 tree mem_expr = MEM_EXPR (mem);
1080 HOST_WIDE_INT offset = -1, length = -1;
1081 tree inner = exp;
1083 while (TREE_CODE (inner) == ARRAY_REF
1084 || TREE_CODE (inner) == NOP_EXPR
1085 || TREE_CODE (inner) == CONVERT_EXPR
1086 || TREE_CODE (inner) == NON_LVALUE_EXPR
1087 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1088 || TREE_CODE (inner) == SAVE_EXPR)
1089 inner = TREE_OPERAND (inner, 0);
1091 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1093 if (MEM_OFFSET (mem)
1094 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1095 offset = INTVAL (MEM_OFFSET (mem));
1097 if (offset >= 0 && len && host_integerp (len, 0))
1098 length = tree_low_cst (len, 0);
1100 while (TREE_CODE (inner) == COMPONENT_REF)
1102 tree field = TREE_OPERAND (inner, 1);
1103 gcc_assert (! DECL_BIT_FIELD (field));
1104 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1105 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1107 if (length >= 0
1108 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1109 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1111 HOST_WIDE_INT size
1112 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1113 /* If we can prove the memory starting at XEXP (mem, 0)
1114 and ending at XEXP (mem, 0) + LENGTH will fit into
1115 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1116 if (offset <= size
1117 && length <= size
1118 && offset + length <= size)
1119 break;
1122 if (offset >= 0
1123 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1124 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1125 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1126 / BITS_PER_UNIT;
1127 else
1129 offset = -1;
1130 length = -1;
1133 mem_expr = TREE_OPERAND (mem_expr, 0);
1134 inner = TREE_OPERAND (inner, 0);
1137 if (mem_expr == NULL)
1138 offset = -1;
1139 if (mem_expr != MEM_EXPR (mem))
1141 set_mem_expr (mem, mem_expr);
1142 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1145 set_mem_alias_set (mem, 0);
1146 set_mem_size (mem, NULL_RTX);
1149 return mem;
1152 /* Built-in functions to perform an untyped call and return. */
1154 /* For each register that may be used for calling a function, this
1155 gives a mode used to copy the register's value. VOIDmode indicates
1156 the register is not used for calling a function. If the machine
1157 has register windows, this gives only the outbound registers.
1158 INCOMING_REGNO gives the corresponding inbound register. */
1159 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1161 /* For each register that may be used for returning values, this gives
1162 a mode used to copy the register's value. VOIDmode indicates the
1163 register is not used for returning values. If the machine has
1164 register windows, this gives only the outbound registers.
1165 INCOMING_REGNO gives the corresponding inbound register. */
1166 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1168 /* For each register that may be used for calling a function, this
1169 gives the offset of that register into the block returned by
1170 __builtin_apply_args. 0 indicates that the register is not
1171 used for calling a function. */
1172 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1174 /* Return the size required for the block returned by __builtin_apply_args,
1175 and initialize apply_args_mode. */
1177 static int
1178 apply_args_size (void)
1180 static int size = -1;
1181 int align;
1182 unsigned int regno;
1183 enum machine_mode mode;
1185 /* The values computed by this function never change. */
1186 if (size < 0)
1188 /* The first value is the incoming arg-pointer. */
1189 size = GET_MODE_SIZE (Pmode);
1191 /* The second value is the structure value address unless this is
1192 passed as an "invisible" first argument. */
1193 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1194 size += GET_MODE_SIZE (Pmode);
1196 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1197 if (FUNCTION_ARG_REGNO_P (regno))
1199 mode = reg_raw_mode[regno];
1201 gcc_assert (mode != VOIDmode);
1203 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1204 if (size % align != 0)
1205 size = CEIL (size, align) * align;
1206 apply_args_reg_offset[regno] = size;
1207 size += GET_MODE_SIZE (mode);
1208 apply_args_mode[regno] = mode;
1210 else
1212 apply_args_mode[regno] = VOIDmode;
1213 apply_args_reg_offset[regno] = 0;
1216 return size;
1219 /* Return the size required for the block returned by __builtin_apply,
1220 and initialize apply_result_mode. */
1222 static int
1223 apply_result_size (void)
1225 static int size = -1;
1226 int align, regno;
1227 enum machine_mode mode;
1229 /* The values computed by this function never change. */
1230 if (size < 0)
1232 size = 0;
1234 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1235 if (FUNCTION_VALUE_REGNO_P (regno))
1237 mode = reg_raw_mode[regno];
1239 gcc_assert (mode != VOIDmode);
1241 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1242 if (size % align != 0)
1243 size = CEIL (size, align) * align;
1244 size += GET_MODE_SIZE (mode);
1245 apply_result_mode[regno] = mode;
1247 else
1248 apply_result_mode[regno] = VOIDmode;
1250 /* Allow targets that use untyped_call and untyped_return to override
1251 the size so that machine-specific information can be stored here. */
1252 #ifdef APPLY_RESULT_SIZE
1253 size = APPLY_RESULT_SIZE;
1254 #endif
1256 return size;
1259 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1260 /* Create a vector describing the result block RESULT. If SAVEP is true,
1261 the result block is used to save the values; otherwise it is used to
1262 restore the values. */
1264 static rtx
1265 result_vector (int savep, rtx result)
1267 int regno, size, align, nelts;
1268 enum machine_mode mode;
1269 rtx reg, mem;
1270 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1272 size = nelts = 0;
1273 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1274 if ((mode = apply_result_mode[regno]) != VOIDmode)
1276 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1277 if (size % align != 0)
1278 size = CEIL (size, align) * align;
1279 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1280 mem = adjust_address (result, mode, size);
1281 savevec[nelts++] = (savep
1282 ? gen_rtx_SET (VOIDmode, mem, reg)
1283 : gen_rtx_SET (VOIDmode, reg, mem));
1284 size += GET_MODE_SIZE (mode);
1286 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1288 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1290 /* Save the state required to perform an untyped call with the same
1291 arguments as were passed to the current function. */
1293 static rtx
1294 expand_builtin_apply_args_1 (void)
1296 rtx registers, tem;
1297 int size, align, regno;
1298 enum machine_mode mode;
1299 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1301 /* Create a block where the arg-pointer, structure value address,
1302 and argument registers can be saved. */
1303 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1305 /* Walk past the arg-pointer and structure value address. */
1306 size = GET_MODE_SIZE (Pmode);
1307 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1308 size += GET_MODE_SIZE (Pmode);
1310 /* Save each register used in calling a function to the block. */
1311 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1312 if ((mode = apply_args_mode[regno]) != VOIDmode)
1314 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1315 if (size % align != 0)
1316 size = CEIL (size, align) * align;
1318 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1320 emit_move_insn (adjust_address (registers, mode, size), tem);
1321 size += GET_MODE_SIZE (mode);
1324 /* Save the arg pointer to the block. */
1325 tem = copy_to_reg (virtual_incoming_args_rtx);
1326 #ifdef STACK_GROWS_DOWNWARD
1327 /* We need the pointer as the caller actually passed them to us, not
1328 as we might have pretended they were passed. Make sure it's a valid
1329 operand, as emit_move_insn isn't expected to handle a PLUS. */
1331 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1332 NULL_RTX);
1333 #endif
1334 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1336 size = GET_MODE_SIZE (Pmode);
1338 /* Save the structure value address unless this is passed as an
1339 "invisible" first argument. */
1340 if (struct_incoming_value)
1342 emit_move_insn (adjust_address (registers, Pmode, size),
1343 copy_to_reg (struct_incoming_value));
1344 size += GET_MODE_SIZE (Pmode);
1347 /* Return the address of the block. */
1348 return copy_addr_to_reg (XEXP (registers, 0));
1351 /* __builtin_apply_args returns block of memory allocated on
1352 the stack into which is stored the arg pointer, structure
1353 value address, static chain, and all the registers that might
1354 possibly be used in performing a function call. The code is
1355 moved to the start of the function so the incoming values are
1356 saved. */
1358 static rtx
1359 expand_builtin_apply_args (void)
1361 /* Don't do __builtin_apply_args more than once in a function.
1362 Save the result of the first call and reuse it. */
1363 if (apply_args_value != 0)
1364 return apply_args_value;
1366 /* When this function is called, it means that registers must be
1367 saved on entry to this function. So we migrate the
1368 call to the first insn of this function. */
1369 rtx temp;
1370 rtx seq;
1372 start_sequence ();
1373 temp = expand_builtin_apply_args_1 ();
1374 seq = get_insns ();
1375 end_sequence ();
1377 apply_args_value = temp;
1379 /* Put the insns after the NOTE that starts the function.
1380 If this is inside a start_sequence, make the outer-level insn
1381 chain current, so the code is placed at the start of the
1382 function. */
1383 push_topmost_sequence ();
1384 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1385 pop_topmost_sequence ();
1386 return temp;
1390 /* Perform an untyped call and save the state required to perform an
1391 untyped return of whatever value was returned by the given function. */
1393 static rtx
1394 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1396 int size, align, regno;
1397 enum machine_mode mode;
1398 rtx incoming_args, result, reg, dest, src, call_insn;
1399 rtx old_stack_level = 0;
1400 rtx call_fusage = 0;
1401 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1403 arguments = convert_memory_address (Pmode, arguments);
1405 /* Create a block where the return registers can be saved. */
1406 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1408 /* Fetch the arg pointer from the ARGUMENTS block. */
1409 incoming_args = gen_reg_rtx (Pmode);
1410 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1411 #ifndef STACK_GROWS_DOWNWARD
1412 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1413 incoming_args, 0, OPTAB_LIB_WIDEN);
1414 #endif
1416 /* Push a new argument block and copy the arguments. Do not allow
1417 the (potential) memcpy call below to interfere with our stack
1418 manipulations. */
1419 do_pending_stack_adjust ();
1420 NO_DEFER_POP;
1422 /* Save the stack with nonlocal if available. */
1423 #ifdef HAVE_save_stack_nonlocal
1424 if (HAVE_save_stack_nonlocal)
1425 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1426 else
1427 #endif
1428 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1430 /* Allocate a block of memory onto the stack and copy the memory
1431 arguments to the outgoing arguments address. */
1432 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1433 dest = virtual_outgoing_args_rtx;
1434 #ifndef STACK_GROWS_DOWNWARD
1435 if (GET_CODE (argsize) == CONST_INT)
1436 dest = plus_constant (dest, -INTVAL (argsize));
1437 else
1438 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1439 #endif
1440 dest = gen_rtx_MEM (BLKmode, dest);
1441 set_mem_align (dest, PARM_BOUNDARY);
1442 src = gen_rtx_MEM (BLKmode, incoming_args);
1443 set_mem_align (src, PARM_BOUNDARY);
1444 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1446 /* Refer to the argument block. */
1447 apply_args_size ();
1448 arguments = gen_rtx_MEM (BLKmode, arguments);
1449 set_mem_align (arguments, PARM_BOUNDARY);
1451 /* Walk past the arg-pointer and structure value address. */
1452 size = GET_MODE_SIZE (Pmode);
1453 if (struct_value)
1454 size += GET_MODE_SIZE (Pmode);
1456 /* Restore each of the registers previously saved. Make USE insns
1457 for each of these registers for use in making the call. */
1458 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1459 if ((mode = apply_args_mode[regno]) != VOIDmode)
1461 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1462 if (size % align != 0)
1463 size = CEIL (size, align) * align;
1464 reg = gen_rtx_REG (mode, regno);
1465 emit_move_insn (reg, adjust_address (arguments, mode, size));
1466 use_reg (&call_fusage, reg);
1467 size += GET_MODE_SIZE (mode);
1470 /* Restore the structure value address unless this is passed as an
1471 "invisible" first argument. */
1472 size = GET_MODE_SIZE (Pmode);
1473 if (struct_value)
1475 rtx value = gen_reg_rtx (Pmode);
1476 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1477 emit_move_insn (struct_value, value);
1478 if (REG_P (struct_value))
1479 use_reg (&call_fusage, struct_value);
1480 size += GET_MODE_SIZE (Pmode);
1483 /* All arguments and registers used for the call are set up by now! */
1484 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1486 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1487 and we don't want to load it into a register as an optimization,
1488 because prepare_call_address already did it if it should be done. */
1489 if (GET_CODE (function) != SYMBOL_REF)
1490 function = memory_address (FUNCTION_MODE, function);
1492 /* Generate the actual call instruction and save the return value. */
1493 #ifdef HAVE_untyped_call
1494 if (HAVE_untyped_call)
1495 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1496 result, result_vector (1, result)));
1497 else
1498 #endif
1499 #ifdef HAVE_call_value
1500 if (HAVE_call_value)
1502 rtx valreg = 0;
1504 /* Locate the unique return register. It is not possible to
1505 express a call that sets more than one return register using
1506 call_value; use untyped_call for that. In fact, untyped_call
1507 only needs to save the return registers in the given block. */
1508 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1509 if ((mode = apply_result_mode[regno]) != VOIDmode)
1511 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1513 valreg = gen_rtx_REG (mode, regno);
1516 emit_call_insn (GEN_CALL_VALUE (valreg,
1517 gen_rtx_MEM (FUNCTION_MODE, function),
1518 const0_rtx, NULL_RTX, const0_rtx));
1520 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1522 else
1523 #endif
1524 gcc_unreachable ();
1526 /* Find the CALL insn we just emitted, and attach the register usage
1527 information. */
1528 call_insn = last_call_insn ();
1529 add_function_usage_to (call_insn, call_fusage);
1531 /* Restore the stack. */
1532 #ifdef HAVE_save_stack_nonlocal
1533 if (HAVE_save_stack_nonlocal)
1534 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1535 else
1536 #endif
1537 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1539 OK_DEFER_POP;
1541 /* Return the address of the result block. */
1542 result = copy_addr_to_reg (XEXP (result, 0));
1543 return convert_memory_address (ptr_mode, result);
1546 /* Perform an untyped return. */
1548 static void
1549 expand_builtin_return (rtx result)
1551 int size, align, regno;
1552 enum machine_mode mode;
1553 rtx reg;
1554 rtx call_fusage = 0;
1556 result = convert_memory_address (Pmode, result);
1558 apply_result_size ();
1559 result = gen_rtx_MEM (BLKmode, result);
1561 #ifdef HAVE_untyped_return
1562 if (HAVE_untyped_return)
1564 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1565 emit_barrier ();
1566 return;
1568 #endif
1570 /* Restore the return value and note that each value is used. */
1571 size = 0;
1572 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1573 if ((mode = apply_result_mode[regno]) != VOIDmode)
1575 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1576 if (size % align != 0)
1577 size = CEIL (size, align) * align;
1578 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1579 emit_move_insn (reg, adjust_address (result, mode, size));
1581 push_to_sequence (call_fusage);
1582 emit_insn (gen_rtx_USE (VOIDmode, reg));
1583 call_fusage = get_insns ();
1584 end_sequence ();
1585 size += GET_MODE_SIZE (mode);
1588 /* Put the USE insns before the return. */
1589 emit_insn (call_fusage);
1591 /* Return whatever values was restored by jumping directly to the end
1592 of the function. */
1593 expand_naked_return ();
1596 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1598 static enum type_class
1599 type_to_class (tree type)
1601 switch (TREE_CODE (type))
1603 case VOID_TYPE: return void_type_class;
1604 case INTEGER_TYPE: return integer_type_class;
1605 case ENUMERAL_TYPE: return enumeral_type_class;
1606 case BOOLEAN_TYPE: return boolean_type_class;
1607 case POINTER_TYPE: return pointer_type_class;
1608 case REFERENCE_TYPE: return reference_type_class;
1609 case OFFSET_TYPE: return offset_type_class;
1610 case REAL_TYPE: return real_type_class;
1611 case COMPLEX_TYPE: return complex_type_class;
1612 case FUNCTION_TYPE: return function_type_class;
1613 case METHOD_TYPE: return method_type_class;
1614 case RECORD_TYPE: return record_type_class;
1615 case UNION_TYPE:
1616 case QUAL_UNION_TYPE: return union_type_class;
1617 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1618 ? string_type_class : array_type_class);
1619 case LANG_TYPE: return lang_type_class;
1620 default: return no_type_class;
1624 /* Expand a call to __builtin_classify_type with arguments found in
1625 ARGLIST. */
1627 static rtx
1628 expand_builtin_classify_type (tree arglist)
1630 if (arglist != 0)
1631 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1632 return GEN_INT (no_type_class);
1635 /* This helper macro, meant to be used in mathfn_built_in below,
1636 determines which among a set of three builtin math functions is
1637 appropriate for a given type mode. The `F' and `L' cases are
1638 automatically generated from the `double' case. */
1639 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1640 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1641 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1642 fcodel = BUILT_IN_MATHFN##L ; break;
1644 /* Return mathematic function equivalent to FN but operating directly
1645 on TYPE, if available. If we can't do the conversion, return zero. */
1646 tree
1647 mathfn_built_in (tree type, enum built_in_function fn)
1649 enum built_in_function fcode, fcodef, fcodel;
1651 switch (fn)
1653 CASE_MATHFN (BUILT_IN_ACOS)
1654 CASE_MATHFN (BUILT_IN_ACOSH)
1655 CASE_MATHFN (BUILT_IN_ASIN)
1656 CASE_MATHFN (BUILT_IN_ASINH)
1657 CASE_MATHFN (BUILT_IN_ATAN)
1658 CASE_MATHFN (BUILT_IN_ATAN2)
1659 CASE_MATHFN (BUILT_IN_ATANH)
1660 CASE_MATHFN (BUILT_IN_CBRT)
1661 CASE_MATHFN (BUILT_IN_CEIL)
1662 CASE_MATHFN (BUILT_IN_COPYSIGN)
1663 CASE_MATHFN (BUILT_IN_COS)
1664 CASE_MATHFN (BUILT_IN_COSH)
1665 CASE_MATHFN (BUILT_IN_DREM)
1666 CASE_MATHFN (BUILT_IN_ERF)
1667 CASE_MATHFN (BUILT_IN_ERFC)
1668 CASE_MATHFN (BUILT_IN_EXP)
1669 CASE_MATHFN (BUILT_IN_EXP10)
1670 CASE_MATHFN (BUILT_IN_EXP2)
1671 CASE_MATHFN (BUILT_IN_EXPM1)
1672 CASE_MATHFN (BUILT_IN_FABS)
1673 CASE_MATHFN (BUILT_IN_FDIM)
1674 CASE_MATHFN (BUILT_IN_FLOOR)
1675 CASE_MATHFN (BUILT_IN_FMA)
1676 CASE_MATHFN (BUILT_IN_FMAX)
1677 CASE_MATHFN (BUILT_IN_FMIN)
1678 CASE_MATHFN (BUILT_IN_FMOD)
1679 CASE_MATHFN (BUILT_IN_FREXP)
1680 CASE_MATHFN (BUILT_IN_GAMMA)
1681 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1682 CASE_MATHFN (BUILT_IN_HYPOT)
1683 CASE_MATHFN (BUILT_IN_ILOGB)
1684 CASE_MATHFN (BUILT_IN_INF)
1685 CASE_MATHFN (BUILT_IN_J0)
1686 CASE_MATHFN (BUILT_IN_J1)
1687 CASE_MATHFN (BUILT_IN_JN)
1688 CASE_MATHFN (BUILT_IN_LCEIL)
1689 CASE_MATHFN (BUILT_IN_LDEXP)
1690 CASE_MATHFN (BUILT_IN_LFLOOR)
1691 CASE_MATHFN (BUILT_IN_LGAMMA)
1692 CASE_MATHFN (BUILT_IN_LLCEIL)
1693 CASE_MATHFN (BUILT_IN_LLFLOOR)
1694 CASE_MATHFN (BUILT_IN_LLRINT)
1695 CASE_MATHFN (BUILT_IN_LLROUND)
1696 CASE_MATHFN (BUILT_IN_LOG)
1697 CASE_MATHFN (BUILT_IN_LOG10)
1698 CASE_MATHFN (BUILT_IN_LOG1P)
1699 CASE_MATHFN (BUILT_IN_LOG2)
1700 CASE_MATHFN (BUILT_IN_LOGB)
1701 CASE_MATHFN (BUILT_IN_LRINT)
1702 CASE_MATHFN (BUILT_IN_LROUND)
1703 CASE_MATHFN (BUILT_IN_MODF)
1704 CASE_MATHFN (BUILT_IN_NAN)
1705 CASE_MATHFN (BUILT_IN_NANS)
1706 CASE_MATHFN (BUILT_IN_NEARBYINT)
1707 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1708 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1709 CASE_MATHFN (BUILT_IN_POW)
1710 CASE_MATHFN (BUILT_IN_POWI)
1711 CASE_MATHFN (BUILT_IN_POW10)
1712 CASE_MATHFN (BUILT_IN_REMAINDER)
1713 CASE_MATHFN (BUILT_IN_REMQUO)
1714 CASE_MATHFN (BUILT_IN_RINT)
1715 CASE_MATHFN (BUILT_IN_ROUND)
1716 CASE_MATHFN (BUILT_IN_SCALB)
1717 CASE_MATHFN (BUILT_IN_SCALBLN)
1718 CASE_MATHFN (BUILT_IN_SCALBN)
1719 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1720 CASE_MATHFN (BUILT_IN_SIN)
1721 CASE_MATHFN (BUILT_IN_SINCOS)
1722 CASE_MATHFN (BUILT_IN_SINH)
1723 CASE_MATHFN (BUILT_IN_SQRT)
1724 CASE_MATHFN (BUILT_IN_TAN)
1725 CASE_MATHFN (BUILT_IN_TANH)
1726 CASE_MATHFN (BUILT_IN_TGAMMA)
1727 CASE_MATHFN (BUILT_IN_TRUNC)
1728 CASE_MATHFN (BUILT_IN_Y0)
1729 CASE_MATHFN (BUILT_IN_Y1)
1730 CASE_MATHFN (BUILT_IN_YN)
1732 default:
1733 return 0;
1736 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1737 return implicit_built_in_decls[fcode];
1738 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1739 return implicit_built_in_decls[fcodef];
1740 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1741 return implicit_built_in_decls[fcodel];
1742 else
1743 return 0;
1746 /* If errno must be maintained, expand the RTL to check if the result,
1747 TARGET, of a built-in function call, EXP, is NaN, and if so set
1748 errno to EDOM. */
1750 static void
1751 expand_errno_check (tree exp, rtx target)
1753 rtx lab = gen_label_rtx ();
1755 /* Test the result; if it is NaN, set errno=EDOM because
1756 the argument was not in the domain. */
1757 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1758 0, lab);
1760 #ifdef TARGET_EDOM
1761 /* If this built-in doesn't throw an exception, set errno directly. */
1762 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1764 #ifdef GEN_ERRNO_RTX
1765 rtx errno_rtx = GEN_ERRNO_RTX;
1766 #else
1767 rtx errno_rtx
1768 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1769 #endif
1770 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1771 emit_label (lab);
1772 return;
1774 #endif
1776 /* We can't set errno=EDOM directly; let the library call do it.
1777 Pop the arguments right away in case the call gets deleted. */
1778 NO_DEFER_POP;
1779 expand_call (exp, target, 0);
1780 OK_DEFER_POP;
1781 emit_label (lab);
1785 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1786 Return 0 if a normal call should be emitted rather than expanding the
1787 function in-line. EXP is the expression that is a call to the builtin
1788 function; if convenient, the result should be placed in TARGET.
1789 SUBTARGET may be used as the target for computing one of EXP's operands. */
1791 static rtx
1792 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1794 optab builtin_optab;
1795 rtx op0, insns, before_call;
1796 tree fndecl = get_callee_fndecl (exp);
1797 tree arglist = TREE_OPERAND (exp, 1);
1798 enum machine_mode mode;
1799 bool errno_set = false;
1800 tree arg, narg;
1802 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1803 return 0;
1805 arg = TREE_VALUE (arglist);
1807 switch (DECL_FUNCTION_CODE (fndecl))
1809 CASE_FLT_FN (BUILT_IN_SQRT):
1810 errno_set = ! tree_expr_nonnegative_p (arg);
1811 builtin_optab = sqrt_optab;
1812 break;
1813 CASE_FLT_FN (BUILT_IN_EXP):
1814 errno_set = true; builtin_optab = exp_optab; break;
1815 CASE_FLT_FN (BUILT_IN_EXP10):
1816 CASE_FLT_FN (BUILT_IN_POW10):
1817 errno_set = true; builtin_optab = exp10_optab; break;
1818 CASE_FLT_FN (BUILT_IN_EXP2):
1819 errno_set = true; builtin_optab = exp2_optab; break;
1820 CASE_FLT_FN (BUILT_IN_EXPM1):
1821 errno_set = true; builtin_optab = expm1_optab; break;
1822 CASE_FLT_FN (BUILT_IN_LOGB):
1823 errno_set = true; builtin_optab = logb_optab; break;
1824 CASE_FLT_FN (BUILT_IN_ILOGB):
1825 errno_set = true; builtin_optab = ilogb_optab; break;
1826 CASE_FLT_FN (BUILT_IN_LOG):
1827 errno_set = true; builtin_optab = log_optab; break;
1828 CASE_FLT_FN (BUILT_IN_LOG10):
1829 errno_set = true; builtin_optab = log10_optab; break;
1830 CASE_FLT_FN (BUILT_IN_LOG2):
1831 errno_set = true; builtin_optab = log2_optab; break;
1832 CASE_FLT_FN (BUILT_IN_LOG1P):
1833 errno_set = true; builtin_optab = log1p_optab; break;
1834 CASE_FLT_FN (BUILT_IN_ASIN):
1835 builtin_optab = asin_optab; break;
1836 CASE_FLT_FN (BUILT_IN_ACOS):
1837 builtin_optab = acos_optab; break;
1838 CASE_FLT_FN (BUILT_IN_TAN):
1839 builtin_optab = tan_optab; break;
1840 CASE_FLT_FN (BUILT_IN_ATAN):
1841 builtin_optab = atan_optab; break;
1842 CASE_FLT_FN (BUILT_IN_FLOOR):
1843 builtin_optab = floor_optab; break;
1844 CASE_FLT_FN (BUILT_IN_CEIL):
1845 builtin_optab = ceil_optab; break;
1846 CASE_FLT_FN (BUILT_IN_TRUNC):
1847 builtin_optab = btrunc_optab; break;
1848 CASE_FLT_FN (BUILT_IN_ROUND):
1849 builtin_optab = round_optab; break;
1850 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1851 builtin_optab = nearbyint_optab; break;
1852 CASE_FLT_FN (BUILT_IN_RINT):
1853 builtin_optab = rint_optab; break;
1854 CASE_FLT_FN (BUILT_IN_LRINT):
1855 CASE_FLT_FN (BUILT_IN_LLRINT):
1856 builtin_optab = lrint_optab; break;
1857 default:
1858 gcc_unreachable ();
1861 /* Make a suitable register to place result in. */
1862 mode = TYPE_MODE (TREE_TYPE (exp));
1864 if (! flag_errno_math || ! HONOR_NANS (mode))
1865 errno_set = false;
1867 /* Before working hard, check whether the instruction is available. */
1868 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1870 target = gen_reg_rtx (mode);
1872 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1873 need to expand the argument again. This way, we will not perform
1874 side-effects more the once. */
1875 narg = builtin_save_expr (arg);
1876 if (narg != arg)
1878 arg = narg;
1879 arglist = build_tree_list (NULL_TREE, arg);
1880 exp = build_function_call_expr (fndecl, arglist);
1883 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1885 start_sequence ();
1887 /* Compute into TARGET.
1888 Set TARGET to wherever the result comes back. */
1889 target = expand_unop (mode, builtin_optab, op0, target, 0);
1891 if (target != 0)
1893 if (errno_set)
1894 expand_errno_check (exp, target);
1896 /* Output the entire sequence. */
1897 insns = get_insns ();
1898 end_sequence ();
1899 emit_insn (insns);
1900 return target;
1903 /* If we were unable to expand via the builtin, stop the sequence
1904 (without outputting the insns) and call to the library function
1905 with the stabilized argument list. */
1906 end_sequence ();
1909 before_call = get_last_insn ();
1911 target = expand_call (exp, target, target == const0_rtx);
1913 /* If this is a sqrt operation and we don't care about errno, try to
1914 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1915 This allows the semantics of the libcall to be visible to the RTL
1916 optimizers. */
1917 if (builtin_optab == sqrt_optab && !errno_set)
1919 /* Search backwards through the insns emitted by expand_call looking
1920 for the instruction with the REG_RETVAL note. */
1921 rtx last = get_last_insn ();
1922 while (last != before_call)
1924 if (find_reg_note (last, REG_RETVAL, NULL))
1926 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1927 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1928 two elements, i.e. symbol_ref(sqrt) and the operand. */
1929 if (note
1930 && GET_CODE (note) == EXPR_LIST
1931 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1932 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1933 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1935 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1936 /* Check operand is a register with expected mode. */
1937 if (operand
1938 && REG_P (operand)
1939 && GET_MODE (operand) == mode)
1941 /* Replace the REG_EQUAL note with a SQRT rtx. */
1942 rtx equiv = gen_rtx_SQRT (mode, operand);
1943 set_unique_reg_note (last, REG_EQUAL, equiv);
1946 break;
1948 last = PREV_INSN (last);
1952 return target;
1955 /* Expand a call to the builtin binary math functions (pow and atan2).
1956 Return 0 if a normal call should be emitted rather than expanding the
1957 function in-line. EXP is the expression that is a call to the builtin
1958 function; if convenient, the result should be placed in TARGET.
1959 SUBTARGET may be used as the target for computing one of EXP's
1960 operands. */
1962 static rtx
1963 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1965 optab builtin_optab;
1966 rtx op0, op1, insns;
1967 int op1_type = REAL_TYPE;
1968 tree fndecl = get_callee_fndecl (exp);
1969 tree arglist = TREE_OPERAND (exp, 1);
1970 tree arg0, arg1, temp, narg;
1971 enum machine_mode mode;
1972 bool errno_set = true;
1973 bool stable = true;
1975 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1976 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1977 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1978 op1_type = INTEGER_TYPE;
1980 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1981 return 0;
1983 arg0 = TREE_VALUE (arglist);
1984 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1986 switch (DECL_FUNCTION_CODE (fndecl))
1988 CASE_FLT_FN (BUILT_IN_POW):
1989 builtin_optab = pow_optab; break;
1990 CASE_FLT_FN (BUILT_IN_ATAN2):
1991 builtin_optab = atan2_optab; break;
1992 CASE_FLT_FN (BUILT_IN_LDEXP):
1993 builtin_optab = ldexp_optab; break;
1994 CASE_FLT_FN (BUILT_IN_FMOD):
1995 builtin_optab = fmod_optab; break;
1996 CASE_FLT_FN (BUILT_IN_DREM):
1997 builtin_optab = drem_optab; break;
1998 default:
1999 gcc_unreachable ();
2002 /* Make a suitable register to place result in. */
2003 mode = TYPE_MODE (TREE_TYPE (exp));
2005 /* Before working hard, check whether the instruction is available. */
2006 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2007 return 0;
2009 target = gen_reg_rtx (mode);
2011 if (! flag_errno_math || ! HONOR_NANS (mode))
2012 errno_set = false;
2014 /* Always stabilize the argument list. */
2015 narg = builtin_save_expr (arg1);
2016 if (narg != arg1)
2018 arg1 = narg;
2019 temp = build_tree_list (NULL_TREE, narg);
2020 stable = false;
2022 else
2023 temp = TREE_CHAIN (arglist);
2025 narg = builtin_save_expr (arg0);
2026 if (narg != arg0)
2028 arg0 = narg;
2029 arglist = tree_cons (NULL_TREE, narg, temp);
2030 stable = false;
2032 else if (! stable)
2033 arglist = tree_cons (NULL_TREE, arg0, temp);
2035 if (! stable)
2036 exp = build_function_call_expr (fndecl, arglist);
2038 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2039 op1 = expand_normal (arg1);
2041 start_sequence ();
2043 /* Compute into TARGET.
2044 Set TARGET to wherever the result comes back. */
2045 target = expand_binop (mode, builtin_optab, op0, op1,
2046 target, 0, OPTAB_DIRECT);
2048 /* If we were unable to expand via the builtin, stop the sequence
2049 (without outputting the insns) and call to the library function
2050 with the stabilized argument list. */
2051 if (target == 0)
2053 end_sequence ();
2054 return expand_call (exp, target, target == const0_rtx);
2057 if (errno_set)
2058 expand_errno_check (exp, target);
2060 /* Output the entire sequence. */
2061 insns = get_insns ();
2062 end_sequence ();
2063 emit_insn (insns);
2065 return target;
2068 /* Expand a call to the builtin sin and cos math functions.
2069 Return 0 if a normal call should be emitted rather than expanding the
2070 function in-line. EXP is the expression that is a call to the builtin
2071 function; if convenient, the result should be placed in TARGET.
2072 SUBTARGET may be used as the target for computing one of EXP's
2073 operands. */
2075 static rtx
2076 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2078 optab builtin_optab;
2079 rtx op0, insns;
2080 tree fndecl = get_callee_fndecl (exp);
2081 tree arglist = TREE_OPERAND (exp, 1);
2082 enum machine_mode mode;
2083 tree arg, narg;
2085 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2086 return 0;
2088 arg = TREE_VALUE (arglist);
2090 switch (DECL_FUNCTION_CODE (fndecl))
2092 CASE_FLT_FN (BUILT_IN_SIN):
2093 CASE_FLT_FN (BUILT_IN_COS):
2094 builtin_optab = sincos_optab; break;
2095 default:
2096 gcc_unreachable ();
2099 /* Make a suitable register to place result in. */
2100 mode = TYPE_MODE (TREE_TYPE (exp));
2102 /* Check if sincos insn is available, otherwise fallback
2103 to sin or cos insn. */
2104 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2105 switch (DECL_FUNCTION_CODE (fndecl))
2107 CASE_FLT_FN (BUILT_IN_SIN):
2108 builtin_optab = sin_optab; break;
2109 CASE_FLT_FN (BUILT_IN_COS):
2110 builtin_optab = cos_optab; break;
2111 default:
2112 gcc_unreachable ();
2116 /* Before working hard, check whether the instruction is available. */
2117 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2119 target = gen_reg_rtx (mode);
2121 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2122 need to expand the argument again. This way, we will not perform
2123 side-effects more the once. */
2124 narg = save_expr (arg);
2125 if (narg != arg)
2127 arg = narg;
2128 arglist = build_tree_list (NULL_TREE, arg);
2129 exp = build_function_call_expr (fndecl, arglist);
2132 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2134 start_sequence ();
2136 /* Compute into TARGET.
2137 Set TARGET to wherever the result comes back. */
2138 if (builtin_optab == sincos_optab)
2140 int result;
2142 switch (DECL_FUNCTION_CODE (fndecl))
2144 CASE_FLT_FN (BUILT_IN_SIN):
2145 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2146 break;
2147 CASE_FLT_FN (BUILT_IN_COS):
2148 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2149 break;
2150 default:
2151 gcc_unreachable ();
2153 gcc_assert (result);
2155 else
2157 target = expand_unop (mode, builtin_optab, op0, target, 0);
2160 if (target != 0)
2162 /* Output the entire sequence. */
2163 insns = get_insns ();
2164 end_sequence ();
2165 emit_insn (insns);
2166 return target;
2169 /* If we were unable to expand via the builtin, stop the sequence
2170 (without outputting the insns) and call to the library function
2171 with the stabilized argument list. */
2172 end_sequence ();
2175 target = expand_call (exp, target, target == const0_rtx);
2177 return target;
2180 /* Expand a call to the builtin sincos math function.
2181 Return 0 if a normal call should be emitted rather than expanding the
2182 function in-line. EXP is the expression that is a call to the builtin
2183 function. */
2185 static rtx
2186 expand_builtin_sincos (tree exp)
2188 rtx op0, op1, op2, target1, target2;
2189 tree arglist = TREE_OPERAND (exp, 1);
2190 enum machine_mode mode;
2191 tree arg, sinp, cosp;
2192 int result;
2194 if (!validate_arglist (arglist, REAL_TYPE,
2195 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2196 return 0;
2198 arg = TREE_VALUE (arglist);
2199 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2200 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2202 /* Make a suitable register to place result in. */
2203 mode = TYPE_MODE (TREE_TYPE (arg));
2205 /* Check if sincos insn is available, otherwise emit the call. */
2206 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2207 return NULL_RTX;
2209 target1 = gen_reg_rtx (mode);
2210 target2 = gen_reg_rtx (mode);
2212 op0 = expand_normal (arg);
2213 op1 = expand_normal (build_fold_indirect_ref (sinp));
2214 op2 = expand_normal (build_fold_indirect_ref (cosp));
2216 /* Compute into target1 and target2.
2217 Set TARGET to wherever the result comes back. */
2218 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2219 gcc_assert (result);
2221 /* Move target1 and target2 to the memory locations indicated
2222 by op1 and op2. */
2223 emit_move_insn (op1, target1);
2224 emit_move_insn (op2, target2);
2226 return const0_rtx;
2229 /* Expand a call to one of the builtin rounding functions (lfloor).
2230 If expanding via optab fails, lower expression to (int)(floor(x)).
2231 EXP is the expression that is a call to the builtin function;
2232 if convenient, the result should be placed in TARGET. SUBTARGET may
2233 be used as the target for computing one of EXP's operands. */
2235 static rtx
2236 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2238 optab builtin_optab;
2239 rtx op0, insns, tmp;
2240 tree fndecl = get_callee_fndecl (exp);
2241 tree arglist = TREE_OPERAND (exp, 1);
2242 enum built_in_function fallback_fn;
2243 tree fallback_fndecl;
2244 enum machine_mode mode;
2245 tree arg, narg;
2247 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2248 gcc_unreachable ();
2250 arg = TREE_VALUE (arglist);
2252 switch (DECL_FUNCTION_CODE (fndecl))
2254 CASE_FLT_FN (BUILT_IN_LCEIL):
2255 CASE_FLT_FN (BUILT_IN_LLCEIL):
2256 builtin_optab = lceil_optab;
2257 fallback_fn = BUILT_IN_CEIL;
2258 break;
2260 CASE_FLT_FN (BUILT_IN_LFLOOR):
2261 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2262 builtin_optab = lfloor_optab;
2263 fallback_fn = BUILT_IN_FLOOR;
2264 break;
2266 default:
2267 gcc_unreachable ();
2270 /* Make a suitable register to place result in. */
2271 mode = TYPE_MODE (TREE_TYPE (exp));
2273 /* Before working hard, check whether the instruction is available. */
2274 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2276 target = gen_reg_rtx (mode);
2278 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2279 need to expand the argument again. This way, we will not perform
2280 side-effects more the once. */
2281 narg = builtin_save_expr (arg);
2282 if (narg != arg)
2284 arg = narg;
2285 arglist = build_tree_list (NULL_TREE, arg);
2286 exp = build_function_call_expr (fndecl, arglist);
2289 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2291 start_sequence ();
2293 /* Compute into TARGET.
2294 Set TARGET to wherever the result comes back. */
2295 target = expand_unop (mode, builtin_optab, op0, target, 0);
2297 if (target != 0)
2299 /* Output the entire sequence. */
2300 insns = get_insns ();
2301 end_sequence ();
2302 emit_insn (insns);
2303 return target;
2306 /* If we were unable to expand via the builtin, stop the sequence
2307 (without outputting the insns). */
2308 end_sequence ();
2311 /* Fall back to floating point rounding optab. */
2312 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2313 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2314 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2315 gcc_assert (fallback_fndecl != NULL_TREE);
2316 exp = build_function_call_expr (fallback_fndecl, arglist);
2318 tmp = expand_normal (exp);
2320 /* Truncate the result of floating point optab to integer
2321 via expand_fix (). */
2322 target = gen_reg_rtx (mode);
2323 expand_fix (target, tmp, 0);
2325 return target;
2328 /* To evaluate powi(x,n), the floating point value x raised to the
2329 constant integer exponent n, we use a hybrid algorithm that
2330 combines the "window method" with look-up tables. For an
2331 introduction to exponentiation algorithms and "addition chains",
2332 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2333 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2334 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2335 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2337 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2338 multiplications to inline before calling the system library's pow
2339 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2340 so this default never requires calling pow, powf or powl. */
2342 #ifndef POWI_MAX_MULTS
2343 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2344 #endif
2346 /* The size of the "optimal power tree" lookup table. All
2347 exponents less than this value are simply looked up in the
2348 powi_table below. This threshold is also used to size the
2349 cache of pseudo registers that hold intermediate results. */
2350 #define POWI_TABLE_SIZE 256
2352 /* The size, in bits of the window, used in the "window method"
2353 exponentiation algorithm. This is equivalent to a radix of
2354 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2355 #define POWI_WINDOW_SIZE 3
2357 /* The following table is an efficient representation of an
2358 "optimal power tree". For each value, i, the corresponding
2359 value, j, in the table states than an optimal evaluation
2360 sequence for calculating pow(x,i) can be found by evaluating
2361 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2362 100 integers is given in Knuth's "Seminumerical algorithms". */
2364 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2366 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2367 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2368 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2369 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2370 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2371 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2372 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2373 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2374 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2375 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2376 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2377 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2378 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2379 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2380 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2381 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2382 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2383 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2384 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2385 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2386 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2387 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2388 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2389 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2390 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2391 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2392 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2393 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2394 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2395 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2396 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2397 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2401 /* Return the number of multiplications required to calculate
2402 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2403 subroutine of powi_cost. CACHE is an array indicating
2404 which exponents have already been calculated. */
2406 static int
2407 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2409 /* If we've already calculated this exponent, then this evaluation
2410 doesn't require any additional multiplications. */
2411 if (cache[n])
2412 return 0;
2414 cache[n] = true;
2415 return powi_lookup_cost (n - powi_table[n], cache)
2416 + powi_lookup_cost (powi_table[n], cache) + 1;
2419 /* Return the number of multiplications required to calculate
2420 powi(x,n) for an arbitrary x, given the exponent N. This
2421 function needs to be kept in sync with expand_powi below. */
2423 static int
2424 powi_cost (HOST_WIDE_INT n)
2426 bool cache[POWI_TABLE_SIZE];
2427 unsigned HOST_WIDE_INT digit;
2428 unsigned HOST_WIDE_INT val;
2429 int result;
2431 if (n == 0)
2432 return 0;
2434 /* Ignore the reciprocal when calculating the cost. */
2435 val = (n < 0) ? -n : n;
2437 /* Initialize the exponent cache. */
2438 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2439 cache[1] = true;
2441 result = 0;
2443 while (val >= POWI_TABLE_SIZE)
2445 if (val & 1)
2447 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2448 result += powi_lookup_cost (digit, cache)
2449 + POWI_WINDOW_SIZE + 1;
2450 val >>= POWI_WINDOW_SIZE;
2452 else
2454 val >>= 1;
2455 result++;
2459 return result + powi_lookup_cost (val, cache);
2462 /* Recursive subroutine of expand_powi. This function takes the array,
2463 CACHE, of already calculated exponents and an exponent N and returns
2464 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2466 static rtx
2467 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2469 unsigned HOST_WIDE_INT digit;
2470 rtx target, result;
2471 rtx op0, op1;
2473 if (n < POWI_TABLE_SIZE)
2475 if (cache[n])
2476 return cache[n];
2478 target = gen_reg_rtx (mode);
2479 cache[n] = target;
2481 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2482 op1 = expand_powi_1 (mode, powi_table[n], cache);
2484 else if (n & 1)
2486 target = gen_reg_rtx (mode);
2487 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2488 op0 = expand_powi_1 (mode, n - digit, cache);
2489 op1 = expand_powi_1 (mode, digit, cache);
2491 else
2493 target = gen_reg_rtx (mode);
2494 op0 = expand_powi_1 (mode, n >> 1, cache);
2495 op1 = op0;
2498 result = expand_mult (mode, op0, op1, target, 0);
2499 if (result != target)
2500 emit_move_insn (target, result);
2501 return target;
2504 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2505 floating point operand in mode MODE, and N is the exponent. This
2506 function needs to be kept in sync with powi_cost above. */
2508 static rtx
2509 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2511 unsigned HOST_WIDE_INT val;
2512 rtx cache[POWI_TABLE_SIZE];
2513 rtx result;
2515 if (n == 0)
2516 return CONST1_RTX (mode);
2518 val = (n < 0) ? -n : n;
2520 memset (cache, 0, sizeof (cache));
2521 cache[1] = x;
2523 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2525 /* If the original exponent was negative, reciprocate the result. */
2526 if (n < 0)
2527 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2528 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2530 return result;
2533 /* Expand a call to the pow built-in mathematical function. Return 0 if
2534 a normal call should be emitted rather than expanding the function
2535 in-line. EXP is the expression that is a call to the builtin
2536 function; if convenient, the result should be placed in TARGET. */
2538 static rtx
2539 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2541 tree arglist = TREE_OPERAND (exp, 1);
2542 tree arg0, arg1;
2544 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2545 return 0;
2547 arg0 = TREE_VALUE (arglist);
2548 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2550 if (TREE_CODE (arg1) == REAL_CST
2551 && ! TREE_CONSTANT_OVERFLOW (arg1))
2553 REAL_VALUE_TYPE cint;
2554 REAL_VALUE_TYPE c;
2555 HOST_WIDE_INT n;
2557 c = TREE_REAL_CST (arg1);
2558 n = real_to_integer (&c);
2559 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2560 if (real_identical (&c, &cint))
2562 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2563 Otherwise, check the number of multiplications required.
2564 Note that pow never sets errno for an integer exponent. */
2565 if ((n >= -1 && n <= 2)
2566 || (flag_unsafe_math_optimizations
2567 && ! optimize_size
2568 && powi_cost (n) <= POWI_MAX_MULTS))
2570 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2571 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2572 op = force_reg (mode, op);
2573 return expand_powi (op, mode, n);
2578 if (! flag_unsafe_math_optimizations)
2579 return NULL_RTX;
2580 return expand_builtin_mathfn_2 (exp, target, subtarget);
2583 /* Expand a call to the powi built-in mathematical function. Return 0 if
2584 a normal call should be emitted rather than expanding the function
2585 in-line. EXP is the expression that is a call to the builtin
2586 function; if convenient, the result should be placed in TARGET. */
2588 static rtx
2589 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2591 tree arglist = TREE_OPERAND (exp, 1);
2592 tree arg0, arg1;
2593 rtx op0, op1;
2594 enum machine_mode mode;
2595 enum machine_mode mode2;
2597 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2598 return 0;
2600 arg0 = TREE_VALUE (arglist);
2601 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2602 mode = TYPE_MODE (TREE_TYPE (exp));
2604 /* Handle constant power. */
2606 if (TREE_CODE (arg1) == INTEGER_CST
2607 && ! TREE_CONSTANT_OVERFLOW (arg1))
2609 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2611 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2612 Otherwise, check the number of multiplications required. */
2613 if ((TREE_INT_CST_HIGH (arg1) == 0
2614 || TREE_INT_CST_HIGH (arg1) == -1)
2615 && ((n >= -1 && n <= 2)
2616 || (! optimize_size
2617 && powi_cost (n) <= POWI_MAX_MULTS)))
2619 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2620 op0 = force_reg (mode, op0);
2621 return expand_powi (op0, mode, n);
2625 /* Emit a libcall to libgcc. */
2627 /* Mode of the 2nd argument must match that of an int. */
2628 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2630 if (target == NULL_RTX)
2631 target = gen_reg_rtx (mode);
2633 op0 = expand_expr (arg0, subtarget, mode, 0);
2634 if (GET_MODE (op0) != mode)
2635 op0 = convert_to_mode (mode, op0, 0);
2636 op1 = expand_expr (arg1, 0, mode2, 0);
2637 if (GET_MODE (op1) != mode2)
2638 op1 = convert_to_mode (mode2, op1, 0);
2640 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2641 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2642 op0, mode, op1, mode2);
2644 return target;
2647 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2648 if we failed the caller should emit a normal call, otherwise
2649 try to get the result in TARGET, if convenient. */
2651 static rtx
2652 expand_builtin_strlen (tree arglist, rtx target,
2653 enum machine_mode target_mode)
2655 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2656 return 0;
2657 else
2659 rtx pat;
2660 tree len, src = TREE_VALUE (arglist);
2661 rtx result, src_reg, char_rtx, before_strlen;
2662 enum machine_mode insn_mode = target_mode, char_mode;
2663 enum insn_code icode = CODE_FOR_nothing;
2664 int align;
2666 /* If the length can be computed at compile-time, return it. */
2667 len = c_strlen (src, 0);
2668 if (len)
2669 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2671 /* If the length can be computed at compile-time and is constant
2672 integer, but there are side-effects in src, evaluate
2673 src for side-effects, then return len.
2674 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2675 can be optimized into: i++; x = 3; */
2676 len = c_strlen (src, 1);
2677 if (len && TREE_CODE (len) == INTEGER_CST)
2679 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2680 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2683 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2685 /* If SRC is not a pointer type, don't do this operation inline. */
2686 if (align == 0)
2687 return 0;
2689 /* Bail out if we can't compute strlen in the right mode. */
2690 while (insn_mode != VOIDmode)
2692 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2693 if (icode != CODE_FOR_nothing)
2694 break;
2696 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2698 if (insn_mode == VOIDmode)
2699 return 0;
2701 /* Make a place to write the result of the instruction. */
2702 result = target;
2703 if (! (result != 0
2704 && REG_P (result)
2705 && GET_MODE (result) == insn_mode
2706 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2707 result = gen_reg_rtx (insn_mode);
2709 /* Make a place to hold the source address. We will not expand
2710 the actual source until we are sure that the expansion will
2711 not fail -- there are trees that cannot be expanded twice. */
2712 src_reg = gen_reg_rtx (Pmode);
2714 /* Mark the beginning of the strlen sequence so we can emit the
2715 source operand later. */
2716 before_strlen = get_last_insn ();
2718 char_rtx = const0_rtx;
2719 char_mode = insn_data[(int) icode].operand[2].mode;
2720 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2721 char_mode))
2722 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2724 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2725 char_rtx, GEN_INT (align));
2726 if (! pat)
2727 return 0;
2728 emit_insn (pat);
2730 /* Now that we are assured of success, expand the source. */
2731 start_sequence ();
2732 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2733 if (pat != src_reg)
2734 emit_move_insn (src_reg, pat);
2735 pat = get_insns ();
2736 end_sequence ();
2738 if (before_strlen)
2739 emit_insn_after (pat, before_strlen);
2740 else
2741 emit_insn_before (pat, get_insns ());
2743 /* Return the value in the proper mode for this function. */
2744 if (GET_MODE (result) == target_mode)
2745 target = result;
2746 else if (target != 0)
2747 convert_move (target, result, 0);
2748 else
2749 target = convert_to_mode (target_mode, result, 0);
2751 return target;
2755 /* Expand a call to the strstr builtin. Return 0 if we failed the
2756 caller should emit a normal call, otherwise try to get the result
2757 in TARGET, if convenient (and in mode MODE if that's convenient). */
2759 static rtx
2760 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2762 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2764 tree result = fold_builtin_strstr (arglist, type);
2765 if (result)
2766 return expand_expr (result, target, mode, EXPAND_NORMAL);
2768 return 0;
2771 /* Expand a call to the strchr builtin. Return 0 if we failed the
2772 caller should emit a normal call, otherwise try to get the result
2773 in TARGET, if convenient (and in mode MODE if that's convenient). */
2775 static rtx
2776 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2778 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2780 tree result = fold_builtin_strchr (arglist, type);
2781 if (result)
2782 return expand_expr (result, target, mode, EXPAND_NORMAL);
2784 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2786 return 0;
2789 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2790 caller should emit a normal call, otherwise try to get the result
2791 in TARGET, if convenient (and in mode MODE if that's convenient). */
2793 static rtx
2794 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2796 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2798 tree result = fold_builtin_strrchr (arglist, type);
2799 if (result)
2800 return expand_expr (result, target, mode, EXPAND_NORMAL);
2802 return 0;
2805 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2806 caller should emit a normal call, otherwise try to get the result
2807 in TARGET, if convenient (and in mode MODE if that's convenient). */
2809 static rtx
2810 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2812 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2814 tree result = fold_builtin_strpbrk (arglist, type);
2815 if (result)
2816 return expand_expr (result, target, mode, EXPAND_NORMAL);
2818 return 0;
2821 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2822 bytes from constant string DATA + OFFSET and return it as target
2823 constant. */
2825 static rtx
2826 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2827 enum machine_mode mode)
2829 const char *str = (const char *) data;
2831 gcc_assert (offset >= 0
2832 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2833 <= strlen (str) + 1));
2835 return c_readstr (str + offset, mode);
2838 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2839 Return 0 if we failed, the caller should emit a normal call,
2840 otherwise try to get the result in TARGET, if convenient (and in
2841 mode MODE if that's convenient). */
2842 static rtx
2843 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2845 tree fndecl = get_callee_fndecl (exp);
2846 tree arglist = TREE_OPERAND (exp, 1);
2847 if (!validate_arglist (arglist,
2848 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2849 return 0;
2850 else
2852 tree dest = TREE_VALUE (arglist);
2853 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2854 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2855 const char *src_str;
2856 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2857 unsigned int dest_align
2858 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2859 rtx dest_mem, src_mem, dest_addr, len_rtx;
2860 tree result = fold_builtin_memcpy (fndecl, arglist);
2862 if (result)
2863 return expand_expr (result, target, mode, EXPAND_NORMAL);
2865 /* If DEST is not a pointer type, call the normal function. */
2866 if (dest_align == 0)
2867 return 0;
2869 /* If either SRC is not a pointer type, don't do this
2870 operation in-line. */
2871 if (src_align == 0)
2872 return 0;
2874 dest_mem = get_memory_rtx (dest, len);
2875 set_mem_align (dest_mem, dest_align);
2876 len_rtx = expand_normal (len);
2877 src_str = c_getstr (src);
2879 /* If SRC is a string constant and block move would be done
2880 by pieces, we can avoid loading the string from memory
2881 and only stored the computed constants. */
2882 if (src_str
2883 && GET_CODE (len_rtx) == CONST_INT
2884 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2885 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2886 (void *) src_str, dest_align))
2888 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2889 builtin_memcpy_read_str,
2890 (void *) src_str, dest_align, 0);
2891 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2892 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2893 return dest_mem;
2896 src_mem = get_memory_rtx (src, len);
2897 set_mem_align (src_mem, src_align);
2899 /* Copy word part most expediently. */
2900 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2901 CALL_EXPR_TAILCALL (exp)
2902 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2904 if (dest_addr == 0)
2906 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2907 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2909 return dest_addr;
2913 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2914 Return 0 if we failed; the caller should emit a normal call,
2915 otherwise try to get the result in TARGET, if convenient (and in
2916 mode MODE if that's convenient). If ENDP is 0 return the
2917 destination pointer, if ENDP is 1 return the end pointer ala
2918 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2919 stpcpy. */
2921 static rtx
2922 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2923 int endp)
2925 if (!validate_arglist (arglist,
2926 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2927 return 0;
2928 /* If return value is ignored, transform mempcpy into memcpy. */
2929 else if (target == const0_rtx)
2931 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2933 if (!fn)
2934 return 0;
2936 return expand_expr (build_function_call_expr (fn, arglist),
2937 target, mode, EXPAND_NORMAL);
2939 else
2941 tree dest = TREE_VALUE (arglist);
2942 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2943 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2944 const char *src_str;
2945 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2946 unsigned int dest_align
2947 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2948 rtx dest_mem, src_mem, len_rtx;
2949 tree result = fold_builtin_mempcpy (arglist, type, endp);
2951 if (result)
2952 return expand_expr (result, target, mode, EXPAND_NORMAL);
2954 /* If either SRC or DEST is not a pointer type, don't do this
2955 operation in-line. */
2956 if (dest_align == 0 || src_align == 0)
2957 return 0;
2959 /* If LEN is not constant, call the normal function. */
2960 if (! host_integerp (len, 1))
2961 return 0;
2963 len_rtx = expand_normal (len);
2964 src_str = c_getstr (src);
2966 /* If SRC is a string constant and block move would be done
2967 by pieces, we can avoid loading the string from memory
2968 and only stored the computed constants. */
2969 if (src_str
2970 && GET_CODE (len_rtx) == CONST_INT
2971 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2972 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2973 (void *) src_str, dest_align))
2975 dest_mem = get_memory_rtx (dest, len);
2976 set_mem_align (dest_mem, dest_align);
2977 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2978 builtin_memcpy_read_str,
2979 (void *) src_str, dest_align, endp);
2980 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2981 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2982 return dest_mem;
2985 if (GET_CODE (len_rtx) == CONST_INT
2986 && can_move_by_pieces (INTVAL (len_rtx),
2987 MIN (dest_align, src_align)))
2989 dest_mem = get_memory_rtx (dest, len);
2990 set_mem_align (dest_mem, dest_align);
2991 src_mem = get_memory_rtx (src, len);
2992 set_mem_align (src_mem, src_align);
2993 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2994 MIN (dest_align, src_align), endp);
2995 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2996 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2997 return dest_mem;
3000 return 0;
3004 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3005 if we failed; the caller should emit a normal call. */
3007 static rtx
3008 expand_builtin_memmove (tree arglist, tree type, rtx target,
3009 enum machine_mode mode, tree orig_exp)
3011 if (!validate_arglist (arglist,
3012 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3013 return 0;
3014 else
3016 tree dest = TREE_VALUE (arglist);
3017 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3018 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3020 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3021 unsigned int dest_align
3022 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3023 tree result = fold_builtin_memmove (arglist, type);
3025 if (result)
3026 return expand_expr (result, target, mode, EXPAND_NORMAL);
3028 /* If DEST is not a pointer type, call the normal function. */
3029 if (dest_align == 0)
3030 return 0;
3032 /* If either SRC is not a pointer type, don't do this
3033 operation in-line. */
3034 if (src_align == 0)
3035 return 0;
3037 /* If src is categorized for a readonly section we can use
3038 normal memcpy. */
3039 if (readonly_data_expr (src))
3041 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3042 if (!fn)
3043 return 0;
3044 fn = build_function_call_expr (fn, arglist);
3045 if (TREE_CODE (fn) == CALL_EXPR)
3046 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3047 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3050 /* If length is 1 and we can expand memcpy call inline,
3051 it is ok to use memcpy as well. */
3052 if (integer_onep (len))
3054 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3055 /*endp=*/0);
3056 if (ret)
3057 return ret;
3060 /* Otherwise, call the normal function. */
3061 return 0;
3065 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3066 if we failed the caller should emit a normal call. */
3068 static rtx
3069 expand_builtin_bcopy (tree exp)
3071 tree arglist = TREE_OPERAND (exp, 1);
3072 tree type = TREE_TYPE (exp);
3073 tree src, dest, size, newarglist;
3075 if (!validate_arglist (arglist,
3076 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3077 return NULL_RTX;
3079 src = TREE_VALUE (arglist);
3080 dest = TREE_VALUE (TREE_CHAIN (arglist));
3081 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3083 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3084 memmove(ptr y, ptr x, size_t z). This is done this way
3085 so that if it isn't expanded inline, we fallback to
3086 calling bcopy instead of memmove. */
3088 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3089 newarglist = tree_cons (NULL_TREE, src, newarglist);
3090 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3092 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3095 #ifndef HAVE_movstr
3096 # define HAVE_movstr 0
3097 # define CODE_FOR_movstr CODE_FOR_nothing
3098 #endif
3100 /* Expand into a movstr instruction, if one is available. Return 0 if
3101 we failed, the caller should emit a normal call, otherwise try to
3102 get the result in TARGET, if convenient. If ENDP is 0 return the
3103 destination pointer, if ENDP is 1 return the end pointer ala
3104 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3105 stpcpy. */
3107 static rtx
3108 expand_movstr (tree dest, tree src, rtx target, int endp)
3110 rtx end;
3111 rtx dest_mem;
3112 rtx src_mem;
3113 rtx insn;
3114 const struct insn_data * data;
3116 if (!HAVE_movstr)
3117 return 0;
3119 dest_mem = get_memory_rtx (dest, NULL);
3120 src_mem = get_memory_rtx (src, NULL);
3121 if (!endp)
3123 target = force_reg (Pmode, XEXP (dest_mem, 0));
3124 dest_mem = replace_equiv_address (dest_mem, target);
3125 end = gen_reg_rtx (Pmode);
3127 else
3129 if (target == 0 || target == const0_rtx)
3131 end = gen_reg_rtx (Pmode);
3132 if (target == 0)
3133 target = end;
3135 else
3136 end = target;
3139 data = insn_data + CODE_FOR_movstr;
3141 if (data->operand[0].mode != VOIDmode)
3142 end = gen_lowpart (data->operand[0].mode, end);
3144 insn = data->genfun (end, dest_mem, src_mem);
3146 gcc_assert (insn);
3148 emit_insn (insn);
3150 /* movstr is supposed to set end to the address of the NUL
3151 terminator. If the caller requested a mempcpy-like return value,
3152 adjust it. */
3153 if (endp == 1 && target != const0_rtx)
3155 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3156 emit_move_insn (target, force_operand (tem, NULL_RTX));
3159 return target;
3162 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3163 if we failed the caller should emit a normal call, otherwise try to get
3164 the result in TARGET, if convenient (and in mode MODE if that's
3165 convenient). */
3167 static rtx
3168 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3170 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3172 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3173 if (result)
3174 return expand_expr (result, target, mode, EXPAND_NORMAL);
3176 return expand_movstr (TREE_VALUE (arglist),
3177 TREE_VALUE (TREE_CHAIN (arglist)),
3178 target, /*endp=*/0);
3180 return 0;
3183 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3184 Return 0 if we failed the caller should emit a normal call,
3185 otherwise try to get the result in TARGET, if convenient (and in
3186 mode MODE if that's convenient). */
3188 static rtx
3189 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3191 tree arglist = TREE_OPERAND (exp, 1);
3192 /* If return value is ignored, transform stpcpy into strcpy. */
3193 if (target == const0_rtx)
3195 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3196 if (!fn)
3197 return 0;
3199 return expand_expr (build_function_call_expr (fn, arglist),
3200 target, mode, EXPAND_NORMAL);
3203 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3204 return 0;
3205 else
3207 tree dst, src, len, lenp1;
3208 tree narglist;
3209 rtx ret;
3211 /* Ensure we get an actual string whose length can be evaluated at
3212 compile-time, not an expression containing a string. This is
3213 because the latter will potentially produce pessimized code
3214 when used to produce the return value. */
3215 src = TREE_VALUE (TREE_CHAIN (arglist));
3216 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3217 return expand_movstr (TREE_VALUE (arglist),
3218 TREE_VALUE (TREE_CHAIN (arglist)),
3219 target, /*endp=*/2);
3221 dst = TREE_VALUE (arglist);
3222 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3223 narglist = build_tree_list (NULL_TREE, lenp1);
3224 narglist = tree_cons (NULL_TREE, src, narglist);
3225 narglist = tree_cons (NULL_TREE, dst, narglist);
3226 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3227 target, mode, /*endp=*/2);
3229 if (ret)
3230 return ret;
3232 if (TREE_CODE (len) == INTEGER_CST)
3234 rtx len_rtx = expand_normal (len);
3236 if (GET_CODE (len_rtx) == CONST_INT)
3238 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3239 arglist, target, mode);
3241 if (ret)
3243 if (! target)
3245 if (mode != VOIDmode)
3246 target = gen_reg_rtx (mode);
3247 else
3248 target = gen_reg_rtx (GET_MODE (ret));
3250 if (GET_MODE (target) != GET_MODE (ret))
3251 ret = gen_lowpart (GET_MODE (target), ret);
3253 ret = plus_constant (ret, INTVAL (len_rtx));
3254 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3255 gcc_assert (ret);
3257 return target;
3262 return expand_movstr (TREE_VALUE (arglist),
3263 TREE_VALUE (TREE_CHAIN (arglist)),
3264 target, /*endp=*/2);
3268 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3269 bytes from constant string DATA + OFFSET and return it as target
3270 constant. */
3272 static rtx
3273 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3274 enum machine_mode mode)
3276 const char *str = (const char *) data;
3278 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3279 return const0_rtx;
3281 return c_readstr (str + offset, mode);
3284 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3285 if we failed the caller should emit a normal call. */
3287 static rtx
3288 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3290 tree fndecl = get_callee_fndecl (exp);
3291 tree arglist = TREE_OPERAND (exp, 1);
3292 if (validate_arglist (arglist,
3293 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3295 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3296 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3297 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3299 if (result)
3300 return expand_expr (result, target, mode, EXPAND_NORMAL);
3302 /* We must be passed a constant len and src parameter. */
3303 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3304 return 0;
3306 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3308 /* We're required to pad with trailing zeros if the requested
3309 len is greater than strlen(s2)+1. In that case try to
3310 use store_by_pieces, if it fails, punt. */
3311 if (tree_int_cst_lt (slen, len))
3313 tree dest = TREE_VALUE (arglist);
3314 unsigned int dest_align
3315 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3316 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3317 rtx dest_mem;
3319 if (!p || dest_align == 0 || !host_integerp (len, 1)
3320 || !can_store_by_pieces (tree_low_cst (len, 1),
3321 builtin_strncpy_read_str,
3322 (void *) p, dest_align))
3323 return 0;
3325 dest_mem = get_memory_rtx (dest, len);
3326 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3327 builtin_strncpy_read_str,
3328 (void *) p, dest_align, 0);
3329 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3330 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3331 return dest_mem;
3334 return 0;
3337 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3338 bytes from constant string DATA + OFFSET and return it as target
3339 constant. */
3341 static rtx
3342 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3343 enum machine_mode mode)
3345 const char *c = (const char *) data;
3346 char *p = alloca (GET_MODE_SIZE (mode));
3348 memset (p, *c, GET_MODE_SIZE (mode));
3350 return c_readstr (p, mode);
3353 /* Callback routine for store_by_pieces. Return the RTL of a register
3354 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3355 char value given in the RTL register data. For example, if mode is
3356 4 bytes wide, return the RTL for 0x01010101*data. */
3358 static rtx
3359 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3360 enum machine_mode mode)
3362 rtx target, coeff;
3363 size_t size;
3364 char *p;
3366 size = GET_MODE_SIZE (mode);
3367 if (size == 1)
3368 return (rtx) data;
3370 p = alloca (size);
3371 memset (p, 1, size);
3372 coeff = c_readstr (p, mode);
3374 target = convert_to_mode (mode, (rtx) data, 1);
3375 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3376 return force_reg (mode, target);
3379 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3380 if we failed the caller should emit a normal call, otherwise try to get
3381 the result in TARGET, if convenient (and in mode MODE if that's
3382 convenient). */
3384 static rtx
3385 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3386 tree orig_exp)
3388 if (!validate_arglist (arglist,
3389 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3390 return 0;
3391 else
3393 tree dest = TREE_VALUE (arglist);
3394 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3395 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3396 tree fndecl, fn;
3397 enum built_in_function fcode;
3398 char c;
3399 unsigned int dest_align;
3400 rtx dest_mem, dest_addr, len_rtx;
3402 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3404 /* If DEST is not a pointer type, don't do this
3405 operation in-line. */
3406 if (dest_align == 0)
3407 return 0;
3409 /* If the LEN parameter is zero, return DEST. */
3410 if (integer_zerop (len))
3412 /* Evaluate and ignore VAL in case it has side-effects. */
3413 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3414 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3417 /* Stabilize the arguments in case we fail. */
3418 dest = builtin_save_expr (dest);
3419 val = builtin_save_expr (val);
3420 len = builtin_save_expr (len);
3422 len_rtx = expand_normal (len);
3423 dest_mem = get_memory_rtx (dest, len);
3425 if (TREE_CODE (val) != INTEGER_CST)
3427 rtx val_rtx;
3429 val_rtx = expand_normal (val);
3430 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3431 val_rtx, 0);
3433 /* Assume that we can memset by pieces if we can store the
3434 * the coefficients by pieces (in the required modes).
3435 * We can't pass builtin_memset_gen_str as that emits RTL. */
3436 c = 1;
3437 if (host_integerp (len, 1)
3438 && !(optimize_size && tree_low_cst (len, 1) > 1)
3439 && can_store_by_pieces (tree_low_cst (len, 1),
3440 builtin_memset_read_str, &c, dest_align))
3442 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3443 val_rtx);
3444 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3445 builtin_memset_gen_str, val_rtx, dest_align, 0);
3447 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3448 dest_align))
3449 goto do_libcall;
3451 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3452 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3453 return dest_mem;
3456 if (target_char_cast (val, &c))
3457 goto do_libcall;
3459 if (c)
3461 if (host_integerp (len, 1)
3462 && !(optimize_size && tree_low_cst (len, 1) > 1)
3463 && can_store_by_pieces (tree_low_cst (len, 1),
3464 builtin_memset_read_str, &c, dest_align))
3465 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3466 builtin_memset_read_str, &c, dest_align, 0);
3467 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3468 dest_align))
3469 goto do_libcall;
3471 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3472 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3473 return dest_mem;
3476 set_mem_align (dest_mem, dest_align);
3477 dest_addr = clear_storage (dest_mem, len_rtx,
3478 CALL_EXPR_TAILCALL (orig_exp)
3479 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3481 if (dest_addr == 0)
3483 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3484 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3487 return dest_addr;
3489 do_libcall:
3490 fndecl = get_callee_fndecl (orig_exp);
3491 fcode = DECL_FUNCTION_CODE (fndecl);
3492 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3493 arglist = build_tree_list (NULL_TREE, len);
3494 if (fcode == BUILT_IN_MEMSET)
3495 arglist = tree_cons (NULL_TREE, val, arglist);
3496 arglist = tree_cons (NULL_TREE, dest, arglist);
3497 fn = build_function_call_expr (fndecl, arglist);
3498 if (TREE_CODE (fn) == CALL_EXPR)
3499 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3500 return expand_call (fn, target, target == const0_rtx);
3504 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3505 if we failed the caller should emit a normal call. */
3507 static rtx
3508 expand_builtin_bzero (tree exp)
3510 tree arglist = TREE_OPERAND (exp, 1);
3511 tree dest, size, newarglist;
3513 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3514 return NULL_RTX;
3516 dest = TREE_VALUE (arglist);
3517 size = TREE_VALUE (TREE_CHAIN (arglist));
3519 /* New argument list transforming bzero(ptr x, int y) to
3520 memset(ptr x, int 0, size_t y). This is done this way
3521 so that if it isn't expanded inline, we fallback to
3522 calling bzero instead of memset. */
3524 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3525 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3526 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3528 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3531 /* Expand expression EXP, which is a call to the memcmp built-in function.
3532 ARGLIST is the argument list for this call. Return 0 if we failed and the
3533 caller should emit a normal call, otherwise try to get the result in
3534 TARGET, if convenient (and in mode MODE, if that's convenient). */
3536 static rtx
3537 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3538 enum machine_mode mode)
3540 if (!validate_arglist (arglist,
3541 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3542 return 0;
3543 else
3545 tree result = fold_builtin_memcmp (arglist);
3546 if (result)
3547 return expand_expr (result, target, mode, EXPAND_NORMAL);
3550 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3552 tree arg1 = TREE_VALUE (arglist);
3553 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3554 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3555 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3556 rtx result;
3557 rtx insn;
3559 int arg1_align
3560 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3561 int arg2_align
3562 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3563 enum machine_mode insn_mode;
3565 #ifdef HAVE_cmpmemsi
3566 if (HAVE_cmpmemsi)
3567 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3568 else
3569 #endif
3570 #ifdef HAVE_cmpstrnsi
3571 if (HAVE_cmpstrnsi)
3572 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3573 else
3574 #endif
3575 return 0;
3577 /* If we don't have POINTER_TYPE, call the function. */
3578 if (arg1_align == 0 || arg2_align == 0)
3579 return 0;
3581 /* Make a place to write the result of the instruction. */
3582 result = target;
3583 if (! (result != 0
3584 && REG_P (result) && GET_MODE (result) == insn_mode
3585 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3586 result = gen_reg_rtx (insn_mode);
3588 arg1_rtx = get_memory_rtx (arg1, len);
3589 arg2_rtx = get_memory_rtx (arg2, len);
3590 arg3_rtx = expand_normal (len);
3592 /* Set MEM_SIZE as appropriate. */
3593 if (GET_CODE (arg3_rtx) == CONST_INT)
3595 set_mem_size (arg1_rtx, arg3_rtx);
3596 set_mem_size (arg2_rtx, arg3_rtx);
3599 #ifdef HAVE_cmpmemsi
3600 if (HAVE_cmpmemsi)
3601 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3602 GEN_INT (MIN (arg1_align, arg2_align)));
3603 else
3604 #endif
3605 #ifdef HAVE_cmpstrnsi
3606 if (HAVE_cmpstrnsi)
3607 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3608 GEN_INT (MIN (arg1_align, arg2_align)));
3609 else
3610 #endif
3611 gcc_unreachable ();
3613 if (insn)
3614 emit_insn (insn);
3615 else
3616 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3617 TYPE_MODE (integer_type_node), 3,
3618 XEXP (arg1_rtx, 0), Pmode,
3619 XEXP (arg2_rtx, 0), Pmode,
3620 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3621 TYPE_UNSIGNED (sizetype)),
3622 TYPE_MODE (sizetype));
3624 /* Return the value in the proper mode for this function. */
3625 mode = TYPE_MODE (TREE_TYPE (exp));
3626 if (GET_MODE (result) == mode)
3627 return result;
3628 else if (target != 0)
3630 convert_move (target, result, 0);
3631 return target;
3633 else
3634 return convert_to_mode (mode, result, 0);
3636 #endif
3638 return 0;
3641 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3642 if we failed the caller should emit a normal call, otherwise try to get
3643 the result in TARGET, if convenient. */
3645 static rtx
3646 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3648 tree arglist = TREE_OPERAND (exp, 1);
3650 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3651 return 0;
3652 else
3654 tree result = fold_builtin_strcmp (arglist);
3655 if (result)
3656 return expand_expr (result, target, mode, EXPAND_NORMAL);
3659 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3660 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3661 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3663 rtx arg1_rtx, arg2_rtx;
3664 rtx result, insn = NULL_RTX;
3665 tree fndecl, fn;
3667 tree arg1 = TREE_VALUE (arglist);
3668 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3669 int arg1_align
3670 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3671 int arg2_align
3672 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3674 /* If we don't have POINTER_TYPE, call the function. */
3675 if (arg1_align == 0 || arg2_align == 0)
3676 return 0;
3678 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3679 arg1 = builtin_save_expr (arg1);
3680 arg2 = builtin_save_expr (arg2);
3682 arg1_rtx = get_memory_rtx (arg1, NULL);
3683 arg2_rtx = get_memory_rtx (arg2, NULL);
3685 #ifdef HAVE_cmpstrsi
3686 /* Try to call cmpstrsi. */
3687 if (HAVE_cmpstrsi)
3689 enum machine_mode insn_mode
3690 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3692 /* Make a place to write the result of the instruction. */
3693 result = target;
3694 if (! (result != 0
3695 && REG_P (result) && GET_MODE (result) == insn_mode
3696 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3697 result = gen_reg_rtx (insn_mode);
3699 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3700 GEN_INT (MIN (arg1_align, arg2_align)));
3702 #endif
3703 #ifdef HAVE_cmpstrnsi
3704 /* Try to determine at least one length and call cmpstrnsi. */
3705 if (!insn && HAVE_cmpstrnsi)
3707 tree len;
3708 rtx arg3_rtx;
3710 enum machine_mode insn_mode
3711 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3712 tree len1 = c_strlen (arg1, 1);
3713 tree len2 = c_strlen (arg2, 1);
3715 if (len1)
3716 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3717 if (len2)
3718 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3720 /* If we don't have a constant length for the first, use the length
3721 of the second, if we know it. We don't require a constant for
3722 this case; some cost analysis could be done if both are available
3723 but neither is constant. For now, assume they're equally cheap,
3724 unless one has side effects. If both strings have constant lengths,
3725 use the smaller. */
3727 if (!len1)
3728 len = len2;
3729 else if (!len2)
3730 len = len1;
3731 else if (TREE_SIDE_EFFECTS (len1))
3732 len = len2;
3733 else if (TREE_SIDE_EFFECTS (len2))
3734 len = len1;
3735 else if (TREE_CODE (len1) != INTEGER_CST)
3736 len = len2;
3737 else if (TREE_CODE (len2) != INTEGER_CST)
3738 len = len1;
3739 else if (tree_int_cst_lt (len1, len2))
3740 len = len1;
3741 else
3742 len = len2;
3744 /* If both arguments have side effects, we cannot optimize. */
3745 if (!len || TREE_SIDE_EFFECTS (len))
3746 goto do_libcall;
3748 arg3_rtx = expand_normal (len);
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 #ifdef HAVE_cmpstrnsi
3779 do_libcall:
3780 #endif
3781 arglist = build_tree_list (NULL_TREE, arg2);
3782 arglist = tree_cons (NULL_TREE, arg1, arglist);
3783 fndecl = get_callee_fndecl (exp);
3784 fn = build_function_call_expr (fndecl, arglist);
3785 if (TREE_CODE (fn) == CALL_EXPR)
3786 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3787 return expand_call (fn, target, target == const0_rtx);
3789 #endif
3790 return 0;
3793 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3794 if we failed the caller should emit a normal call, otherwise try to get
3795 the result in TARGET, if convenient. */
3797 static rtx
3798 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3800 tree arglist = TREE_OPERAND (exp, 1);
3802 if (!validate_arglist (arglist,
3803 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3804 return 0;
3805 else
3807 tree result = fold_builtin_strncmp (arglist);
3808 if (result)
3809 return expand_expr (result, target, mode, EXPAND_NORMAL);
3812 /* If c_strlen can determine an expression for one of the string
3813 lengths, and it doesn't have side effects, then emit cmpstrnsi
3814 using length MIN(strlen(string)+1, arg3). */
3815 #ifdef HAVE_cmpstrnsi
3816 if (HAVE_cmpstrnsi)
3818 tree arg1 = TREE_VALUE (arglist);
3819 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3820 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3821 tree len, len1, len2;
3822 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3823 rtx result, insn;
3824 tree fndecl, fn;
3826 int arg1_align
3827 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3828 int arg2_align
3829 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3830 enum machine_mode insn_mode
3831 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3833 len1 = c_strlen (arg1, 1);
3834 len2 = c_strlen (arg2, 1);
3836 if (len1)
3837 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3838 if (len2)
3839 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3841 /* If we don't have a constant length for the first, use the length
3842 of the second, if we know it. We don't require a constant for
3843 this case; some cost analysis could be done if both are available
3844 but neither is constant. For now, assume they're equally cheap,
3845 unless one has side effects. If both strings have constant lengths,
3846 use the smaller. */
3848 if (!len1)
3849 len = len2;
3850 else if (!len2)
3851 len = len1;
3852 else if (TREE_SIDE_EFFECTS (len1))
3853 len = len2;
3854 else if (TREE_SIDE_EFFECTS (len2))
3855 len = len1;
3856 else if (TREE_CODE (len1) != INTEGER_CST)
3857 len = len2;
3858 else if (TREE_CODE (len2) != INTEGER_CST)
3859 len = len1;
3860 else if (tree_int_cst_lt (len1, len2))
3861 len = len1;
3862 else
3863 len = len2;
3865 /* If both arguments have side effects, we cannot optimize. */
3866 if (!len || TREE_SIDE_EFFECTS (len))
3867 return 0;
3869 /* The actual new length parameter is MIN(len,arg3). */
3870 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3871 fold_convert (TREE_TYPE (len), arg3));
3873 /* If we don't have POINTER_TYPE, call the function. */
3874 if (arg1_align == 0 || arg2_align == 0)
3875 return 0;
3877 /* Make a place to write the result of the instruction. */
3878 result = target;
3879 if (! (result != 0
3880 && REG_P (result) && GET_MODE (result) == insn_mode
3881 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3882 result = gen_reg_rtx (insn_mode);
3884 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3885 arg1 = builtin_save_expr (arg1);
3886 arg2 = builtin_save_expr (arg2);
3887 len = builtin_save_expr (len);
3889 arg1_rtx = get_memory_rtx (arg1, len);
3890 arg2_rtx = get_memory_rtx (arg2, len);
3891 arg3_rtx = expand_normal (len);
3892 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3893 GEN_INT (MIN (arg1_align, arg2_align)));
3894 if (insn)
3896 emit_insn (insn);
3898 /* Return the value in the proper mode for this function. */
3899 mode = TYPE_MODE (TREE_TYPE (exp));
3900 if (GET_MODE (result) == mode)
3901 return result;
3902 if (target == 0)
3903 return convert_to_mode (mode, result, 0);
3904 convert_move (target, result, 0);
3905 return target;
3908 /* Expand the library call ourselves using a stabilized argument
3909 list to avoid re-evaluating the function's arguments twice. */
3910 arglist = build_tree_list (NULL_TREE, len);
3911 arglist = tree_cons (NULL_TREE, arg2, arglist);
3912 arglist = tree_cons (NULL_TREE, arg1, arglist);
3913 fndecl = get_callee_fndecl (exp);
3914 fn = build_function_call_expr (fndecl, arglist);
3915 if (TREE_CODE (fn) == CALL_EXPR)
3916 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3917 return expand_call (fn, target, target == const0_rtx);
3919 #endif
3920 return 0;
3923 /* Expand expression EXP, which is a call to the strcat builtin.
3924 Return 0 if we failed the caller should emit a normal call,
3925 otherwise try to get the result in TARGET, if convenient. */
3927 static rtx
3928 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3930 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3931 return 0;
3932 else
3934 tree dst = TREE_VALUE (arglist),
3935 src = TREE_VALUE (TREE_CHAIN (arglist));
3936 const char *p = c_getstr (src);
3938 /* If the string length is zero, return the dst parameter. */
3939 if (p && *p == '\0')
3940 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3942 if (!optimize_size)
3944 /* See if we can store by pieces into (dst + strlen(dst)). */
3945 tree newsrc, newdst,
3946 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3947 rtx insns;
3949 /* Stabilize the argument list. */
3950 newsrc = builtin_save_expr (src);
3951 if (newsrc != src)
3952 arglist = build_tree_list (NULL_TREE, newsrc);
3953 else
3954 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3956 dst = builtin_save_expr (dst);
3958 start_sequence ();
3960 /* Create strlen (dst). */
3961 newdst =
3962 build_function_call_expr (strlen_fn,
3963 build_tree_list (NULL_TREE, dst));
3964 /* Create (dst + (cast) strlen (dst)). */
3965 newdst = fold_convert (TREE_TYPE (dst), newdst);
3966 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3968 newdst = builtin_save_expr (newdst);
3969 arglist = tree_cons (NULL_TREE, newdst, arglist);
3971 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3973 end_sequence (); /* Stop sequence. */
3974 return 0;
3977 /* Output the entire sequence. */
3978 insns = get_insns ();
3979 end_sequence ();
3980 emit_insn (insns);
3982 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3985 return 0;
3989 /* Expand expression EXP, which is a call to the strncat builtin.
3990 Return 0 if we failed the caller should emit a normal call,
3991 otherwise try to get the result in TARGET, if convenient. */
3993 static rtx
3994 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3996 if (validate_arglist (arglist,
3997 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3999 tree result = fold_builtin_strncat (arglist);
4000 if (result)
4001 return expand_expr (result, target, mode, EXPAND_NORMAL);
4003 return 0;
4006 /* Expand expression EXP, which is a call to the strspn builtin.
4007 Return 0 if we failed the caller should emit a normal call,
4008 otherwise try to get the result in TARGET, if convenient. */
4010 static rtx
4011 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4013 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4015 tree result = fold_builtin_strspn (arglist);
4016 if (result)
4017 return expand_expr (result, target, mode, EXPAND_NORMAL);
4019 return 0;
4022 /* Expand expression EXP, which is a call to the strcspn builtin.
4023 Return 0 if we failed the caller should emit a normal call,
4024 otherwise try to get the result in TARGET, if convenient. */
4026 static rtx
4027 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4029 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4031 tree result = fold_builtin_strcspn (arglist);
4032 if (result)
4033 return expand_expr (result, target, mode, EXPAND_NORMAL);
4035 return 0;
4038 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4039 if that's convenient. */
4042 expand_builtin_saveregs (void)
4044 rtx val, seq;
4046 /* Don't do __builtin_saveregs more than once in a function.
4047 Save the result of the first call and reuse it. */
4048 if (saveregs_value != 0)
4049 return saveregs_value;
4051 /* When this function is called, it means that registers must be
4052 saved on entry to this function. So we migrate the call to the
4053 first insn of this function. */
4055 start_sequence ();
4057 /* Do whatever the machine needs done in this case. */
4058 val = targetm.calls.expand_builtin_saveregs ();
4060 seq = get_insns ();
4061 end_sequence ();
4063 saveregs_value = val;
4065 /* Put the insns after the NOTE that starts the function. If this
4066 is inside a start_sequence, make the outer-level insn chain current, so
4067 the code is placed at the start of the function. */
4068 push_topmost_sequence ();
4069 emit_insn_after (seq, entry_of_function ());
4070 pop_topmost_sequence ();
4072 return val;
4075 /* __builtin_args_info (N) returns word N of the arg space info
4076 for the current function. The number and meanings of words
4077 is controlled by the definition of CUMULATIVE_ARGS. */
4079 static rtx
4080 expand_builtin_args_info (tree arglist)
4082 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4083 int *word_ptr = (int *) &current_function_args_info;
4085 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4087 if (arglist != 0)
4089 if (!host_integerp (TREE_VALUE (arglist), 0))
4090 error ("argument of %<__builtin_args_info%> must be constant");
4091 else
4093 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4095 if (wordnum < 0 || wordnum >= nwords)
4096 error ("argument of %<__builtin_args_info%> out of range");
4097 else
4098 return GEN_INT (word_ptr[wordnum]);
4101 else
4102 error ("missing argument in %<__builtin_args_info%>");
4104 return const0_rtx;
4107 /* Expand a call to __builtin_next_arg. */
4109 static rtx
4110 expand_builtin_next_arg (void)
4112 /* Checking arguments is already done in fold_builtin_next_arg
4113 that must be called before this function. */
4114 return expand_binop (Pmode, add_optab,
4115 current_function_internal_arg_pointer,
4116 current_function_arg_offset_rtx,
4117 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4120 /* Make it easier for the backends by protecting the valist argument
4121 from multiple evaluations. */
4123 static tree
4124 stabilize_va_list (tree valist, int needs_lvalue)
4126 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4128 if (TREE_SIDE_EFFECTS (valist))
4129 valist = save_expr (valist);
4131 /* For this case, the backends will be expecting a pointer to
4132 TREE_TYPE (va_list_type_node), but it's possible we've
4133 actually been given an array (an actual va_list_type_node).
4134 So fix it. */
4135 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4137 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4138 valist = build_fold_addr_expr_with_type (valist, p1);
4141 else
4143 tree pt;
4145 if (! needs_lvalue)
4147 if (! TREE_SIDE_EFFECTS (valist))
4148 return valist;
4150 pt = build_pointer_type (va_list_type_node);
4151 valist = fold_build1 (ADDR_EXPR, pt, valist);
4152 TREE_SIDE_EFFECTS (valist) = 1;
4155 if (TREE_SIDE_EFFECTS (valist))
4156 valist = save_expr (valist);
4157 valist = build_fold_indirect_ref (valist);
4160 return valist;
4163 /* The "standard" definition of va_list is void*. */
4165 tree
4166 std_build_builtin_va_list (void)
4168 return ptr_type_node;
4171 /* The "standard" implementation of va_start: just assign `nextarg' to
4172 the variable. */
4174 void
4175 std_expand_builtin_va_start (tree valist, rtx nextarg)
4177 tree t;
4179 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4180 make_tree (ptr_type_node, nextarg));
4181 TREE_SIDE_EFFECTS (t) = 1;
4183 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4186 /* Expand ARGLIST, from a call to __builtin_va_start. */
4188 static rtx
4189 expand_builtin_va_start (tree arglist)
4191 rtx nextarg;
4192 tree chain, valist;
4194 chain = TREE_CHAIN (arglist);
4196 if (!chain)
4198 error ("too few arguments to function %<va_start%>");
4199 return const0_rtx;
4202 if (fold_builtin_next_arg (chain))
4203 return const0_rtx;
4205 nextarg = expand_builtin_next_arg ();
4206 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4208 #ifdef EXPAND_BUILTIN_VA_START
4209 EXPAND_BUILTIN_VA_START (valist, nextarg);
4210 #else
4211 std_expand_builtin_va_start (valist, nextarg);
4212 #endif
4214 return const0_rtx;
4217 /* The "standard" implementation of va_arg: read the value from the
4218 current (padded) address and increment by the (padded) size. */
4220 tree
4221 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4223 tree addr, t, type_size, rounded_size, valist_tmp;
4224 unsigned HOST_WIDE_INT align, boundary;
4225 bool indirect;
4227 #ifdef ARGS_GROW_DOWNWARD
4228 /* All of the alignment and movement below is for args-grow-up machines.
4229 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4230 implement their own specialized gimplify_va_arg_expr routines. */
4231 gcc_unreachable ();
4232 #endif
4234 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4235 if (indirect)
4236 type = build_pointer_type (type);
4238 align = PARM_BOUNDARY / BITS_PER_UNIT;
4239 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4241 /* Hoist the valist value into a temporary for the moment. */
4242 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4244 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4245 requires greater alignment, we must perform dynamic alignment. */
4246 if (boundary > align
4247 && !integer_zerop (TYPE_SIZE (type)))
4249 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4250 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4251 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4252 gimplify_and_add (t, pre_p);
4254 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4255 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4256 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4257 gimplify_and_add (t, pre_p);
4259 else
4260 boundary = align;
4262 /* If the actual alignment is less than the alignment of the type,
4263 adjust the type accordingly so that we don't assume strict alignment
4264 when deferencing the pointer. */
4265 boundary *= BITS_PER_UNIT;
4266 if (boundary < TYPE_ALIGN (type))
4268 type = build_variant_type_copy (type);
4269 TYPE_ALIGN (type) = boundary;
4272 /* Compute the rounded size of the type. */
4273 type_size = size_in_bytes (type);
4274 rounded_size = round_up (type_size, align);
4276 /* Reduce rounded_size so it's sharable with the postqueue. */
4277 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4279 /* Get AP. */
4280 addr = valist_tmp;
4281 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4283 /* Small args are padded downward. */
4284 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4285 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4286 size_binop (MINUS_EXPR, rounded_size, type_size));
4287 t = fold_convert (TREE_TYPE (addr), t);
4288 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4291 /* Compute new value for AP. */
4292 t = fold_convert (TREE_TYPE (valist), rounded_size);
4293 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4294 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4295 gimplify_and_add (t, pre_p);
4297 addr = fold_convert (build_pointer_type (type), addr);
4299 if (indirect)
4300 addr = build_va_arg_indirect_ref (addr);
4302 return build_va_arg_indirect_ref (addr);
4305 /* Build an indirect-ref expression over the given TREE, which represents a
4306 piece of a va_arg() expansion. */
4307 tree
4308 build_va_arg_indirect_ref (tree addr)
4310 addr = build_fold_indirect_ref (addr);
4312 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4313 mf_mark (addr);
4315 return addr;
4318 /* Return a dummy expression of type TYPE in order to keep going after an
4319 error. */
4321 static tree
4322 dummy_object (tree type)
4324 tree t = build_int_cst (build_pointer_type (type), 0);
4325 return build1 (INDIRECT_REF, type, t);
4328 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4329 builtin function, but a very special sort of operator. */
4331 enum gimplify_status
4332 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4334 tree promoted_type, want_va_type, have_va_type;
4335 tree valist = TREE_OPERAND (*expr_p, 0);
4336 tree type = TREE_TYPE (*expr_p);
4337 tree t;
4339 /* Verify that valist is of the proper type. */
4340 want_va_type = va_list_type_node;
4341 have_va_type = TREE_TYPE (valist);
4343 if (have_va_type == error_mark_node)
4344 return GS_ERROR;
4346 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4348 /* If va_list is an array type, the argument may have decayed
4349 to a pointer type, e.g. by being passed to another function.
4350 In that case, unwrap both types so that we can compare the
4351 underlying records. */
4352 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4353 || POINTER_TYPE_P (have_va_type))
4355 want_va_type = TREE_TYPE (want_va_type);
4356 have_va_type = TREE_TYPE (have_va_type);
4360 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4362 error ("first argument to %<va_arg%> not of type %<va_list%>");
4363 return GS_ERROR;
4366 /* Generate a diagnostic for requesting data of a type that cannot
4367 be passed through `...' due to type promotion at the call site. */
4368 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4369 != type)
4371 static bool gave_help;
4373 /* Unfortunately, this is merely undefined, rather than a constraint
4374 violation, so we cannot make this an error. If this call is never
4375 executed, the program is still strictly conforming. */
4376 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4377 type, promoted_type);
4378 if (! gave_help)
4380 gave_help = true;
4381 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4382 promoted_type, type);
4385 /* We can, however, treat "undefined" any way we please.
4386 Call abort to encourage the user to fix the program. */
4387 inform ("if this code is reached, the program will abort");
4388 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4389 NULL);
4390 append_to_statement_list (t, pre_p);
4392 /* This is dead code, but go ahead and finish so that the
4393 mode of the result comes out right. */
4394 *expr_p = dummy_object (type);
4395 return GS_ALL_DONE;
4397 else
4399 /* Make it easier for the backends by protecting the valist argument
4400 from multiple evaluations. */
4401 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4403 /* For this case, the backends will be expecting a pointer to
4404 TREE_TYPE (va_list_type_node), but it's possible we've
4405 actually been given an array (an actual va_list_type_node).
4406 So fix it. */
4407 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4409 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4410 valist = build_fold_addr_expr_with_type (valist, p1);
4412 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4414 else
4415 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4417 if (!targetm.gimplify_va_arg_expr)
4418 /* FIXME:Once most targets are converted we should merely
4419 assert this is non-null. */
4420 return GS_ALL_DONE;
4422 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4423 return GS_OK;
4427 /* Expand ARGLIST, from a call to __builtin_va_end. */
4429 static rtx
4430 expand_builtin_va_end (tree arglist)
4432 tree valist = TREE_VALUE (arglist);
4434 /* Evaluate for side effects, if needed. I hate macros that don't
4435 do that. */
4436 if (TREE_SIDE_EFFECTS (valist))
4437 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4439 return const0_rtx;
4442 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4443 builtin rather than just as an assignment in stdarg.h because of the
4444 nastiness of array-type va_list types. */
4446 static rtx
4447 expand_builtin_va_copy (tree arglist)
4449 tree dst, src, t;
4451 dst = TREE_VALUE (arglist);
4452 src = TREE_VALUE (TREE_CHAIN (arglist));
4454 dst = stabilize_va_list (dst, 1);
4455 src = stabilize_va_list (src, 0);
4457 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4459 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4460 TREE_SIDE_EFFECTS (t) = 1;
4461 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4463 else
4465 rtx dstb, srcb, size;
4467 /* Evaluate to pointers. */
4468 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4469 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4470 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4471 VOIDmode, EXPAND_NORMAL);
4473 dstb = convert_memory_address (Pmode, dstb);
4474 srcb = convert_memory_address (Pmode, srcb);
4476 /* "Dereference" to BLKmode memories. */
4477 dstb = gen_rtx_MEM (BLKmode, dstb);
4478 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4479 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4480 srcb = gen_rtx_MEM (BLKmode, srcb);
4481 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4482 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4484 /* Copy. */
4485 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4488 return const0_rtx;
4491 /* Expand a call to one of the builtin functions __builtin_frame_address or
4492 __builtin_return_address. */
4494 static rtx
4495 expand_builtin_frame_address (tree fndecl, tree arglist)
4497 /* The argument must be a nonnegative integer constant.
4498 It counts the number of frames to scan up the stack.
4499 The value is the return address saved in that frame. */
4500 if (arglist == 0)
4501 /* Warning about missing arg was already issued. */
4502 return const0_rtx;
4503 else if (! host_integerp (TREE_VALUE (arglist), 1))
4505 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4506 error ("invalid argument to %<__builtin_frame_address%>");
4507 else
4508 error ("invalid argument to %<__builtin_return_address%>");
4509 return const0_rtx;
4511 else
4513 rtx tem
4514 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4515 tree_low_cst (TREE_VALUE (arglist), 1));
4517 /* Some ports cannot access arbitrary stack frames. */
4518 if (tem == NULL)
4520 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4521 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4522 else
4523 warning (0, "unsupported argument to %<__builtin_return_address%>");
4524 return const0_rtx;
4527 /* For __builtin_frame_address, return what we've got. */
4528 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4529 return tem;
4531 if (!REG_P (tem)
4532 && ! CONSTANT_P (tem))
4533 tem = copy_to_mode_reg (Pmode, tem);
4534 return tem;
4538 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4539 we failed and the caller should emit a normal call, otherwise try to get
4540 the result in TARGET, if convenient. */
4542 static rtx
4543 expand_builtin_alloca (tree arglist, rtx target)
4545 rtx op0;
4546 rtx result;
4548 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4549 should always expand to function calls. These can be intercepted
4550 in libmudflap. */
4551 if (flag_mudflap)
4552 return 0;
4554 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4555 return 0;
4557 /* Compute the argument. */
4558 op0 = expand_normal (TREE_VALUE (arglist));
4560 /* Allocate the desired space. */
4561 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4562 result = convert_memory_address (ptr_mode, result);
4564 return result;
4567 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4568 Return 0 if a normal call should be emitted rather than expanding the
4569 function in-line. If convenient, the result should be placed in TARGET.
4570 SUBTARGET may be used as the target for computing one of EXP's operands. */
4572 static rtx
4573 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4574 rtx subtarget, optab op_optab)
4576 rtx op0;
4577 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4578 return 0;
4580 /* Compute the argument. */
4581 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4582 /* Compute op, into TARGET if possible.
4583 Set TARGET to wherever the result comes back. */
4584 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4585 op_optab, op0, target, 1);
4586 gcc_assert (target);
4588 return convert_to_mode (target_mode, target, 0);
4591 /* If the string passed to fputs is a constant and is one character
4592 long, we attempt to transform this call into __builtin_fputc(). */
4594 static rtx
4595 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4597 /* Verify the arguments in the original call. */
4598 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4600 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4601 unlocked, NULL_TREE);
4602 if (result)
4603 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4605 return 0;
4608 /* Expand a call to __builtin_expect. We return our argument and emit a
4609 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4610 a non-jump context. */
4612 static rtx
4613 expand_builtin_expect (tree arglist, rtx target)
4615 tree exp, c;
4616 rtx note, rtx_c;
4618 if (arglist == NULL_TREE
4619 || TREE_CHAIN (arglist) == NULL_TREE)
4620 return const0_rtx;
4621 exp = TREE_VALUE (arglist);
4622 c = TREE_VALUE (TREE_CHAIN (arglist));
4624 if (TREE_CODE (c) != INTEGER_CST)
4626 error ("second argument to %<__builtin_expect%> must be a constant");
4627 c = integer_zero_node;
4630 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4632 /* Don't bother with expected value notes for integral constants. */
4633 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4635 /* We do need to force this into a register so that we can be
4636 moderately sure to be able to correctly interpret the branch
4637 condition later. */
4638 target = force_reg (GET_MODE (target), target);
4640 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4642 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4643 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4646 return target;
4649 /* Like expand_builtin_expect, except do this in a jump context. This is
4650 called from do_jump if the conditional is a __builtin_expect. Return either
4651 a list of insns to emit the jump or NULL if we cannot optimize
4652 __builtin_expect. We need to optimize this at jump time so that machines
4653 like the PowerPC don't turn the test into a SCC operation, and then jump
4654 based on the test being 0/1. */
4657 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4659 tree arglist = TREE_OPERAND (exp, 1);
4660 tree arg0 = TREE_VALUE (arglist);
4661 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4662 rtx ret = NULL_RTX;
4664 /* Only handle __builtin_expect (test, 0) and
4665 __builtin_expect (test, 1). */
4666 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4667 && (integer_zerop (arg1) || integer_onep (arg1)))
4669 rtx insn, drop_through_label, temp;
4671 /* Expand the jump insns. */
4672 start_sequence ();
4673 do_jump (arg0, if_false_label, if_true_label);
4674 ret = get_insns ();
4676 drop_through_label = get_last_insn ();
4677 if (drop_through_label && NOTE_P (drop_through_label))
4678 drop_through_label = prev_nonnote_insn (drop_through_label);
4679 if (drop_through_label && !LABEL_P (drop_through_label))
4680 drop_through_label = NULL_RTX;
4681 end_sequence ();
4683 if (! if_true_label)
4684 if_true_label = drop_through_label;
4685 if (! if_false_label)
4686 if_false_label = drop_through_label;
4688 /* Go through and add the expect's to each of the conditional jumps. */
4689 insn = ret;
4690 while (insn != NULL_RTX)
4692 rtx next = NEXT_INSN (insn);
4694 if (JUMP_P (insn) && any_condjump_p (insn))
4696 rtx ifelse = SET_SRC (pc_set (insn));
4697 rtx then_dest = XEXP (ifelse, 1);
4698 rtx else_dest = XEXP (ifelse, 2);
4699 int taken = -1;
4701 /* First check if we recognize any of the labels. */
4702 if (GET_CODE (then_dest) == LABEL_REF
4703 && XEXP (then_dest, 0) == if_true_label)
4704 taken = 1;
4705 else if (GET_CODE (then_dest) == LABEL_REF
4706 && XEXP (then_dest, 0) == if_false_label)
4707 taken = 0;
4708 else if (GET_CODE (else_dest) == LABEL_REF
4709 && XEXP (else_dest, 0) == if_false_label)
4710 taken = 1;
4711 else if (GET_CODE (else_dest) == LABEL_REF
4712 && XEXP (else_dest, 0) == if_true_label)
4713 taken = 0;
4714 /* Otherwise check where we drop through. */
4715 else if (else_dest == pc_rtx)
4717 if (next && NOTE_P (next))
4718 next = next_nonnote_insn (next);
4720 if (next && JUMP_P (next)
4721 && any_uncondjump_p (next))
4722 temp = XEXP (SET_SRC (pc_set (next)), 0);
4723 else
4724 temp = next;
4726 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4727 else that can't possibly match either target label. */
4728 if (temp == if_false_label)
4729 taken = 1;
4730 else if (temp == if_true_label)
4731 taken = 0;
4733 else if (then_dest == pc_rtx)
4735 if (next && NOTE_P (next))
4736 next = next_nonnote_insn (next);
4738 if (next && JUMP_P (next)
4739 && any_uncondjump_p (next))
4740 temp = XEXP (SET_SRC (pc_set (next)), 0);
4741 else
4742 temp = next;
4744 if (temp == if_false_label)
4745 taken = 0;
4746 else if (temp == if_true_label)
4747 taken = 1;
4750 if (taken != -1)
4752 /* If the test is expected to fail, reverse the
4753 probabilities. */
4754 if (integer_zerop (arg1))
4755 taken = 1 - taken;
4756 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4760 insn = next;
4764 return ret;
4767 void
4768 expand_builtin_trap (void)
4770 #ifdef HAVE_trap
4771 if (HAVE_trap)
4772 emit_insn (gen_trap ());
4773 else
4774 #endif
4775 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4776 emit_barrier ();
4779 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4780 Return 0 if a normal call should be emitted rather than expanding
4781 the function inline. If convenient, the result should be placed
4782 in TARGET. SUBTARGET may be used as the target for computing
4783 the operand. */
4785 static rtx
4786 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4788 enum machine_mode mode;
4789 tree arg;
4790 rtx op0;
4792 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4793 return 0;
4795 arg = TREE_VALUE (arglist);
4796 mode = TYPE_MODE (TREE_TYPE (arg));
4797 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4798 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4801 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4802 Return NULL is a normal call should be emitted rather than expanding the
4803 function inline. If convenient, the result should be placed in TARGET.
4804 SUBTARGET may be used as the target for computing the operand. */
4806 static rtx
4807 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4809 rtx op0, op1;
4810 tree arg;
4812 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4813 return 0;
4815 arg = TREE_VALUE (arglist);
4816 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4818 arg = TREE_VALUE (TREE_CHAIN (arglist));
4819 op1 = expand_normal (arg);
4821 return expand_copysign (op0, op1, target);
4824 /* Create a new constant string literal and return a char* pointer to it.
4825 The STRING_CST value is the LEN characters at STR. */
4826 tree
4827 build_string_literal (int len, const char *str)
4829 tree t, elem, index, type;
4831 t = build_string (len, str);
4832 elem = build_type_variant (char_type_node, 1, 0);
4833 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4834 type = build_array_type (elem, index);
4835 TREE_TYPE (t) = type;
4836 TREE_CONSTANT (t) = 1;
4837 TREE_INVARIANT (t) = 1;
4838 TREE_READONLY (t) = 1;
4839 TREE_STATIC (t) = 1;
4841 type = build_pointer_type (type);
4842 t = build1 (ADDR_EXPR, type, t);
4844 type = build_pointer_type (elem);
4845 t = build1 (NOP_EXPR, type, t);
4846 return t;
4849 /* Expand EXP, a call to printf or printf_unlocked.
4850 Return 0 if a normal call should be emitted rather than transforming
4851 the function inline. If convenient, the result should be placed in
4852 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4853 call. */
4854 static rtx
4855 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4856 bool unlocked)
4858 tree arglist = TREE_OPERAND (exp, 1);
4859 /* If we're using an unlocked function, assume the other unlocked
4860 functions exist explicitly. */
4861 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4862 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4863 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4864 : implicit_built_in_decls[BUILT_IN_PUTS];
4865 const char *fmt_str;
4866 tree fn, fmt, arg;
4868 /* If the return value is used, don't do the transformation. */
4869 if (target != const0_rtx)
4870 return 0;
4872 /* Verify the required arguments in the original call. */
4873 if (! arglist)
4874 return 0;
4875 fmt = TREE_VALUE (arglist);
4876 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4877 return 0;
4878 arglist = TREE_CHAIN (arglist);
4880 /* Check whether the format is a literal string constant. */
4881 fmt_str = c_getstr (fmt);
4882 if (fmt_str == NULL)
4883 return 0;
4885 if (!init_target_chars())
4886 return 0;
4888 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4889 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4891 if (! arglist
4892 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4893 || TREE_CHAIN (arglist))
4894 return 0;
4895 fn = fn_puts;
4897 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4898 else if (strcmp (fmt_str, target_percent_c) == 0)
4900 if (! arglist
4901 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4902 || TREE_CHAIN (arglist))
4903 return 0;
4904 fn = fn_putchar;
4906 else
4908 /* We can't handle anything else with % args or %% ... yet. */
4909 if (strchr (fmt_str, target_percent))
4910 return 0;
4912 if (arglist)
4913 return 0;
4915 /* If the format specifier was "", printf does nothing. */
4916 if (fmt_str[0] == '\0')
4917 return const0_rtx;
4918 /* If the format specifier has length of 1, call putchar. */
4919 if (fmt_str[1] == '\0')
4921 /* Given printf("c"), (where c is any one character,)
4922 convert "c"[0] to an int and pass that to the replacement
4923 function. */
4924 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4925 arglist = build_tree_list (NULL_TREE, arg);
4926 fn = fn_putchar;
4928 else
4930 /* If the format specifier was "string\n", call puts("string"). */
4931 size_t len = strlen (fmt_str);
4932 if ((unsigned char)fmt_str[len - 1] == target_newline)
4934 /* Create a NUL-terminated string that's one char shorter
4935 than the original, stripping off the trailing '\n'. */
4936 char *newstr = alloca (len);
4937 memcpy (newstr, fmt_str, len - 1);
4938 newstr[len - 1] = 0;
4940 arg = build_string_literal (len, newstr);
4941 arglist = build_tree_list (NULL_TREE, arg);
4942 fn = fn_puts;
4944 else
4945 /* We'd like to arrange to call fputs(string,stdout) here,
4946 but we need stdout and don't have a way to get it yet. */
4947 return 0;
4951 if (!fn)
4952 return 0;
4953 fn = build_function_call_expr (fn, arglist);
4954 if (TREE_CODE (fn) == CALL_EXPR)
4955 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4956 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4959 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4960 Return 0 if a normal call should be emitted rather than transforming
4961 the function inline. If convenient, the result should be placed in
4962 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4963 call. */
4964 static rtx
4965 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4966 bool unlocked)
4968 tree arglist = TREE_OPERAND (exp, 1);
4969 /* If we're using an unlocked function, assume the other unlocked
4970 functions exist explicitly. */
4971 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4972 : implicit_built_in_decls[BUILT_IN_FPUTC];
4973 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4974 : implicit_built_in_decls[BUILT_IN_FPUTS];
4975 const char *fmt_str;
4976 tree fn, fmt, fp, arg;
4978 /* If the return value is used, don't do the transformation. */
4979 if (target != const0_rtx)
4980 return 0;
4982 /* Verify the required arguments in the original call. */
4983 if (! arglist)
4984 return 0;
4985 fp = TREE_VALUE (arglist);
4986 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4987 return 0;
4988 arglist = TREE_CHAIN (arglist);
4989 if (! arglist)
4990 return 0;
4991 fmt = TREE_VALUE (arglist);
4992 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4993 return 0;
4994 arglist = TREE_CHAIN (arglist);
4996 /* Check whether the format is a literal string constant. */
4997 fmt_str = c_getstr (fmt);
4998 if (fmt_str == NULL)
4999 return 0;
5001 if (!init_target_chars())
5002 return 0;
5004 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5005 if (strcmp (fmt_str, target_percent_s) == 0)
5007 if (! arglist
5008 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5009 || TREE_CHAIN (arglist))
5010 return 0;
5011 arg = TREE_VALUE (arglist);
5012 arglist = build_tree_list (NULL_TREE, fp);
5013 arglist = tree_cons (NULL_TREE, arg, arglist);
5014 fn = fn_fputs;
5016 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5017 else if (strcmp (fmt_str, target_percent_c) == 0)
5019 if (! arglist
5020 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5021 || TREE_CHAIN (arglist))
5022 return 0;
5023 arg = TREE_VALUE (arglist);
5024 arglist = build_tree_list (NULL_TREE, fp);
5025 arglist = tree_cons (NULL_TREE, arg, arglist);
5026 fn = fn_fputc;
5028 else
5030 /* We can't handle anything else with % args or %% ... yet. */
5031 if (strchr (fmt_str, target_percent))
5032 return 0;
5034 if (arglist)
5035 return 0;
5037 /* If the format specifier was "", fprintf does nothing. */
5038 if (fmt_str[0] == '\0')
5040 /* Evaluate and ignore FILE* argument for side-effects. */
5041 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5042 return const0_rtx;
5045 /* When "string" doesn't contain %, replace all cases of
5046 fprintf(stream,string) with fputs(string,stream). The fputs
5047 builtin will take care of special cases like length == 1. */
5048 arglist = build_tree_list (NULL_TREE, fp);
5049 arglist = tree_cons (NULL_TREE, fmt, arglist);
5050 fn = fn_fputs;
5053 if (!fn)
5054 return 0;
5055 fn = build_function_call_expr (fn, arglist);
5056 if (TREE_CODE (fn) == CALL_EXPR)
5057 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5058 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5061 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5062 a normal call should be emitted rather than expanding the function
5063 inline. If convenient, the result should be placed in TARGET with
5064 mode MODE. */
5066 static rtx
5067 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5069 tree orig_arglist, dest, fmt;
5070 const char *fmt_str;
5072 orig_arglist = arglist;
5074 /* Verify the required arguments in the original call. */
5075 if (! arglist)
5076 return 0;
5077 dest = TREE_VALUE (arglist);
5078 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5079 return 0;
5080 arglist = TREE_CHAIN (arglist);
5081 if (! arglist)
5082 return 0;
5083 fmt = TREE_VALUE (arglist);
5084 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5085 return 0;
5086 arglist = TREE_CHAIN (arglist);
5088 /* Check whether the format is a literal string constant. */
5089 fmt_str = c_getstr (fmt);
5090 if (fmt_str == NULL)
5091 return 0;
5093 if (!init_target_chars())
5094 return 0;
5096 /* If the format doesn't contain % args or %%, use strcpy. */
5097 if (strchr (fmt_str, target_percent) == 0)
5099 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5100 tree exp;
5102 if (arglist || ! fn)
5103 return 0;
5104 expand_expr (build_function_call_expr (fn, orig_arglist),
5105 const0_rtx, VOIDmode, EXPAND_NORMAL);
5106 if (target == const0_rtx)
5107 return const0_rtx;
5108 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5109 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5111 /* If the format is "%s", use strcpy if the result isn't used. */
5112 else if (strcmp (fmt_str, target_percent_s) == 0)
5114 tree fn, arg, len;
5115 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5117 if (! fn)
5118 return 0;
5120 if (! arglist || TREE_CHAIN (arglist))
5121 return 0;
5122 arg = TREE_VALUE (arglist);
5123 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5124 return 0;
5126 if (target != const0_rtx)
5128 len = c_strlen (arg, 1);
5129 if (! len || TREE_CODE (len) != INTEGER_CST)
5130 return 0;
5132 else
5133 len = NULL_TREE;
5135 arglist = build_tree_list (NULL_TREE, arg);
5136 arglist = tree_cons (NULL_TREE, dest, arglist);
5137 expand_expr (build_function_call_expr (fn, arglist),
5138 const0_rtx, VOIDmode, EXPAND_NORMAL);
5140 if (target == const0_rtx)
5141 return const0_rtx;
5142 return expand_expr (len, target, mode, EXPAND_NORMAL);
5145 return 0;
5148 /* Expand a call to either the entry or exit function profiler. */
5150 static rtx
5151 expand_builtin_profile_func (bool exitp)
5153 rtx this, which;
5155 this = DECL_RTL (current_function_decl);
5156 gcc_assert (MEM_P (this));
5157 this = XEXP (this, 0);
5159 if (exitp)
5160 which = profile_function_exit_libfunc;
5161 else
5162 which = profile_function_entry_libfunc;
5164 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5165 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5167 Pmode);
5169 return const0_rtx;
5172 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5174 static rtx
5175 round_trampoline_addr (rtx tramp)
5177 rtx temp, addend, mask;
5179 /* If we don't need too much alignment, we'll have been guaranteed
5180 proper alignment by get_trampoline_type. */
5181 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5182 return tramp;
5184 /* Round address up to desired boundary. */
5185 temp = gen_reg_rtx (Pmode);
5186 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5187 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5189 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5190 temp, 0, OPTAB_LIB_WIDEN);
5191 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5192 temp, 0, OPTAB_LIB_WIDEN);
5194 return tramp;
5197 static rtx
5198 expand_builtin_init_trampoline (tree arglist)
5200 tree t_tramp, t_func, t_chain;
5201 rtx r_tramp, r_func, r_chain;
5202 #ifdef TRAMPOLINE_TEMPLATE
5203 rtx blktramp;
5204 #endif
5206 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5207 POINTER_TYPE, VOID_TYPE))
5208 return NULL_RTX;
5210 t_tramp = TREE_VALUE (arglist);
5211 arglist = TREE_CHAIN (arglist);
5212 t_func = TREE_VALUE (arglist);
5213 arglist = TREE_CHAIN (arglist);
5214 t_chain = TREE_VALUE (arglist);
5216 r_tramp = expand_normal (t_tramp);
5217 r_func = expand_normal (t_func);
5218 r_chain = expand_normal (t_chain);
5220 /* Generate insns to initialize the trampoline. */
5221 r_tramp = round_trampoline_addr (r_tramp);
5222 #ifdef TRAMPOLINE_TEMPLATE
5223 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5224 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5225 emit_block_move (blktramp, assemble_trampoline_template (),
5226 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5227 #endif
5228 trampolines_created = 1;
5229 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5231 return const0_rtx;
5234 static rtx
5235 expand_builtin_adjust_trampoline (tree arglist)
5237 rtx tramp;
5239 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5240 return NULL_RTX;
5242 tramp = expand_normal (TREE_VALUE (arglist));
5243 tramp = round_trampoline_addr (tramp);
5244 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5245 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5246 #endif
5248 return tramp;
5251 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5252 Return NULL_RTX if a normal call should be emitted rather than expanding
5253 the function in-line. EXP is the expression that is a call to the builtin
5254 function; if convenient, the result should be placed in TARGET. */
5256 static rtx
5257 expand_builtin_signbit (tree exp, rtx target)
5259 const struct real_format *fmt;
5260 enum machine_mode fmode, imode, rmode;
5261 HOST_WIDE_INT hi, lo;
5262 tree arg, arglist;
5263 int word, bitpos;
5264 rtx temp;
5266 arglist = TREE_OPERAND (exp, 1);
5267 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5268 return 0;
5270 arg = TREE_VALUE (arglist);
5271 fmode = TYPE_MODE (TREE_TYPE (arg));
5272 rmode = TYPE_MODE (TREE_TYPE (exp));
5273 fmt = REAL_MODE_FORMAT (fmode);
5275 /* For floating point formats without a sign bit, implement signbit
5276 as "ARG < 0.0". */
5277 bitpos = fmt->signbit_ro;
5278 if (bitpos < 0)
5280 /* But we can't do this if the format supports signed zero. */
5281 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5282 return 0;
5284 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5285 build_real (TREE_TYPE (arg), dconst0));
5286 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5289 temp = expand_normal (arg);
5290 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5292 imode = int_mode_for_mode (fmode);
5293 if (imode == BLKmode)
5294 return 0;
5295 temp = gen_lowpart (imode, temp);
5297 else
5299 imode = word_mode;
5300 /* Handle targets with different FP word orders. */
5301 if (FLOAT_WORDS_BIG_ENDIAN)
5302 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5303 else
5304 word = bitpos / BITS_PER_WORD;
5305 temp = operand_subword_force (temp, word, fmode);
5306 bitpos = bitpos % BITS_PER_WORD;
5309 /* Force the intermediate word_mode (or narrower) result into a
5310 register. This avoids attempting to create paradoxical SUBREGs
5311 of floating point modes below. */
5312 temp = force_reg (imode, temp);
5314 /* If the bitpos is within the "result mode" lowpart, the operation
5315 can be implement with a single bitwise AND. Otherwise, we need
5316 a right shift and an AND. */
5318 if (bitpos < GET_MODE_BITSIZE (rmode))
5320 if (bitpos < HOST_BITS_PER_WIDE_INT)
5322 hi = 0;
5323 lo = (HOST_WIDE_INT) 1 << bitpos;
5325 else
5327 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5328 lo = 0;
5331 if (imode != rmode)
5332 temp = gen_lowpart (rmode, temp);
5333 temp = expand_binop (rmode, and_optab, temp,
5334 immed_double_const (lo, hi, rmode),
5335 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5337 else
5339 /* Perform a logical right shift to place the signbit in the least
5340 significant bit, then truncate the result to the desired mode
5341 and mask just this bit. */
5342 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5343 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5344 temp = gen_lowpart (rmode, temp);
5345 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5346 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5349 return temp;
5352 /* Expand fork or exec calls. TARGET is the desired target of the
5353 call. ARGLIST is the list of arguments of the call. FN is the
5354 identificator of the actual function. IGNORE is nonzero if the
5355 value is to be ignored. */
5357 static rtx
5358 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5360 tree id, decl;
5361 tree call;
5363 /* If we are not profiling, just call the function. */
5364 if (!profile_arc_flag)
5365 return NULL_RTX;
5367 /* Otherwise call the wrapper. This should be equivalent for the rest of
5368 compiler, so the code does not diverge, and the wrapper may run the
5369 code necessary for keeping the profiling sane. */
5371 switch (DECL_FUNCTION_CODE (fn))
5373 case BUILT_IN_FORK:
5374 id = get_identifier ("__gcov_fork");
5375 break;
5377 case BUILT_IN_EXECL:
5378 id = get_identifier ("__gcov_execl");
5379 break;
5381 case BUILT_IN_EXECV:
5382 id = get_identifier ("__gcov_execv");
5383 break;
5385 case BUILT_IN_EXECLP:
5386 id = get_identifier ("__gcov_execlp");
5387 break;
5389 case BUILT_IN_EXECLE:
5390 id = get_identifier ("__gcov_execle");
5391 break;
5393 case BUILT_IN_EXECVP:
5394 id = get_identifier ("__gcov_execvp");
5395 break;
5397 case BUILT_IN_EXECVE:
5398 id = get_identifier ("__gcov_execve");
5399 break;
5401 default:
5402 gcc_unreachable ();
5405 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5406 DECL_EXTERNAL (decl) = 1;
5407 TREE_PUBLIC (decl) = 1;
5408 DECL_ARTIFICIAL (decl) = 1;
5409 TREE_NOTHROW (decl) = 1;
5410 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5411 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5412 call = build_function_call_expr (decl, arglist);
5414 return expand_call (call, target, ignore);
5418 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5419 the pointer in these functions is void*, the tree optimizers may remove
5420 casts. The mode computed in expand_builtin isn't reliable either, due
5421 to __sync_bool_compare_and_swap.
5423 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5424 group of builtins. This gives us log2 of the mode size. */
5426 static inline enum machine_mode
5427 get_builtin_sync_mode (int fcode_diff)
5429 /* The size is not negotiable, so ask not to get BLKmode in return
5430 if the target indicates that a smaller size would be better. */
5431 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5434 /* Expand the memory expression LOC and return the appropriate memory operand
5435 for the builtin_sync operations. */
5437 static rtx
5438 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5440 rtx addr, mem;
5442 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5444 /* Note that we explicitly do not want any alias information for this
5445 memory, so that we kill all other live memories. Otherwise we don't
5446 satisfy the full barrier semantics of the intrinsic. */
5447 mem = validize_mem (gen_rtx_MEM (mode, addr));
5449 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5450 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5451 MEM_VOLATILE_P (mem) = 1;
5453 return mem;
5456 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5457 ARGLIST is the operands list to the function. CODE is the rtx code
5458 that corresponds to the arithmetic or logical operation from the name;
5459 an exception here is that NOT actually means NAND. TARGET is an optional
5460 place for us to store the results; AFTER is true if this is the
5461 fetch_and_xxx form. IGNORE is true if we don't actually care about
5462 the result of the operation at all. */
5464 static rtx
5465 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5466 enum rtx_code code, bool after,
5467 rtx target, bool ignore)
5469 rtx val, mem;
5471 /* Expand the operands. */
5472 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5474 arglist = TREE_CHAIN (arglist);
5475 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5477 if (ignore)
5478 return expand_sync_operation (mem, val, code);
5479 else
5480 return expand_sync_fetch_operation (mem, val, code, after, target);
5483 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5484 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5485 true if this is the boolean form. TARGET is a place for us to store the
5486 results; this is NOT optional if IS_BOOL is true. */
5488 static rtx
5489 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5490 bool is_bool, rtx target)
5492 rtx old_val, new_val, mem;
5494 /* Expand the operands. */
5495 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5497 arglist = TREE_CHAIN (arglist);
5498 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5500 arglist = TREE_CHAIN (arglist);
5501 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5503 if (is_bool)
5504 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5505 else
5506 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5509 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5510 general form is actually an atomic exchange, and some targets only
5511 support a reduced form with the second argument being a constant 1.
5512 ARGLIST is the operands list to the function; TARGET is an optional
5513 place for us to store the results. */
5515 static rtx
5516 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5517 rtx target)
5519 rtx val, mem;
5521 /* Expand the operands. */
5522 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5524 arglist = TREE_CHAIN (arglist);
5525 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5527 return expand_sync_lock_test_and_set (mem, val, target);
5530 /* Expand the __sync_synchronize intrinsic. */
5532 static void
5533 expand_builtin_synchronize (void)
5535 tree x;
5537 #ifdef HAVE_memory_barrier
5538 if (HAVE_memory_barrier)
5540 emit_insn (gen_memory_barrier ());
5541 return;
5543 #endif
5545 /* If no explicit memory barrier instruction is available, create an
5546 empty asm stmt with a memory clobber. */
5547 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5548 tree_cons (NULL, build_string (6, "memory"), NULL));
5549 ASM_VOLATILE_P (x) = 1;
5550 expand_asm_expr (x);
5553 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5554 to the function. */
5556 static void
5557 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5559 enum insn_code icode;
5560 rtx mem, insn;
5561 rtx val = const0_rtx;
5563 /* Expand the operands. */
5564 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5566 /* If there is an explicit operation in the md file, use it. */
5567 icode = sync_lock_release[mode];
5568 if (icode != CODE_FOR_nothing)
5570 if (!insn_data[icode].operand[1].predicate (val, mode))
5571 val = force_reg (mode, val);
5573 insn = GEN_FCN (icode) (mem, val);
5574 if (insn)
5576 emit_insn (insn);
5577 return;
5581 /* Otherwise we can implement this operation by emitting a barrier
5582 followed by a store of zero. */
5583 expand_builtin_synchronize ();
5584 emit_move_insn (mem, val);
5587 /* Expand an expression EXP that calls a built-in function,
5588 with result going to TARGET if that's convenient
5589 (and in mode MODE if that's convenient).
5590 SUBTARGET may be used as the target for computing one of EXP's operands.
5591 IGNORE is nonzero if the value is to be ignored. */
5594 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5595 int ignore)
5597 tree fndecl = get_callee_fndecl (exp);
5598 tree arglist = TREE_OPERAND (exp, 1);
5599 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5600 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5602 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5603 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5605 /* When not optimizing, generate calls to library functions for a certain
5606 set of builtins. */
5607 if (!optimize
5608 && !called_as_built_in (fndecl)
5609 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5610 && fcode != BUILT_IN_ALLOCA)
5611 return expand_call (exp, target, ignore);
5613 /* The built-in function expanders test for target == const0_rtx
5614 to determine whether the function's result will be ignored. */
5615 if (ignore)
5616 target = const0_rtx;
5618 /* If the result of a pure or const built-in function is ignored, and
5619 none of its arguments are volatile, we can avoid expanding the
5620 built-in call and just evaluate the arguments for side-effects. */
5621 if (target == const0_rtx
5622 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5624 bool volatilep = false;
5625 tree arg;
5627 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5628 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5630 volatilep = true;
5631 break;
5634 if (! volatilep)
5636 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5637 expand_expr (TREE_VALUE (arg), const0_rtx,
5638 VOIDmode, EXPAND_NORMAL);
5639 return const0_rtx;
5643 switch (fcode)
5645 CASE_FLT_FN (BUILT_IN_FABS):
5646 target = expand_builtin_fabs (arglist, target, subtarget);
5647 if (target)
5648 return target;
5649 break;
5651 CASE_FLT_FN (BUILT_IN_COPYSIGN):
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_FLT_FN (BUILT_IN_CABS):
5660 break;
5662 CASE_FLT_FN (BUILT_IN_EXP):
5663 CASE_FLT_FN (BUILT_IN_EXP10):
5664 CASE_FLT_FN (BUILT_IN_POW10):
5665 CASE_FLT_FN (BUILT_IN_EXP2):
5666 CASE_FLT_FN (BUILT_IN_EXPM1):
5667 CASE_FLT_FN (BUILT_IN_LOGB):
5668 CASE_FLT_FN (BUILT_IN_ILOGB):
5669 CASE_FLT_FN (BUILT_IN_LOG):
5670 CASE_FLT_FN (BUILT_IN_LOG10):
5671 CASE_FLT_FN (BUILT_IN_LOG2):
5672 CASE_FLT_FN (BUILT_IN_LOG1P):
5673 CASE_FLT_FN (BUILT_IN_TAN):
5674 CASE_FLT_FN (BUILT_IN_ASIN):
5675 CASE_FLT_FN (BUILT_IN_ACOS):
5676 CASE_FLT_FN (BUILT_IN_ATAN):
5677 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5678 because of possible accuracy problems. */
5679 if (! flag_unsafe_math_optimizations)
5680 break;
5681 CASE_FLT_FN (BUILT_IN_SQRT):
5682 CASE_FLT_FN (BUILT_IN_FLOOR):
5683 CASE_FLT_FN (BUILT_IN_CEIL):
5684 CASE_FLT_FN (BUILT_IN_TRUNC):
5685 CASE_FLT_FN (BUILT_IN_ROUND):
5686 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5687 CASE_FLT_FN (BUILT_IN_RINT):
5688 CASE_FLT_FN (BUILT_IN_LRINT):
5689 CASE_FLT_FN (BUILT_IN_LLRINT):
5690 target = expand_builtin_mathfn (exp, target, subtarget);
5691 if (target)
5692 return target;
5693 break;
5695 CASE_FLT_FN (BUILT_IN_LCEIL):
5696 CASE_FLT_FN (BUILT_IN_LLCEIL):
5697 CASE_FLT_FN (BUILT_IN_LFLOOR):
5698 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5699 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5700 if (target)
5701 return target;
5702 break;
5704 CASE_FLT_FN (BUILT_IN_POW):
5705 target = expand_builtin_pow (exp, target, subtarget);
5706 if (target)
5707 return target;
5708 break;
5710 CASE_FLT_FN (BUILT_IN_POWI):
5711 target = expand_builtin_powi (exp, target, subtarget);
5712 if (target)
5713 return target;
5714 break;
5716 CASE_FLT_FN (BUILT_IN_ATAN2):
5717 CASE_FLT_FN (BUILT_IN_LDEXP):
5718 CASE_FLT_FN (BUILT_IN_FMOD):
5719 CASE_FLT_FN (BUILT_IN_DREM):
5720 if (! flag_unsafe_math_optimizations)
5721 break;
5722 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5723 if (target)
5724 return target;
5725 break;
5727 CASE_FLT_FN (BUILT_IN_SIN):
5728 CASE_FLT_FN (BUILT_IN_COS):
5729 if (! flag_unsafe_math_optimizations)
5730 break;
5731 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5732 if (target)
5733 return target;
5734 break;
5736 CASE_FLT_FN (BUILT_IN_SINCOS):
5737 if (! flag_unsafe_math_optimizations)
5738 break;
5739 target = expand_builtin_sincos (exp);
5740 if (target)
5741 return target;
5742 break;
5744 case BUILT_IN_APPLY_ARGS:
5745 return expand_builtin_apply_args ();
5747 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5748 FUNCTION with a copy of the parameters described by
5749 ARGUMENTS, and ARGSIZE. It returns a block of memory
5750 allocated on the stack into which is stored all the registers
5751 that might possibly be used for returning the result of a
5752 function. ARGUMENTS is the value returned by
5753 __builtin_apply_args. ARGSIZE is the number of bytes of
5754 arguments that must be copied. ??? How should this value be
5755 computed? We'll also need a safe worst case value for varargs
5756 functions. */
5757 case BUILT_IN_APPLY:
5758 if (!validate_arglist (arglist, POINTER_TYPE,
5759 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5760 && !validate_arglist (arglist, REFERENCE_TYPE,
5761 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5762 return const0_rtx;
5763 else
5765 int i;
5766 tree t;
5767 rtx ops[3];
5769 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5770 ops[i] = expand_normal (TREE_VALUE (t));
5772 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5775 /* __builtin_return (RESULT) causes the function to return the
5776 value described by RESULT. RESULT is address of the block of
5777 memory returned by __builtin_apply. */
5778 case BUILT_IN_RETURN:
5779 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5780 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5781 return const0_rtx;
5783 case BUILT_IN_SAVEREGS:
5784 return expand_builtin_saveregs ();
5786 case BUILT_IN_ARGS_INFO:
5787 return expand_builtin_args_info (arglist);
5789 /* Return the address of the first anonymous stack arg. */
5790 case BUILT_IN_NEXT_ARG:
5791 if (fold_builtin_next_arg (arglist))
5792 return const0_rtx;
5793 return expand_builtin_next_arg ();
5795 case BUILT_IN_CLASSIFY_TYPE:
5796 return expand_builtin_classify_type (arglist);
5798 case BUILT_IN_CONSTANT_P:
5799 return const0_rtx;
5801 case BUILT_IN_FRAME_ADDRESS:
5802 case BUILT_IN_RETURN_ADDRESS:
5803 return expand_builtin_frame_address (fndecl, arglist);
5805 /* Returns the address of the area where the structure is returned.
5806 0 otherwise. */
5807 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5808 if (arglist != 0
5809 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5810 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5811 return const0_rtx;
5812 else
5813 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5815 case BUILT_IN_ALLOCA:
5816 target = expand_builtin_alloca (arglist, target);
5817 if (target)
5818 return target;
5819 break;
5821 case BUILT_IN_STACK_SAVE:
5822 return expand_stack_save ();
5824 case BUILT_IN_STACK_RESTORE:
5825 expand_stack_restore (TREE_VALUE (arglist));
5826 return const0_rtx;
5828 CASE_INT_FN (BUILT_IN_FFS):
5829 case BUILT_IN_FFSIMAX:
5830 target = expand_builtin_unop (target_mode, arglist, target,
5831 subtarget, ffs_optab);
5832 if (target)
5833 return target;
5834 break;
5836 CASE_INT_FN (BUILT_IN_CLZ):
5837 case BUILT_IN_CLZIMAX:
5838 target = expand_builtin_unop (target_mode, arglist, target,
5839 subtarget, clz_optab);
5840 if (target)
5841 return target;
5842 break;
5844 CASE_INT_FN (BUILT_IN_CTZ):
5845 case BUILT_IN_CTZIMAX:
5846 target = expand_builtin_unop (target_mode, arglist, target,
5847 subtarget, ctz_optab);
5848 if (target)
5849 return target;
5850 break;
5852 CASE_INT_FN (BUILT_IN_POPCOUNT):
5853 case BUILT_IN_POPCOUNTIMAX:
5854 target = expand_builtin_unop (target_mode, arglist, target,
5855 subtarget, popcount_optab);
5856 if (target)
5857 return target;
5858 break;
5860 CASE_INT_FN (BUILT_IN_PARITY):
5861 case BUILT_IN_PARITYIMAX:
5862 target = expand_builtin_unop (target_mode, arglist, target,
5863 subtarget, parity_optab);
5864 if (target)
5865 return target;
5866 break;
5868 case BUILT_IN_STRLEN:
5869 target = expand_builtin_strlen (arglist, target, target_mode);
5870 if (target)
5871 return target;
5872 break;
5874 case BUILT_IN_STRCPY:
5875 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5876 if (target)
5877 return target;
5878 break;
5880 case BUILT_IN_STRNCPY:
5881 target = expand_builtin_strncpy (exp, target, mode);
5882 if (target)
5883 return target;
5884 break;
5886 case BUILT_IN_STPCPY:
5887 target = expand_builtin_stpcpy (exp, target, mode);
5888 if (target)
5889 return target;
5890 break;
5892 case BUILT_IN_STRCAT:
5893 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5894 if (target)
5895 return target;
5896 break;
5898 case BUILT_IN_STRNCAT:
5899 target = expand_builtin_strncat (arglist, target, mode);
5900 if (target)
5901 return target;
5902 break;
5904 case BUILT_IN_STRSPN:
5905 target = expand_builtin_strspn (arglist, target, mode);
5906 if (target)
5907 return target;
5908 break;
5910 case BUILT_IN_STRCSPN:
5911 target = expand_builtin_strcspn (arglist, target, mode);
5912 if (target)
5913 return target;
5914 break;
5916 case BUILT_IN_STRSTR:
5917 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5918 if (target)
5919 return target;
5920 break;
5922 case BUILT_IN_STRPBRK:
5923 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5924 if (target)
5925 return target;
5926 break;
5928 case BUILT_IN_INDEX:
5929 case BUILT_IN_STRCHR:
5930 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5931 if (target)
5932 return target;
5933 break;
5935 case BUILT_IN_RINDEX:
5936 case BUILT_IN_STRRCHR:
5937 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5938 if (target)
5939 return target;
5940 break;
5942 case BUILT_IN_MEMCPY:
5943 target = expand_builtin_memcpy (exp, target, mode);
5944 if (target)
5945 return target;
5946 break;
5948 case BUILT_IN_MEMPCPY:
5949 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5950 if (target)
5951 return target;
5952 break;
5954 case BUILT_IN_MEMMOVE:
5955 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5956 mode, exp);
5957 if (target)
5958 return target;
5959 break;
5961 case BUILT_IN_BCOPY:
5962 target = expand_builtin_bcopy (exp);
5963 if (target)
5964 return target;
5965 break;
5967 case BUILT_IN_MEMSET:
5968 target = expand_builtin_memset (arglist, target, mode, exp);
5969 if (target)
5970 return target;
5971 break;
5973 case BUILT_IN_BZERO:
5974 target = expand_builtin_bzero (exp);
5975 if (target)
5976 return target;
5977 break;
5979 case BUILT_IN_STRCMP:
5980 target = expand_builtin_strcmp (exp, target, mode);
5981 if (target)
5982 return target;
5983 break;
5985 case BUILT_IN_STRNCMP:
5986 target = expand_builtin_strncmp (exp, target, mode);
5987 if (target)
5988 return target;
5989 break;
5991 case BUILT_IN_BCMP:
5992 case BUILT_IN_MEMCMP:
5993 target = expand_builtin_memcmp (exp, arglist, target, mode);
5994 if (target)
5995 return target;
5996 break;
5998 case BUILT_IN_SETJMP:
5999 target = expand_builtin_setjmp (arglist, target);
6000 if (target)
6001 return target;
6002 break;
6004 /* __builtin_longjmp is passed a pointer to an array of five words.
6005 It's similar to the C library longjmp function but works with
6006 __builtin_setjmp above. */
6007 case BUILT_IN_LONGJMP:
6008 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6009 break;
6010 else
6012 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6013 VOIDmode, EXPAND_NORMAL);
6014 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6016 if (value != const1_rtx)
6018 error ("%<__builtin_longjmp%> second argument must be 1");
6019 return const0_rtx;
6022 expand_builtin_longjmp (buf_addr, value);
6023 return const0_rtx;
6026 case BUILT_IN_NONLOCAL_GOTO:
6027 target = expand_builtin_nonlocal_goto (arglist);
6028 if (target)
6029 return target;
6030 break;
6032 /* This updates the setjmp buffer that is its argument with the value
6033 of the current stack pointer. */
6034 case BUILT_IN_UPDATE_SETJMP_BUF:
6035 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6037 rtx buf_addr
6038 = expand_normal (TREE_VALUE (arglist));
6040 expand_builtin_update_setjmp_buf (buf_addr);
6041 return const0_rtx;
6043 break;
6045 case BUILT_IN_TRAP:
6046 expand_builtin_trap ();
6047 return const0_rtx;
6049 case BUILT_IN_PRINTF:
6050 target = expand_builtin_printf (exp, target, mode, false);
6051 if (target)
6052 return target;
6053 break;
6055 case BUILT_IN_PRINTF_UNLOCKED:
6056 target = expand_builtin_printf (exp, target, mode, true);
6057 if (target)
6058 return target;
6059 break;
6061 case BUILT_IN_FPUTS:
6062 target = expand_builtin_fputs (arglist, target, false);
6063 if (target)
6064 return target;
6065 break;
6066 case BUILT_IN_FPUTS_UNLOCKED:
6067 target = expand_builtin_fputs (arglist, target, true);
6068 if (target)
6069 return target;
6070 break;
6072 case BUILT_IN_FPRINTF:
6073 target = expand_builtin_fprintf (exp, target, mode, false);
6074 if (target)
6075 return target;
6076 break;
6078 case BUILT_IN_FPRINTF_UNLOCKED:
6079 target = expand_builtin_fprintf (exp, target, mode, true);
6080 if (target)
6081 return target;
6082 break;
6084 case BUILT_IN_SPRINTF:
6085 target = expand_builtin_sprintf (arglist, target, mode);
6086 if (target)
6087 return target;
6088 break;
6090 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6091 target = expand_builtin_signbit (exp, target);
6092 if (target)
6093 return target;
6094 break;
6096 /* Various hooks for the DWARF 2 __throw routine. */
6097 case BUILT_IN_UNWIND_INIT:
6098 expand_builtin_unwind_init ();
6099 return const0_rtx;
6100 case BUILT_IN_DWARF_CFA:
6101 return virtual_cfa_rtx;
6102 #ifdef DWARF2_UNWIND_INFO
6103 case BUILT_IN_DWARF_SP_COLUMN:
6104 return expand_builtin_dwarf_sp_column ();
6105 case BUILT_IN_INIT_DWARF_REG_SIZES:
6106 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6107 return const0_rtx;
6108 #endif
6109 case BUILT_IN_FROB_RETURN_ADDR:
6110 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6111 case BUILT_IN_EXTRACT_RETURN_ADDR:
6112 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6113 case BUILT_IN_EH_RETURN:
6114 expand_builtin_eh_return (TREE_VALUE (arglist),
6115 TREE_VALUE (TREE_CHAIN (arglist)));
6116 return const0_rtx;
6117 #ifdef EH_RETURN_DATA_REGNO
6118 case BUILT_IN_EH_RETURN_DATA_REGNO:
6119 return expand_builtin_eh_return_data_regno (arglist);
6120 #endif
6121 case BUILT_IN_EXTEND_POINTER:
6122 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6124 case BUILT_IN_VA_START:
6125 case BUILT_IN_STDARG_START:
6126 return expand_builtin_va_start (arglist);
6127 case BUILT_IN_VA_END:
6128 return expand_builtin_va_end (arglist);
6129 case BUILT_IN_VA_COPY:
6130 return expand_builtin_va_copy (arglist);
6131 case BUILT_IN_EXPECT:
6132 return expand_builtin_expect (arglist, target);
6133 case BUILT_IN_PREFETCH:
6134 expand_builtin_prefetch (arglist);
6135 return const0_rtx;
6137 case BUILT_IN_PROFILE_FUNC_ENTER:
6138 return expand_builtin_profile_func (false);
6139 case BUILT_IN_PROFILE_FUNC_EXIT:
6140 return expand_builtin_profile_func (true);
6142 case BUILT_IN_INIT_TRAMPOLINE:
6143 return expand_builtin_init_trampoline (arglist);
6144 case BUILT_IN_ADJUST_TRAMPOLINE:
6145 return expand_builtin_adjust_trampoline (arglist);
6147 case BUILT_IN_FORK:
6148 case BUILT_IN_EXECL:
6149 case BUILT_IN_EXECV:
6150 case BUILT_IN_EXECLP:
6151 case BUILT_IN_EXECLE:
6152 case BUILT_IN_EXECVP:
6153 case BUILT_IN_EXECVE:
6154 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6155 if (target)
6156 return target;
6157 break;
6159 case BUILT_IN_FETCH_AND_ADD_1:
6160 case BUILT_IN_FETCH_AND_ADD_2:
6161 case BUILT_IN_FETCH_AND_ADD_4:
6162 case BUILT_IN_FETCH_AND_ADD_8:
6163 case BUILT_IN_FETCH_AND_ADD_16:
6164 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6165 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6166 false, target, ignore);
6167 if (target)
6168 return target;
6169 break;
6171 case BUILT_IN_FETCH_AND_SUB_1:
6172 case BUILT_IN_FETCH_AND_SUB_2:
6173 case BUILT_IN_FETCH_AND_SUB_4:
6174 case BUILT_IN_FETCH_AND_SUB_8:
6175 case BUILT_IN_FETCH_AND_SUB_16:
6176 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6177 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6178 false, target, ignore);
6179 if (target)
6180 return target;
6181 break;
6183 case BUILT_IN_FETCH_AND_OR_1:
6184 case BUILT_IN_FETCH_AND_OR_2:
6185 case BUILT_IN_FETCH_AND_OR_4:
6186 case BUILT_IN_FETCH_AND_OR_8:
6187 case BUILT_IN_FETCH_AND_OR_16:
6188 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6189 target = expand_builtin_sync_operation (mode, arglist, IOR,
6190 false, target, ignore);
6191 if (target)
6192 return target;
6193 break;
6195 case BUILT_IN_FETCH_AND_AND_1:
6196 case BUILT_IN_FETCH_AND_AND_2:
6197 case BUILT_IN_FETCH_AND_AND_4:
6198 case BUILT_IN_FETCH_AND_AND_8:
6199 case BUILT_IN_FETCH_AND_AND_16:
6200 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6201 target = expand_builtin_sync_operation (mode, arglist, AND,
6202 false, target, ignore);
6203 if (target)
6204 return target;
6205 break;
6207 case BUILT_IN_FETCH_AND_XOR_1:
6208 case BUILT_IN_FETCH_AND_XOR_2:
6209 case BUILT_IN_FETCH_AND_XOR_4:
6210 case BUILT_IN_FETCH_AND_XOR_8:
6211 case BUILT_IN_FETCH_AND_XOR_16:
6212 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6213 target = expand_builtin_sync_operation (mode, arglist, XOR,
6214 false, target, ignore);
6215 if (target)
6216 return target;
6217 break;
6219 case BUILT_IN_FETCH_AND_NAND_1:
6220 case BUILT_IN_FETCH_AND_NAND_2:
6221 case BUILT_IN_FETCH_AND_NAND_4:
6222 case BUILT_IN_FETCH_AND_NAND_8:
6223 case BUILT_IN_FETCH_AND_NAND_16:
6224 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6225 target = expand_builtin_sync_operation (mode, arglist, NOT,
6226 false, target, ignore);
6227 if (target)
6228 return target;
6229 break;
6231 case BUILT_IN_ADD_AND_FETCH_1:
6232 case BUILT_IN_ADD_AND_FETCH_2:
6233 case BUILT_IN_ADD_AND_FETCH_4:
6234 case BUILT_IN_ADD_AND_FETCH_8:
6235 case BUILT_IN_ADD_AND_FETCH_16:
6236 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6237 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6238 true, target, ignore);
6239 if (target)
6240 return target;
6241 break;
6243 case BUILT_IN_SUB_AND_FETCH_1:
6244 case BUILT_IN_SUB_AND_FETCH_2:
6245 case BUILT_IN_SUB_AND_FETCH_4:
6246 case BUILT_IN_SUB_AND_FETCH_8:
6247 case BUILT_IN_SUB_AND_FETCH_16:
6248 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6249 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6250 true, target, ignore);
6251 if (target)
6252 return target;
6253 break;
6255 case BUILT_IN_OR_AND_FETCH_1:
6256 case BUILT_IN_OR_AND_FETCH_2:
6257 case BUILT_IN_OR_AND_FETCH_4:
6258 case BUILT_IN_OR_AND_FETCH_8:
6259 case BUILT_IN_OR_AND_FETCH_16:
6260 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6261 target = expand_builtin_sync_operation (mode, arglist, IOR,
6262 true, target, ignore);
6263 if (target)
6264 return target;
6265 break;
6267 case BUILT_IN_AND_AND_FETCH_1:
6268 case BUILT_IN_AND_AND_FETCH_2:
6269 case BUILT_IN_AND_AND_FETCH_4:
6270 case BUILT_IN_AND_AND_FETCH_8:
6271 case BUILT_IN_AND_AND_FETCH_16:
6272 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6273 target = expand_builtin_sync_operation (mode, arglist, AND,
6274 true, target, ignore);
6275 if (target)
6276 return target;
6277 break;
6279 case BUILT_IN_XOR_AND_FETCH_1:
6280 case BUILT_IN_XOR_AND_FETCH_2:
6281 case BUILT_IN_XOR_AND_FETCH_4:
6282 case BUILT_IN_XOR_AND_FETCH_8:
6283 case BUILT_IN_XOR_AND_FETCH_16:
6284 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6285 target = expand_builtin_sync_operation (mode, arglist, XOR,
6286 true, target, ignore);
6287 if (target)
6288 return target;
6289 break;
6291 case BUILT_IN_NAND_AND_FETCH_1:
6292 case BUILT_IN_NAND_AND_FETCH_2:
6293 case BUILT_IN_NAND_AND_FETCH_4:
6294 case BUILT_IN_NAND_AND_FETCH_8:
6295 case BUILT_IN_NAND_AND_FETCH_16:
6296 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6297 target = expand_builtin_sync_operation (mode, arglist, NOT,
6298 true, target, ignore);
6299 if (target)
6300 return target;
6301 break;
6303 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6304 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6305 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6306 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6307 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6308 if (mode == VOIDmode)
6309 mode = TYPE_MODE (boolean_type_node);
6310 if (!target || !register_operand (target, mode))
6311 target = gen_reg_rtx (mode);
6313 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6314 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6315 if (target)
6316 return target;
6317 break;
6319 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6320 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6321 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6322 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6323 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6324 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6325 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6326 if (target)
6327 return target;
6328 break;
6330 case BUILT_IN_LOCK_TEST_AND_SET_1:
6331 case BUILT_IN_LOCK_TEST_AND_SET_2:
6332 case BUILT_IN_LOCK_TEST_AND_SET_4:
6333 case BUILT_IN_LOCK_TEST_AND_SET_8:
6334 case BUILT_IN_LOCK_TEST_AND_SET_16:
6335 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6336 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6337 if (target)
6338 return target;
6339 break;
6341 case BUILT_IN_LOCK_RELEASE_1:
6342 case BUILT_IN_LOCK_RELEASE_2:
6343 case BUILT_IN_LOCK_RELEASE_4:
6344 case BUILT_IN_LOCK_RELEASE_8:
6345 case BUILT_IN_LOCK_RELEASE_16:
6346 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6347 expand_builtin_lock_release (mode, arglist);
6348 return const0_rtx;
6350 case BUILT_IN_SYNCHRONIZE:
6351 expand_builtin_synchronize ();
6352 return const0_rtx;
6354 case BUILT_IN_OBJECT_SIZE:
6355 return expand_builtin_object_size (exp);
6357 case BUILT_IN_MEMCPY_CHK:
6358 case BUILT_IN_MEMPCPY_CHK:
6359 case BUILT_IN_MEMMOVE_CHK:
6360 case BUILT_IN_MEMSET_CHK:
6361 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6362 if (target)
6363 return target;
6364 break;
6366 case BUILT_IN_STRCPY_CHK:
6367 case BUILT_IN_STPCPY_CHK:
6368 case BUILT_IN_STRNCPY_CHK:
6369 case BUILT_IN_STRCAT_CHK:
6370 case BUILT_IN_SNPRINTF_CHK:
6371 case BUILT_IN_VSNPRINTF_CHK:
6372 maybe_emit_chk_warning (exp, fcode);
6373 break;
6375 case BUILT_IN_SPRINTF_CHK:
6376 case BUILT_IN_VSPRINTF_CHK:
6377 maybe_emit_sprintf_chk_warning (exp, fcode);
6378 break;
6380 default: /* just do library call, if unknown builtin */
6381 break;
6384 /* The switch statement above can drop through to cause the function
6385 to be called normally. */
6386 return expand_call (exp, target, ignore);
6389 /* Determine whether a tree node represents a call to a built-in
6390 function. If the tree T is a call to a built-in function with
6391 the right number of arguments of the appropriate types, return
6392 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6393 Otherwise the return value is END_BUILTINS. */
6395 enum built_in_function
6396 builtin_mathfn_code (tree t)
6398 tree fndecl, arglist, parmlist;
6399 tree argtype, parmtype;
6401 if (TREE_CODE (t) != CALL_EXPR
6402 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6403 return END_BUILTINS;
6405 fndecl = get_callee_fndecl (t);
6406 if (fndecl == NULL_TREE
6407 || TREE_CODE (fndecl) != FUNCTION_DECL
6408 || ! DECL_BUILT_IN (fndecl)
6409 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6410 return END_BUILTINS;
6412 arglist = TREE_OPERAND (t, 1);
6413 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6414 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6416 /* If a function doesn't take a variable number of arguments,
6417 the last element in the list will have type `void'. */
6418 parmtype = TREE_VALUE (parmlist);
6419 if (VOID_TYPE_P (parmtype))
6421 if (arglist)
6422 return END_BUILTINS;
6423 return DECL_FUNCTION_CODE (fndecl);
6426 if (! arglist)
6427 return END_BUILTINS;
6429 argtype = TREE_TYPE (TREE_VALUE (arglist));
6431 if (SCALAR_FLOAT_TYPE_P (parmtype))
6433 if (! SCALAR_FLOAT_TYPE_P (argtype))
6434 return END_BUILTINS;
6436 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6438 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6439 return END_BUILTINS;
6441 else if (POINTER_TYPE_P (parmtype))
6443 if (! POINTER_TYPE_P (argtype))
6444 return END_BUILTINS;
6446 else if (INTEGRAL_TYPE_P (parmtype))
6448 if (! INTEGRAL_TYPE_P (argtype))
6449 return END_BUILTINS;
6451 else
6452 return END_BUILTINS;
6454 arglist = TREE_CHAIN (arglist);
6457 /* Variable-length argument list. */
6458 return DECL_FUNCTION_CODE (fndecl);
6461 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6462 constant. ARGLIST is the argument list of the call. */
6464 static tree
6465 fold_builtin_constant_p (tree arglist)
6467 if (arglist == 0)
6468 return 0;
6470 arglist = TREE_VALUE (arglist);
6472 /* We return 1 for a numeric type that's known to be a constant
6473 value at compile-time or for an aggregate type that's a
6474 literal constant. */
6475 STRIP_NOPS (arglist);
6477 /* If we know this is a constant, emit the constant of one. */
6478 if (CONSTANT_CLASS_P (arglist)
6479 || (TREE_CODE (arglist) == CONSTRUCTOR
6480 && TREE_CONSTANT (arglist)))
6481 return integer_one_node;
6482 if (TREE_CODE (arglist) == ADDR_EXPR)
6484 tree op = TREE_OPERAND (arglist, 0);
6485 if (TREE_CODE (op) == STRING_CST
6486 || (TREE_CODE (op) == ARRAY_REF
6487 && integer_zerop (TREE_OPERAND (op, 1))
6488 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6489 return integer_one_node;
6492 /* If this expression has side effects, show we don't know it to be a
6493 constant. Likewise if it's a pointer or aggregate type since in
6494 those case we only want literals, since those are only optimized
6495 when generating RTL, not later.
6496 And finally, if we are compiling an initializer, not code, we
6497 need to return a definite result now; there's not going to be any
6498 more optimization done. */
6499 if (TREE_SIDE_EFFECTS (arglist)
6500 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6501 || POINTER_TYPE_P (TREE_TYPE (arglist))
6502 || cfun == 0
6503 || folding_initializer)
6504 return integer_zero_node;
6506 return 0;
6509 /* Fold a call to __builtin_expect, if we expect that a comparison against
6510 the argument will fold to a constant. In practice, this means a true
6511 constant or the address of a non-weak symbol. ARGLIST is the argument
6512 list of the call. */
6514 static tree
6515 fold_builtin_expect (tree arglist)
6517 tree arg, inner;
6519 if (arglist == 0)
6520 return 0;
6522 arg = TREE_VALUE (arglist);
6524 /* If the argument isn't invariant, then there's nothing we can do. */
6525 if (!TREE_INVARIANT (arg))
6526 return 0;
6528 /* If we're looking at an address of a weak decl, then do not fold. */
6529 inner = arg;
6530 STRIP_NOPS (inner);
6531 if (TREE_CODE (inner) == ADDR_EXPR)
6535 inner = TREE_OPERAND (inner, 0);
6537 while (TREE_CODE (inner) == COMPONENT_REF
6538 || TREE_CODE (inner) == ARRAY_REF);
6539 if (DECL_P (inner) && DECL_WEAK (inner))
6540 return 0;
6543 /* Otherwise, ARG already has the proper type for the return value. */
6544 return arg;
6547 /* Fold a call to __builtin_classify_type. */
6549 static tree
6550 fold_builtin_classify_type (tree arglist)
6552 if (arglist == 0)
6553 return build_int_cst (NULL_TREE, no_type_class);
6555 return build_int_cst (NULL_TREE,
6556 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6559 /* Fold a call to __builtin_strlen. */
6561 static tree
6562 fold_builtin_strlen (tree arglist)
6564 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6565 return NULL_TREE;
6566 else
6568 tree len = c_strlen (TREE_VALUE (arglist), 0);
6570 if (len)
6572 /* Convert from the internal "sizetype" type to "size_t". */
6573 if (size_type_node)
6574 len = fold_convert (size_type_node, len);
6575 return len;
6578 return NULL_TREE;
6582 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6584 static tree
6585 fold_builtin_inf (tree type, int warn)
6587 REAL_VALUE_TYPE real;
6589 /* __builtin_inff is intended to be usable to define INFINITY on all
6590 targets. If an infinity is not available, INFINITY expands "to a
6591 positive constant of type float that overflows at translation
6592 time", footnote "In this case, using INFINITY will violate the
6593 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6594 Thus we pedwarn to ensure this constraint violation is
6595 diagnosed. */
6596 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6597 pedwarn ("target format does not support infinity");
6599 real_inf (&real);
6600 return build_real (type, real);
6603 /* Fold a call to __builtin_nan or __builtin_nans. */
6605 static tree
6606 fold_builtin_nan (tree arglist, tree type, int quiet)
6608 REAL_VALUE_TYPE real;
6609 const char *str;
6611 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6612 return 0;
6613 str = c_getstr (TREE_VALUE (arglist));
6614 if (!str)
6615 return 0;
6617 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6618 return 0;
6620 return build_real (type, real);
6623 /* Return true if the floating point expression T has an integer value.
6624 We also allow +Inf, -Inf and NaN to be considered integer values. */
6626 static bool
6627 integer_valued_real_p (tree t)
6629 switch (TREE_CODE (t))
6631 case FLOAT_EXPR:
6632 return true;
6634 case ABS_EXPR:
6635 case SAVE_EXPR:
6636 case NON_LVALUE_EXPR:
6637 return integer_valued_real_p (TREE_OPERAND (t, 0));
6639 case COMPOUND_EXPR:
6640 case MODIFY_EXPR:
6641 case BIND_EXPR:
6642 return integer_valued_real_p (TREE_OPERAND (t, 1));
6644 case PLUS_EXPR:
6645 case MINUS_EXPR:
6646 case MULT_EXPR:
6647 case MIN_EXPR:
6648 case MAX_EXPR:
6649 return integer_valued_real_p (TREE_OPERAND (t, 0))
6650 && integer_valued_real_p (TREE_OPERAND (t, 1));
6652 case COND_EXPR:
6653 return integer_valued_real_p (TREE_OPERAND (t, 1))
6654 && integer_valued_real_p (TREE_OPERAND (t, 2));
6656 case REAL_CST:
6657 if (! TREE_CONSTANT_OVERFLOW (t))
6659 REAL_VALUE_TYPE c, cint;
6661 c = TREE_REAL_CST (t);
6662 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6663 return real_identical (&c, &cint);
6665 break;
6667 case NOP_EXPR:
6669 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6670 if (TREE_CODE (type) == INTEGER_TYPE)
6671 return true;
6672 if (TREE_CODE (type) == REAL_TYPE)
6673 return integer_valued_real_p (TREE_OPERAND (t, 0));
6674 break;
6677 case CALL_EXPR:
6678 switch (builtin_mathfn_code (t))
6680 CASE_FLT_FN (BUILT_IN_CEIL):
6681 CASE_FLT_FN (BUILT_IN_FLOOR):
6682 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6683 CASE_FLT_FN (BUILT_IN_RINT):
6684 CASE_FLT_FN (BUILT_IN_ROUND):
6685 CASE_FLT_FN (BUILT_IN_TRUNC):
6686 return true;
6688 default:
6689 break;
6691 break;
6693 default:
6694 break;
6696 return false;
6699 /* EXP is assumed to be builtin call where truncation can be propagated
6700 across (for instance floor((double)f) == (double)floorf (f).
6701 Do the transformation. */
6703 static tree
6704 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6706 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6707 tree arg;
6709 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6710 return 0;
6712 arg = TREE_VALUE (arglist);
6713 /* Integer rounding functions are idempotent. */
6714 if (fcode == builtin_mathfn_code (arg))
6715 return arg;
6717 /* If argument is already integer valued, and we don't need to worry
6718 about setting errno, there's no need to perform rounding. */
6719 if (! flag_errno_math && integer_valued_real_p (arg))
6720 return arg;
6722 if (optimize)
6724 tree arg0 = strip_float_extensions (arg);
6725 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6726 tree newtype = TREE_TYPE (arg0);
6727 tree decl;
6729 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6730 && (decl = mathfn_built_in (newtype, fcode)))
6732 arglist =
6733 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6734 return fold_convert (ftype,
6735 build_function_call_expr (decl, arglist));
6738 return 0;
6741 /* EXP is assumed to be builtin call which can narrow the FP type of
6742 the argument, for instance lround((double)f) -> lroundf (f). */
6744 static tree
6745 fold_fixed_mathfn (tree fndecl, tree arglist)
6747 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6748 tree arg;
6750 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6751 return 0;
6753 arg = TREE_VALUE (arglist);
6755 /* If argument is already integer valued, and we don't need to worry
6756 about setting errno, there's no need to perform rounding. */
6757 if (! flag_errno_math && integer_valued_real_p (arg))
6758 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6760 if (optimize)
6762 tree ftype = TREE_TYPE (arg);
6763 tree arg0 = strip_float_extensions (arg);
6764 tree newtype = TREE_TYPE (arg0);
6765 tree decl;
6767 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6768 && (decl = mathfn_built_in (newtype, fcode)))
6770 arglist =
6771 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6772 return build_function_call_expr (decl, arglist);
6776 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6777 sizeof (long long) == sizeof (long). */
6778 if (TYPE_PRECISION (long_long_integer_type_node)
6779 == TYPE_PRECISION (long_integer_type_node))
6781 tree newfn = NULL_TREE;
6782 switch (fcode)
6784 CASE_FLT_FN (BUILT_IN_LLCEIL):
6785 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6786 break;
6788 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6789 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6790 break;
6792 CASE_FLT_FN (BUILT_IN_LLROUND):
6793 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6794 break;
6796 CASE_FLT_FN (BUILT_IN_LLRINT):
6797 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6798 break;
6800 default:
6801 break;
6804 if (newfn)
6806 tree newcall = build_function_call_expr (newfn, arglist);
6807 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6811 return 0;
6814 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6815 is the argument list, TYPE is the return type and FNDECL is the
6816 original function DECL. Return NULL_TREE if no if no simplification
6817 can be made. */
6819 static tree
6820 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6822 tree arg;
6824 if (!arglist || TREE_CHAIN (arglist))
6825 return NULL_TREE;
6827 arg = TREE_VALUE (arglist);
6828 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6829 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6830 return NULL_TREE;
6832 /* Evaluate cabs of a constant at compile-time. */
6833 if (flag_unsafe_math_optimizations
6834 && TREE_CODE (arg) == COMPLEX_CST
6835 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6836 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6837 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6838 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6840 REAL_VALUE_TYPE r, i;
6842 r = TREE_REAL_CST (TREE_REALPART (arg));
6843 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6845 real_arithmetic (&r, MULT_EXPR, &r, &r);
6846 real_arithmetic (&i, MULT_EXPR, &i, &i);
6847 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6848 if (real_sqrt (&r, TYPE_MODE (type), &r)
6849 || ! flag_trapping_math)
6850 return build_real (type, r);
6853 /* If either part is zero, cabs is fabs of the other. */
6854 if (TREE_CODE (arg) == COMPLEX_EXPR
6855 && real_zerop (TREE_OPERAND (arg, 0)))
6856 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6857 if (TREE_CODE (arg) == COMPLEX_EXPR
6858 && real_zerop (TREE_OPERAND (arg, 1)))
6859 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6861 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6862 if (TREE_CODE (arg) == NEGATE_EXPR
6863 || TREE_CODE (arg) == CONJ_EXPR)
6865 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6866 return build_function_call_expr (fndecl, arglist);
6869 /* Don't do this when optimizing for size. */
6870 if (flag_unsafe_math_optimizations
6871 && optimize && !optimize_size)
6873 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6875 if (sqrtfn != NULL_TREE)
6877 tree rpart, ipart, result, arglist;
6879 arg = builtin_save_expr (arg);
6881 rpart = fold_build1 (REALPART_EXPR, type, arg);
6882 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6884 rpart = builtin_save_expr (rpart);
6885 ipart = builtin_save_expr (ipart);
6887 result = fold_build2 (PLUS_EXPR, type,
6888 fold_build2 (MULT_EXPR, type,
6889 rpart, rpart),
6890 fold_build2 (MULT_EXPR, type,
6891 ipart, ipart));
6893 arglist = build_tree_list (NULL_TREE, result);
6894 return build_function_call_expr (sqrtfn, arglist);
6898 return NULL_TREE;
6901 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6902 NULL_TREE if no simplification can be made. */
6904 static tree
6905 fold_builtin_sqrt (tree arglist, tree type)
6908 enum built_in_function fcode;
6909 tree arg = TREE_VALUE (arglist);
6911 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6912 return NULL_TREE;
6914 /* Optimize sqrt of constant value. */
6915 if (TREE_CODE (arg) == REAL_CST
6916 && ! TREE_CONSTANT_OVERFLOW (arg))
6918 REAL_VALUE_TYPE r, x;
6920 x = TREE_REAL_CST (arg);
6921 if (real_sqrt (&r, TYPE_MODE (type), &x)
6922 || (!flag_trapping_math && !flag_errno_math))
6923 return build_real (type, r);
6926 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6927 fcode = builtin_mathfn_code (arg);
6928 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6930 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6931 arg = fold_build2 (MULT_EXPR, type,
6932 TREE_VALUE (TREE_OPERAND (arg, 1)),
6933 build_real (type, dconsthalf));
6934 arglist = build_tree_list (NULL_TREE, arg);
6935 return build_function_call_expr (expfn, arglist);
6938 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6939 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6941 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6943 if (powfn)
6945 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6946 tree tree_root;
6947 /* The inner root was either sqrt or cbrt. */
6948 REAL_VALUE_TYPE dconstroot =
6949 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6951 /* Adjust for the outer root. */
6952 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6953 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6954 tree_root = build_real (type, dconstroot);
6955 arglist = tree_cons (NULL_TREE, arg0,
6956 build_tree_list (NULL_TREE, tree_root));
6957 return build_function_call_expr (powfn, arglist);
6961 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6962 if (flag_unsafe_math_optimizations
6963 && (fcode == BUILT_IN_POW
6964 || fcode == BUILT_IN_POWF
6965 || fcode == BUILT_IN_POWL))
6967 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6968 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6969 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6970 tree narg1;
6971 if (!tree_expr_nonnegative_p (arg0))
6972 arg0 = build1 (ABS_EXPR, type, arg0);
6973 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6974 build_real (type, dconsthalf));
6975 arglist = tree_cons (NULL_TREE, arg0,
6976 build_tree_list (NULL_TREE, narg1));
6977 return build_function_call_expr (powfn, arglist);
6980 return NULL_TREE;
6983 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6984 NULL_TREE if no simplification can be made. */
6985 static tree
6986 fold_builtin_cbrt (tree arglist, tree type)
6988 tree arg = TREE_VALUE (arglist);
6989 const enum built_in_function fcode = builtin_mathfn_code (arg);
6991 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6992 return NULL_TREE;
6994 /* Optimize cbrt of constant value. */
6995 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6996 return arg;
6998 if (flag_unsafe_math_optimizations)
7000 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7001 if (BUILTIN_EXPONENT_P (fcode))
7003 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7004 const REAL_VALUE_TYPE third_trunc =
7005 real_value_truncate (TYPE_MODE (type), dconstthird);
7006 arg = fold_build2 (MULT_EXPR, type,
7007 TREE_VALUE (TREE_OPERAND (arg, 1)),
7008 build_real (type, third_trunc));
7009 arglist = build_tree_list (NULL_TREE, arg);
7010 return build_function_call_expr (expfn, arglist);
7013 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7014 if (BUILTIN_SQRT_P (fcode))
7016 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7018 if (powfn)
7020 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7021 tree tree_root;
7022 REAL_VALUE_TYPE dconstroot = dconstthird;
7024 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7025 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7026 tree_root = build_real (type, dconstroot);
7027 arglist = tree_cons (NULL_TREE, arg0,
7028 build_tree_list (NULL_TREE, tree_root));
7029 return build_function_call_expr (powfn, arglist);
7033 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7034 if (BUILTIN_CBRT_P (fcode))
7036 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7037 if (tree_expr_nonnegative_p (arg0))
7039 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7041 if (powfn)
7043 tree tree_root;
7044 REAL_VALUE_TYPE dconstroot;
7046 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7047 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7048 tree_root = build_real (type, dconstroot);
7049 arglist = tree_cons (NULL_TREE, arg0,
7050 build_tree_list (NULL_TREE, tree_root));
7051 return build_function_call_expr (powfn, arglist);
7056 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7057 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7058 || fcode == BUILT_IN_POWL)
7060 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7061 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7062 if (tree_expr_nonnegative_p (arg00))
7064 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7065 const REAL_VALUE_TYPE dconstroot
7066 = real_value_truncate (TYPE_MODE (type), dconstthird);
7067 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7068 build_real (type, dconstroot));
7069 arglist = tree_cons (NULL_TREE, arg00,
7070 build_tree_list (NULL_TREE, narg01));
7071 return build_function_call_expr (powfn, arglist);
7075 return NULL_TREE;
7078 /* Fold function call to builtin sin, sinf, or sinl. Return
7079 NULL_TREE if no simplification can be made. */
7080 static tree
7081 fold_builtin_sin (tree arglist)
7083 tree arg = TREE_VALUE (arglist);
7085 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7086 return NULL_TREE;
7088 /* Optimize sin (0.0) = 0.0. */
7089 if (real_zerop (arg))
7090 return arg;
7092 return NULL_TREE;
7095 /* Fold function call to builtin cos, cosf, or cosl. Return
7096 NULL_TREE if no simplification can be made. */
7097 static tree
7098 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7100 tree arg = TREE_VALUE (arglist);
7102 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7103 return NULL_TREE;
7105 /* Optimize cos (0.0) = 1.0. */
7106 if (real_zerop (arg))
7107 return build_real (type, dconst1);
7109 /* Optimize cos(-x) into cos (x). */
7110 if (TREE_CODE (arg) == NEGATE_EXPR)
7112 tree args = build_tree_list (NULL_TREE,
7113 TREE_OPERAND (arg, 0));
7114 return build_function_call_expr (fndecl, args);
7117 return NULL_TREE;
7120 /* Fold function call to builtin tan, tanf, or tanl. Return
7121 NULL_TREE if no simplification can be made. */
7122 static tree
7123 fold_builtin_tan (tree arglist)
7125 enum built_in_function fcode;
7126 tree arg = TREE_VALUE (arglist);
7128 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7129 return NULL_TREE;
7131 /* Optimize tan(0.0) = 0.0. */
7132 if (real_zerop (arg))
7133 return arg;
7135 /* Optimize tan(atan(x)) = x. */
7136 fcode = builtin_mathfn_code (arg);
7137 if (flag_unsafe_math_optimizations
7138 && (fcode == BUILT_IN_ATAN
7139 || fcode == BUILT_IN_ATANF
7140 || fcode == BUILT_IN_ATANL))
7141 return TREE_VALUE (TREE_OPERAND (arg, 1));
7143 return NULL_TREE;
7146 /* Fold function call to builtin atan, atanf, or atanl. Return
7147 NULL_TREE if no simplification can be made. */
7149 static tree
7150 fold_builtin_atan (tree arglist, tree type)
7153 tree arg = TREE_VALUE (arglist);
7155 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7156 return NULL_TREE;
7158 /* Optimize atan(0.0) = 0.0. */
7159 if (real_zerop (arg))
7160 return arg;
7162 /* Optimize atan(1.0) = pi/4. */
7163 if (real_onep (arg))
7165 REAL_VALUE_TYPE cst;
7167 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7168 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7169 return build_real (type, cst);
7172 return NULL_TREE;
7175 /* Fold function call to builtin trunc, truncf or truncl. Return
7176 NULL_TREE if no simplification can be made. */
7178 static tree
7179 fold_builtin_trunc (tree fndecl, tree arglist)
7181 tree arg;
7183 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7184 return 0;
7186 /* Optimize trunc of constant value. */
7187 arg = TREE_VALUE (arglist);
7188 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7190 REAL_VALUE_TYPE r, x;
7191 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7193 x = TREE_REAL_CST (arg);
7194 real_trunc (&r, TYPE_MODE (type), &x);
7195 return build_real (type, r);
7198 return fold_trunc_transparent_mathfn (fndecl, arglist);
7201 /* Fold function call to builtin floor, floorf or floorl. Return
7202 NULL_TREE if no simplification can be made. */
7204 static tree
7205 fold_builtin_floor (tree fndecl, tree arglist)
7207 tree arg;
7209 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7210 return 0;
7212 /* Optimize floor of constant value. */
7213 arg = TREE_VALUE (arglist);
7214 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7216 REAL_VALUE_TYPE x;
7218 x = TREE_REAL_CST (arg);
7219 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7221 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7222 REAL_VALUE_TYPE r;
7224 real_floor (&r, TYPE_MODE (type), &x);
7225 return build_real (type, r);
7229 return fold_trunc_transparent_mathfn (fndecl, arglist);
7232 /* Fold function call to builtin ceil, ceilf or ceill. Return
7233 NULL_TREE if no simplification can be made. */
7235 static tree
7236 fold_builtin_ceil (tree fndecl, tree arglist)
7238 tree arg;
7240 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7241 return 0;
7243 /* Optimize ceil of constant value. */
7244 arg = TREE_VALUE (arglist);
7245 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7247 REAL_VALUE_TYPE x;
7249 x = TREE_REAL_CST (arg);
7250 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7252 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7253 REAL_VALUE_TYPE r;
7255 real_ceil (&r, TYPE_MODE (type), &x);
7256 return build_real (type, r);
7260 return fold_trunc_transparent_mathfn (fndecl, arglist);
7263 /* Fold function call to builtin round, roundf or roundl. Return
7264 NULL_TREE if no simplification can be made. */
7266 static tree
7267 fold_builtin_round (tree fndecl, tree arglist)
7269 tree arg;
7271 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7272 return 0;
7274 /* Optimize round of constant value. */
7275 arg = TREE_VALUE (arglist);
7276 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7278 REAL_VALUE_TYPE x;
7280 x = TREE_REAL_CST (arg);
7281 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7283 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7284 REAL_VALUE_TYPE r;
7286 real_round (&r, TYPE_MODE (type), &x);
7287 return build_real (type, r);
7291 return fold_trunc_transparent_mathfn (fndecl, arglist);
7294 /* Fold function call to builtin lround, lroundf or lroundl (or the
7295 corresponding long long versions) and other rounding functions.
7296 Return NULL_TREE if no simplification can be made. */
7298 static tree
7299 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7301 tree arg;
7303 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7304 return 0;
7306 /* Optimize lround of constant value. */
7307 arg = TREE_VALUE (arglist);
7308 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7310 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7312 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7314 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7315 tree ftype = TREE_TYPE (arg), result;
7316 HOST_WIDE_INT hi, lo;
7317 REAL_VALUE_TYPE r;
7319 switch (DECL_FUNCTION_CODE (fndecl))
7321 CASE_FLT_FN (BUILT_IN_LFLOOR):
7322 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7323 real_floor (&r, TYPE_MODE (ftype), &x);
7324 break;
7326 CASE_FLT_FN (BUILT_IN_LCEIL):
7327 CASE_FLT_FN (BUILT_IN_LLCEIL):
7328 real_ceil (&r, TYPE_MODE (ftype), &x);
7329 break;
7331 CASE_FLT_FN (BUILT_IN_LROUND):
7332 CASE_FLT_FN (BUILT_IN_LLROUND):
7333 real_round (&r, TYPE_MODE (ftype), &x);
7334 break;
7336 default:
7337 gcc_unreachable ();
7340 REAL_VALUE_TO_INT (&lo, &hi, r);
7341 result = build_int_cst_wide (NULL_TREE, lo, hi);
7342 if (int_fits_type_p (result, itype))
7343 return fold_convert (itype, result);
7347 return fold_fixed_mathfn (fndecl, arglist);
7350 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7351 and their long and long long variants (i.e. ffsl and ffsll).
7352 Return NULL_TREE if no simplification can be made. */
7354 static tree
7355 fold_builtin_bitop (tree fndecl, tree arglist)
7357 tree arg;
7359 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7360 return NULL_TREE;
7362 /* Optimize for constant argument. */
7363 arg = TREE_VALUE (arglist);
7364 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7366 HOST_WIDE_INT hi, width, result;
7367 unsigned HOST_WIDE_INT lo;
7368 tree type;
7370 type = TREE_TYPE (arg);
7371 width = TYPE_PRECISION (type);
7372 lo = TREE_INT_CST_LOW (arg);
7374 /* Clear all the bits that are beyond the type's precision. */
7375 if (width > HOST_BITS_PER_WIDE_INT)
7377 hi = TREE_INT_CST_HIGH (arg);
7378 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7379 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7381 else
7383 hi = 0;
7384 if (width < HOST_BITS_PER_WIDE_INT)
7385 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7388 switch (DECL_FUNCTION_CODE (fndecl))
7390 CASE_INT_FN (BUILT_IN_FFS):
7391 if (lo != 0)
7392 result = exact_log2 (lo & -lo) + 1;
7393 else if (hi != 0)
7394 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7395 else
7396 result = 0;
7397 break;
7399 CASE_INT_FN (BUILT_IN_CLZ):
7400 if (hi != 0)
7401 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7402 else if (lo != 0)
7403 result = width - floor_log2 (lo) - 1;
7404 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7405 result = width;
7406 break;
7408 CASE_INT_FN (BUILT_IN_CTZ):
7409 if (lo != 0)
7410 result = exact_log2 (lo & -lo);
7411 else if (hi != 0)
7412 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7413 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7414 result = width;
7415 break;
7417 CASE_INT_FN (BUILT_IN_POPCOUNT):
7418 result = 0;
7419 while (lo)
7420 result++, lo &= lo - 1;
7421 while (hi)
7422 result++, hi &= hi - 1;
7423 break;
7425 CASE_INT_FN (BUILT_IN_PARITY):
7426 result = 0;
7427 while (lo)
7428 result++, lo &= lo - 1;
7429 while (hi)
7430 result++, hi &= hi - 1;
7431 result &= 1;
7432 break;
7434 default:
7435 gcc_unreachable ();
7438 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7441 return NULL_TREE;
7444 /* Return true if EXPR is the real constant contained in VALUE. */
7446 static bool
7447 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7449 STRIP_NOPS (expr);
7451 return ((TREE_CODE (expr) == REAL_CST
7452 && ! TREE_CONSTANT_OVERFLOW (expr)
7453 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7454 || (TREE_CODE (expr) == COMPLEX_CST
7455 && real_dconstp (TREE_REALPART (expr), value)
7456 && real_zerop (TREE_IMAGPART (expr))));
7459 /* A subroutine of fold_builtin to fold the various logarithmic
7460 functions. EXP is the CALL_EXPR of a call to a builtin logN
7461 function. VALUE is the base of the logN function. */
7463 static tree
7464 fold_builtin_logarithm (tree fndecl, tree arglist,
7465 const REAL_VALUE_TYPE *value)
7467 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7469 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7470 tree arg = TREE_VALUE (arglist);
7471 const enum built_in_function fcode = builtin_mathfn_code (arg);
7473 /* Optimize logN(1.0) = 0.0. */
7474 if (real_onep (arg))
7475 return build_real (type, dconst0);
7477 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7478 exactly, then only do this if flag_unsafe_math_optimizations. */
7479 if (exact_real_truncate (TYPE_MODE (type), value)
7480 || flag_unsafe_math_optimizations)
7482 const REAL_VALUE_TYPE value_truncate =
7483 real_value_truncate (TYPE_MODE (type), *value);
7484 if (real_dconstp (arg, &value_truncate))
7485 return build_real (type, dconst1);
7488 /* Special case, optimize logN(expN(x)) = x. */
7489 if (flag_unsafe_math_optimizations
7490 && ((value == &dconste
7491 && (fcode == BUILT_IN_EXP
7492 || fcode == BUILT_IN_EXPF
7493 || fcode == BUILT_IN_EXPL))
7494 || (value == &dconst2
7495 && (fcode == BUILT_IN_EXP2
7496 || fcode == BUILT_IN_EXP2F
7497 || fcode == BUILT_IN_EXP2L))
7498 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7499 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7501 /* Optimize logN(func()) for various exponential functions. We
7502 want to determine the value "x" and the power "exponent" in
7503 order to transform logN(x**exponent) into exponent*logN(x). */
7504 if (flag_unsafe_math_optimizations)
7506 tree exponent = 0, x = 0;
7508 switch (fcode)
7510 CASE_FLT_FN (BUILT_IN_EXP):
7511 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7512 x = build_real (type,
7513 real_value_truncate (TYPE_MODE (type), dconste));
7514 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7515 break;
7516 CASE_FLT_FN (BUILT_IN_EXP2):
7517 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7518 x = build_real (type, dconst2);
7519 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7520 break;
7521 CASE_FLT_FN (BUILT_IN_EXP10):
7522 CASE_FLT_FN (BUILT_IN_POW10):
7523 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7524 x = build_real (type, dconst10);
7525 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7526 break;
7527 CASE_FLT_FN (BUILT_IN_SQRT):
7528 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7529 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7530 exponent = build_real (type, dconsthalf);
7531 break;
7532 CASE_FLT_FN (BUILT_IN_CBRT):
7533 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7534 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7535 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7536 dconstthird));
7537 break;
7538 CASE_FLT_FN (BUILT_IN_POW):
7539 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7540 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7541 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7542 break;
7543 default:
7544 break;
7547 /* Now perform the optimization. */
7548 if (x && exponent)
7550 tree logfn;
7551 arglist = build_tree_list (NULL_TREE, x);
7552 logfn = build_function_call_expr (fndecl, arglist);
7553 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7558 return 0;
7561 /* Fold a builtin function call to pow, powf, or powl. Return
7562 NULL_TREE if no simplification can be made. */
7563 static tree
7564 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7566 tree arg0 = TREE_VALUE (arglist);
7567 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7569 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7570 return NULL_TREE;
7572 /* Optimize pow(1.0,y) = 1.0. */
7573 if (real_onep (arg0))
7574 return omit_one_operand (type, build_real (type, dconst1), arg1);
7576 if (TREE_CODE (arg1) == REAL_CST
7577 && ! TREE_CONSTANT_OVERFLOW (arg1))
7579 REAL_VALUE_TYPE cint;
7580 REAL_VALUE_TYPE c;
7581 HOST_WIDE_INT n;
7583 c = TREE_REAL_CST (arg1);
7585 /* Optimize pow(x,0.0) = 1.0. */
7586 if (REAL_VALUES_EQUAL (c, dconst0))
7587 return omit_one_operand (type, build_real (type, dconst1),
7588 arg0);
7590 /* Optimize pow(x,1.0) = x. */
7591 if (REAL_VALUES_EQUAL (c, dconst1))
7592 return arg0;
7594 /* Optimize pow(x,-1.0) = 1.0/x. */
7595 if (REAL_VALUES_EQUAL (c, dconstm1))
7596 return fold_build2 (RDIV_EXPR, type,
7597 build_real (type, dconst1), arg0);
7599 /* Optimize pow(x,0.5) = sqrt(x). */
7600 if (flag_unsafe_math_optimizations
7601 && REAL_VALUES_EQUAL (c, dconsthalf))
7603 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7605 if (sqrtfn != NULL_TREE)
7607 tree arglist = build_tree_list (NULL_TREE, arg0);
7608 return build_function_call_expr (sqrtfn, arglist);
7612 /* Check for an integer exponent. */
7613 n = real_to_integer (&c);
7614 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7615 if (real_identical (&c, &cint))
7617 /* Attempt to evaluate pow at compile-time. */
7618 if (TREE_CODE (arg0) == REAL_CST
7619 && ! TREE_CONSTANT_OVERFLOW (arg0))
7621 REAL_VALUE_TYPE x;
7622 bool inexact;
7624 x = TREE_REAL_CST (arg0);
7625 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7626 if (flag_unsafe_math_optimizations || !inexact)
7627 return build_real (type, x);
7630 /* Strip sign ops from even integer powers. */
7631 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7633 tree narg0 = fold_strip_sign_ops (arg0);
7634 if (narg0)
7636 arglist = build_tree_list (NULL_TREE, arg1);
7637 arglist = tree_cons (NULL_TREE, narg0, arglist);
7638 return build_function_call_expr (fndecl, arglist);
7644 if (flag_unsafe_math_optimizations)
7646 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7648 /* Optimize pow(expN(x),y) = expN(x*y). */
7649 if (BUILTIN_EXPONENT_P (fcode))
7651 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7652 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7653 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7654 arglist = build_tree_list (NULL_TREE, arg);
7655 return build_function_call_expr (expfn, arglist);
7658 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7659 if (BUILTIN_SQRT_P (fcode))
7661 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7662 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7663 build_real (type, dconsthalf));
7665 arglist = tree_cons (NULL_TREE, narg0,
7666 build_tree_list (NULL_TREE, narg1));
7667 return build_function_call_expr (fndecl, arglist);
7670 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7671 if (BUILTIN_CBRT_P (fcode))
7673 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7674 if (tree_expr_nonnegative_p (arg))
7676 const REAL_VALUE_TYPE dconstroot
7677 = real_value_truncate (TYPE_MODE (type), dconstthird);
7678 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7679 build_real (type, dconstroot));
7680 arglist = tree_cons (NULL_TREE, arg,
7681 build_tree_list (NULL_TREE, narg1));
7682 return build_function_call_expr (fndecl, arglist);
7686 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7687 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7688 || fcode == BUILT_IN_POWL)
7690 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7691 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7692 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7693 arglist = tree_cons (NULL_TREE, arg00,
7694 build_tree_list (NULL_TREE, narg1));
7695 return build_function_call_expr (fndecl, arglist);
7699 return NULL_TREE;
7702 /* Fold a builtin function call to powi, powif, or powil. Return
7703 NULL_TREE if no simplification can be made. */
7704 static tree
7705 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7707 tree arg0 = TREE_VALUE (arglist);
7708 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7710 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7711 return NULL_TREE;
7713 /* Optimize pow(1.0,y) = 1.0. */
7714 if (real_onep (arg0))
7715 return omit_one_operand (type, build_real (type, dconst1), arg1);
7717 if (host_integerp (arg1, 0))
7719 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7721 /* Evaluate powi at compile-time. */
7722 if (TREE_CODE (arg0) == REAL_CST
7723 && ! TREE_CONSTANT_OVERFLOW (arg0))
7725 REAL_VALUE_TYPE x;
7726 x = TREE_REAL_CST (arg0);
7727 real_powi (&x, TYPE_MODE (type), &x, c);
7728 return build_real (type, x);
7731 /* Optimize pow(x,0) = 1.0. */
7732 if (c == 0)
7733 return omit_one_operand (type, build_real (type, dconst1),
7734 arg0);
7736 /* Optimize pow(x,1) = x. */
7737 if (c == 1)
7738 return arg0;
7740 /* Optimize pow(x,-1) = 1.0/x. */
7741 if (c == -1)
7742 return fold_build2 (RDIV_EXPR, type,
7743 build_real (type, dconst1), arg0);
7746 return NULL_TREE;
7749 /* A subroutine of fold_builtin to fold the various exponent
7750 functions. EXP is the CALL_EXPR of a call to a builtin function.
7751 VALUE is the value which will be raised to a power. */
7753 static tree
7754 fold_builtin_exponent (tree fndecl, tree arglist,
7755 const REAL_VALUE_TYPE *value)
7757 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7759 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7760 tree arg = TREE_VALUE (arglist);
7762 /* Optimize exp*(0.0) = 1.0. */
7763 if (real_zerop (arg))
7764 return build_real (type, dconst1);
7766 /* Optimize expN(1.0) = N. */
7767 if (real_onep (arg))
7769 REAL_VALUE_TYPE cst;
7771 real_convert (&cst, TYPE_MODE (type), value);
7772 return build_real (type, cst);
7775 /* Attempt to evaluate expN(integer) at compile-time. */
7776 if (flag_unsafe_math_optimizations
7777 && TREE_CODE (arg) == REAL_CST
7778 && ! TREE_CONSTANT_OVERFLOW (arg))
7780 REAL_VALUE_TYPE cint;
7781 REAL_VALUE_TYPE c;
7782 HOST_WIDE_INT n;
7784 c = TREE_REAL_CST (arg);
7785 n = real_to_integer (&c);
7786 real_from_integer (&cint, VOIDmode, n,
7787 n < 0 ? -1 : 0, 0);
7788 if (real_identical (&c, &cint))
7790 REAL_VALUE_TYPE x;
7792 real_powi (&x, TYPE_MODE (type), value, n);
7793 return build_real (type, x);
7797 /* Optimize expN(logN(x)) = x. */
7798 if (flag_unsafe_math_optimizations)
7800 const enum built_in_function fcode = builtin_mathfn_code (arg);
7802 if ((value == &dconste
7803 && (fcode == BUILT_IN_LOG
7804 || fcode == BUILT_IN_LOGF
7805 || fcode == BUILT_IN_LOGL))
7806 || (value == &dconst2
7807 && (fcode == BUILT_IN_LOG2
7808 || fcode == BUILT_IN_LOG2F
7809 || fcode == BUILT_IN_LOG2L))
7810 || (value == &dconst10
7811 && (fcode == BUILT_IN_LOG10
7812 || fcode == BUILT_IN_LOG10F
7813 || fcode == BUILT_IN_LOG10L)))
7814 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7818 return 0;
7821 /* Fold function call to builtin memcpy. Return
7822 NULL_TREE if no simplification can be made. */
7824 static tree
7825 fold_builtin_memcpy (tree fndecl, tree arglist)
7827 tree dest, src, len;
7829 if (!validate_arglist (arglist,
7830 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7831 return 0;
7833 dest = TREE_VALUE (arglist);
7834 src = TREE_VALUE (TREE_CHAIN (arglist));
7835 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7837 /* If the LEN parameter is zero, return DEST. */
7838 if (integer_zerop (len))
7839 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7841 /* If SRC and DEST are the same (and not volatile), return DEST. */
7842 if (operand_equal_p (src, dest, 0))
7843 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7845 return 0;
7848 /* Fold function call to builtin mempcpy. Return
7849 NULL_TREE if no simplification can be made. */
7851 static tree
7852 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7854 if (validate_arglist (arglist,
7855 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7857 tree dest = TREE_VALUE (arglist);
7858 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7859 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7861 /* If the LEN parameter is zero, return DEST. */
7862 if (integer_zerop (len))
7863 return omit_one_operand (type, dest, src);
7865 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7866 if (operand_equal_p (src, dest, 0))
7868 if (endp == 0)
7869 return omit_one_operand (type, dest, len);
7871 if (endp == 2)
7872 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7873 ssize_int (1));
7875 len = fold_convert (TREE_TYPE (dest), len);
7876 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7877 return fold_convert (type, len);
7880 return 0;
7883 /* Fold function call to builtin memmove. Return
7884 NULL_TREE if no simplification can be made. */
7886 static tree
7887 fold_builtin_memmove (tree arglist, tree type)
7889 tree dest, src, len;
7891 if (!validate_arglist (arglist,
7892 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7893 return 0;
7895 dest = TREE_VALUE (arglist);
7896 src = TREE_VALUE (TREE_CHAIN (arglist));
7897 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7899 /* If the LEN parameter is zero, return DEST. */
7900 if (integer_zerop (len))
7901 return omit_one_operand (type, dest, src);
7903 /* If SRC and DEST are the same (and not volatile), return DEST. */
7904 if (operand_equal_p (src, dest, 0))
7905 return omit_one_operand (type, dest, len);
7907 return 0;
7910 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7911 the length of the string to be copied. Return NULL_TREE if no
7912 simplification can be made. */
7914 tree
7915 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7917 tree dest, src, fn;
7919 if (!validate_arglist (arglist,
7920 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7921 return 0;
7923 dest = TREE_VALUE (arglist);
7924 src = TREE_VALUE (TREE_CHAIN (arglist));
7926 /* If SRC and DEST are the same (and not volatile), return DEST. */
7927 if (operand_equal_p (src, dest, 0))
7928 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7930 if (optimize_size)
7931 return 0;
7933 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7934 if (!fn)
7935 return 0;
7937 if (!len)
7939 len = c_strlen (src, 1);
7940 if (! len || TREE_SIDE_EFFECTS (len))
7941 return 0;
7944 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7945 arglist = build_tree_list (NULL_TREE, len);
7946 arglist = tree_cons (NULL_TREE, src, arglist);
7947 arglist = tree_cons (NULL_TREE, dest, arglist);
7948 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7949 build_function_call_expr (fn, arglist));
7952 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7953 the length of the source string. Return NULL_TREE if no simplification
7954 can be made. */
7956 tree
7957 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7959 tree dest, src, len, fn;
7961 if (!validate_arglist (arglist,
7962 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7963 return 0;
7965 dest = TREE_VALUE (arglist);
7966 src = TREE_VALUE (TREE_CHAIN (arglist));
7967 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7969 /* If the LEN parameter is zero, return DEST. */
7970 if (integer_zerop (len))
7971 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7973 /* We can't compare slen with len as constants below if len is not a
7974 constant. */
7975 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7976 return 0;
7978 if (!slen)
7979 slen = c_strlen (src, 1);
7981 /* Now, we must be passed a constant src ptr parameter. */
7982 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7983 return 0;
7985 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7987 /* We do not support simplification of this case, though we do
7988 support it when expanding trees into RTL. */
7989 /* FIXME: generate a call to __builtin_memset. */
7990 if (tree_int_cst_lt (slen, len))
7991 return 0;
7993 /* OK transform into builtin memcpy. */
7994 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7995 if (!fn)
7996 return 0;
7997 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7998 build_function_call_expr (fn, arglist));
8001 /* Fold function call to builtin memcmp. Return
8002 NULL_TREE if no simplification can be made. */
8004 static tree
8005 fold_builtin_memcmp (tree arglist)
8007 tree arg1, arg2, len;
8008 const char *p1, *p2;
8010 if (!validate_arglist (arglist,
8011 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8012 return 0;
8014 arg1 = TREE_VALUE (arglist);
8015 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8016 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8018 /* If the LEN parameter is zero, return zero. */
8019 if (integer_zerop (len))
8020 return omit_two_operands (integer_type_node, integer_zero_node,
8021 arg1, arg2);
8023 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8024 if (operand_equal_p (arg1, arg2, 0))
8025 return omit_one_operand (integer_type_node, integer_zero_node, len);
8027 p1 = c_getstr (arg1);
8028 p2 = c_getstr (arg2);
8030 /* If all arguments are constant, and the value of len is not greater
8031 than the lengths of arg1 and arg2, evaluate at compile-time. */
8032 if (host_integerp (len, 1) && p1 && p2
8033 && compare_tree_int (len, strlen (p1) + 1) <= 0
8034 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8036 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8038 if (r > 0)
8039 return integer_one_node;
8040 else if (r < 0)
8041 return integer_minus_one_node;
8042 else
8043 return integer_zero_node;
8046 /* If len parameter is one, return an expression corresponding to
8047 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8048 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8050 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8051 tree cst_uchar_ptr_node
8052 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8054 tree ind1 = fold_convert (integer_type_node,
8055 build1 (INDIRECT_REF, cst_uchar_node,
8056 fold_convert (cst_uchar_ptr_node,
8057 arg1)));
8058 tree ind2 = fold_convert (integer_type_node,
8059 build1 (INDIRECT_REF, cst_uchar_node,
8060 fold_convert (cst_uchar_ptr_node,
8061 arg2)));
8062 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8065 return 0;
8068 /* Fold function call to builtin strcmp. Return
8069 NULL_TREE if no simplification can be made. */
8071 static tree
8072 fold_builtin_strcmp (tree arglist)
8074 tree arg1, arg2;
8075 const char *p1, *p2;
8077 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8078 return 0;
8080 arg1 = TREE_VALUE (arglist);
8081 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8083 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8084 if (operand_equal_p (arg1, arg2, 0))
8085 return integer_zero_node;
8087 p1 = c_getstr (arg1);
8088 p2 = c_getstr (arg2);
8090 if (p1 && p2)
8092 const int i = strcmp (p1, p2);
8093 if (i < 0)
8094 return integer_minus_one_node;
8095 else if (i > 0)
8096 return integer_one_node;
8097 else
8098 return integer_zero_node;
8101 /* If the second arg is "", return *(const unsigned char*)arg1. */
8102 if (p2 && *p2 == '\0')
8104 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8105 tree cst_uchar_ptr_node
8106 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8108 return fold_convert (integer_type_node,
8109 build1 (INDIRECT_REF, cst_uchar_node,
8110 fold_convert (cst_uchar_ptr_node,
8111 arg1)));
8114 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8115 if (p1 && *p1 == '\0')
8117 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8118 tree cst_uchar_ptr_node
8119 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8121 tree temp = fold_convert (integer_type_node,
8122 build1 (INDIRECT_REF, cst_uchar_node,
8123 fold_convert (cst_uchar_ptr_node,
8124 arg2)));
8125 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8128 return 0;
8131 /* Fold function call to builtin strncmp. Return
8132 NULL_TREE if no simplification can be made. */
8134 static tree
8135 fold_builtin_strncmp (tree arglist)
8137 tree arg1, arg2, len;
8138 const char *p1, *p2;
8140 if (!validate_arglist (arglist,
8141 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8142 return 0;
8144 arg1 = TREE_VALUE (arglist);
8145 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8146 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8148 /* If the LEN parameter is zero, return zero. */
8149 if (integer_zerop (len))
8150 return omit_two_operands (integer_type_node, integer_zero_node,
8151 arg1, arg2);
8153 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8154 if (operand_equal_p (arg1, arg2, 0))
8155 return omit_one_operand (integer_type_node, integer_zero_node, len);
8157 p1 = c_getstr (arg1);
8158 p2 = c_getstr (arg2);
8160 if (host_integerp (len, 1) && p1 && p2)
8162 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8163 if (i > 0)
8164 return integer_one_node;
8165 else if (i < 0)
8166 return integer_minus_one_node;
8167 else
8168 return integer_zero_node;
8171 /* If the second arg is "", and the length is greater than zero,
8172 return *(const unsigned char*)arg1. */
8173 if (p2 && *p2 == '\0'
8174 && TREE_CODE (len) == INTEGER_CST
8175 && tree_int_cst_sgn (len) == 1)
8177 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8178 tree cst_uchar_ptr_node
8179 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8181 return fold_convert (integer_type_node,
8182 build1 (INDIRECT_REF, cst_uchar_node,
8183 fold_convert (cst_uchar_ptr_node,
8184 arg1)));
8187 /* If the first arg is "", and the length is greater than zero,
8188 return -*(const unsigned char*)arg2. */
8189 if (p1 && *p1 == '\0'
8190 && TREE_CODE (len) == INTEGER_CST
8191 && tree_int_cst_sgn (len) == 1)
8193 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8194 tree cst_uchar_ptr_node
8195 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8197 tree temp = fold_convert (integer_type_node,
8198 build1 (INDIRECT_REF, cst_uchar_node,
8199 fold_convert (cst_uchar_ptr_node,
8200 arg2)));
8201 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8204 /* If len parameter is one, return an expression corresponding to
8205 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8206 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8208 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8209 tree cst_uchar_ptr_node
8210 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8212 tree ind1 = fold_convert (integer_type_node,
8213 build1 (INDIRECT_REF, cst_uchar_node,
8214 fold_convert (cst_uchar_ptr_node,
8215 arg1)));
8216 tree ind2 = fold_convert (integer_type_node,
8217 build1 (INDIRECT_REF, cst_uchar_node,
8218 fold_convert (cst_uchar_ptr_node,
8219 arg2)));
8220 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8223 return 0;
8226 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8227 NULL_TREE if no simplification can be made. */
8229 static tree
8230 fold_builtin_signbit (tree fndecl, tree arglist)
8232 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8233 tree arg, temp;
8235 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8236 return NULL_TREE;
8238 arg = TREE_VALUE (arglist);
8240 /* If ARG is a compile-time constant, determine the result. */
8241 if (TREE_CODE (arg) == REAL_CST
8242 && !TREE_CONSTANT_OVERFLOW (arg))
8244 REAL_VALUE_TYPE c;
8246 c = TREE_REAL_CST (arg);
8247 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8248 return fold_convert (type, temp);
8251 /* If ARG is non-negative, the result is always zero. */
8252 if (tree_expr_nonnegative_p (arg))
8253 return omit_one_operand (type, integer_zero_node, arg);
8255 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8256 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8257 return fold_build2 (LT_EXPR, type, arg,
8258 build_real (TREE_TYPE (arg), dconst0));
8260 return NULL_TREE;
8263 /* Fold function call to builtin copysign, copysignf or copysignl.
8264 Return NULL_TREE if no simplification can be made. */
8266 static tree
8267 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8269 tree arg1, arg2, tem;
8271 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8272 return NULL_TREE;
8274 arg1 = TREE_VALUE (arglist);
8275 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8277 /* copysign(X,X) is X. */
8278 if (operand_equal_p (arg1, arg2, 0))
8279 return fold_convert (type, arg1);
8281 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8282 if (TREE_CODE (arg1) == REAL_CST
8283 && TREE_CODE (arg2) == REAL_CST
8284 && !TREE_CONSTANT_OVERFLOW (arg1)
8285 && !TREE_CONSTANT_OVERFLOW (arg2))
8287 REAL_VALUE_TYPE c1, c2;
8289 c1 = TREE_REAL_CST (arg1);
8290 c2 = TREE_REAL_CST (arg2);
8291 /* c1.sign := c2.sign. */
8292 real_copysign (&c1, &c2);
8293 return build_real (type, c1);
8296 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8297 Remember to evaluate Y for side-effects. */
8298 if (tree_expr_nonnegative_p (arg2))
8299 return omit_one_operand (type,
8300 fold_build1 (ABS_EXPR, type, arg1),
8301 arg2);
8303 /* Strip sign changing operations for the first argument. */
8304 tem = fold_strip_sign_ops (arg1);
8305 if (tem)
8307 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8308 return build_function_call_expr (fndecl, arglist);
8311 return NULL_TREE;
8314 /* Fold a call to builtin isascii. */
8316 static tree
8317 fold_builtin_isascii (tree arglist)
8319 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8320 return 0;
8321 else
8323 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8324 tree arg = TREE_VALUE (arglist);
8326 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8327 build_int_cst (NULL_TREE,
8328 ~ (unsigned HOST_WIDE_INT) 0x7f));
8329 arg = fold_build2 (EQ_EXPR, integer_type_node,
8330 arg, integer_zero_node);
8332 if (in_gimple_form && !TREE_CONSTANT (arg))
8333 return NULL_TREE;
8334 else
8335 return arg;
8339 /* Fold a call to builtin toascii. */
8341 static tree
8342 fold_builtin_toascii (tree arglist)
8344 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8345 return 0;
8346 else
8348 /* Transform toascii(c) -> (c & 0x7f). */
8349 tree arg = TREE_VALUE (arglist);
8351 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8352 build_int_cst (NULL_TREE, 0x7f));
8356 /* Fold a call to builtin isdigit. */
8358 static tree
8359 fold_builtin_isdigit (tree arglist)
8361 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8362 return 0;
8363 else
8365 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8366 /* According to the C standard, isdigit is unaffected by locale.
8367 However, it definitely is affected by the target character set. */
8368 tree arg;
8369 unsigned HOST_WIDE_INT target_digit0
8370 = lang_hooks.to_target_charset ('0');
8372 if (target_digit0 == 0)
8373 return NULL_TREE;
8375 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8376 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8377 build_int_cst (unsigned_type_node, target_digit0));
8378 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8379 build_int_cst (unsigned_type_node, 9));
8380 if (in_gimple_form && !TREE_CONSTANT (arg))
8381 return NULL_TREE;
8382 else
8383 return arg;
8387 /* Fold a call to fabs, fabsf or fabsl. */
8389 static tree
8390 fold_builtin_fabs (tree arglist, tree type)
8392 tree arg;
8394 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8395 return 0;
8397 arg = TREE_VALUE (arglist);
8398 arg = fold_convert (type, arg);
8399 if (TREE_CODE (arg) == REAL_CST)
8400 return fold_abs_const (arg, type);
8401 return fold_build1 (ABS_EXPR, type, arg);
8404 /* Fold a call to abs, labs, llabs or imaxabs. */
8406 static tree
8407 fold_builtin_abs (tree arglist, tree type)
8409 tree arg;
8411 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8412 return 0;
8414 arg = TREE_VALUE (arglist);
8415 arg = fold_convert (type, arg);
8416 if (TREE_CODE (arg) == INTEGER_CST)
8417 return fold_abs_const (arg, type);
8418 return fold_build1 (ABS_EXPR, type, arg);
8421 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8422 EXP is the CALL_EXPR for the call. */
8424 static tree
8425 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8427 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8428 tree arg;
8429 REAL_VALUE_TYPE r;
8431 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8433 /* Check that we have exactly one argument. */
8434 if (arglist == 0)
8436 error ("too few arguments to function %qs",
8437 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8438 return error_mark_node;
8440 else if (TREE_CHAIN (arglist) != 0)
8442 error ("too many arguments to function %qs",
8443 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8444 return error_mark_node;
8446 else
8448 error ("non-floating-point argument to function %qs",
8449 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8450 return error_mark_node;
8454 arg = TREE_VALUE (arglist);
8455 switch (builtin_index)
8457 case BUILT_IN_ISINF:
8458 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8459 return omit_one_operand (type, integer_zero_node, arg);
8461 if (TREE_CODE (arg) == REAL_CST)
8463 r = TREE_REAL_CST (arg);
8464 if (real_isinf (&r))
8465 return real_compare (GT_EXPR, &r, &dconst0)
8466 ? integer_one_node : integer_minus_one_node;
8467 else
8468 return integer_zero_node;
8471 return NULL_TREE;
8473 case BUILT_IN_FINITE:
8474 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8475 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8476 return omit_one_operand (type, integer_zero_node, arg);
8478 if (TREE_CODE (arg) == REAL_CST)
8480 r = TREE_REAL_CST (arg);
8481 return real_isinf (&r) || real_isnan (&r)
8482 ? integer_zero_node : integer_one_node;
8485 return NULL_TREE;
8487 case BUILT_IN_ISNAN:
8488 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8489 return omit_one_operand (type, integer_zero_node, arg);
8491 if (TREE_CODE (arg) == REAL_CST)
8493 r = TREE_REAL_CST (arg);
8494 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8497 arg = builtin_save_expr (arg);
8498 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8500 default:
8501 gcc_unreachable ();
8505 /* Fold a call to an unordered comparison function such as
8506 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8507 being called and ARGLIST is the argument list for the call.
8508 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8509 the opposite of the desired result. UNORDERED_CODE is used
8510 for modes that can hold NaNs and ORDERED_CODE is used for
8511 the rest. */
8513 static tree
8514 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8515 enum tree_code unordered_code,
8516 enum tree_code ordered_code)
8518 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8519 enum tree_code code;
8520 tree arg0, arg1;
8521 tree type0, type1;
8522 enum tree_code code0, code1;
8523 tree cmp_type = NULL_TREE;
8525 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8527 /* Check that we have exactly two arguments. */
8528 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8530 error ("too few arguments to function %qs",
8531 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8532 return error_mark_node;
8534 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8536 error ("too many arguments to function %qs",
8537 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8538 return error_mark_node;
8542 arg0 = TREE_VALUE (arglist);
8543 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8545 type0 = TREE_TYPE (arg0);
8546 type1 = TREE_TYPE (arg1);
8548 code0 = TREE_CODE (type0);
8549 code1 = TREE_CODE (type1);
8551 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8552 /* Choose the wider of two real types. */
8553 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8554 ? type0 : type1;
8555 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8556 cmp_type = type0;
8557 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8558 cmp_type = type1;
8559 else
8561 error ("non-floating-point argument to function %qs",
8562 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8563 return error_mark_node;
8566 arg0 = fold_convert (cmp_type, arg0);
8567 arg1 = fold_convert (cmp_type, arg1);
8569 if (unordered_code == UNORDERED_EXPR)
8571 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8572 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8573 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8576 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8577 : ordered_code;
8578 return fold_build1 (TRUTH_NOT_EXPR, type,
8579 fold_build2 (code, type, arg0, arg1));
8582 /* Used by constant folding to simplify calls to builtin functions. EXP is
8583 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8584 result of the function call is ignored. This function returns NULL_TREE
8585 if no simplification was possible. */
8587 static tree
8588 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8590 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8591 enum built_in_function fcode;
8593 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8594 return targetm.fold_builtin (fndecl, arglist, ignore);
8596 fcode = DECL_FUNCTION_CODE (fndecl);
8597 switch (fcode)
8599 case BUILT_IN_FPUTS:
8600 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8602 case BUILT_IN_FPUTS_UNLOCKED:
8603 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8605 case BUILT_IN_STRSTR:
8606 return fold_builtin_strstr (arglist, type);
8608 case BUILT_IN_STRCAT:
8609 return fold_builtin_strcat (arglist);
8611 case BUILT_IN_STRNCAT:
8612 return fold_builtin_strncat (arglist);
8614 case BUILT_IN_STRSPN:
8615 return fold_builtin_strspn (arglist);
8617 case BUILT_IN_STRCSPN:
8618 return fold_builtin_strcspn (arglist);
8620 case BUILT_IN_STRCHR:
8621 case BUILT_IN_INDEX:
8622 return fold_builtin_strchr (arglist, type);
8624 case BUILT_IN_STRRCHR:
8625 case BUILT_IN_RINDEX:
8626 return fold_builtin_strrchr (arglist, type);
8628 case BUILT_IN_STRCPY:
8629 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8631 case BUILT_IN_STRNCPY:
8632 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8634 case BUILT_IN_STRCMP:
8635 return fold_builtin_strcmp (arglist);
8637 case BUILT_IN_STRNCMP:
8638 return fold_builtin_strncmp (arglist);
8640 case BUILT_IN_STRPBRK:
8641 return fold_builtin_strpbrk (arglist, type);
8643 case BUILT_IN_BCMP:
8644 case BUILT_IN_MEMCMP:
8645 return fold_builtin_memcmp (arglist);
8647 case BUILT_IN_SPRINTF:
8648 return fold_builtin_sprintf (arglist, ignore);
8650 case BUILT_IN_CONSTANT_P:
8652 tree val;
8654 val = fold_builtin_constant_p (arglist);
8655 /* Gimplification will pull the CALL_EXPR for the builtin out of
8656 an if condition. When not optimizing, we'll not CSE it back.
8657 To avoid link error types of regressions, return false now. */
8658 if (!val && !optimize)
8659 val = integer_zero_node;
8661 return val;
8664 case BUILT_IN_EXPECT:
8665 return fold_builtin_expect (arglist);
8667 case BUILT_IN_CLASSIFY_TYPE:
8668 return fold_builtin_classify_type (arglist);
8670 case BUILT_IN_STRLEN:
8671 return fold_builtin_strlen (arglist);
8673 CASE_FLT_FN (BUILT_IN_FABS):
8674 return fold_builtin_fabs (arglist, type);
8676 case BUILT_IN_ABS:
8677 case BUILT_IN_LABS:
8678 case BUILT_IN_LLABS:
8679 case BUILT_IN_IMAXABS:
8680 return fold_builtin_abs (arglist, type);
8682 CASE_FLT_FN (BUILT_IN_CONJ):
8683 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8684 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8685 break;
8687 CASE_FLT_FN (BUILT_IN_CREAL):
8688 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8689 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8690 TREE_VALUE (arglist)));
8691 break;
8693 CASE_FLT_FN (BUILT_IN_CIMAG):
8694 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8695 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8696 TREE_VALUE (arglist)));
8697 break;
8699 CASE_FLT_FN (BUILT_IN_CABS):
8700 return fold_builtin_cabs (arglist, type, fndecl);
8702 CASE_FLT_FN (BUILT_IN_SQRT):
8703 return fold_builtin_sqrt (arglist, type);
8705 CASE_FLT_FN (BUILT_IN_CBRT):
8706 return fold_builtin_cbrt (arglist, type);
8708 CASE_FLT_FN (BUILT_IN_SIN):
8709 return fold_builtin_sin (arglist);
8711 CASE_FLT_FN (BUILT_IN_COS):
8712 return fold_builtin_cos (arglist, type, fndecl);
8714 CASE_FLT_FN (BUILT_IN_EXP):
8715 return fold_builtin_exponent (fndecl, arglist, &dconste);
8717 CASE_FLT_FN (BUILT_IN_EXP2):
8718 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8720 CASE_FLT_FN (BUILT_IN_EXP10):
8721 CASE_FLT_FN (BUILT_IN_POW10):
8722 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8724 CASE_FLT_FN (BUILT_IN_LOG):
8725 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8727 CASE_FLT_FN (BUILT_IN_LOG2):
8728 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8730 CASE_FLT_FN (BUILT_IN_LOG10):
8731 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8733 CASE_FLT_FN (BUILT_IN_TAN):
8734 return fold_builtin_tan (arglist);
8736 CASE_FLT_FN (BUILT_IN_ATAN):
8737 return fold_builtin_atan (arglist, type);
8739 CASE_FLT_FN (BUILT_IN_POW):
8740 return fold_builtin_pow (fndecl, arglist, type);
8742 CASE_FLT_FN (BUILT_IN_POWI):
8743 return fold_builtin_powi (fndecl, arglist, type);
8745 CASE_FLT_FN (BUILT_IN_INF):
8746 case BUILT_IN_INFD32:
8747 case BUILT_IN_INFD64:
8748 case BUILT_IN_INFD128:
8749 return fold_builtin_inf (type, true);
8751 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8752 return fold_builtin_inf (type, false);
8754 CASE_FLT_FN (BUILT_IN_NAN):
8755 case BUILT_IN_NAND32:
8756 case BUILT_IN_NAND64:
8757 case BUILT_IN_NAND128:
8758 return fold_builtin_nan (arglist, type, true);
8760 CASE_FLT_FN (BUILT_IN_NANS):
8761 return fold_builtin_nan (arglist, type, false);
8763 CASE_FLT_FN (BUILT_IN_FLOOR):
8764 return fold_builtin_floor (fndecl, arglist);
8766 CASE_FLT_FN (BUILT_IN_CEIL):
8767 return fold_builtin_ceil (fndecl, arglist);
8769 CASE_FLT_FN (BUILT_IN_TRUNC):
8770 return fold_builtin_trunc (fndecl, arglist);
8772 CASE_FLT_FN (BUILT_IN_ROUND):
8773 return fold_builtin_round (fndecl, arglist);
8775 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8776 CASE_FLT_FN (BUILT_IN_RINT):
8777 return fold_trunc_transparent_mathfn (fndecl, arglist);
8779 CASE_FLT_FN (BUILT_IN_LCEIL):
8780 CASE_FLT_FN (BUILT_IN_LLCEIL):
8781 CASE_FLT_FN (BUILT_IN_LFLOOR):
8782 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8783 CASE_FLT_FN (BUILT_IN_LROUND):
8784 CASE_FLT_FN (BUILT_IN_LLROUND):
8785 return fold_builtin_int_roundingfn (fndecl, arglist);
8787 CASE_FLT_FN (BUILT_IN_LRINT):
8788 CASE_FLT_FN (BUILT_IN_LLRINT):
8789 return fold_fixed_mathfn (fndecl, arglist);
8791 CASE_INT_FN (BUILT_IN_FFS):
8792 CASE_INT_FN (BUILT_IN_CLZ):
8793 CASE_INT_FN (BUILT_IN_CTZ):
8794 CASE_INT_FN (BUILT_IN_POPCOUNT):
8795 CASE_INT_FN (BUILT_IN_PARITY):
8796 return fold_builtin_bitop (fndecl, arglist);
8798 case BUILT_IN_MEMCPY:
8799 return fold_builtin_memcpy (fndecl, arglist);
8801 case BUILT_IN_MEMPCPY:
8802 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8804 case BUILT_IN_MEMMOVE:
8805 return fold_builtin_memmove (arglist, type);
8807 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8808 return fold_builtin_signbit (fndecl, arglist);
8810 case BUILT_IN_ISASCII:
8811 return fold_builtin_isascii (arglist);
8813 case BUILT_IN_TOASCII:
8814 return fold_builtin_toascii (arglist);
8816 case BUILT_IN_ISDIGIT:
8817 return fold_builtin_isdigit (arglist);
8819 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8820 return fold_builtin_copysign (fndecl, arglist, type);
8822 CASE_FLT_FN (BUILT_IN_FINITE):
8823 case BUILT_IN_FINITED32:
8824 case BUILT_IN_FINITED64:
8825 case BUILT_IN_FINITED128:
8826 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8828 CASE_FLT_FN (BUILT_IN_ISINF):
8829 case BUILT_IN_ISINFD32:
8830 case BUILT_IN_ISINFD64:
8831 case BUILT_IN_ISINFD128:
8832 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8834 CASE_FLT_FN (BUILT_IN_ISNAN):
8835 case BUILT_IN_ISNAND32:
8836 case BUILT_IN_ISNAND64:
8837 case BUILT_IN_ISNAND128:
8838 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8840 case BUILT_IN_ISGREATER:
8841 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8842 case BUILT_IN_ISGREATEREQUAL:
8843 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8844 case BUILT_IN_ISLESS:
8845 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8846 case BUILT_IN_ISLESSEQUAL:
8847 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8848 case BUILT_IN_ISLESSGREATER:
8849 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8850 case BUILT_IN_ISUNORDERED:
8851 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8852 NOP_EXPR);
8854 /* We do the folding for va_start in the expander. */
8855 case BUILT_IN_VA_START:
8856 break;
8858 case BUILT_IN_OBJECT_SIZE:
8859 return fold_builtin_object_size (arglist);
8860 case BUILT_IN_MEMCPY_CHK:
8861 case BUILT_IN_MEMPCPY_CHK:
8862 case BUILT_IN_MEMMOVE_CHK:
8863 case BUILT_IN_MEMSET_CHK:
8864 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8865 DECL_FUNCTION_CODE (fndecl));
8866 case BUILT_IN_STRCPY_CHK:
8867 case BUILT_IN_STPCPY_CHK:
8868 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8869 DECL_FUNCTION_CODE (fndecl));
8870 case BUILT_IN_STRNCPY_CHK:
8871 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8872 case BUILT_IN_STRCAT_CHK:
8873 return fold_builtin_strcat_chk (fndecl, arglist);
8874 case BUILT_IN_STRNCAT_CHK:
8875 return fold_builtin_strncat_chk (fndecl, arglist);
8876 case BUILT_IN_SPRINTF_CHK:
8877 case BUILT_IN_VSPRINTF_CHK:
8878 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8879 case BUILT_IN_SNPRINTF_CHK:
8880 case BUILT_IN_VSNPRINTF_CHK:
8881 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8882 DECL_FUNCTION_CODE (fndecl));
8884 case BUILT_IN_PRINTF:
8885 case BUILT_IN_PRINTF_UNLOCKED:
8886 case BUILT_IN_VPRINTF:
8887 case BUILT_IN_PRINTF_CHK:
8888 case BUILT_IN_VPRINTF_CHK:
8889 return fold_builtin_printf (fndecl, arglist, ignore,
8890 DECL_FUNCTION_CODE (fndecl));
8892 case BUILT_IN_FPRINTF:
8893 case BUILT_IN_FPRINTF_UNLOCKED:
8894 case BUILT_IN_VFPRINTF:
8895 case BUILT_IN_FPRINTF_CHK:
8896 case BUILT_IN_VFPRINTF_CHK:
8897 return fold_builtin_fprintf (fndecl, arglist, ignore,
8898 DECL_FUNCTION_CODE (fndecl));
8900 default:
8901 break;
8904 return 0;
8907 /* A wrapper function for builtin folding that prevents warnings for
8908 "statement without effect" and the like, caused by removing the
8909 call node earlier than the warning is generated. */
8911 tree
8912 fold_builtin (tree fndecl, tree arglist, bool ignore)
8914 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8915 if (exp)
8917 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8918 TREE_NO_WARNING (exp) = 1;
8921 return exp;
8924 /* Conveniently construct a function call expression. */
8926 tree
8927 build_function_call_expr (tree fn, tree arglist)
8929 tree call_expr;
8931 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8932 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8933 call_expr, arglist, NULL_TREE);
8936 /* This function validates the types of a function call argument list
8937 represented as a tree chain of parameters against a specified list
8938 of tree_codes. If the last specifier is a 0, that represents an
8939 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8941 static int
8942 validate_arglist (tree arglist, ...)
8944 enum tree_code code;
8945 int res = 0;
8946 va_list ap;
8948 va_start (ap, arglist);
8952 code = va_arg (ap, enum tree_code);
8953 switch (code)
8955 case 0:
8956 /* This signifies an ellipses, any further arguments are all ok. */
8957 res = 1;
8958 goto end;
8959 case VOID_TYPE:
8960 /* This signifies an endlink, if no arguments remain, return
8961 true, otherwise return false. */
8962 res = arglist == 0;
8963 goto end;
8964 default:
8965 /* If no parameters remain or the parameter's code does not
8966 match the specified code, return false. Otherwise continue
8967 checking any remaining arguments. */
8968 if (arglist == 0)
8969 goto end;
8970 if (code == POINTER_TYPE)
8972 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8973 goto end;
8975 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8976 goto end;
8977 break;
8979 arglist = TREE_CHAIN (arglist);
8981 while (1);
8983 /* We need gotos here since we can only have one VA_CLOSE in a
8984 function. */
8985 end: ;
8986 va_end (ap);
8988 return res;
8991 /* Default target-specific builtin expander that does nothing. */
8994 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8995 rtx target ATTRIBUTE_UNUSED,
8996 rtx subtarget ATTRIBUTE_UNUSED,
8997 enum machine_mode mode ATTRIBUTE_UNUSED,
8998 int ignore ATTRIBUTE_UNUSED)
9000 return NULL_RTX;
9003 /* Returns true is EXP represents data that would potentially reside
9004 in a readonly section. */
9006 static bool
9007 readonly_data_expr (tree exp)
9009 STRIP_NOPS (exp);
9011 if (TREE_CODE (exp) != ADDR_EXPR)
9012 return false;
9014 exp = get_base_address (TREE_OPERAND (exp, 0));
9015 if (!exp)
9016 return false;
9018 /* Make sure we call decl_readonly_section only for trees it
9019 can handle (since it returns true for everything it doesn't
9020 understand). */
9021 if (TREE_CODE (exp) == STRING_CST
9022 || TREE_CODE (exp) == CONSTRUCTOR
9023 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9024 return decl_readonly_section (exp, 0);
9025 else
9026 return false;
9029 /* Simplify a call to the strstr builtin.
9031 Return 0 if no simplification was possible, otherwise return the
9032 simplified form of the call as a tree.
9034 The simplified form may be a constant or other expression which
9035 computes the same value, but in a more efficient manner (including
9036 calls to other builtin functions).
9038 The call may contain arguments which need to be evaluated, but
9039 which are not useful to determine the result of the call. In
9040 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9041 COMPOUND_EXPR will be an argument which must be evaluated.
9042 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9043 COMPOUND_EXPR in the chain will contain the tree for the simplified
9044 form of the builtin function call. */
9046 static tree
9047 fold_builtin_strstr (tree arglist, tree type)
9049 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9050 return 0;
9051 else
9053 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9054 tree fn;
9055 const char *p1, *p2;
9057 p2 = c_getstr (s2);
9058 if (p2 == NULL)
9059 return 0;
9061 p1 = c_getstr (s1);
9062 if (p1 != NULL)
9064 const char *r = strstr (p1, p2);
9065 tree tem;
9067 if (r == NULL)
9068 return build_int_cst (TREE_TYPE (s1), 0);
9070 /* Return an offset into the constant string argument. */
9071 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9072 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9073 return fold_convert (type, tem);
9076 /* The argument is const char *, and the result is char *, so we need
9077 a type conversion here to avoid a warning. */
9078 if (p2[0] == '\0')
9079 return fold_convert (type, s1);
9081 if (p2[1] != '\0')
9082 return 0;
9084 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9085 if (!fn)
9086 return 0;
9088 /* New argument list transforming strstr(s1, s2) to
9089 strchr(s1, s2[0]). */
9090 arglist = build_tree_list (NULL_TREE,
9091 build_int_cst (NULL_TREE, p2[0]));
9092 arglist = tree_cons (NULL_TREE, s1, arglist);
9093 return build_function_call_expr (fn, arglist);
9097 /* Simplify a call to the strchr builtin.
9099 Return 0 if no simplification was possible, otherwise return the
9100 simplified form of the call as a tree.
9102 The simplified form may be a constant or other expression which
9103 computes the same value, but in a more efficient manner (including
9104 calls to other builtin functions).
9106 The call may contain arguments which need to be evaluated, but
9107 which are not useful to determine the result of the call. In
9108 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9109 COMPOUND_EXPR will be an argument which must be evaluated.
9110 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9111 COMPOUND_EXPR in the chain will contain the tree for the simplified
9112 form of the builtin function call. */
9114 static tree
9115 fold_builtin_strchr (tree arglist, tree type)
9117 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9118 return 0;
9119 else
9121 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9122 const char *p1;
9124 if (TREE_CODE (s2) != INTEGER_CST)
9125 return 0;
9127 p1 = c_getstr (s1);
9128 if (p1 != NULL)
9130 char c;
9131 const char *r;
9132 tree tem;
9134 if (target_char_cast (s2, &c))
9135 return 0;
9137 r = strchr (p1, c);
9139 if (r == NULL)
9140 return build_int_cst (TREE_TYPE (s1), 0);
9142 /* Return an offset into the constant string argument. */
9143 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9144 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9145 return fold_convert (type, tem);
9147 return 0;
9151 /* Simplify a call to the strrchr builtin.
9153 Return 0 if no simplification was possible, otherwise return the
9154 simplified form of the call as a tree.
9156 The simplified form may be a constant or other expression which
9157 computes the same value, but in a more efficient manner (including
9158 calls to other builtin functions).
9160 The call may contain arguments which need to be evaluated, but
9161 which are not useful to determine the result of the call. In
9162 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9163 COMPOUND_EXPR will be an argument which must be evaluated.
9164 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9165 COMPOUND_EXPR in the chain will contain the tree for the simplified
9166 form of the builtin function call. */
9168 static tree
9169 fold_builtin_strrchr (tree arglist, tree type)
9171 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9172 return 0;
9173 else
9175 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9176 tree fn;
9177 const char *p1;
9179 if (TREE_CODE (s2) != INTEGER_CST)
9180 return 0;
9182 p1 = c_getstr (s1);
9183 if (p1 != NULL)
9185 char c;
9186 const char *r;
9187 tree tem;
9189 if (target_char_cast (s2, &c))
9190 return 0;
9192 r = strrchr (p1, c);
9194 if (r == NULL)
9195 return build_int_cst (TREE_TYPE (s1), 0);
9197 /* Return an offset into the constant string argument. */
9198 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9199 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9200 return fold_convert (type, tem);
9203 if (! integer_zerop (s2))
9204 return 0;
9206 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9207 if (!fn)
9208 return 0;
9210 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9211 return build_function_call_expr (fn, arglist);
9215 /* Simplify a call to the strpbrk builtin.
9217 Return 0 if no simplification was possible, otherwise return the
9218 simplified form of the call as a tree.
9220 The simplified form may be a constant or other expression which
9221 computes the same value, but in a more efficient manner (including
9222 calls to other builtin functions).
9224 The call may contain arguments which need to be evaluated, but
9225 which are not useful to determine the result of the call. In
9226 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9227 COMPOUND_EXPR will be an argument which must be evaluated.
9228 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9229 COMPOUND_EXPR in the chain will contain the tree for the simplified
9230 form of the builtin function call. */
9232 static tree
9233 fold_builtin_strpbrk (tree arglist, tree type)
9235 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9236 return 0;
9237 else
9239 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9240 tree fn;
9241 const char *p1, *p2;
9243 p2 = c_getstr (s2);
9244 if (p2 == NULL)
9245 return 0;
9247 p1 = c_getstr (s1);
9248 if (p1 != NULL)
9250 const char *r = strpbrk (p1, p2);
9251 tree tem;
9253 if (r == NULL)
9254 return build_int_cst (TREE_TYPE (s1), 0);
9256 /* Return an offset into the constant string argument. */
9257 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9258 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9259 return fold_convert (type, tem);
9262 if (p2[0] == '\0')
9263 /* strpbrk(x, "") == NULL.
9264 Evaluate and ignore s1 in case it had side-effects. */
9265 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9267 if (p2[1] != '\0')
9268 return 0; /* Really call strpbrk. */
9270 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9271 if (!fn)
9272 return 0;
9274 /* New argument list transforming strpbrk(s1, s2) to
9275 strchr(s1, s2[0]). */
9276 arglist = build_tree_list (NULL_TREE,
9277 build_int_cst (NULL_TREE, p2[0]));
9278 arglist = tree_cons (NULL_TREE, s1, arglist);
9279 return build_function_call_expr (fn, arglist);
9283 /* Simplify a call to the strcat builtin.
9285 Return 0 if no simplification was possible, otherwise return the
9286 simplified form of the call as a tree.
9288 The simplified form may be a constant or other expression which
9289 computes the same value, but in a more efficient manner (including
9290 calls to other builtin functions).
9292 The call may contain arguments which need to be evaluated, but
9293 which are not useful to determine the result of the call. In
9294 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9295 COMPOUND_EXPR will be an argument which must be evaluated.
9296 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9297 COMPOUND_EXPR in the chain will contain the tree for the simplified
9298 form of the builtin function call. */
9300 static tree
9301 fold_builtin_strcat (tree arglist)
9303 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9304 return 0;
9305 else
9307 tree dst = TREE_VALUE (arglist),
9308 src = TREE_VALUE (TREE_CHAIN (arglist));
9309 const char *p = c_getstr (src);
9311 /* If the string length is zero, return the dst parameter. */
9312 if (p && *p == '\0')
9313 return dst;
9315 return 0;
9319 /* Simplify a call to the strncat builtin.
9321 Return 0 if no simplification was possible, otherwise return the
9322 simplified form of the call as a tree.
9324 The simplified form may be a constant or other expression which
9325 computes the same value, but in a more efficient manner (including
9326 calls to other builtin functions).
9328 The call may contain arguments which need to be evaluated, but
9329 which are not useful to determine the result of the call. In
9330 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9331 COMPOUND_EXPR will be an argument which must be evaluated.
9332 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9333 COMPOUND_EXPR in the chain will contain the tree for the simplified
9334 form of the builtin function call. */
9336 static tree
9337 fold_builtin_strncat (tree arglist)
9339 if (!validate_arglist (arglist,
9340 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9341 return 0;
9342 else
9344 tree dst = TREE_VALUE (arglist);
9345 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9346 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9347 const char *p = c_getstr (src);
9349 /* If the requested length is zero, or the src parameter string
9350 length is zero, return the dst parameter. */
9351 if (integer_zerop (len) || (p && *p == '\0'))
9352 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9354 /* If the requested len is greater than or equal to the string
9355 length, call strcat. */
9356 if (TREE_CODE (len) == INTEGER_CST && p
9357 && compare_tree_int (len, strlen (p)) >= 0)
9359 tree newarglist
9360 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9361 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9363 /* If the replacement _DECL isn't initialized, don't do the
9364 transformation. */
9365 if (!fn)
9366 return 0;
9368 return build_function_call_expr (fn, newarglist);
9370 return 0;
9374 /* Simplify a call to the strspn builtin.
9376 Return 0 if no simplification was possible, otherwise return the
9377 simplified form of the call as a tree.
9379 The simplified form may be a constant or other expression which
9380 computes the same value, but in a more efficient manner (including
9381 calls to other builtin functions).
9383 The call may contain arguments which need to be evaluated, but
9384 which are not useful to determine the result of the call. In
9385 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9386 COMPOUND_EXPR will be an argument which must be evaluated.
9387 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9388 COMPOUND_EXPR in the chain will contain the tree for the simplified
9389 form of the builtin function call. */
9391 static tree
9392 fold_builtin_strspn (tree arglist)
9394 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9395 return 0;
9396 else
9398 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9399 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9401 /* If both arguments are constants, evaluate at compile-time. */
9402 if (p1 && p2)
9404 const size_t r = strspn (p1, p2);
9405 return size_int (r);
9408 /* If either argument is "", return 0. */
9409 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9410 /* Evaluate and ignore both arguments in case either one has
9411 side-effects. */
9412 return omit_two_operands (integer_type_node, integer_zero_node,
9413 s1, s2);
9414 return 0;
9418 /* Simplify a call to the strcspn builtin.
9420 Return 0 if no simplification was possible, otherwise return the
9421 simplified form of the call as a tree.
9423 The simplified form may be a constant or other expression which
9424 computes the same value, but in a more efficient manner (including
9425 calls to other builtin functions).
9427 The call may contain arguments which need to be evaluated, but
9428 which are not useful to determine the result of the call. In
9429 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9430 COMPOUND_EXPR will be an argument which must be evaluated.
9431 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9432 COMPOUND_EXPR in the chain will contain the tree for the simplified
9433 form of the builtin function call. */
9435 static tree
9436 fold_builtin_strcspn (tree arglist)
9438 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9439 return 0;
9440 else
9442 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9443 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9445 /* If both arguments are constants, evaluate at compile-time. */
9446 if (p1 && p2)
9448 const size_t r = strcspn (p1, p2);
9449 return size_int (r);
9452 /* If the first argument is "", return 0. */
9453 if (p1 && *p1 == '\0')
9455 /* Evaluate and ignore argument s2 in case it has
9456 side-effects. */
9457 return omit_one_operand (integer_type_node,
9458 integer_zero_node, s2);
9461 /* If the second argument is "", return __builtin_strlen(s1). */
9462 if (p2 && *p2 == '\0')
9464 tree newarglist = build_tree_list (NULL_TREE, s1),
9465 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9467 /* If the replacement _DECL isn't initialized, don't do the
9468 transformation. */
9469 if (!fn)
9470 return 0;
9472 return build_function_call_expr (fn, newarglist);
9474 return 0;
9478 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9479 by the builtin will be ignored. UNLOCKED is true is true if this
9480 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9481 the known length of the string. Return NULL_TREE if no simplification
9482 was possible. */
9484 tree
9485 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9487 tree fn;
9488 /* If we're using an unlocked function, assume the other unlocked
9489 functions exist explicitly. */
9490 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9491 : implicit_built_in_decls[BUILT_IN_FPUTC];
9492 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9493 : implicit_built_in_decls[BUILT_IN_FWRITE];
9495 /* If the return value is used, don't do the transformation. */
9496 if (!ignore)
9497 return 0;
9499 /* Verify the arguments in the original call. */
9500 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9501 return 0;
9503 if (! len)
9504 len = c_strlen (TREE_VALUE (arglist), 0);
9506 /* Get the length of the string passed to fputs. If the length
9507 can't be determined, punt. */
9508 if (!len
9509 || TREE_CODE (len) != INTEGER_CST)
9510 return 0;
9512 switch (compare_tree_int (len, 1))
9514 case -1: /* length is 0, delete the call entirely . */
9515 return omit_one_operand (integer_type_node, integer_zero_node,
9516 TREE_VALUE (TREE_CHAIN (arglist)));
9518 case 0: /* length is 1, call fputc. */
9520 const char *p = c_getstr (TREE_VALUE (arglist));
9522 if (p != NULL)
9524 /* New argument list transforming fputs(string, stream) to
9525 fputc(string[0], stream). */
9526 arglist = build_tree_list (NULL_TREE,
9527 TREE_VALUE (TREE_CHAIN (arglist)));
9528 arglist = tree_cons (NULL_TREE,
9529 build_int_cst (NULL_TREE, p[0]),
9530 arglist);
9531 fn = fn_fputc;
9532 break;
9535 /* FALLTHROUGH */
9536 case 1: /* length is greater than 1, call fwrite. */
9538 tree string_arg;
9540 /* If optimizing for size keep fputs. */
9541 if (optimize_size)
9542 return 0;
9543 string_arg = TREE_VALUE (arglist);
9544 /* New argument list transforming fputs(string, stream) to
9545 fwrite(string, 1, len, stream). */
9546 arglist = build_tree_list (NULL_TREE,
9547 TREE_VALUE (TREE_CHAIN (arglist)));
9548 arglist = tree_cons (NULL_TREE, len, arglist);
9549 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9550 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9551 fn = fn_fwrite;
9552 break;
9554 default:
9555 gcc_unreachable ();
9558 /* If the replacement _DECL isn't initialized, don't do the
9559 transformation. */
9560 if (!fn)
9561 return 0;
9563 /* These optimizations are only performed when the result is ignored,
9564 hence there's no need to cast the result to integer_type_node. */
9565 return build_function_call_expr (fn, arglist);
9568 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9569 produced. False otherwise. This is done so that we don't output the error
9570 or warning twice or three times. */
9571 bool
9572 fold_builtin_next_arg (tree arglist)
9574 tree fntype = TREE_TYPE (current_function_decl);
9576 if (TYPE_ARG_TYPES (fntype) == 0
9577 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9578 == void_type_node))
9580 error ("%<va_start%> used in function with fixed args");
9581 return true;
9583 else if (!arglist)
9585 /* Evidently an out of date version of <stdarg.h>; can't validate
9586 va_start's second argument, but can still work as intended. */
9587 warning (0, "%<__builtin_next_arg%> called without an argument");
9588 return true;
9590 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9591 when we checked the arguments and if needed issued a warning. */
9592 else if (!TREE_CHAIN (arglist)
9593 || !integer_zerop (TREE_VALUE (arglist))
9594 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9595 || TREE_CHAIN (TREE_CHAIN (arglist)))
9597 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9598 tree arg = TREE_VALUE (arglist);
9600 if (TREE_CHAIN (arglist))
9602 error ("%<va_start%> used with too many arguments");
9603 return true;
9606 /* Strip off all nops for the sake of the comparison. This
9607 is not quite the same as STRIP_NOPS. It does more.
9608 We must also strip off INDIRECT_EXPR for C++ reference
9609 parameters. */
9610 while (TREE_CODE (arg) == NOP_EXPR
9611 || TREE_CODE (arg) == CONVERT_EXPR
9612 || TREE_CODE (arg) == NON_LVALUE_EXPR
9613 || TREE_CODE (arg) == INDIRECT_REF)
9614 arg = TREE_OPERAND (arg, 0);
9615 if (arg != last_parm)
9617 /* FIXME: Sometimes with the tree optimizers we can get the
9618 not the last argument even though the user used the last
9619 argument. We just warn and set the arg to be the last
9620 argument so that we will get wrong-code because of
9621 it. */
9622 warning (0, "second parameter of %<va_start%> not last named argument");
9624 /* We want to verify the second parameter just once before the tree
9625 optimizers are run and then avoid keeping it in the tree,
9626 as otherwise we could warn even for correct code like:
9627 void foo (int i, ...)
9628 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9629 TREE_VALUE (arglist) = integer_zero_node;
9630 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9632 return false;
9636 /* Simplify a call to the sprintf builtin.
9638 Return 0 if no simplification was possible, otherwise return the
9639 simplified form of the call as a tree. If IGNORED is true, it means that
9640 the caller does not use the returned value of the function. */
9642 static tree
9643 fold_builtin_sprintf (tree arglist, int ignored)
9645 tree call, retval, dest, fmt;
9646 const char *fmt_str = NULL;
9648 /* Verify the required arguments in the original call. We deal with two
9649 types of sprintf() calls: 'sprintf (str, fmt)' and
9650 'sprintf (dest, "%s", orig)'. */
9651 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9652 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9653 VOID_TYPE))
9654 return NULL_TREE;
9656 /* Get the destination string and the format specifier. */
9657 dest = TREE_VALUE (arglist);
9658 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9660 /* Check whether the format is a literal string constant. */
9661 fmt_str = c_getstr (fmt);
9662 if (fmt_str == NULL)
9663 return NULL_TREE;
9665 call = NULL_TREE;
9666 retval = NULL_TREE;
9668 if (!init_target_chars())
9669 return 0;
9671 /* If the format doesn't contain % args or %%, use strcpy. */
9672 if (strchr (fmt_str, target_percent) == NULL)
9674 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9676 if (!fn)
9677 return NULL_TREE;
9679 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9680 'format' is known to contain no % formats. */
9681 arglist = build_tree_list (NULL_TREE, fmt);
9682 arglist = tree_cons (NULL_TREE, dest, arglist);
9683 call = build_function_call_expr (fn, arglist);
9684 if (!ignored)
9685 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9688 /* If the format is "%s", use strcpy if the result isn't used. */
9689 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9691 tree fn, orig;
9692 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9694 if (!fn)
9695 return NULL_TREE;
9697 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9698 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9699 arglist = build_tree_list (NULL_TREE, orig);
9700 arglist = tree_cons (NULL_TREE, dest, arglist);
9701 if (!ignored)
9703 retval = c_strlen (orig, 1);
9704 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9705 return NULL_TREE;
9707 call = build_function_call_expr (fn, arglist);
9710 if (call && retval)
9712 retval = fold_convert
9713 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9714 retval);
9715 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9717 else
9718 return call;
9721 /* Expand a call to __builtin_object_size. */
9724 expand_builtin_object_size (tree exp)
9726 tree ost;
9727 int object_size_type;
9728 tree fndecl = get_callee_fndecl (exp);
9729 tree arglist = TREE_OPERAND (exp, 1);
9730 location_t locus = EXPR_LOCATION (exp);
9732 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9734 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9735 &locus, fndecl);
9736 expand_builtin_trap ();
9737 return const0_rtx;
9740 ost = TREE_VALUE (TREE_CHAIN (arglist));
9741 STRIP_NOPS (ost);
9743 if (TREE_CODE (ost) != INTEGER_CST
9744 || tree_int_cst_sgn (ost) < 0
9745 || compare_tree_int (ost, 3) > 0)
9747 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9748 &locus, fndecl);
9749 expand_builtin_trap ();
9750 return const0_rtx;
9753 object_size_type = tree_low_cst (ost, 0);
9755 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9758 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9759 FCODE is the BUILT_IN_* to use.
9760 Return 0 if we failed; the caller should emit a normal call,
9761 otherwise try to get the result in TARGET, if convenient (and in
9762 mode MODE if that's convenient). */
9764 static rtx
9765 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9766 enum built_in_function fcode)
9768 tree arglist = TREE_OPERAND (exp, 1);
9769 tree dest, src, len, size;
9771 if (!validate_arglist (arglist,
9772 POINTER_TYPE,
9773 fcode == BUILT_IN_MEMSET_CHK
9774 ? INTEGER_TYPE : POINTER_TYPE,
9775 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9776 return 0;
9778 dest = TREE_VALUE (arglist);
9779 src = TREE_VALUE (TREE_CHAIN (arglist));
9780 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9781 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9783 if (! host_integerp (size, 1))
9784 return 0;
9786 if (host_integerp (len, 1) || integer_all_onesp (size))
9788 tree fn;
9790 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9792 location_t locus = EXPR_LOCATION (exp);
9793 warning (0, "%Hcall to %D will always overflow destination buffer",
9794 &locus, get_callee_fndecl (exp));
9795 return 0;
9798 arglist = build_tree_list (NULL_TREE, len);
9799 arglist = tree_cons (NULL_TREE, src, arglist);
9800 arglist = tree_cons (NULL_TREE, dest, arglist);
9802 fn = NULL_TREE;
9803 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9804 mem{cpy,pcpy,move,set} is available. */
9805 switch (fcode)
9807 case BUILT_IN_MEMCPY_CHK:
9808 fn = built_in_decls[BUILT_IN_MEMCPY];
9809 break;
9810 case BUILT_IN_MEMPCPY_CHK:
9811 fn = built_in_decls[BUILT_IN_MEMPCPY];
9812 break;
9813 case BUILT_IN_MEMMOVE_CHK:
9814 fn = built_in_decls[BUILT_IN_MEMMOVE];
9815 break;
9816 case BUILT_IN_MEMSET_CHK:
9817 fn = built_in_decls[BUILT_IN_MEMSET];
9818 break;
9819 default:
9820 break;
9823 if (! fn)
9824 return 0;
9826 fn = build_function_call_expr (fn, arglist);
9827 if (TREE_CODE (fn) == CALL_EXPR)
9828 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9829 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9831 else if (fcode == BUILT_IN_MEMSET_CHK)
9832 return 0;
9833 else
9835 unsigned int dest_align
9836 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9838 /* If DEST is not a pointer type, call the normal function. */
9839 if (dest_align == 0)
9840 return 0;
9842 /* If SRC and DEST are the same (and not volatile), do nothing. */
9843 if (operand_equal_p (src, dest, 0))
9845 tree expr;
9847 if (fcode != BUILT_IN_MEMPCPY_CHK)
9849 /* Evaluate and ignore LEN in case it has side-effects. */
9850 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9851 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9854 len = fold_convert (TREE_TYPE (dest), len);
9855 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9856 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9859 /* __memmove_chk special case. */
9860 if (fcode == BUILT_IN_MEMMOVE_CHK)
9862 unsigned int src_align
9863 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9865 if (src_align == 0)
9866 return 0;
9868 /* If src is categorized for a readonly section we can use
9869 normal __memcpy_chk. */
9870 if (readonly_data_expr (src))
9872 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9873 if (!fn)
9874 return 0;
9875 fn = build_function_call_expr (fn, arglist);
9876 if (TREE_CODE (fn) == CALL_EXPR)
9877 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9878 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9881 return 0;
9885 /* Emit warning if a buffer overflow is detected at compile time. */
9887 static void
9888 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9890 int arg_mask, is_strlen = 0;
9891 tree arglist = TREE_OPERAND (exp, 1), a;
9892 tree len, size;
9893 location_t locus;
9895 switch (fcode)
9897 case BUILT_IN_STRCPY_CHK:
9898 case BUILT_IN_STPCPY_CHK:
9899 /* For __strcat_chk the warning will be emitted only if overflowing
9900 by at least strlen (dest) + 1 bytes. */
9901 case BUILT_IN_STRCAT_CHK:
9902 arg_mask = 6;
9903 is_strlen = 1;
9904 break;
9905 case BUILT_IN_STRNCPY_CHK:
9906 arg_mask = 12;
9907 break;
9908 case BUILT_IN_SNPRINTF_CHK:
9909 case BUILT_IN_VSNPRINTF_CHK:
9910 arg_mask = 10;
9911 break;
9912 default:
9913 gcc_unreachable ();
9916 len = NULL_TREE;
9917 size = NULL_TREE;
9918 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9919 if (arg_mask & 1)
9921 if (len)
9922 size = a;
9923 else
9924 len = a;
9927 if (!len || !size)
9928 return;
9930 len = TREE_VALUE (len);
9931 size = TREE_VALUE (size);
9933 if (! host_integerp (size, 1) || integer_all_onesp (size))
9934 return;
9936 if (is_strlen)
9938 len = c_strlen (len, 1);
9939 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9940 return;
9942 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9943 return;
9945 locus = EXPR_LOCATION (exp);
9946 warning (0, "%Hcall to %D will always overflow destination buffer",
9947 &locus, get_callee_fndecl (exp));
9950 /* Emit warning if a buffer overflow is detected at compile time
9951 in __sprintf_chk/__vsprintf_chk calls. */
9953 static void
9954 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9956 tree arglist = TREE_OPERAND (exp, 1);
9957 tree dest, size, len, fmt, flag;
9958 const char *fmt_str;
9960 /* Verify the required arguments in the original call. */
9961 if (! arglist)
9962 return;
9963 dest = TREE_VALUE (arglist);
9964 arglist = TREE_CHAIN (arglist);
9965 if (! arglist)
9966 return;
9967 flag = TREE_VALUE (arglist);
9968 arglist = TREE_CHAIN (arglist);
9969 if (! arglist)
9970 return;
9971 size = TREE_VALUE (arglist);
9972 arglist = TREE_CHAIN (arglist);
9973 if (! arglist)
9974 return;
9975 fmt = TREE_VALUE (arglist);
9976 arglist = TREE_CHAIN (arglist);
9978 if (! host_integerp (size, 1) || integer_all_onesp (size))
9979 return;
9981 /* Check whether the format is a literal string constant. */
9982 fmt_str = c_getstr (fmt);
9983 if (fmt_str == NULL)
9984 return;
9986 if (!init_target_chars())
9987 return;
9989 /* If the format doesn't contain % args or %%, we know its size. */
9990 if (strchr (fmt_str, target_percent) == 0)
9991 len = build_int_cstu (size_type_node, strlen (fmt_str));
9992 /* If the format is "%s" and first ... argument is a string literal,
9993 we know it too. */
9994 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9996 tree arg;
9998 if (! arglist)
9999 return;
10000 arg = TREE_VALUE (arglist);
10001 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10002 return;
10004 len = c_strlen (arg, 1);
10005 if (!len || ! host_integerp (len, 1))
10006 return;
10008 else
10009 return;
10011 if (! tree_int_cst_lt (len, size))
10013 location_t locus = EXPR_LOCATION (exp);
10014 warning (0, "%Hcall to %D will always overflow destination buffer",
10015 &locus, get_callee_fndecl (exp));
10019 /* Fold a call to __builtin_object_size, if possible. */
10021 tree
10022 fold_builtin_object_size (tree arglist)
10024 tree ptr, ost, ret = 0;
10025 int object_size_type;
10027 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10028 return 0;
10030 ptr = TREE_VALUE (arglist);
10031 ost = TREE_VALUE (TREE_CHAIN (arglist));
10032 STRIP_NOPS (ost);
10034 if (TREE_CODE (ost) != INTEGER_CST
10035 || tree_int_cst_sgn (ost) < 0
10036 || compare_tree_int (ost, 3) > 0)
10037 return 0;
10039 object_size_type = tree_low_cst (ost, 0);
10041 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10042 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10043 and (size_t) 0 for types 2 and 3. */
10044 if (TREE_SIDE_EFFECTS (ptr))
10045 return fold_convert (size_type_node,
10046 object_size_type < 2
10047 ? integer_minus_one_node : integer_zero_node);
10049 if (TREE_CODE (ptr) == ADDR_EXPR)
10050 ret = build_int_cstu (size_type_node,
10051 compute_builtin_object_size (ptr, object_size_type));
10053 else if (TREE_CODE (ptr) == SSA_NAME)
10055 unsigned HOST_WIDE_INT bytes;
10057 /* If object size is not known yet, delay folding until
10058 later. Maybe subsequent passes will help determining
10059 it. */
10060 bytes = compute_builtin_object_size (ptr, object_size_type);
10061 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10062 ? -1 : 0))
10063 ret = build_int_cstu (size_type_node, bytes);
10066 if (ret)
10068 ret = force_fit_type (ret, -1, false, false);
10069 if (TREE_CONSTANT_OVERFLOW (ret))
10070 ret = 0;
10073 return ret;
10076 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10077 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10078 code of the builtin. If MAXLEN is not NULL, it is maximum length
10079 passed as third argument. */
10081 tree
10082 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10083 enum built_in_function fcode)
10085 tree dest, src, len, size, fn;
10087 if (!validate_arglist (arglist,
10088 POINTER_TYPE,
10089 fcode == BUILT_IN_MEMSET_CHK
10090 ? INTEGER_TYPE : POINTER_TYPE,
10091 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10092 return 0;
10094 dest = TREE_VALUE (arglist);
10095 /* Actually val for __memset_chk, but it doesn't matter. */
10096 src = TREE_VALUE (TREE_CHAIN (arglist));
10097 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10098 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10100 /* If SRC and DEST are the same (and not volatile), return DEST
10101 (resp. DEST+LEN for __mempcpy_chk). */
10102 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10104 if (fcode != BUILT_IN_MEMPCPY_CHK)
10105 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10106 else
10108 tree temp = fold_convert (TREE_TYPE (dest), len);
10109 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10110 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10114 if (! host_integerp (size, 1))
10115 return 0;
10117 if (! integer_all_onesp (size))
10119 if (! host_integerp (len, 1))
10121 /* If LEN is not constant, try MAXLEN too.
10122 For MAXLEN only allow optimizing into non-_ocs function
10123 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10124 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10126 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10128 /* (void) __mempcpy_chk () can be optimized into
10129 (void) __memcpy_chk (). */
10130 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10131 if (!fn)
10132 return 0;
10134 return build_function_call_expr (fn, arglist);
10136 return 0;
10139 else
10140 maxlen = len;
10142 if (tree_int_cst_lt (size, maxlen))
10143 return 0;
10146 arglist = build_tree_list (NULL_TREE, len);
10147 arglist = tree_cons (NULL_TREE, src, arglist);
10148 arglist = tree_cons (NULL_TREE, dest, arglist);
10150 fn = NULL_TREE;
10151 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10152 mem{cpy,pcpy,move,set} is available. */
10153 switch (fcode)
10155 case BUILT_IN_MEMCPY_CHK:
10156 fn = built_in_decls[BUILT_IN_MEMCPY];
10157 break;
10158 case BUILT_IN_MEMPCPY_CHK:
10159 fn = built_in_decls[BUILT_IN_MEMPCPY];
10160 break;
10161 case BUILT_IN_MEMMOVE_CHK:
10162 fn = built_in_decls[BUILT_IN_MEMMOVE];
10163 break;
10164 case BUILT_IN_MEMSET_CHK:
10165 fn = built_in_decls[BUILT_IN_MEMSET];
10166 break;
10167 default:
10168 break;
10171 if (!fn)
10172 return 0;
10174 return build_function_call_expr (fn, arglist);
10177 /* Fold a call to the __st[rp]cpy_chk builtin.
10178 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10179 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10180 strings passed as second argument. */
10182 tree
10183 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10184 enum built_in_function fcode)
10186 tree dest, src, size, len, fn;
10188 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10189 VOID_TYPE))
10190 return 0;
10192 dest = TREE_VALUE (arglist);
10193 src = TREE_VALUE (TREE_CHAIN (arglist));
10194 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10196 /* If SRC and DEST are the same (and not volatile), return DEST. */
10197 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10198 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10200 if (! host_integerp (size, 1))
10201 return 0;
10203 if (! integer_all_onesp (size))
10205 len = c_strlen (src, 1);
10206 if (! len || ! host_integerp (len, 1))
10208 /* If LEN is not constant, try MAXLEN too.
10209 For MAXLEN only allow optimizing into non-_ocs function
10210 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10211 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10213 if (fcode == BUILT_IN_STPCPY_CHK)
10215 if (! ignore)
10216 return 0;
10218 /* If return value of __stpcpy_chk is ignored,
10219 optimize into __strcpy_chk. */
10220 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10221 if (!fn)
10222 return 0;
10224 return build_function_call_expr (fn, arglist);
10227 if (! len || TREE_SIDE_EFFECTS (len))
10228 return 0;
10230 /* If c_strlen returned something, but not a constant,
10231 transform __strcpy_chk into __memcpy_chk. */
10232 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10233 if (!fn)
10234 return 0;
10236 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10237 arglist = build_tree_list (NULL_TREE, size);
10238 arglist = tree_cons (NULL_TREE, len, arglist);
10239 arglist = tree_cons (NULL_TREE, src, arglist);
10240 arglist = tree_cons (NULL_TREE, dest, arglist);
10241 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10242 build_function_call_expr (fn, arglist));
10245 else
10246 maxlen = len;
10248 if (! tree_int_cst_lt (maxlen, size))
10249 return 0;
10252 arglist = build_tree_list (NULL_TREE, src);
10253 arglist = tree_cons (NULL_TREE, dest, arglist);
10255 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10256 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10257 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10258 if (!fn)
10259 return 0;
10261 return build_function_call_expr (fn, arglist);
10264 /* Fold a call to the __strncpy_chk builtin.
10265 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10267 tree
10268 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10270 tree dest, src, size, len, fn;
10272 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10273 INTEGER_TYPE, VOID_TYPE))
10274 return 0;
10276 dest = TREE_VALUE (arglist);
10277 src = TREE_VALUE (TREE_CHAIN (arglist));
10278 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10279 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10281 if (! host_integerp (size, 1))
10282 return 0;
10284 if (! integer_all_onesp (size))
10286 if (! host_integerp (len, 1))
10288 /* If LEN is not constant, try MAXLEN too.
10289 For MAXLEN only allow optimizing into non-_ocs function
10290 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10291 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10292 return 0;
10294 else
10295 maxlen = len;
10297 if (tree_int_cst_lt (size, maxlen))
10298 return 0;
10301 arglist = build_tree_list (NULL_TREE, len);
10302 arglist = tree_cons (NULL_TREE, src, arglist);
10303 arglist = tree_cons (NULL_TREE, dest, arglist);
10305 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10306 fn = built_in_decls[BUILT_IN_STRNCPY];
10307 if (!fn)
10308 return 0;
10310 return build_function_call_expr (fn, arglist);
10313 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10315 static tree
10316 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10318 tree dest, src, size, fn;
10319 const char *p;
10321 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10322 VOID_TYPE))
10323 return 0;
10325 dest = TREE_VALUE (arglist);
10326 src = TREE_VALUE (TREE_CHAIN (arglist));
10327 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10329 p = c_getstr (src);
10330 /* If the SRC parameter is "", return DEST. */
10331 if (p && *p == '\0')
10332 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10334 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10335 return 0;
10337 arglist = build_tree_list (NULL_TREE, src);
10338 arglist = tree_cons (NULL_TREE, dest, arglist);
10340 /* If __builtin_strcat_chk is used, assume strcat is available. */
10341 fn = built_in_decls[BUILT_IN_STRCAT];
10342 if (!fn)
10343 return 0;
10345 return build_function_call_expr (fn, arglist);
10348 /* Fold a call to the __strncat_chk builtin EXP. */
10350 static tree
10351 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10353 tree dest, src, size, len, fn;
10354 const char *p;
10356 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10357 INTEGER_TYPE, VOID_TYPE))
10358 return 0;
10360 dest = TREE_VALUE (arglist);
10361 src = TREE_VALUE (TREE_CHAIN (arglist));
10362 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10363 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10365 p = c_getstr (src);
10366 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10367 if (p && *p == '\0')
10368 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10369 else if (integer_zerop (len))
10370 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10372 if (! host_integerp (size, 1))
10373 return 0;
10375 if (! integer_all_onesp (size))
10377 tree src_len = c_strlen (src, 1);
10378 if (src_len
10379 && host_integerp (src_len, 1)
10380 && host_integerp (len, 1)
10381 && ! tree_int_cst_lt (len, src_len))
10383 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10384 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10385 if (!fn)
10386 return 0;
10388 arglist = build_tree_list (NULL_TREE, size);
10389 arglist = tree_cons (NULL_TREE, src, arglist);
10390 arglist = tree_cons (NULL_TREE, dest, arglist);
10391 return build_function_call_expr (fn, arglist);
10393 return 0;
10396 arglist = build_tree_list (NULL_TREE, len);
10397 arglist = tree_cons (NULL_TREE, src, arglist);
10398 arglist = tree_cons (NULL_TREE, dest, arglist);
10400 /* If __builtin_strncat_chk is used, assume strncat is available. */
10401 fn = built_in_decls[BUILT_IN_STRNCAT];
10402 if (!fn)
10403 return 0;
10405 return build_function_call_expr (fn, arglist);
10408 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10409 a normal call should be emitted rather than expanding the function
10410 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10412 static tree
10413 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10415 tree dest, size, len, fn, fmt, flag;
10416 const char *fmt_str;
10418 /* Verify the required arguments in the original call. */
10419 if (! arglist)
10420 return 0;
10421 dest = TREE_VALUE (arglist);
10422 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10423 return 0;
10424 arglist = TREE_CHAIN (arglist);
10425 if (! arglist)
10426 return 0;
10427 flag = TREE_VALUE (arglist);
10428 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10429 return 0;
10430 arglist = TREE_CHAIN (arglist);
10431 if (! arglist)
10432 return 0;
10433 size = TREE_VALUE (arglist);
10434 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10435 return 0;
10436 arglist = TREE_CHAIN (arglist);
10437 if (! arglist)
10438 return 0;
10439 fmt = TREE_VALUE (arglist);
10440 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10441 return 0;
10442 arglist = TREE_CHAIN (arglist);
10444 if (! host_integerp (size, 1))
10445 return 0;
10447 len = NULL_TREE;
10449 if (!init_target_chars())
10450 return 0;
10452 /* Check whether the format is a literal string constant. */
10453 fmt_str = c_getstr (fmt);
10454 if (fmt_str != NULL)
10456 /* If the format doesn't contain % args or %%, we know the size. */
10457 if (strchr (fmt_str, target_percent) == 0)
10459 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10460 len = build_int_cstu (size_type_node, strlen (fmt_str));
10462 /* If the format is "%s" and first ... argument is a string literal,
10463 we know the size too. */
10464 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10466 tree arg;
10468 if (arglist && !TREE_CHAIN (arglist))
10470 arg = TREE_VALUE (arglist);
10471 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10473 len = c_strlen (arg, 1);
10474 if (! len || ! host_integerp (len, 1))
10475 len = NULL_TREE;
10481 if (! integer_all_onesp (size))
10483 if (! len || ! tree_int_cst_lt (len, size))
10484 return 0;
10487 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10488 or if format doesn't contain % chars or is "%s". */
10489 if (! integer_zerop (flag))
10491 if (fmt_str == NULL)
10492 return 0;
10493 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10494 return 0;
10497 arglist = tree_cons (NULL_TREE, fmt, arglist);
10498 arglist = tree_cons (NULL_TREE, dest, arglist);
10500 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10501 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10502 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10503 if (!fn)
10504 return 0;
10506 return build_function_call_expr (fn, arglist);
10509 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10510 a normal call should be emitted rather than expanding the function
10511 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10512 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10513 passed as second argument. */
10515 tree
10516 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10517 enum built_in_function fcode)
10519 tree dest, size, len, fn, fmt, flag;
10520 const char *fmt_str;
10522 /* Verify the required arguments in the original call. */
10523 if (! arglist)
10524 return 0;
10525 dest = TREE_VALUE (arglist);
10526 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10527 return 0;
10528 arglist = TREE_CHAIN (arglist);
10529 if (! arglist)
10530 return 0;
10531 len = TREE_VALUE (arglist);
10532 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10533 return 0;
10534 arglist = TREE_CHAIN (arglist);
10535 if (! arglist)
10536 return 0;
10537 flag = TREE_VALUE (arglist);
10538 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10539 return 0;
10540 arglist = TREE_CHAIN (arglist);
10541 if (! arglist)
10542 return 0;
10543 size = TREE_VALUE (arglist);
10544 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10545 return 0;
10546 arglist = TREE_CHAIN (arglist);
10547 if (! arglist)
10548 return 0;
10549 fmt = TREE_VALUE (arglist);
10550 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10551 return 0;
10552 arglist = TREE_CHAIN (arglist);
10554 if (! host_integerp (size, 1))
10555 return 0;
10557 if (! integer_all_onesp (size))
10559 if (! host_integerp (len, 1))
10561 /* If LEN is not constant, try MAXLEN too.
10562 For MAXLEN only allow optimizing into non-_ocs function
10563 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10564 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10565 return 0;
10567 else
10568 maxlen = len;
10570 if (tree_int_cst_lt (size, maxlen))
10571 return 0;
10574 if (!init_target_chars())
10575 return 0;
10577 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10578 or if format doesn't contain % chars or is "%s". */
10579 if (! integer_zerop (flag))
10581 fmt_str = c_getstr (fmt);
10582 if (fmt_str == NULL)
10583 return 0;
10584 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10585 return 0;
10588 arglist = tree_cons (NULL_TREE, fmt, arglist);
10589 arglist = tree_cons (NULL_TREE, len, arglist);
10590 arglist = tree_cons (NULL_TREE, dest, arglist);
10592 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10593 available. */
10594 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10595 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10596 if (!fn)
10597 return 0;
10599 return build_function_call_expr (fn, arglist);
10602 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10604 Return 0 if no simplification was possible, otherwise return the
10605 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10606 code of the function to be simplified. */
10608 static tree
10609 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10610 enum built_in_function fcode)
10612 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10613 const char *fmt_str = NULL;
10615 /* If the return value is used, don't do the transformation. */
10616 if (! ignore)
10617 return 0;
10619 /* Verify the required arguments in the original call. */
10620 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10622 tree flag;
10624 if (! arglist)
10625 return 0;
10626 flag = TREE_VALUE (arglist);
10627 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10628 || TREE_SIDE_EFFECTS (flag))
10629 return 0;
10630 arglist = TREE_CHAIN (arglist);
10633 if (! arglist)
10634 return 0;
10635 fmt = TREE_VALUE (arglist);
10636 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10637 return 0;
10638 arglist = TREE_CHAIN (arglist);
10640 /* Check whether the format is a literal string constant. */
10641 fmt_str = c_getstr (fmt);
10642 if (fmt_str == NULL)
10643 return NULL_TREE;
10645 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10647 /* If we're using an unlocked function, assume the other
10648 unlocked functions exist explicitly. */
10649 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10650 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10652 else
10654 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10655 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10658 if (!init_target_chars())
10659 return 0;
10661 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10663 const char *str;
10665 if (strcmp (fmt_str, target_percent_s) == 0)
10667 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10668 return 0;
10670 if (! arglist
10671 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10672 || TREE_CHAIN (arglist))
10673 return 0;
10675 str = c_getstr (TREE_VALUE (arglist));
10676 if (str == NULL)
10677 return 0;
10679 else
10681 /* The format specifier doesn't contain any '%' characters. */
10682 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10683 && arglist)
10684 return 0;
10685 str = fmt_str;
10688 /* If the string was "", printf does nothing. */
10689 if (str[0] == '\0')
10690 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10692 /* If the string has length of 1, call putchar. */
10693 if (str[1] == '\0')
10695 /* Given printf("c"), (where c is any one character,)
10696 convert "c"[0] to an int and pass that to the replacement
10697 function. */
10698 arg = build_int_cst (NULL_TREE, str[0]);
10699 arglist = build_tree_list (NULL_TREE, arg);
10700 fn = fn_putchar;
10702 else
10704 /* If the string was "string\n", call puts("string"). */
10705 size_t len = strlen (str);
10706 if ((unsigned char)str[len - 1] == target_newline)
10708 /* Create a NUL-terminated string that's one char shorter
10709 than the original, stripping off the trailing '\n'. */
10710 char *newstr = alloca (len);
10711 memcpy (newstr, str, len - 1);
10712 newstr[len - 1] = 0;
10714 arg = build_string_literal (len, newstr);
10715 arglist = build_tree_list (NULL_TREE, arg);
10716 fn = fn_puts;
10718 else
10719 /* We'd like to arrange to call fputs(string,stdout) here,
10720 but we need stdout and don't have a way to get it yet. */
10721 return 0;
10725 /* The other optimizations can be done only on the non-va_list variants. */
10726 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10727 return 0;
10729 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10730 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10732 if (! arglist
10733 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10734 || TREE_CHAIN (arglist))
10735 return 0;
10736 fn = fn_puts;
10739 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10740 else if (strcmp (fmt_str, target_percent_c) == 0)
10742 if (! arglist
10743 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10744 || TREE_CHAIN (arglist))
10745 return 0;
10746 fn = fn_putchar;
10749 if (!fn)
10750 return 0;
10752 call = build_function_call_expr (fn, arglist);
10753 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10756 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10758 Return 0 if no simplification was possible, otherwise return the
10759 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10760 code of the function to be simplified. */
10762 static tree
10763 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10764 enum built_in_function fcode)
10766 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10767 const char *fmt_str = NULL;
10769 /* If the return value is used, don't do the transformation. */
10770 if (! ignore)
10771 return 0;
10773 /* Verify the required arguments in the original call. */
10774 if (! arglist)
10775 return 0;
10776 fp = TREE_VALUE (arglist);
10777 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10778 return 0;
10779 arglist = TREE_CHAIN (arglist);
10781 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10783 tree flag;
10785 if (! arglist)
10786 return 0;
10787 flag = TREE_VALUE (arglist);
10788 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10789 || TREE_SIDE_EFFECTS (flag))
10790 return 0;
10791 arglist = TREE_CHAIN (arglist);
10794 if (! arglist)
10795 return 0;
10796 fmt = TREE_VALUE (arglist);
10797 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10798 return 0;
10799 arglist = TREE_CHAIN (arglist);
10801 /* Check whether the format is a literal string constant. */
10802 fmt_str = c_getstr (fmt);
10803 if (fmt_str == NULL)
10804 return NULL_TREE;
10806 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10808 /* If we're using an unlocked function, assume the other
10809 unlocked functions exist explicitly. */
10810 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10811 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10813 else
10815 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10816 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10819 if (!init_target_chars())
10820 return 0;
10822 /* If the format doesn't contain % args or %%, use strcpy. */
10823 if (strchr (fmt_str, target_percent) == NULL)
10825 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10826 && arglist)
10827 return 0;
10829 /* If the format specifier was "", fprintf does nothing. */
10830 if (fmt_str[0] == '\0')
10832 /* If FP has side-effects, just wait until gimplification is
10833 done. */
10834 if (TREE_SIDE_EFFECTS (fp))
10835 return 0;
10837 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10840 /* When "string" doesn't contain %, replace all cases of
10841 fprintf (fp, string) with fputs (string, fp). The fputs
10842 builtin will take care of special cases like length == 1. */
10843 arglist = build_tree_list (NULL_TREE, fp);
10844 arglist = tree_cons (NULL_TREE, fmt, arglist);
10845 fn = fn_fputs;
10848 /* The other optimizations can be done only on the non-va_list variants. */
10849 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10850 return 0;
10852 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10853 else if (strcmp (fmt_str, target_percent_s) == 0)
10855 if (! arglist
10856 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10857 || TREE_CHAIN (arglist))
10858 return 0;
10859 arg = TREE_VALUE (arglist);
10860 arglist = build_tree_list (NULL_TREE, fp);
10861 arglist = tree_cons (NULL_TREE, arg, arglist);
10862 fn = fn_fputs;
10865 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10866 else if (strcmp (fmt_str, target_percent_c) == 0)
10868 if (! arglist
10869 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10870 || TREE_CHAIN (arglist))
10871 return 0;
10872 arg = TREE_VALUE (arglist);
10873 arglist = build_tree_list (NULL_TREE, fp);
10874 arglist = tree_cons (NULL_TREE, arg, arglist);
10875 fn = fn_fputc;
10878 if (!fn)
10879 return 0;
10881 call = build_function_call_expr (fn, arglist);
10882 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10885 /* Initialize format string characters in the target charset. */
10887 static bool
10888 init_target_chars (void)
10890 static bool init;
10891 if (!init)
10893 target_newline = lang_hooks.to_target_charset ('\n');
10894 target_percent = lang_hooks.to_target_charset ('%');
10895 target_c = lang_hooks.to_target_charset ('c');
10896 target_s = lang_hooks.to_target_charset ('s');
10897 if (target_newline == 0 || target_percent == 0 || target_c == 0
10898 || target_s == 0)
10899 return false;
10901 target_percent_c[0] = target_percent;
10902 target_percent_c[1] = target_c;
10903 target_percent_c[2] = '\0';
10905 target_percent_s[0] = target_percent;
10906 target_percent_s[1] = target_s;
10907 target_percent_s[2] = '\0';
10909 target_percent_s_newline[0] = target_percent;
10910 target_percent_s_newline[1] = target_s;
10911 target_percent_s_newline[2] = target_newline;
10912 target_percent_s_newline[3] = '\0';
10914 init = true;
10916 return true;