* Make-lang.in (cp/pt.o): Depend on vecprim.h.
[official-gcc.git] / gcc / builtins.c
blob836f965443287d3fbead3778d992c5f946685701
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_cabs (tree, tree);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_sin (tree);
155 static tree fold_builtin_cos (tree, tree, tree);
156 static tree fold_builtin_tan (tree);
157 static tree fold_builtin_atan (tree, tree);
158 static tree fold_builtin_trunc (tree, tree);
159 static tree fold_builtin_floor (tree, tree);
160 static tree fold_builtin_ceil (tree, tree);
161 static tree fold_builtin_round (tree, tree);
162 static tree fold_builtin_int_roundingfn (tree, tree);
163 static tree fold_builtin_bitop (tree, tree);
164 static tree fold_builtin_memcpy (tree, tree);
165 static tree fold_builtin_mempcpy (tree, tree, int);
166 static tree fold_builtin_memmove (tree, tree);
167 static tree fold_builtin_strchr (tree, tree);
168 static tree fold_builtin_memcmp (tree);
169 static tree fold_builtin_strcmp (tree);
170 static tree fold_builtin_strncmp (tree);
171 static tree fold_builtin_signbit (tree, tree);
172 static tree fold_builtin_copysign (tree, tree, tree);
173 static tree fold_builtin_isascii (tree);
174 static tree fold_builtin_toascii (tree);
175 static tree fold_builtin_isdigit (tree);
176 static tree fold_builtin_fabs (tree, tree);
177 static tree fold_builtin_abs (tree, tree);
178 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 enum tree_code);
180 static tree fold_builtin_1 (tree, tree, bool);
182 static tree fold_builtin_strpbrk (tree, tree);
183 static tree fold_builtin_strstr (tree, tree);
184 static tree fold_builtin_strrchr (tree, tree);
185 static tree fold_builtin_strcat (tree);
186 static tree fold_builtin_strncat (tree);
187 static tree fold_builtin_strspn (tree);
188 static tree fold_builtin_strcspn (tree);
189 static tree fold_builtin_sprintf (tree, int);
191 static rtx expand_builtin_object_size (tree);
192 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
193 enum built_in_function);
194 static void maybe_emit_chk_warning (tree, enum built_in_function);
195 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
196 static tree fold_builtin_object_size (tree);
197 static tree fold_builtin_strcat_chk (tree, tree);
198 static tree fold_builtin_strncat_chk (tree, tree);
199 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
200 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
201 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline;
205 static unsigned HOST_WIDE_INT target_percent;
206 static unsigned HOST_WIDE_INT target_c;
207 static unsigned HOST_WIDE_INT target_s;
208 static char target_percent_c[3];
209 static char target_percent_s[3];
210 static char target_percent_s_newline[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node)
218 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
219 if (strncmp (name, "__builtin_", 10) == 0)
220 return true;
221 if (strncmp (name, "__sync_", 7) == 0)
222 return true;
223 return false;
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
234 static int
235 get_pointer_alignment (tree exp, unsigned int max_align)
237 unsigned int align, inner;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
240 return 0;
242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243 align = MIN (align, max_align);
245 while (1)
247 switch (TREE_CODE (exp))
249 case NOP_EXPR:
250 case CONVERT_EXPR:
251 case NON_LVALUE_EXPR:
252 exp = TREE_OPERAND (exp, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254 return align;
256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257 align = MIN (inner, max_align);
258 break;
260 case PLUS_EXPR:
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
263 ALIGN. */
264 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265 return align;
267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268 & (max_align / BITS_PER_UNIT - 1))
269 != 0)
270 max_align >>= 1;
272 exp = TREE_OPERAND (exp, 0);
273 break;
275 case ADDR_EXPR:
276 /* See what we are pointing at and look at its alignment. */
277 exp = TREE_OPERAND (exp, 0);
278 inner = max_align;
279 while (handled_component_p (exp))
281 /* Fields in a structure can be packed, honor DECL_ALIGN
282 of the FIELD_DECL. For all other references the conservative
283 alignment is the element type alignment. */
284 if (TREE_CODE (exp) == COMPONENT_REF)
285 inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
286 else
287 inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
288 exp = TREE_OPERAND (exp, 0);
290 if (TREE_CODE (exp) == FUNCTION_DECL)
291 align = FUNCTION_BOUNDARY;
292 else if (DECL_P (exp))
293 align = MIN (inner, DECL_ALIGN (exp));
294 #ifdef CONSTANT_ALIGNMENT
295 else if (CONSTANT_CLASS_P (exp))
296 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
297 #endif
298 else
299 align = MIN (align, inner);
300 return MIN (align, max_align);
302 default:
303 return align;
308 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
309 way, because it could contain a zero byte in the middle.
310 TREE_STRING_LENGTH is the size of the character array, not the string.
312 ONLY_VALUE should be nonzero if the result is not going to be emitted
313 into the instruction stream and zero if it is going to be expanded.
314 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
315 is returned, otherwise NULL, since
316 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
317 evaluate the side-effects.
319 The value returned is of type `ssizetype'.
321 Unfortunately, string_constant can't access the values of const char
322 arrays with initializers, so neither can we do so here. */
324 tree
325 c_strlen (tree src, int only_value)
327 tree offset_node;
328 HOST_WIDE_INT offset;
329 int max;
330 const char *ptr;
332 STRIP_NOPS (src);
333 if (TREE_CODE (src) == COND_EXPR
334 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
336 tree len1, len2;
338 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
339 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
340 if (tree_int_cst_equal (len1, len2))
341 return len1;
344 if (TREE_CODE (src) == COMPOUND_EXPR
345 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
346 return c_strlen (TREE_OPERAND (src, 1), only_value);
348 src = string_constant (src, &offset_node);
349 if (src == 0)
350 return 0;
352 max = TREE_STRING_LENGTH (src) - 1;
353 ptr = TREE_STRING_POINTER (src);
355 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
357 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
358 compute the offset to the following null if we don't know where to
359 start searching for it. */
360 int i;
362 for (i = 0; i < max; i++)
363 if (ptr[i] == 0)
364 return 0;
366 /* We don't know the starting offset, but we do know that the string
367 has no internal zero bytes. We can assume that the offset falls
368 within the bounds of the string; otherwise, the programmer deserves
369 what he gets. Subtract the offset from the length of the string,
370 and return that. This would perhaps not be valid if we were dealing
371 with named arrays in addition to literal string constants. */
373 return size_diffop (size_int (max), offset_node);
376 /* We have a known offset into the string. Start searching there for
377 a null character if we can represent it as a single HOST_WIDE_INT. */
378 if (offset_node == 0)
379 offset = 0;
380 else if (! host_integerp (offset_node, 0))
381 offset = -1;
382 else
383 offset = tree_low_cst (offset_node, 0);
385 /* If the offset is known to be out of bounds, warn, and call strlen at
386 runtime. */
387 if (offset < 0 || offset > max)
389 warning (0, "offset outside bounds of constant string");
390 return 0;
393 /* Use strlen to search for the first zero byte. Since any strings
394 constructed with build_string will have nulls appended, we win even
395 if we get handed something like (char[4])"abcd".
397 Since OFFSET is our starting index into the string, no further
398 calculation is needed. */
399 return ssize_int (strlen (ptr + offset));
402 /* Return a char pointer for a C string if it is a string constant
403 or sum of string constant and integer constant. */
405 static const char *
406 c_getstr (tree src)
408 tree offset_node;
410 src = string_constant (src, &offset_node);
411 if (src == 0)
412 return 0;
414 if (offset_node == 0)
415 return TREE_STRING_POINTER (src);
416 else if (!host_integerp (offset_node, 1)
417 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
418 return 0;
420 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
423 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
424 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
426 static rtx
427 c_readstr (const char *str, enum machine_mode mode)
429 HOST_WIDE_INT c[2];
430 HOST_WIDE_INT ch;
431 unsigned int i, j;
433 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
435 c[0] = 0;
436 c[1] = 0;
437 ch = 1;
438 for (i = 0; i < GET_MODE_SIZE (mode); i++)
440 j = i;
441 if (WORDS_BIG_ENDIAN)
442 j = GET_MODE_SIZE (mode) - i - 1;
443 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
444 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
445 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
446 j *= BITS_PER_UNIT;
447 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
449 if (ch)
450 ch = (unsigned char) str[i];
451 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
453 return immed_double_const (c[0], c[1], mode);
456 /* Cast a target constant CST to target CHAR and if that value fits into
457 host char type, return zero and put that value into variable pointed to by
458 P. */
460 static int
461 target_char_cast (tree cst, char *p)
463 unsigned HOST_WIDE_INT val, hostval;
465 if (!host_integerp (cst, 1)
466 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
467 return 1;
469 val = tree_low_cst (cst, 1);
470 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
471 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
473 hostval = val;
474 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
475 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
477 if (val != hostval)
478 return 1;
480 *p = hostval;
481 return 0;
484 /* Similar to save_expr, but assumes that arbitrary code is not executed
485 in between the multiple evaluations. In particular, we assume that a
486 non-addressable local variable will not be modified. */
488 static tree
489 builtin_save_expr (tree exp)
491 if (TREE_ADDRESSABLE (exp) == 0
492 && (TREE_CODE (exp) == PARM_DECL
493 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
494 return exp;
496 return save_expr (exp);
499 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
500 times to get the address of either a higher stack frame, or a return
501 address located within it (depending on FNDECL_CODE). */
503 static rtx
504 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
506 int i;
508 #ifdef INITIAL_FRAME_ADDRESS_RTX
509 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
510 #else
511 rtx tem;
513 /* For a zero count, we don't care what frame address we return, so frame
514 pointer elimination is OK, and using the soft frame pointer is OK.
515 For a nonzero count, we require a stable offset from the current frame
516 pointer to the previous one, so we must use the hard frame pointer, and
517 we must disable frame pointer elimination. */
518 if (count == 0)
519 tem = frame_pointer_rtx;
520 else
522 tem = hard_frame_pointer_rtx;
524 /* Tell reload not to eliminate the frame pointer. */
525 current_function_accesses_prior_frames = 1;
527 #endif
529 /* Some machines need special handling before we can access
530 arbitrary frames. For example, on the sparc, we must first flush
531 all register windows to the stack. */
532 #ifdef SETUP_FRAME_ADDRESSES
533 if (count > 0)
534 SETUP_FRAME_ADDRESSES ();
535 #endif
537 /* On the sparc, the return address is not in the frame, it is in a
538 register. There is no way to access it off of the current frame
539 pointer, but it can be accessed off the previous frame pointer by
540 reading the value from the register window save area. */
541 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
542 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
543 count--;
544 #endif
546 /* Scan back COUNT frames to the specified frame. */
547 for (i = 0; i < count; i++)
549 /* Assume the dynamic chain pointer is in the word that the
550 frame address points to, unless otherwise specified. */
551 #ifdef DYNAMIC_CHAIN_ADDRESS
552 tem = DYNAMIC_CHAIN_ADDRESS (tem);
553 #endif
554 tem = memory_address (Pmode, tem);
555 tem = gen_frame_mem (Pmode, tem);
556 tem = copy_to_reg (tem);
559 /* For __builtin_frame_address, return what we've got. */
560 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
561 return tem;
563 /* For __builtin_return_address, Get the return address from that
564 frame. */
565 #ifdef RETURN_ADDR_RTX
566 tem = RETURN_ADDR_RTX (count, tem);
567 #else
568 tem = memory_address (Pmode,
569 plus_constant (tem, GET_MODE_SIZE (Pmode)));
570 tem = gen_frame_mem (Pmode, tem);
571 #endif
572 return tem;
575 /* Alias set used for setjmp buffer. */
576 static HOST_WIDE_INT setjmp_alias_set = -1;
578 /* Construct the leading half of a __builtin_setjmp call. Control will
579 return to RECEIVER_LABEL. This is used directly by sjlj exception
580 handling code. */
582 void
583 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
585 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
586 rtx stack_save;
587 rtx mem;
589 if (setjmp_alias_set == -1)
590 setjmp_alias_set = new_alias_set ();
592 buf_addr = convert_memory_address (Pmode, buf_addr);
594 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
596 /* We store the frame pointer and the address of receiver_label in
597 the buffer and use the rest of it for the stack save area, which
598 is machine-dependent. */
600 mem = gen_rtx_MEM (Pmode, buf_addr);
601 set_mem_alias_set (mem, setjmp_alias_set);
602 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
604 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
605 set_mem_alias_set (mem, setjmp_alias_set);
607 emit_move_insn (validize_mem (mem),
608 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
610 stack_save = gen_rtx_MEM (sa_mode,
611 plus_constant (buf_addr,
612 2 * GET_MODE_SIZE (Pmode)));
613 set_mem_alias_set (stack_save, setjmp_alias_set);
614 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
616 /* If there is further processing to do, do it. */
617 #ifdef HAVE_builtin_setjmp_setup
618 if (HAVE_builtin_setjmp_setup)
619 emit_insn (gen_builtin_setjmp_setup (buf_addr));
620 #endif
622 /* Tell optimize_save_area_alloca that extra work is going to
623 need to go on during alloca. */
624 current_function_calls_setjmp = 1;
626 /* Set this so all the registers get saved in our frame; we need to be
627 able to copy the saved values for any registers from frames we unwind. */
628 current_function_has_nonlocal_label = 1;
631 /* Construct the trailing part of a __builtin_setjmp call.
632 This is used directly by sjlj exception handling code. */
634 void
635 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
637 /* Clobber the FP when we get here, so we have to make sure it's
638 marked as used by this function. */
639 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
641 /* Mark the static chain as clobbered here so life information
642 doesn't get messed up for it. */
643 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
645 /* Now put in the code to restore the frame pointer, and argument
646 pointer, if needed. */
647 #ifdef HAVE_nonlocal_goto
648 if (! HAVE_nonlocal_goto)
649 #endif
650 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
652 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
653 if (fixed_regs[ARG_POINTER_REGNUM])
655 #ifdef ELIMINABLE_REGS
656 size_t i;
657 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
659 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
660 if (elim_regs[i].from == ARG_POINTER_REGNUM
661 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
662 break;
664 if (i == ARRAY_SIZE (elim_regs))
665 #endif
667 /* Now restore our arg pointer from the address at which it
668 was saved in our stack frame. */
669 emit_move_insn (virtual_incoming_args_rtx,
670 copy_to_reg (get_arg_pointer_save_area (cfun)));
673 #endif
675 #ifdef HAVE_builtin_setjmp_receiver
676 if (HAVE_builtin_setjmp_receiver)
677 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
678 else
679 #endif
680 #ifdef HAVE_nonlocal_goto_receiver
681 if (HAVE_nonlocal_goto_receiver)
682 emit_insn (gen_nonlocal_goto_receiver ());
683 else
684 #endif
685 { /* Nothing */ }
687 /* @@@ This is a kludge. Not all machine descriptions define a blockage
688 insn, but we must not allow the code we just generated to be reordered
689 by scheduling. Specifically, the update of the frame pointer must
690 happen immediately, not later. So emit an ASM_INPUT to act as blockage
691 insn. */
692 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
695 /* __builtin_setjmp is passed a pointer to an array of five words (not
696 all will be used on all machines). It operates similarly to the C
697 library function of the same name, but is more efficient. Much of
698 the code below (and for longjmp) is copied from the handling of
699 non-local gotos.
701 NOTE: This is intended for use by GNAT and the exception handling
702 scheme in the compiler and will only work in the method used by
703 them. */
705 static rtx
706 expand_builtin_setjmp (tree arglist, rtx target)
708 rtx buf_addr, next_lab, cont_lab;
710 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
711 return NULL_RTX;
713 if (target == 0 || !REG_P (target)
714 || REGNO (target) < FIRST_PSEUDO_REGISTER)
715 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
717 buf_addr = expand_normal (TREE_VALUE (arglist));
719 next_lab = gen_label_rtx ();
720 cont_lab = gen_label_rtx ();
722 expand_builtin_setjmp_setup (buf_addr, next_lab);
724 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
725 ensure that pending stack adjustments are flushed. */
726 emit_move_insn (target, const0_rtx);
727 emit_jump (cont_lab);
729 emit_label (next_lab);
731 expand_builtin_setjmp_receiver (next_lab);
733 /* Set TARGET to one. */
734 emit_move_insn (target, const1_rtx);
735 emit_label (cont_lab);
737 /* Tell flow about the strange goings on. Putting `next_lab' on
738 `nonlocal_goto_handler_labels' to indicates that function
739 calls may traverse the arc back to this label. */
741 current_function_has_nonlocal_label = 1;
742 nonlocal_goto_handler_labels
743 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
745 return target;
748 /* __builtin_longjmp is passed a pointer to an array of five words (not
749 all will be used on all machines). It operates similarly to the C
750 library function of the same name, but is more efficient. Much of
751 the code below is copied from the handling of non-local gotos.
753 NOTE: This is intended for use by GNAT and the exception handling
754 scheme in the compiler and will only work in the method used by
755 them. */
757 static void
758 expand_builtin_longjmp (rtx buf_addr, rtx value)
760 rtx fp, lab, stack, insn, last;
761 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
763 if (setjmp_alias_set == -1)
764 setjmp_alias_set = new_alias_set ();
766 buf_addr = convert_memory_address (Pmode, buf_addr);
768 buf_addr = force_reg (Pmode, buf_addr);
770 /* We used to store value in static_chain_rtx, but that fails if pointers
771 are smaller than integers. We instead require that the user must pass
772 a second argument of 1, because that is what builtin_setjmp will
773 return. This also makes EH slightly more efficient, since we are no
774 longer copying around a value that we don't care about. */
775 gcc_assert (value == const1_rtx);
777 last = get_last_insn ();
778 #ifdef HAVE_builtin_longjmp
779 if (HAVE_builtin_longjmp)
780 emit_insn (gen_builtin_longjmp (buf_addr));
781 else
782 #endif
784 fp = gen_rtx_MEM (Pmode, buf_addr);
785 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
786 GET_MODE_SIZE (Pmode)));
788 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
789 2 * GET_MODE_SIZE (Pmode)));
790 set_mem_alias_set (fp, setjmp_alias_set);
791 set_mem_alias_set (lab, setjmp_alias_set);
792 set_mem_alias_set (stack, setjmp_alias_set);
794 /* Pick up FP, label, and SP from the block and jump. This code is
795 from expand_goto in stmt.c; see there for detailed comments. */
796 #ifdef HAVE_nonlocal_goto
797 if (HAVE_nonlocal_goto)
798 /* We have to pass a value to the nonlocal_goto pattern that will
799 get copied into the static_chain pointer, but it does not matter
800 what that value is, because builtin_setjmp does not use it. */
801 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
802 else
803 #endif
805 lab = copy_to_reg (lab);
807 emit_insn (gen_rtx_CLOBBER (VOIDmode,
808 gen_rtx_MEM (BLKmode,
809 gen_rtx_SCRATCH (VOIDmode))));
810 emit_insn (gen_rtx_CLOBBER (VOIDmode,
811 gen_rtx_MEM (BLKmode,
812 hard_frame_pointer_rtx)));
814 emit_move_insn (hard_frame_pointer_rtx, fp);
815 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
817 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
818 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
819 emit_indirect_jump (lab);
823 /* Search backwards and mark the jump insn as a non-local goto.
824 Note that this precludes the use of __builtin_longjmp to a
825 __builtin_setjmp target in the same function. However, we've
826 already cautioned the user that these functions are for
827 internal exception handling use only. */
828 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
830 gcc_assert (insn != last);
832 if (JUMP_P (insn))
834 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
835 REG_NOTES (insn));
836 break;
838 else if (CALL_P (insn))
839 break;
843 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
844 and the address of the save area. */
846 static rtx
847 expand_builtin_nonlocal_goto (tree arglist)
849 tree t_label, t_save_area;
850 rtx r_label, r_save_area, r_fp, r_sp, insn;
852 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
853 return NULL_RTX;
855 t_label = TREE_VALUE (arglist);
856 arglist = TREE_CHAIN (arglist);
857 t_save_area = TREE_VALUE (arglist);
859 r_label = expand_normal (t_label);
860 r_label = convert_memory_address (Pmode, r_label);
861 r_save_area = expand_normal (t_save_area);
862 r_save_area = convert_memory_address (Pmode, r_save_area);
863 r_fp = gen_rtx_MEM (Pmode, r_save_area);
864 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
865 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
867 current_function_has_nonlocal_goto = 1;
869 #ifdef HAVE_nonlocal_goto
870 /* ??? We no longer need to pass the static chain value, afaik. */
871 if (HAVE_nonlocal_goto)
872 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
873 else
874 #endif
876 r_label = copy_to_reg (r_label);
878 emit_insn (gen_rtx_CLOBBER (VOIDmode,
879 gen_rtx_MEM (BLKmode,
880 gen_rtx_SCRATCH (VOIDmode))));
882 emit_insn (gen_rtx_CLOBBER (VOIDmode,
883 gen_rtx_MEM (BLKmode,
884 hard_frame_pointer_rtx)));
886 /* Restore frame pointer for containing function.
887 This sets the actual hard register used for the frame pointer
888 to the location of the function's incoming static chain info.
889 The non-local goto handler will then adjust it to contain the
890 proper value and reload the argument pointer, if needed. */
891 emit_move_insn (hard_frame_pointer_rtx, r_fp);
892 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
894 /* USE of hard_frame_pointer_rtx added for consistency;
895 not clear if really needed. */
896 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
897 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
898 emit_indirect_jump (r_label);
901 /* Search backwards to the jump insn and mark it as a
902 non-local goto. */
903 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
905 if (JUMP_P (insn))
907 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
908 const0_rtx, REG_NOTES (insn));
909 break;
911 else if (CALL_P (insn))
912 break;
915 return const0_rtx;
918 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
919 (not all will be used on all machines) that was passed to __builtin_setjmp.
920 It updates the stack pointer in that block to correspond to the current
921 stack pointer. */
923 static void
924 expand_builtin_update_setjmp_buf (rtx buf_addr)
926 enum machine_mode sa_mode = Pmode;
927 rtx stack_save;
930 #ifdef HAVE_save_stack_nonlocal
931 if (HAVE_save_stack_nonlocal)
932 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
933 #endif
934 #ifdef STACK_SAVEAREA_MODE
935 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
936 #endif
938 stack_save
939 = gen_rtx_MEM (sa_mode,
940 memory_address
941 (sa_mode,
942 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
944 #ifdef HAVE_setjmp
945 if (HAVE_setjmp)
946 emit_insn (gen_setjmp ());
947 #endif
949 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
952 /* Expand a call to __builtin_prefetch. For a target that does not support
953 data prefetch, evaluate the memory address argument in case it has side
954 effects. */
956 static void
957 expand_builtin_prefetch (tree arglist)
959 tree arg0, arg1, arg2;
960 rtx op0, op1, op2;
962 if (!validate_arglist (arglist, POINTER_TYPE, 0))
963 return;
965 arg0 = TREE_VALUE (arglist);
966 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
967 zero (read) and argument 2 (locality) defaults to 3 (high degree of
968 locality). */
969 if (TREE_CHAIN (arglist))
971 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
972 if (TREE_CHAIN (TREE_CHAIN (arglist)))
973 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
974 else
975 arg2 = build_int_cst (NULL_TREE, 3);
977 else
979 arg1 = integer_zero_node;
980 arg2 = build_int_cst (NULL_TREE, 3);
983 /* Argument 0 is an address. */
984 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
986 /* Argument 1 (read/write flag) must be a compile-time constant int. */
987 if (TREE_CODE (arg1) != INTEGER_CST)
989 error ("second argument to %<__builtin_prefetch%> must be a constant");
990 arg1 = integer_zero_node;
992 op1 = expand_normal (arg1);
993 /* Argument 1 must be either zero or one. */
994 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
996 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
997 " using zero");
998 op1 = const0_rtx;
1001 /* Argument 2 (locality) must be a compile-time constant int. */
1002 if (TREE_CODE (arg2) != INTEGER_CST)
1004 error ("third argument to %<__builtin_prefetch%> must be a constant");
1005 arg2 = integer_zero_node;
1007 op2 = expand_normal (arg2);
1008 /* Argument 2 must be 0, 1, 2, or 3. */
1009 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1011 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1012 op2 = const0_rtx;
1015 #ifdef HAVE_prefetch
1016 if (HAVE_prefetch)
1018 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1019 (op0,
1020 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1021 || (GET_MODE (op0) != Pmode))
1023 op0 = convert_memory_address (Pmode, op0);
1024 op0 = force_reg (Pmode, op0);
1026 emit_insn (gen_prefetch (op0, op1, op2));
1028 #endif
1030 /* Don't do anything with direct references to volatile memory, but
1031 generate code to handle other side effects. */
1032 if (!MEM_P (op0) && side_effects_p (op0))
1033 emit_insn (op0);
1036 /* Get a MEM rtx for expression EXP which is the address of an operand
1037 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1038 the maximum length of the block of memory that might be accessed or
1039 NULL if unknown. */
1041 static rtx
1042 get_memory_rtx (tree exp, tree len)
1044 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1045 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1047 /* Get an expression we can use to find the attributes to assign to MEM.
1048 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1049 we can. First remove any nops. */
1050 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1051 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1052 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1053 exp = TREE_OPERAND (exp, 0);
1055 if (TREE_CODE (exp) == ADDR_EXPR)
1056 exp = TREE_OPERAND (exp, 0);
1057 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1058 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1059 else
1060 exp = NULL;
1062 /* Honor attributes derived from exp, except for the alias set
1063 (as builtin stringops may alias with anything) and the size
1064 (as stringops may access multiple array elements). */
1065 if (exp)
1067 set_mem_attributes (mem, exp, 0);
1069 /* Allow the string and memory builtins to overflow from one
1070 field into another, see http://gcc.gnu.org/PR23561.
1071 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1072 memory accessed by the string or memory builtin will fit
1073 within the field. */
1074 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1076 tree mem_expr = MEM_EXPR (mem);
1077 HOST_WIDE_INT offset = -1, length = -1;
1078 tree inner = exp;
1080 while (TREE_CODE (inner) == ARRAY_REF
1081 || TREE_CODE (inner) == NOP_EXPR
1082 || TREE_CODE (inner) == CONVERT_EXPR
1083 || TREE_CODE (inner) == NON_LVALUE_EXPR
1084 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1085 || TREE_CODE (inner) == SAVE_EXPR)
1086 inner = TREE_OPERAND (inner, 0);
1088 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1090 if (MEM_OFFSET (mem)
1091 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1092 offset = INTVAL (MEM_OFFSET (mem));
1094 if (offset >= 0 && len && host_integerp (len, 0))
1095 length = tree_low_cst (len, 0);
1097 while (TREE_CODE (inner) == COMPONENT_REF)
1099 tree field = TREE_OPERAND (inner, 1);
1100 gcc_assert (! DECL_BIT_FIELD (field));
1101 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1102 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1104 if (length >= 0
1105 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1106 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1108 HOST_WIDE_INT size
1109 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1110 /* If we can prove the memory starting at XEXP (mem, 0)
1111 and ending at XEXP (mem, 0) + LENGTH will fit into
1112 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1113 if (offset <= size
1114 && length <= size
1115 && offset + length <= size)
1116 break;
1119 if (offset >= 0
1120 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1121 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1122 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1123 / BITS_PER_UNIT;
1124 else
1126 offset = -1;
1127 length = -1;
1130 mem_expr = TREE_OPERAND (mem_expr, 0);
1131 inner = TREE_OPERAND (inner, 0);
1134 if (mem_expr == NULL)
1135 offset = -1;
1136 if (mem_expr != MEM_EXPR (mem))
1138 set_mem_expr (mem, mem_expr);
1139 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1142 set_mem_alias_set (mem, 0);
1143 set_mem_size (mem, NULL_RTX);
1146 return mem;
1149 /* Built-in functions to perform an untyped call and return. */
1151 /* For each register that may be used for calling a function, this
1152 gives a mode used to copy the register's value. VOIDmode indicates
1153 the register is not used for calling a function. If the machine
1154 has register windows, this gives only the outbound registers.
1155 INCOMING_REGNO gives the corresponding inbound register. */
1156 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1158 /* For each register that may be used for returning values, this gives
1159 a mode used to copy the register's value. VOIDmode indicates the
1160 register is not used for returning values. If the machine has
1161 register windows, this gives only the outbound registers.
1162 INCOMING_REGNO gives the corresponding inbound register. */
1163 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1165 /* For each register that may be used for calling a function, this
1166 gives the offset of that register into the block returned by
1167 __builtin_apply_args. 0 indicates that the register is not
1168 used for calling a function. */
1169 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1171 /* Return the size required for the block returned by __builtin_apply_args,
1172 and initialize apply_args_mode. */
1174 static int
1175 apply_args_size (void)
1177 static int size = -1;
1178 int align;
1179 unsigned int regno;
1180 enum machine_mode mode;
1182 /* The values computed by this function never change. */
1183 if (size < 0)
1185 /* The first value is the incoming arg-pointer. */
1186 size = GET_MODE_SIZE (Pmode);
1188 /* The second value is the structure value address unless this is
1189 passed as an "invisible" first argument. */
1190 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1191 size += GET_MODE_SIZE (Pmode);
1193 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1194 if (FUNCTION_ARG_REGNO_P (regno))
1196 mode = reg_raw_mode[regno];
1198 gcc_assert (mode != VOIDmode);
1200 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1201 if (size % align != 0)
1202 size = CEIL (size, align) * align;
1203 apply_args_reg_offset[regno] = size;
1204 size += GET_MODE_SIZE (mode);
1205 apply_args_mode[regno] = mode;
1207 else
1209 apply_args_mode[regno] = VOIDmode;
1210 apply_args_reg_offset[regno] = 0;
1213 return size;
1216 /* Return the size required for the block returned by __builtin_apply,
1217 and initialize apply_result_mode. */
1219 static int
1220 apply_result_size (void)
1222 static int size = -1;
1223 int align, regno;
1224 enum machine_mode mode;
1226 /* The values computed by this function never change. */
1227 if (size < 0)
1229 size = 0;
1231 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1232 if (FUNCTION_VALUE_REGNO_P (regno))
1234 mode = reg_raw_mode[regno];
1236 gcc_assert (mode != VOIDmode);
1238 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1239 if (size % align != 0)
1240 size = CEIL (size, align) * align;
1241 size += GET_MODE_SIZE (mode);
1242 apply_result_mode[regno] = mode;
1244 else
1245 apply_result_mode[regno] = VOIDmode;
1247 /* Allow targets that use untyped_call and untyped_return to override
1248 the size so that machine-specific information can be stored here. */
1249 #ifdef APPLY_RESULT_SIZE
1250 size = APPLY_RESULT_SIZE;
1251 #endif
1253 return size;
1256 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1257 /* Create a vector describing the result block RESULT. If SAVEP is true,
1258 the result block is used to save the values; otherwise it is used to
1259 restore the values. */
1261 static rtx
1262 result_vector (int savep, rtx result)
1264 int regno, size, align, nelts;
1265 enum machine_mode mode;
1266 rtx reg, mem;
1267 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1269 size = nelts = 0;
1270 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1271 if ((mode = apply_result_mode[regno]) != VOIDmode)
1273 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1274 if (size % align != 0)
1275 size = CEIL (size, align) * align;
1276 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1277 mem = adjust_address (result, mode, size);
1278 savevec[nelts++] = (savep
1279 ? gen_rtx_SET (VOIDmode, mem, reg)
1280 : gen_rtx_SET (VOIDmode, reg, mem));
1281 size += GET_MODE_SIZE (mode);
1283 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1285 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1287 /* Save the state required to perform an untyped call with the same
1288 arguments as were passed to the current function. */
1290 static rtx
1291 expand_builtin_apply_args_1 (void)
1293 rtx registers, tem;
1294 int size, align, regno;
1295 enum machine_mode mode;
1296 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1298 /* Create a block where the arg-pointer, structure value address,
1299 and argument registers can be saved. */
1300 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1302 /* Walk past the arg-pointer and structure value address. */
1303 size = GET_MODE_SIZE (Pmode);
1304 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1305 size += GET_MODE_SIZE (Pmode);
1307 /* Save each register used in calling a function to the block. */
1308 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1309 if ((mode = apply_args_mode[regno]) != VOIDmode)
1311 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1312 if (size % align != 0)
1313 size = CEIL (size, align) * align;
1315 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1317 emit_move_insn (adjust_address (registers, mode, size), tem);
1318 size += GET_MODE_SIZE (mode);
1321 /* Save the arg pointer to the block. */
1322 tem = copy_to_reg (virtual_incoming_args_rtx);
1323 #ifdef STACK_GROWS_DOWNWARD
1324 /* We need the pointer as the caller actually passed them to us, not
1325 as we might have pretended they were passed. Make sure it's a valid
1326 operand, as emit_move_insn isn't expected to handle a PLUS. */
1328 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1329 NULL_RTX);
1330 #endif
1331 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1333 size = GET_MODE_SIZE (Pmode);
1335 /* Save the structure value address unless this is passed as an
1336 "invisible" first argument. */
1337 if (struct_incoming_value)
1339 emit_move_insn (adjust_address (registers, Pmode, size),
1340 copy_to_reg (struct_incoming_value));
1341 size += GET_MODE_SIZE (Pmode);
1344 /* Return the address of the block. */
1345 return copy_addr_to_reg (XEXP (registers, 0));
1348 /* __builtin_apply_args returns block of memory allocated on
1349 the stack into which is stored the arg pointer, structure
1350 value address, static chain, and all the registers that might
1351 possibly be used in performing a function call. The code is
1352 moved to the start of the function so the incoming values are
1353 saved. */
1355 static rtx
1356 expand_builtin_apply_args (void)
1358 /* Don't do __builtin_apply_args more than once in a function.
1359 Save the result of the first call and reuse it. */
1360 if (apply_args_value != 0)
1361 return apply_args_value;
1363 /* When this function is called, it means that registers must be
1364 saved on entry to this function. So we migrate the
1365 call to the first insn of this function. */
1366 rtx temp;
1367 rtx seq;
1369 start_sequence ();
1370 temp = expand_builtin_apply_args_1 ();
1371 seq = get_insns ();
1372 end_sequence ();
1374 apply_args_value = temp;
1376 /* Put the insns after the NOTE that starts the function.
1377 If this is inside a start_sequence, make the outer-level insn
1378 chain current, so the code is placed at the start of the
1379 function. */
1380 push_topmost_sequence ();
1381 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1382 pop_topmost_sequence ();
1383 return temp;
1387 /* Perform an untyped call and save the state required to perform an
1388 untyped return of whatever value was returned by the given function. */
1390 static rtx
1391 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1393 int size, align, regno;
1394 enum machine_mode mode;
1395 rtx incoming_args, result, reg, dest, src, call_insn;
1396 rtx old_stack_level = 0;
1397 rtx call_fusage = 0;
1398 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1400 arguments = convert_memory_address (Pmode, arguments);
1402 /* Create a block where the return registers can be saved. */
1403 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1405 /* Fetch the arg pointer from the ARGUMENTS block. */
1406 incoming_args = gen_reg_rtx (Pmode);
1407 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1408 #ifndef STACK_GROWS_DOWNWARD
1409 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1410 incoming_args, 0, OPTAB_LIB_WIDEN);
1411 #endif
1413 /* Push a new argument block and copy the arguments. Do not allow
1414 the (potential) memcpy call below to interfere with our stack
1415 manipulations. */
1416 do_pending_stack_adjust ();
1417 NO_DEFER_POP;
1419 /* Save the stack with nonlocal if available. */
1420 #ifdef HAVE_save_stack_nonlocal
1421 if (HAVE_save_stack_nonlocal)
1422 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1423 else
1424 #endif
1425 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1427 /* Allocate a block of memory onto the stack and copy the memory
1428 arguments to the outgoing arguments address. */
1429 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1430 dest = virtual_outgoing_args_rtx;
1431 #ifndef STACK_GROWS_DOWNWARD
1432 if (GET_CODE (argsize) == CONST_INT)
1433 dest = plus_constant (dest, -INTVAL (argsize));
1434 else
1435 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1436 #endif
1437 dest = gen_rtx_MEM (BLKmode, dest);
1438 set_mem_align (dest, PARM_BOUNDARY);
1439 src = gen_rtx_MEM (BLKmode, incoming_args);
1440 set_mem_align (src, PARM_BOUNDARY);
1441 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1443 /* Refer to the argument block. */
1444 apply_args_size ();
1445 arguments = gen_rtx_MEM (BLKmode, arguments);
1446 set_mem_align (arguments, PARM_BOUNDARY);
1448 /* Walk past the arg-pointer and structure value address. */
1449 size = GET_MODE_SIZE (Pmode);
1450 if (struct_value)
1451 size += GET_MODE_SIZE (Pmode);
1453 /* Restore each of the registers previously saved. Make USE insns
1454 for each of these registers for use in making the call. */
1455 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1456 if ((mode = apply_args_mode[regno]) != VOIDmode)
1458 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1459 if (size % align != 0)
1460 size = CEIL (size, align) * align;
1461 reg = gen_rtx_REG (mode, regno);
1462 emit_move_insn (reg, adjust_address (arguments, mode, size));
1463 use_reg (&call_fusage, reg);
1464 size += GET_MODE_SIZE (mode);
1467 /* Restore the structure value address unless this is passed as an
1468 "invisible" first argument. */
1469 size = GET_MODE_SIZE (Pmode);
1470 if (struct_value)
1472 rtx value = gen_reg_rtx (Pmode);
1473 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1474 emit_move_insn (struct_value, value);
1475 if (REG_P (struct_value))
1476 use_reg (&call_fusage, struct_value);
1477 size += GET_MODE_SIZE (Pmode);
1480 /* All arguments and registers used for the call are set up by now! */
1481 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1483 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1484 and we don't want to load it into a register as an optimization,
1485 because prepare_call_address already did it if it should be done. */
1486 if (GET_CODE (function) != SYMBOL_REF)
1487 function = memory_address (FUNCTION_MODE, function);
1489 /* Generate the actual call instruction and save the return value. */
1490 #ifdef HAVE_untyped_call
1491 if (HAVE_untyped_call)
1492 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1493 result, result_vector (1, result)));
1494 else
1495 #endif
1496 #ifdef HAVE_call_value
1497 if (HAVE_call_value)
1499 rtx valreg = 0;
1501 /* Locate the unique return register. It is not possible to
1502 express a call that sets more than one return register using
1503 call_value; use untyped_call for that. In fact, untyped_call
1504 only needs to save the return registers in the given block. */
1505 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1506 if ((mode = apply_result_mode[regno]) != VOIDmode)
1508 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1510 valreg = gen_rtx_REG (mode, regno);
1513 emit_call_insn (GEN_CALL_VALUE (valreg,
1514 gen_rtx_MEM (FUNCTION_MODE, function),
1515 const0_rtx, NULL_RTX, const0_rtx));
1517 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1519 else
1520 #endif
1521 gcc_unreachable ();
1523 /* Find the CALL insn we just emitted, and attach the register usage
1524 information. */
1525 call_insn = last_call_insn ();
1526 add_function_usage_to (call_insn, call_fusage);
1528 /* Restore the stack. */
1529 #ifdef HAVE_save_stack_nonlocal
1530 if (HAVE_save_stack_nonlocal)
1531 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1532 else
1533 #endif
1534 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1536 OK_DEFER_POP;
1538 /* Return the address of the result block. */
1539 result = copy_addr_to_reg (XEXP (result, 0));
1540 return convert_memory_address (ptr_mode, result);
1543 /* Perform an untyped return. */
1545 static void
1546 expand_builtin_return (rtx result)
1548 int size, align, regno;
1549 enum machine_mode mode;
1550 rtx reg;
1551 rtx call_fusage = 0;
1553 result = convert_memory_address (Pmode, result);
1555 apply_result_size ();
1556 result = gen_rtx_MEM (BLKmode, result);
1558 #ifdef HAVE_untyped_return
1559 if (HAVE_untyped_return)
1561 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1562 emit_barrier ();
1563 return;
1565 #endif
1567 /* Restore the return value and note that each value is used. */
1568 size = 0;
1569 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1570 if ((mode = apply_result_mode[regno]) != VOIDmode)
1572 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1573 if (size % align != 0)
1574 size = CEIL (size, align) * align;
1575 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1576 emit_move_insn (reg, adjust_address (result, mode, size));
1578 push_to_sequence (call_fusage);
1579 emit_insn (gen_rtx_USE (VOIDmode, reg));
1580 call_fusage = get_insns ();
1581 end_sequence ();
1582 size += GET_MODE_SIZE (mode);
1585 /* Put the USE insns before the return. */
1586 emit_insn (call_fusage);
1588 /* Return whatever values was restored by jumping directly to the end
1589 of the function. */
1590 expand_naked_return ();
1593 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1595 static enum type_class
1596 type_to_class (tree type)
1598 switch (TREE_CODE (type))
1600 case VOID_TYPE: return void_type_class;
1601 case INTEGER_TYPE: return integer_type_class;
1602 case ENUMERAL_TYPE: return enumeral_type_class;
1603 case BOOLEAN_TYPE: return boolean_type_class;
1604 case POINTER_TYPE: return pointer_type_class;
1605 case REFERENCE_TYPE: return reference_type_class;
1606 case OFFSET_TYPE: return offset_type_class;
1607 case REAL_TYPE: return real_type_class;
1608 case COMPLEX_TYPE: return complex_type_class;
1609 case FUNCTION_TYPE: return function_type_class;
1610 case METHOD_TYPE: return method_type_class;
1611 case RECORD_TYPE: return record_type_class;
1612 case UNION_TYPE:
1613 case QUAL_UNION_TYPE: return union_type_class;
1614 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1615 ? string_type_class : array_type_class);
1616 case LANG_TYPE: return lang_type_class;
1617 default: return no_type_class;
1621 /* Expand a call to __builtin_classify_type with arguments found in
1622 ARGLIST. */
1624 static rtx
1625 expand_builtin_classify_type (tree arglist)
1627 if (arglist != 0)
1628 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1629 return GEN_INT (no_type_class);
1632 /* This helper macro, meant to be used in mathfn_built_in below,
1633 determines which among a set of three builtin math functions is
1634 appropriate for a given type mode. The `F' and `L' cases are
1635 automatically generated from the `double' case. */
1636 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1637 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1638 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1639 fcodel = BUILT_IN_MATHFN##L ; break;
1641 /* Return mathematic function equivalent to FN but operating directly
1642 on TYPE, if available. If we can't do the conversion, return zero. */
1643 tree
1644 mathfn_built_in (tree type, enum built_in_function fn)
1646 enum built_in_function fcode, fcodef, fcodel;
1648 switch (fn)
1650 CASE_MATHFN (BUILT_IN_ACOS)
1651 CASE_MATHFN (BUILT_IN_ACOSH)
1652 CASE_MATHFN (BUILT_IN_ASIN)
1653 CASE_MATHFN (BUILT_IN_ASINH)
1654 CASE_MATHFN (BUILT_IN_ATAN)
1655 CASE_MATHFN (BUILT_IN_ATAN2)
1656 CASE_MATHFN (BUILT_IN_ATANH)
1657 CASE_MATHFN (BUILT_IN_CBRT)
1658 CASE_MATHFN (BUILT_IN_CEIL)
1659 CASE_MATHFN (BUILT_IN_COPYSIGN)
1660 CASE_MATHFN (BUILT_IN_COS)
1661 CASE_MATHFN (BUILT_IN_COSH)
1662 CASE_MATHFN (BUILT_IN_DREM)
1663 CASE_MATHFN (BUILT_IN_ERF)
1664 CASE_MATHFN (BUILT_IN_ERFC)
1665 CASE_MATHFN (BUILT_IN_EXP)
1666 CASE_MATHFN (BUILT_IN_EXP10)
1667 CASE_MATHFN (BUILT_IN_EXP2)
1668 CASE_MATHFN (BUILT_IN_EXPM1)
1669 CASE_MATHFN (BUILT_IN_FABS)
1670 CASE_MATHFN (BUILT_IN_FDIM)
1671 CASE_MATHFN (BUILT_IN_FLOOR)
1672 CASE_MATHFN (BUILT_IN_FMA)
1673 CASE_MATHFN (BUILT_IN_FMAX)
1674 CASE_MATHFN (BUILT_IN_FMIN)
1675 CASE_MATHFN (BUILT_IN_FMOD)
1676 CASE_MATHFN (BUILT_IN_FREXP)
1677 CASE_MATHFN (BUILT_IN_GAMMA)
1678 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1679 CASE_MATHFN (BUILT_IN_HYPOT)
1680 CASE_MATHFN (BUILT_IN_ILOGB)
1681 CASE_MATHFN (BUILT_IN_INF)
1682 CASE_MATHFN (BUILT_IN_J0)
1683 CASE_MATHFN (BUILT_IN_J1)
1684 CASE_MATHFN (BUILT_IN_JN)
1685 CASE_MATHFN (BUILT_IN_LCEIL)
1686 CASE_MATHFN (BUILT_IN_LDEXP)
1687 CASE_MATHFN (BUILT_IN_LFLOOR)
1688 CASE_MATHFN (BUILT_IN_LGAMMA)
1689 CASE_MATHFN (BUILT_IN_LLCEIL)
1690 CASE_MATHFN (BUILT_IN_LLFLOOR)
1691 CASE_MATHFN (BUILT_IN_LLRINT)
1692 CASE_MATHFN (BUILT_IN_LLROUND)
1693 CASE_MATHFN (BUILT_IN_LOG)
1694 CASE_MATHFN (BUILT_IN_LOG10)
1695 CASE_MATHFN (BUILT_IN_LOG1P)
1696 CASE_MATHFN (BUILT_IN_LOG2)
1697 CASE_MATHFN (BUILT_IN_LOGB)
1698 CASE_MATHFN (BUILT_IN_LRINT)
1699 CASE_MATHFN (BUILT_IN_LROUND)
1700 CASE_MATHFN (BUILT_IN_MODF)
1701 CASE_MATHFN (BUILT_IN_NAN)
1702 CASE_MATHFN (BUILT_IN_NANS)
1703 CASE_MATHFN (BUILT_IN_NEARBYINT)
1704 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1705 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1706 CASE_MATHFN (BUILT_IN_POW)
1707 CASE_MATHFN (BUILT_IN_POWI)
1708 CASE_MATHFN (BUILT_IN_POW10)
1709 CASE_MATHFN (BUILT_IN_REMAINDER)
1710 CASE_MATHFN (BUILT_IN_REMQUO)
1711 CASE_MATHFN (BUILT_IN_RINT)
1712 CASE_MATHFN (BUILT_IN_ROUND)
1713 CASE_MATHFN (BUILT_IN_SCALB)
1714 CASE_MATHFN (BUILT_IN_SCALBLN)
1715 CASE_MATHFN (BUILT_IN_SCALBN)
1716 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1717 CASE_MATHFN (BUILT_IN_SIN)
1718 CASE_MATHFN (BUILT_IN_SINCOS)
1719 CASE_MATHFN (BUILT_IN_SINH)
1720 CASE_MATHFN (BUILT_IN_SQRT)
1721 CASE_MATHFN (BUILT_IN_TAN)
1722 CASE_MATHFN (BUILT_IN_TANH)
1723 CASE_MATHFN (BUILT_IN_TGAMMA)
1724 CASE_MATHFN (BUILT_IN_TRUNC)
1725 CASE_MATHFN (BUILT_IN_Y0)
1726 CASE_MATHFN (BUILT_IN_Y1)
1727 CASE_MATHFN (BUILT_IN_YN)
1729 default:
1730 return 0;
1733 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1734 return implicit_built_in_decls[fcode];
1735 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1736 return implicit_built_in_decls[fcodef];
1737 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1738 return implicit_built_in_decls[fcodel];
1739 else
1740 return 0;
1743 /* If errno must be maintained, expand the RTL to check if the result,
1744 TARGET, of a built-in function call, EXP, is NaN, and if so set
1745 errno to EDOM. */
1747 static void
1748 expand_errno_check (tree exp, rtx target)
1750 rtx lab = gen_label_rtx ();
1752 /* Test the result; if it is NaN, set errno=EDOM because
1753 the argument was not in the domain. */
1754 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1755 0, lab);
1757 #ifdef TARGET_EDOM
1758 /* If this built-in doesn't throw an exception, set errno directly. */
1759 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1761 #ifdef GEN_ERRNO_RTX
1762 rtx errno_rtx = GEN_ERRNO_RTX;
1763 #else
1764 rtx errno_rtx
1765 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1766 #endif
1767 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1768 emit_label (lab);
1769 return;
1771 #endif
1773 /* We can't set errno=EDOM directly; let the library call do it.
1774 Pop the arguments right away in case the call gets deleted. */
1775 NO_DEFER_POP;
1776 expand_call (exp, target, 0);
1777 OK_DEFER_POP;
1778 emit_label (lab);
1782 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1783 Return 0 if a normal call should be emitted rather than expanding the
1784 function in-line. EXP is the expression that is a call to the builtin
1785 function; if convenient, the result should be placed in TARGET.
1786 SUBTARGET may be used as the target for computing one of EXP's operands. */
1788 static rtx
1789 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1791 optab builtin_optab;
1792 rtx op0, insns, before_call;
1793 tree fndecl = get_callee_fndecl (exp);
1794 tree arglist = TREE_OPERAND (exp, 1);
1795 enum machine_mode mode;
1796 bool errno_set = false;
1797 tree arg, narg;
1799 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1800 return 0;
1802 arg = TREE_VALUE (arglist);
1804 switch (DECL_FUNCTION_CODE (fndecl))
1806 CASE_FLT_FN (BUILT_IN_SQRT):
1807 errno_set = ! tree_expr_nonnegative_p (arg);
1808 builtin_optab = sqrt_optab;
1809 break;
1810 CASE_FLT_FN (BUILT_IN_EXP):
1811 errno_set = true; builtin_optab = exp_optab; break;
1812 CASE_FLT_FN (BUILT_IN_EXP10):
1813 CASE_FLT_FN (BUILT_IN_POW10):
1814 errno_set = true; builtin_optab = exp10_optab; break;
1815 CASE_FLT_FN (BUILT_IN_EXP2):
1816 errno_set = true; builtin_optab = exp2_optab; break;
1817 CASE_FLT_FN (BUILT_IN_EXPM1):
1818 errno_set = true; builtin_optab = expm1_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOGB):
1820 errno_set = true; builtin_optab = logb_optab; break;
1821 CASE_FLT_FN (BUILT_IN_ILOGB):
1822 errno_set = true; builtin_optab = ilogb_optab; break;
1823 CASE_FLT_FN (BUILT_IN_LOG):
1824 errno_set = true; builtin_optab = log_optab; break;
1825 CASE_FLT_FN (BUILT_IN_LOG10):
1826 errno_set = true; builtin_optab = log10_optab; break;
1827 CASE_FLT_FN (BUILT_IN_LOG2):
1828 errno_set = true; builtin_optab = log2_optab; break;
1829 CASE_FLT_FN (BUILT_IN_LOG1P):
1830 errno_set = true; builtin_optab = log1p_optab; break;
1831 CASE_FLT_FN (BUILT_IN_ASIN):
1832 builtin_optab = asin_optab; break;
1833 CASE_FLT_FN (BUILT_IN_ACOS):
1834 builtin_optab = acos_optab; break;
1835 CASE_FLT_FN (BUILT_IN_TAN):
1836 builtin_optab = tan_optab; break;
1837 CASE_FLT_FN (BUILT_IN_ATAN):
1838 builtin_optab = atan_optab; break;
1839 CASE_FLT_FN (BUILT_IN_FLOOR):
1840 builtin_optab = floor_optab; break;
1841 CASE_FLT_FN (BUILT_IN_CEIL):
1842 builtin_optab = ceil_optab; break;
1843 CASE_FLT_FN (BUILT_IN_TRUNC):
1844 builtin_optab = btrunc_optab; break;
1845 CASE_FLT_FN (BUILT_IN_ROUND):
1846 builtin_optab = round_optab; break;
1847 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1848 builtin_optab = nearbyint_optab; break;
1849 CASE_FLT_FN (BUILT_IN_RINT):
1850 builtin_optab = rint_optab; break;
1851 CASE_FLT_FN (BUILT_IN_LRINT):
1852 CASE_FLT_FN (BUILT_IN_LLRINT):
1853 builtin_optab = lrint_optab; break;
1854 default:
1855 gcc_unreachable ();
1858 /* Make a suitable register to place result in. */
1859 mode = TYPE_MODE (TREE_TYPE (exp));
1861 if (! flag_errno_math || ! HONOR_NANS (mode))
1862 errno_set = false;
1864 /* Before working hard, check whether the instruction is available. */
1865 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1867 target = gen_reg_rtx (mode);
1869 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1870 need to expand the argument again. This way, we will not perform
1871 side-effects more the once. */
1872 narg = builtin_save_expr (arg);
1873 if (narg != arg)
1875 arg = narg;
1876 arglist = build_tree_list (NULL_TREE, arg);
1877 exp = build_function_call_expr (fndecl, arglist);
1880 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1882 start_sequence ();
1884 /* Compute into TARGET.
1885 Set TARGET to wherever the result comes back. */
1886 target = expand_unop (mode, builtin_optab, op0, target, 0);
1888 if (target != 0)
1890 if (errno_set)
1891 expand_errno_check (exp, target);
1893 /* Output the entire sequence. */
1894 insns = get_insns ();
1895 end_sequence ();
1896 emit_insn (insns);
1897 return target;
1900 /* If we were unable to expand via the builtin, stop the sequence
1901 (without outputting the insns) and call to the library function
1902 with the stabilized argument list. */
1903 end_sequence ();
1906 before_call = get_last_insn ();
1908 target = expand_call (exp, target, target == const0_rtx);
1910 /* If this is a sqrt operation and we don't care about errno, try to
1911 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1912 This allows the semantics of the libcall to be visible to the RTL
1913 optimizers. */
1914 if (builtin_optab == sqrt_optab && !errno_set)
1916 /* Search backwards through the insns emitted by expand_call looking
1917 for the instruction with the REG_RETVAL note. */
1918 rtx last = get_last_insn ();
1919 while (last != before_call)
1921 if (find_reg_note (last, REG_RETVAL, NULL))
1923 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1924 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1925 two elements, i.e. symbol_ref(sqrt) and the operand. */
1926 if (note
1927 && GET_CODE (note) == EXPR_LIST
1928 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1929 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1930 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1932 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1933 /* Check operand is a register with expected mode. */
1934 if (operand
1935 && REG_P (operand)
1936 && GET_MODE (operand) == mode)
1938 /* Replace the REG_EQUAL note with a SQRT rtx. */
1939 rtx equiv = gen_rtx_SQRT (mode, operand);
1940 set_unique_reg_note (last, REG_EQUAL, equiv);
1943 break;
1945 last = PREV_INSN (last);
1949 return target;
1952 /* Expand a call to the builtin binary math functions (pow and atan2).
1953 Return 0 if a normal call should be emitted rather than expanding the
1954 function in-line. EXP is the expression that is a call to the builtin
1955 function; if convenient, the result should be placed in TARGET.
1956 SUBTARGET may be used as the target for computing one of EXP's
1957 operands. */
1959 static rtx
1960 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1962 optab builtin_optab;
1963 rtx op0, op1, insns;
1964 int op1_type = REAL_TYPE;
1965 tree fndecl = get_callee_fndecl (exp);
1966 tree arglist = TREE_OPERAND (exp, 1);
1967 tree arg0, arg1, temp, narg;
1968 enum machine_mode mode;
1969 bool errno_set = true;
1970 bool stable = true;
1972 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1973 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1974 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1975 op1_type = INTEGER_TYPE;
1977 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1978 return 0;
1980 arg0 = TREE_VALUE (arglist);
1981 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1983 switch (DECL_FUNCTION_CODE (fndecl))
1985 CASE_FLT_FN (BUILT_IN_POW):
1986 builtin_optab = pow_optab; break;
1987 CASE_FLT_FN (BUILT_IN_ATAN2):
1988 builtin_optab = atan2_optab; break;
1989 CASE_FLT_FN (BUILT_IN_LDEXP):
1990 builtin_optab = ldexp_optab; break;
1991 CASE_FLT_FN (BUILT_IN_FMOD):
1992 builtin_optab = fmod_optab; break;
1993 CASE_FLT_FN (BUILT_IN_DREM):
1994 builtin_optab = drem_optab; break;
1995 default:
1996 gcc_unreachable ();
1999 /* Make a suitable register to place result in. */
2000 mode = TYPE_MODE (TREE_TYPE (exp));
2002 /* Before working hard, check whether the instruction is available. */
2003 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2004 return 0;
2006 target = gen_reg_rtx (mode);
2008 if (! flag_errno_math || ! HONOR_NANS (mode))
2009 errno_set = false;
2011 /* Always stabilize the argument list. */
2012 narg = builtin_save_expr (arg1);
2013 if (narg != arg1)
2015 arg1 = narg;
2016 temp = build_tree_list (NULL_TREE, narg);
2017 stable = false;
2019 else
2020 temp = TREE_CHAIN (arglist);
2022 narg = builtin_save_expr (arg0);
2023 if (narg != arg0)
2025 arg0 = narg;
2026 arglist = tree_cons (NULL_TREE, narg, temp);
2027 stable = false;
2029 else if (! stable)
2030 arglist = tree_cons (NULL_TREE, arg0, temp);
2032 if (! stable)
2033 exp = build_function_call_expr (fndecl, arglist);
2035 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2036 op1 = expand_normal (arg1);
2038 start_sequence ();
2040 /* Compute into TARGET.
2041 Set TARGET to wherever the result comes back. */
2042 target = expand_binop (mode, builtin_optab, op0, op1,
2043 target, 0, OPTAB_DIRECT);
2045 /* If we were unable to expand via the builtin, stop the sequence
2046 (without outputting the insns) and call to the library function
2047 with the stabilized argument list. */
2048 if (target == 0)
2050 end_sequence ();
2051 return expand_call (exp, target, target == const0_rtx);
2054 if (errno_set)
2055 expand_errno_check (exp, target);
2057 /* Output the entire sequence. */
2058 insns = get_insns ();
2059 end_sequence ();
2060 emit_insn (insns);
2062 return target;
2065 /* Expand a call to the builtin sin and cos math functions.
2066 Return 0 if a normal call should be emitted rather than expanding the
2067 function in-line. EXP is the expression that is a call to the builtin
2068 function; if convenient, the result should be placed in TARGET.
2069 SUBTARGET may be used as the target for computing one of EXP's
2070 operands. */
2072 static rtx
2073 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2075 optab builtin_optab;
2076 rtx op0, insns;
2077 tree fndecl = get_callee_fndecl (exp);
2078 tree arglist = TREE_OPERAND (exp, 1);
2079 enum machine_mode mode;
2080 tree arg, narg;
2082 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2083 return 0;
2085 arg = TREE_VALUE (arglist);
2087 switch (DECL_FUNCTION_CODE (fndecl))
2089 CASE_FLT_FN (BUILT_IN_SIN):
2090 CASE_FLT_FN (BUILT_IN_COS):
2091 builtin_optab = sincos_optab; break;
2092 default:
2093 gcc_unreachable ();
2096 /* Make a suitable register to place result in. */
2097 mode = TYPE_MODE (TREE_TYPE (exp));
2099 /* Check if sincos insn is available, otherwise fallback
2100 to sin or cos insn. */
2101 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2102 switch (DECL_FUNCTION_CODE (fndecl))
2104 CASE_FLT_FN (BUILT_IN_SIN):
2105 builtin_optab = sin_optab; break;
2106 CASE_FLT_FN (BUILT_IN_COS):
2107 builtin_optab = cos_optab; break;
2108 default:
2109 gcc_unreachable ();
2113 /* Before working hard, check whether the instruction is available. */
2114 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2116 target = gen_reg_rtx (mode);
2118 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2119 need to expand the argument again. This way, we will not perform
2120 side-effects more the once. */
2121 narg = save_expr (arg);
2122 if (narg != arg)
2124 arg = narg;
2125 arglist = build_tree_list (NULL_TREE, arg);
2126 exp = build_function_call_expr (fndecl, arglist);
2129 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2131 start_sequence ();
2133 /* Compute into TARGET.
2134 Set TARGET to wherever the result comes back. */
2135 if (builtin_optab == sincos_optab)
2137 int result;
2139 switch (DECL_FUNCTION_CODE (fndecl))
2141 CASE_FLT_FN (BUILT_IN_SIN):
2142 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2143 break;
2144 CASE_FLT_FN (BUILT_IN_COS):
2145 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2146 break;
2147 default:
2148 gcc_unreachable ();
2150 gcc_assert (result);
2152 else
2154 target = expand_unop (mode, builtin_optab, op0, target, 0);
2157 if (target != 0)
2159 /* Output the entire sequence. */
2160 insns = get_insns ();
2161 end_sequence ();
2162 emit_insn (insns);
2163 return target;
2166 /* If we were unable to expand via the builtin, stop the sequence
2167 (without outputting the insns) and call to the library function
2168 with the stabilized argument list. */
2169 end_sequence ();
2172 target = expand_call (exp, target, target == const0_rtx);
2174 return target;
2177 /* Expand a call to the builtin sincos math function.
2178 Return 0 if a normal call should be emitted rather than expanding the
2179 function in-line. EXP is the expression that is a call to the builtin
2180 function. */
2182 static rtx
2183 expand_builtin_sincos (tree exp)
2185 rtx op0, op1, op2, target1, target2;
2186 tree arglist = TREE_OPERAND (exp, 1);
2187 enum machine_mode mode;
2188 tree arg, sinp, cosp;
2189 int result;
2191 if (!validate_arglist (arglist, REAL_TYPE,
2192 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2193 return 0;
2195 arg = TREE_VALUE (arglist);
2196 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2197 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2199 /* Make a suitable register to place result in. */
2200 mode = TYPE_MODE (TREE_TYPE (arg));
2202 /* Check if sincos insn is available, otherwise emit the call. */
2203 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2204 return NULL_RTX;
2206 target1 = gen_reg_rtx (mode);
2207 target2 = gen_reg_rtx (mode);
2209 op0 = expand_normal (arg);
2210 op1 = expand_normal (build_fold_indirect_ref (sinp));
2211 op2 = expand_normal (build_fold_indirect_ref (cosp));
2213 /* Compute into target1 and target2.
2214 Set TARGET to wherever the result comes back. */
2215 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2216 gcc_assert (result);
2218 /* Move target1 and target2 to the memory locations indicated
2219 by op1 and op2. */
2220 emit_move_insn (op1, target1);
2221 emit_move_insn (op2, target2);
2223 return const0_rtx;
2226 /* Expand a call to one of the builtin rounding functions (lfloor).
2227 If expanding via optab fails, lower expression to (int)(floor(x)).
2228 EXP is the expression that is a call to the builtin function;
2229 if convenient, the result should be placed in TARGET. SUBTARGET may
2230 be used as the target for computing one of EXP's operands. */
2232 static rtx
2233 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2235 optab builtin_optab;
2236 rtx op0, insns, tmp;
2237 tree fndecl = get_callee_fndecl (exp);
2238 tree arglist = TREE_OPERAND (exp, 1);
2239 enum built_in_function fallback_fn;
2240 tree fallback_fndecl;
2241 enum machine_mode mode;
2242 tree arg, narg;
2244 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2245 gcc_unreachable ();
2247 arg = TREE_VALUE (arglist);
2249 switch (DECL_FUNCTION_CODE (fndecl))
2251 CASE_FLT_FN (BUILT_IN_LCEIL):
2252 CASE_FLT_FN (BUILT_IN_LLCEIL):
2253 builtin_optab = lceil_optab;
2254 fallback_fn = BUILT_IN_CEIL;
2255 break;
2257 CASE_FLT_FN (BUILT_IN_LFLOOR):
2258 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2259 builtin_optab = lfloor_optab;
2260 fallback_fn = BUILT_IN_FLOOR;
2261 break;
2263 default:
2264 gcc_unreachable ();
2267 /* Make a suitable register to place result in. */
2268 mode = TYPE_MODE (TREE_TYPE (exp));
2270 /* Before working hard, check whether the instruction is available. */
2271 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2273 target = gen_reg_rtx (mode);
2275 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2276 need to expand the argument again. This way, we will not perform
2277 side-effects more the once. */
2278 narg = builtin_save_expr (arg);
2279 if (narg != arg)
2281 arg = narg;
2282 arglist = build_tree_list (NULL_TREE, arg);
2283 exp = build_function_call_expr (fndecl, arglist);
2286 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2288 start_sequence ();
2290 /* Compute into TARGET.
2291 Set TARGET to wherever the result comes back. */
2292 target = expand_unop (mode, builtin_optab, op0, target, 0);
2294 if (target != 0)
2296 /* Output the entire sequence. */
2297 insns = get_insns ();
2298 end_sequence ();
2299 emit_insn (insns);
2300 return target;
2303 /* If we were unable to expand via the builtin, stop the sequence
2304 (without outputting the insns). */
2305 end_sequence ();
2308 /* Fall back to floating point rounding optab. */
2309 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2310 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2311 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2312 gcc_assert (fallback_fndecl != NULL_TREE);
2313 exp = build_function_call_expr (fallback_fndecl, arglist);
2315 tmp = expand_normal (exp);
2317 /* Truncate the result of floating point optab to integer
2318 via expand_fix (). */
2319 target = gen_reg_rtx (mode);
2320 expand_fix (target, tmp, 0);
2322 return target;
2325 /* To evaluate powi(x,n), the floating point value x raised to the
2326 constant integer exponent n, we use a hybrid algorithm that
2327 combines the "window method" with look-up tables. For an
2328 introduction to exponentiation algorithms and "addition chains",
2329 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2330 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2331 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2332 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2334 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2335 multiplications to inline before calling the system library's pow
2336 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2337 so this default never requires calling pow, powf or powl. */
2339 #ifndef POWI_MAX_MULTS
2340 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2341 #endif
2343 /* The size of the "optimal power tree" lookup table. All
2344 exponents less than this value are simply looked up in the
2345 powi_table below. This threshold is also used to size the
2346 cache of pseudo registers that hold intermediate results. */
2347 #define POWI_TABLE_SIZE 256
2349 /* The size, in bits of the window, used in the "window method"
2350 exponentiation algorithm. This is equivalent to a radix of
2351 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2352 #define POWI_WINDOW_SIZE 3
2354 /* The following table is an efficient representation of an
2355 "optimal power tree". For each value, i, the corresponding
2356 value, j, in the table states than an optimal evaluation
2357 sequence for calculating pow(x,i) can be found by evaluating
2358 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2359 100 integers is given in Knuth's "Seminumerical algorithms". */
2361 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2363 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2364 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2365 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2366 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2367 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2368 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2369 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2370 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2371 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2372 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2373 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2374 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2375 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2376 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2377 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2378 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2379 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2380 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2381 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2382 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2383 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2384 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2385 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2386 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2387 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2388 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2389 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2390 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2391 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2392 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2393 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2394 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2398 /* Return the number of multiplications required to calculate
2399 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2400 subroutine of powi_cost. CACHE is an array indicating
2401 which exponents have already been calculated. */
2403 static int
2404 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2406 /* If we've already calculated this exponent, then this evaluation
2407 doesn't require any additional multiplications. */
2408 if (cache[n])
2409 return 0;
2411 cache[n] = true;
2412 return powi_lookup_cost (n - powi_table[n], cache)
2413 + powi_lookup_cost (powi_table[n], cache) + 1;
2416 /* Return the number of multiplications required to calculate
2417 powi(x,n) for an arbitrary x, given the exponent N. This
2418 function needs to be kept in sync with expand_powi below. */
2420 static int
2421 powi_cost (HOST_WIDE_INT n)
2423 bool cache[POWI_TABLE_SIZE];
2424 unsigned HOST_WIDE_INT digit;
2425 unsigned HOST_WIDE_INT val;
2426 int result;
2428 if (n == 0)
2429 return 0;
2431 /* Ignore the reciprocal when calculating the cost. */
2432 val = (n < 0) ? -n : n;
2434 /* Initialize the exponent cache. */
2435 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2436 cache[1] = true;
2438 result = 0;
2440 while (val >= POWI_TABLE_SIZE)
2442 if (val & 1)
2444 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2445 result += powi_lookup_cost (digit, cache)
2446 + POWI_WINDOW_SIZE + 1;
2447 val >>= POWI_WINDOW_SIZE;
2449 else
2451 val >>= 1;
2452 result++;
2456 return result + powi_lookup_cost (val, cache);
2459 /* Recursive subroutine of expand_powi. This function takes the array,
2460 CACHE, of already calculated exponents and an exponent N and returns
2461 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2463 static rtx
2464 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2466 unsigned HOST_WIDE_INT digit;
2467 rtx target, result;
2468 rtx op0, op1;
2470 if (n < POWI_TABLE_SIZE)
2472 if (cache[n])
2473 return cache[n];
2475 target = gen_reg_rtx (mode);
2476 cache[n] = target;
2478 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2479 op1 = expand_powi_1 (mode, powi_table[n], cache);
2481 else if (n & 1)
2483 target = gen_reg_rtx (mode);
2484 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2485 op0 = expand_powi_1 (mode, n - digit, cache);
2486 op1 = expand_powi_1 (mode, digit, cache);
2488 else
2490 target = gen_reg_rtx (mode);
2491 op0 = expand_powi_1 (mode, n >> 1, cache);
2492 op1 = op0;
2495 result = expand_mult (mode, op0, op1, target, 0);
2496 if (result != target)
2497 emit_move_insn (target, result);
2498 return target;
2501 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2502 floating point operand in mode MODE, and N is the exponent. This
2503 function needs to be kept in sync with powi_cost above. */
2505 static rtx
2506 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2508 unsigned HOST_WIDE_INT val;
2509 rtx cache[POWI_TABLE_SIZE];
2510 rtx result;
2512 if (n == 0)
2513 return CONST1_RTX (mode);
2515 val = (n < 0) ? -n : n;
2517 memset (cache, 0, sizeof (cache));
2518 cache[1] = x;
2520 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2522 /* If the original exponent was negative, reciprocate the result. */
2523 if (n < 0)
2524 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2525 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2527 return result;
2530 /* Expand a call to the pow built-in mathematical function. Return 0 if
2531 a normal call should be emitted rather than expanding the function
2532 in-line. EXP is the expression that is a call to the builtin
2533 function; if convenient, the result should be placed in TARGET. */
2535 static rtx
2536 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2538 tree arglist = TREE_OPERAND (exp, 1);
2539 tree arg0, arg1;
2541 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2542 return 0;
2544 arg0 = TREE_VALUE (arglist);
2545 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2547 if (TREE_CODE (arg1) == REAL_CST
2548 && ! TREE_CONSTANT_OVERFLOW (arg1))
2550 REAL_VALUE_TYPE cint;
2551 REAL_VALUE_TYPE c;
2552 HOST_WIDE_INT n;
2554 c = TREE_REAL_CST (arg1);
2555 n = real_to_integer (&c);
2556 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2557 if (real_identical (&c, &cint))
2559 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2560 Otherwise, check the number of multiplications required.
2561 Note that pow never sets errno for an integer exponent. */
2562 if ((n >= -1 && n <= 2)
2563 || (flag_unsafe_math_optimizations
2564 && ! optimize_size
2565 && powi_cost (n) <= POWI_MAX_MULTS))
2567 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2568 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2569 op = force_reg (mode, op);
2570 return expand_powi (op, mode, n);
2575 if (! flag_unsafe_math_optimizations)
2576 return NULL_RTX;
2577 return expand_builtin_mathfn_2 (exp, target, subtarget);
2580 /* Expand a call to the powi built-in mathematical function. Return 0 if
2581 a normal call should be emitted rather than expanding the function
2582 in-line. EXP is the expression that is a call to the builtin
2583 function; if convenient, the result should be placed in TARGET. */
2585 static rtx
2586 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2588 tree arglist = TREE_OPERAND (exp, 1);
2589 tree arg0, arg1;
2590 rtx op0, op1;
2591 enum machine_mode mode;
2592 enum machine_mode mode2;
2594 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2595 return 0;
2597 arg0 = TREE_VALUE (arglist);
2598 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2599 mode = TYPE_MODE (TREE_TYPE (exp));
2601 /* Handle constant power. */
2603 if (TREE_CODE (arg1) == INTEGER_CST
2604 && ! TREE_CONSTANT_OVERFLOW (arg1))
2606 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2608 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2609 Otherwise, check the number of multiplications required. */
2610 if ((TREE_INT_CST_HIGH (arg1) == 0
2611 || TREE_INT_CST_HIGH (arg1) == -1)
2612 && ((n >= -1 && n <= 2)
2613 || (! optimize_size
2614 && powi_cost (n) <= POWI_MAX_MULTS)))
2616 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2617 op0 = force_reg (mode, op0);
2618 return expand_powi (op0, mode, n);
2622 /* Emit a libcall to libgcc. */
2624 /* Mode of the 2nd argument must match that of an int. */
2625 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2627 if (target == NULL_RTX)
2628 target = gen_reg_rtx (mode);
2630 op0 = expand_expr (arg0, subtarget, mode, 0);
2631 if (GET_MODE (op0) != mode)
2632 op0 = convert_to_mode (mode, op0, 0);
2633 op1 = expand_expr (arg1, 0, mode2, 0);
2634 if (GET_MODE (op1) != mode2)
2635 op1 = convert_to_mode (mode2, op1, 0);
2637 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2638 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2639 op0, mode, op1, mode2);
2641 return target;
2644 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2645 if we failed the caller should emit a normal call, otherwise
2646 try to get the result in TARGET, if convenient. */
2648 static rtx
2649 expand_builtin_strlen (tree arglist, rtx target,
2650 enum machine_mode target_mode)
2652 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2653 return 0;
2654 else
2656 rtx pat;
2657 tree len, src = TREE_VALUE (arglist);
2658 rtx result, src_reg, char_rtx, before_strlen;
2659 enum machine_mode insn_mode = target_mode, char_mode;
2660 enum insn_code icode = CODE_FOR_nothing;
2661 int align;
2663 /* If the length can be computed at compile-time, return it. */
2664 len = c_strlen (src, 0);
2665 if (len)
2666 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2668 /* If the length can be computed at compile-time and is constant
2669 integer, but there are side-effects in src, evaluate
2670 src for side-effects, then return len.
2671 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2672 can be optimized into: i++; x = 3; */
2673 len = c_strlen (src, 1);
2674 if (len && TREE_CODE (len) == INTEGER_CST)
2676 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2677 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2680 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2682 /* If SRC is not a pointer type, don't do this operation inline. */
2683 if (align == 0)
2684 return 0;
2686 /* Bail out if we can't compute strlen in the right mode. */
2687 while (insn_mode != VOIDmode)
2689 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2690 if (icode != CODE_FOR_nothing)
2691 break;
2693 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2695 if (insn_mode == VOIDmode)
2696 return 0;
2698 /* Make a place to write the result of the instruction. */
2699 result = target;
2700 if (! (result != 0
2701 && REG_P (result)
2702 && GET_MODE (result) == insn_mode
2703 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2704 result = gen_reg_rtx (insn_mode);
2706 /* Make a place to hold the source address. We will not expand
2707 the actual source until we are sure that the expansion will
2708 not fail -- there are trees that cannot be expanded twice. */
2709 src_reg = gen_reg_rtx (Pmode);
2711 /* Mark the beginning of the strlen sequence so we can emit the
2712 source operand later. */
2713 before_strlen = get_last_insn ();
2715 char_rtx = const0_rtx;
2716 char_mode = insn_data[(int) icode].operand[2].mode;
2717 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2718 char_mode))
2719 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2721 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2722 char_rtx, GEN_INT (align));
2723 if (! pat)
2724 return 0;
2725 emit_insn (pat);
2727 /* Now that we are assured of success, expand the source. */
2728 start_sequence ();
2729 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2730 if (pat != src_reg)
2731 emit_move_insn (src_reg, pat);
2732 pat = get_insns ();
2733 end_sequence ();
2735 if (before_strlen)
2736 emit_insn_after (pat, before_strlen);
2737 else
2738 emit_insn_before (pat, get_insns ());
2740 /* Return the value in the proper mode for this function. */
2741 if (GET_MODE (result) == target_mode)
2742 target = result;
2743 else if (target != 0)
2744 convert_move (target, result, 0);
2745 else
2746 target = convert_to_mode (target_mode, result, 0);
2748 return target;
2752 /* Expand a call to the strstr builtin. Return 0 if we failed the
2753 caller should emit a normal call, otherwise try to get the result
2754 in TARGET, if convenient (and in mode MODE if that's convenient). */
2756 static rtx
2757 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2759 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2761 tree result = fold_builtin_strstr (arglist, type);
2762 if (result)
2763 return expand_expr (result, target, mode, EXPAND_NORMAL);
2765 return 0;
2768 /* Expand a call to the strchr builtin. Return 0 if we failed the
2769 caller should emit a normal call, otherwise try to get the result
2770 in TARGET, if convenient (and in mode MODE if that's convenient). */
2772 static rtx
2773 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2775 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2777 tree result = fold_builtin_strchr (arglist, type);
2778 if (result)
2779 return expand_expr (result, target, mode, EXPAND_NORMAL);
2781 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2783 return 0;
2786 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2787 caller should emit a normal call, otherwise try to get the result
2788 in TARGET, if convenient (and in mode MODE if that's convenient). */
2790 static rtx
2791 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2793 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2795 tree result = fold_builtin_strrchr (arglist, type);
2796 if (result)
2797 return expand_expr (result, target, mode, EXPAND_NORMAL);
2799 return 0;
2802 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2803 caller should emit a normal call, otherwise try to get the result
2804 in TARGET, if convenient (and in mode MODE if that's convenient). */
2806 static rtx
2807 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2809 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2811 tree result = fold_builtin_strpbrk (arglist, type);
2812 if (result)
2813 return expand_expr (result, target, mode, EXPAND_NORMAL);
2815 return 0;
2818 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2819 bytes from constant string DATA + OFFSET and return it as target
2820 constant. */
2822 static rtx
2823 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2824 enum machine_mode mode)
2826 const char *str = (const char *) data;
2828 gcc_assert (offset >= 0
2829 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2830 <= strlen (str) + 1));
2832 return c_readstr (str + offset, mode);
2835 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2836 Return 0 if we failed, the caller should emit a normal call,
2837 otherwise try to get the result in TARGET, if convenient (and in
2838 mode MODE if that's convenient). */
2839 static rtx
2840 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2842 tree fndecl = get_callee_fndecl (exp);
2843 tree arglist = TREE_OPERAND (exp, 1);
2844 if (!validate_arglist (arglist,
2845 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2846 return 0;
2847 else
2849 tree dest = TREE_VALUE (arglist);
2850 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2851 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2852 const char *src_str;
2853 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2854 unsigned int dest_align
2855 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2856 rtx dest_mem, src_mem, dest_addr, len_rtx;
2857 tree result = fold_builtin_memcpy (fndecl, arglist);
2859 if (result)
2860 return expand_expr (result, target, mode, EXPAND_NORMAL);
2862 /* If DEST is not a pointer type, call the normal function. */
2863 if (dest_align == 0)
2864 return 0;
2866 /* If either SRC is not a pointer type, don't do this
2867 operation in-line. */
2868 if (src_align == 0)
2869 return 0;
2871 dest_mem = get_memory_rtx (dest, len);
2872 set_mem_align (dest_mem, dest_align);
2873 len_rtx = expand_normal (len);
2874 src_str = c_getstr (src);
2876 /* If SRC is a string constant and block move would be done
2877 by pieces, we can avoid loading the string from memory
2878 and only stored the computed constants. */
2879 if (src_str
2880 && GET_CODE (len_rtx) == CONST_INT
2881 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2882 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2883 (void *) src_str, dest_align))
2885 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2886 builtin_memcpy_read_str,
2887 (void *) src_str, dest_align, 0);
2888 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2889 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2890 return dest_mem;
2893 src_mem = get_memory_rtx (src, len);
2894 set_mem_align (src_mem, src_align);
2896 /* Copy word part most expediently. */
2897 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2898 CALL_EXPR_TAILCALL (exp)
2899 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2901 if (dest_addr == 0)
2903 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2904 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2906 return dest_addr;
2910 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2911 Return 0 if we failed; the caller should emit a normal call,
2912 otherwise try to get the result in TARGET, if convenient (and in
2913 mode MODE if that's convenient). If ENDP is 0 return the
2914 destination pointer, if ENDP is 1 return the end pointer ala
2915 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2916 stpcpy. */
2918 static rtx
2919 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2920 int endp)
2922 if (!validate_arglist (arglist,
2923 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2924 return 0;
2925 /* If return value is ignored, transform mempcpy into memcpy. */
2926 else if (target == const0_rtx)
2928 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2930 if (!fn)
2931 return 0;
2933 return expand_expr (build_function_call_expr (fn, arglist),
2934 target, mode, EXPAND_NORMAL);
2936 else
2938 tree dest = TREE_VALUE (arglist);
2939 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2940 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2941 const char *src_str;
2942 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2943 unsigned int dest_align
2944 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2945 rtx dest_mem, src_mem, len_rtx;
2946 tree result = fold_builtin_mempcpy (arglist, type, endp);
2948 if (result)
2949 return expand_expr (result, target, mode, EXPAND_NORMAL);
2951 /* If either SRC or DEST is not a pointer type, don't do this
2952 operation in-line. */
2953 if (dest_align == 0 || src_align == 0)
2954 return 0;
2956 /* If LEN is not constant, call the normal function. */
2957 if (! host_integerp (len, 1))
2958 return 0;
2960 len_rtx = expand_normal (len);
2961 src_str = c_getstr (src);
2963 /* If SRC is a string constant and block move would be done
2964 by pieces, we can avoid loading the string from memory
2965 and only stored the computed constants. */
2966 if (src_str
2967 && GET_CODE (len_rtx) == CONST_INT
2968 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2969 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2970 (void *) src_str, dest_align))
2972 dest_mem = get_memory_rtx (dest, len);
2973 set_mem_align (dest_mem, dest_align);
2974 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2975 builtin_memcpy_read_str,
2976 (void *) src_str, dest_align, endp);
2977 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2978 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2979 return dest_mem;
2982 if (GET_CODE (len_rtx) == CONST_INT
2983 && can_move_by_pieces (INTVAL (len_rtx),
2984 MIN (dest_align, src_align)))
2986 dest_mem = get_memory_rtx (dest, len);
2987 set_mem_align (dest_mem, dest_align);
2988 src_mem = get_memory_rtx (src, len);
2989 set_mem_align (src_mem, src_align);
2990 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2991 MIN (dest_align, src_align), endp);
2992 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2993 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2994 return dest_mem;
2997 return 0;
3001 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3002 if we failed; the caller should emit a normal call. */
3004 static rtx
3005 expand_builtin_memmove (tree arglist, tree type, rtx target,
3006 enum machine_mode mode, tree orig_exp)
3008 if (!validate_arglist (arglist,
3009 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3010 return 0;
3011 else
3013 tree dest = TREE_VALUE (arglist);
3014 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3015 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3017 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3018 unsigned int dest_align
3019 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3020 tree result = fold_builtin_memmove (arglist, type);
3022 if (result)
3023 return expand_expr (result, target, mode, EXPAND_NORMAL);
3025 /* If DEST is not a pointer type, call the normal function. */
3026 if (dest_align == 0)
3027 return 0;
3029 /* If either SRC is not a pointer type, don't do this
3030 operation in-line. */
3031 if (src_align == 0)
3032 return 0;
3034 /* If src is categorized for a readonly section we can use
3035 normal memcpy. */
3036 if (readonly_data_expr (src))
3038 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3039 if (!fn)
3040 return 0;
3041 fn = build_function_call_expr (fn, arglist);
3042 if (TREE_CODE (fn) == CALL_EXPR)
3043 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3044 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3047 /* If length is 1 and we can expand memcpy call inline,
3048 it is ok to use memcpy as well. */
3049 if (integer_onep (len))
3051 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3052 /*endp=*/0);
3053 if (ret)
3054 return ret;
3057 /* Otherwise, call the normal function. */
3058 return 0;
3062 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3063 if we failed the caller should emit a normal call. */
3065 static rtx
3066 expand_builtin_bcopy (tree exp)
3068 tree arglist = TREE_OPERAND (exp, 1);
3069 tree type = TREE_TYPE (exp);
3070 tree src, dest, size, newarglist;
3072 if (!validate_arglist (arglist,
3073 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3074 return NULL_RTX;
3076 src = TREE_VALUE (arglist);
3077 dest = TREE_VALUE (TREE_CHAIN (arglist));
3078 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3080 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3081 memmove(ptr y, ptr x, size_t z). This is done this way
3082 so that if it isn't expanded inline, we fallback to
3083 calling bcopy instead of memmove. */
3085 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3086 newarglist = tree_cons (NULL_TREE, src, newarglist);
3087 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3089 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3092 #ifndef HAVE_movstr
3093 # define HAVE_movstr 0
3094 # define CODE_FOR_movstr CODE_FOR_nothing
3095 #endif
3097 /* Expand into a movstr instruction, if one is available. Return 0 if
3098 we failed, the caller should emit a normal call, otherwise try to
3099 get the result in TARGET, if convenient. If ENDP is 0 return the
3100 destination pointer, if ENDP is 1 return the end pointer ala
3101 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3102 stpcpy. */
3104 static rtx
3105 expand_movstr (tree dest, tree src, rtx target, int endp)
3107 rtx end;
3108 rtx dest_mem;
3109 rtx src_mem;
3110 rtx insn;
3111 const struct insn_data * data;
3113 if (!HAVE_movstr)
3114 return 0;
3116 dest_mem = get_memory_rtx (dest, NULL);
3117 src_mem = get_memory_rtx (src, NULL);
3118 if (!endp)
3120 target = force_reg (Pmode, XEXP (dest_mem, 0));
3121 dest_mem = replace_equiv_address (dest_mem, target);
3122 end = gen_reg_rtx (Pmode);
3124 else
3126 if (target == 0 || target == const0_rtx)
3128 end = gen_reg_rtx (Pmode);
3129 if (target == 0)
3130 target = end;
3132 else
3133 end = target;
3136 data = insn_data + CODE_FOR_movstr;
3138 if (data->operand[0].mode != VOIDmode)
3139 end = gen_lowpart (data->operand[0].mode, end);
3141 insn = data->genfun (end, dest_mem, src_mem);
3143 gcc_assert (insn);
3145 emit_insn (insn);
3147 /* movstr is supposed to set end to the address of the NUL
3148 terminator. If the caller requested a mempcpy-like return value,
3149 adjust it. */
3150 if (endp == 1 && target != const0_rtx)
3152 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3153 emit_move_insn (target, force_operand (tem, NULL_RTX));
3156 return target;
3159 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3160 if we failed the caller should emit a normal call, otherwise try to get
3161 the result in TARGET, if convenient (and in mode MODE if that's
3162 convenient). */
3164 static rtx
3165 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3167 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3169 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3170 if (result)
3171 return expand_expr (result, target, mode, EXPAND_NORMAL);
3173 return expand_movstr (TREE_VALUE (arglist),
3174 TREE_VALUE (TREE_CHAIN (arglist)),
3175 target, /*endp=*/0);
3177 return 0;
3180 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3181 Return 0 if we failed the caller should emit a normal call,
3182 otherwise try to get the result in TARGET, if convenient (and in
3183 mode MODE if that's convenient). */
3185 static rtx
3186 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3188 tree arglist = TREE_OPERAND (exp, 1);
3189 /* If return value is ignored, transform stpcpy into strcpy. */
3190 if (target == const0_rtx)
3192 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3193 if (!fn)
3194 return 0;
3196 return expand_expr (build_function_call_expr (fn, arglist),
3197 target, mode, EXPAND_NORMAL);
3200 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3201 return 0;
3202 else
3204 tree dst, src, len, lenp1;
3205 tree narglist;
3206 rtx ret;
3208 /* Ensure we get an actual string whose length can be evaluated at
3209 compile-time, not an expression containing a string. This is
3210 because the latter will potentially produce pessimized code
3211 when used to produce the return value. */
3212 src = TREE_VALUE (TREE_CHAIN (arglist));
3213 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3214 return expand_movstr (TREE_VALUE (arglist),
3215 TREE_VALUE (TREE_CHAIN (arglist)),
3216 target, /*endp=*/2);
3218 dst = TREE_VALUE (arglist);
3219 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3220 narglist = build_tree_list (NULL_TREE, lenp1);
3221 narglist = tree_cons (NULL_TREE, src, narglist);
3222 narglist = tree_cons (NULL_TREE, dst, narglist);
3223 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3224 target, mode, /*endp=*/2);
3226 if (ret)
3227 return ret;
3229 if (TREE_CODE (len) == INTEGER_CST)
3231 rtx len_rtx = expand_normal (len);
3233 if (GET_CODE (len_rtx) == CONST_INT)
3235 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3236 arglist, target, mode);
3238 if (ret)
3240 if (! target)
3242 if (mode != VOIDmode)
3243 target = gen_reg_rtx (mode);
3244 else
3245 target = gen_reg_rtx (GET_MODE (ret));
3247 if (GET_MODE (target) != GET_MODE (ret))
3248 ret = gen_lowpart (GET_MODE (target), ret);
3250 ret = plus_constant (ret, INTVAL (len_rtx));
3251 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3252 gcc_assert (ret);
3254 return target;
3259 return expand_movstr (TREE_VALUE (arglist),
3260 TREE_VALUE (TREE_CHAIN (arglist)),
3261 target, /*endp=*/2);
3265 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3266 bytes from constant string DATA + OFFSET and return it as target
3267 constant. */
3269 static rtx
3270 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3271 enum machine_mode mode)
3273 const char *str = (const char *) data;
3275 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3276 return const0_rtx;
3278 return c_readstr (str + offset, mode);
3281 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3282 if we failed the caller should emit a normal call. */
3284 static rtx
3285 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3287 tree fndecl = get_callee_fndecl (exp);
3288 tree arglist = TREE_OPERAND (exp, 1);
3289 if (validate_arglist (arglist,
3290 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3292 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3293 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3294 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3296 if (result)
3297 return expand_expr (result, target, mode, EXPAND_NORMAL);
3299 /* We must be passed a constant len and src parameter. */
3300 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3301 return 0;
3303 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3305 /* We're required to pad with trailing zeros if the requested
3306 len is greater than strlen(s2)+1. In that case try to
3307 use store_by_pieces, if it fails, punt. */
3308 if (tree_int_cst_lt (slen, len))
3310 tree dest = TREE_VALUE (arglist);
3311 unsigned int dest_align
3312 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3313 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3314 rtx dest_mem;
3316 if (!p || dest_align == 0 || !host_integerp (len, 1)
3317 || !can_store_by_pieces (tree_low_cst (len, 1),
3318 builtin_strncpy_read_str,
3319 (void *) p, dest_align))
3320 return 0;
3322 dest_mem = get_memory_rtx (dest, len);
3323 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3324 builtin_strncpy_read_str,
3325 (void *) p, dest_align, 0);
3326 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3327 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3328 return dest_mem;
3331 return 0;
3334 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3335 bytes from constant string DATA + OFFSET and return it as target
3336 constant. */
3338 static rtx
3339 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3340 enum machine_mode mode)
3342 const char *c = (const char *) data;
3343 char *p = alloca (GET_MODE_SIZE (mode));
3345 memset (p, *c, GET_MODE_SIZE (mode));
3347 return c_readstr (p, mode);
3350 /* Callback routine for store_by_pieces. Return the RTL of a register
3351 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3352 char value given in the RTL register data. For example, if mode is
3353 4 bytes wide, return the RTL for 0x01010101*data. */
3355 static rtx
3356 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3357 enum machine_mode mode)
3359 rtx target, coeff;
3360 size_t size;
3361 char *p;
3363 size = GET_MODE_SIZE (mode);
3364 if (size == 1)
3365 return (rtx) data;
3367 p = alloca (size);
3368 memset (p, 1, size);
3369 coeff = c_readstr (p, mode);
3371 target = convert_to_mode (mode, (rtx) data, 1);
3372 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3373 return force_reg (mode, target);
3376 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3377 if we failed the caller should emit a normal call, otherwise try to get
3378 the result in TARGET, if convenient (and in mode MODE if that's
3379 convenient). */
3381 static rtx
3382 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3383 tree orig_exp)
3385 if (!validate_arglist (arglist,
3386 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3387 return 0;
3388 else
3390 tree dest = TREE_VALUE (arglist);
3391 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3392 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3393 tree fndecl, fn;
3394 enum built_in_function fcode;
3395 char c;
3396 unsigned int dest_align;
3397 rtx dest_mem, dest_addr, len_rtx;
3399 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3401 /* If DEST is not a pointer type, don't do this
3402 operation in-line. */
3403 if (dest_align == 0)
3404 return 0;
3406 /* If the LEN parameter is zero, return DEST. */
3407 if (integer_zerop (len))
3409 /* Evaluate and ignore VAL in case it has side-effects. */
3410 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3411 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3414 /* Stabilize the arguments in case we fail. */
3415 dest = builtin_save_expr (dest);
3416 val = builtin_save_expr (val);
3417 len = builtin_save_expr (len);
3419 len_rtx = expand_normal (len);
3420 dest_mem = get_memory_rtx (dest, len);
3422 if (TREE_CODE (val) != INTEGER_CST)
3424 tree cval;
3425 rtx val_rtx;
3427 cval = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
3428 val_rtx = expand_normal (cval);
3430 /* Assume that we can memset by pieces if we can store the
3431 * the coefficients by pieces (in the required modes).
3432 * We can't pass builtin_memset_gen_str as that emits RTL. */
3433 c = 1;
3434 if (host_integerp (len, 1)
3435 && !(optimize_size && tree_low_cst (len, 1) > 1)
3436 && can_store_by_pieces (tree_low_cst (len, 1),
3437 builtin_memset_read_str, &c, dest_align))
3439 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3440 val_rtx);
3441 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3442 builtin_memset_gen_str, val_rtx, dest_align, 0);
3444 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3445 dest_align))
3446 goto do_libcall;
3448 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3449 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3450 return dest_mem;
3453 if (target_char_cast (val, &c))
3454 goto do_libcall;
3456 if (c)
3458 if (host_integerp (len, 1)
3459 && !(optimize_size && tree_low_cst (len, 1) > 1)
3460 && can_store_by_pieces (tree_low_cst (len, 1),
3461 builtin_memset_read_str, &c, dest_align))
3462 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3463 builtin_memset_read_str, &c, dest_align, 0);
3464 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3465 dest_align))
3466 goto do_libcall;
3468 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3469 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3470 return dest_mem;
3473 set_mem_align (dest_mem, dest_align);
3474 dest_addr = clear_storage (dest_mem, len_rtx,
3475 CALL_EXPR_TAILCALL (orig_exp)
3476 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3478 if (dest_addr == 0)
3480 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3481 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3484 return dest_addr;
3486 do_libcall:
3487 fndecl = get_callee_fndecl (orig_exp);
3488 fcode = DECL_FUNCTION_CODE (fndecl);
3489 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3490 arglist = build_tree_list (NULL_TREE, len);
3491 if (fcode == BUILT_IN_MEMSET)
3492 arglist = tree_cons (NULL_TREE, val, arglist);
3493 arglist = tree_cons (NULL_TREE, dest, arglist);
3494 fn = build_function_call_expr (fndecl, arglist);
3495 if (TREE_CODE (fn) == CALL_EXPR)
3496 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3497 return expand_call (fn, target, target == const0_rtx);
3501 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3502 if we failed the caller should emit a normal call. */
3504 static rtx
3505 expand_builtin_bzero (tree exp)
3507 tree arglist = TREE_OPERAND (exp, 1);
3508 tree dest, size, newarglist;
3510 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3511 return NULL_RTX;
3513 dest = TREE_VALUE (arglist);
3514 size = TREE_VALUE (TREE_CHAIN (arglist));
3516 /* New argument list transforming bzero(ptr x, int y) to
3517 memset(ptr x, int 0, size_t y). This is done this way
3518 so that if it isn't expanded inline, we fallback to
3519 calling bzero instead of memset. */
3521 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3522 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3523 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3525 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3528 /* Expand expression EXP, which is a call to the memcmp built-in function.
3529 ARGLIST is the argument list for this call. Return 0 if we failed and the
3530 caller should emit a normal call, otherwise try to get the result in
3531 TARGET, if convenient (and in mode MODE, if that's convenient). */
3533 static rtx
3534 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3535 enum machine_mode mode)
3537 if (!validate_arglist (arglist,
3538 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3539 return 0;
3540 else
3542 tree result = fold_builtin_memcmp (arglist);
3543 if (result)
3544 return expand_expr (result, target, mode, EXPAND_NORMAL);
3547 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3549 tree arg1 = TREE_VALUE (arglist);
3550 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3551 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3552 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3553 rtx result;
3554 rtx insn;
3556 int arg1_align
3557 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3558 int arg2_align
3559 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3560 enum machine_mode insn_mode;
3562 #ifdef HAVE_cmpmemsi
3563 if (HAVE_cmpmemsi)
3564 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3565 else
3566 #endif
3567 #ifdef HAVE_cmpstrnsi
3568 if (HAVE_cmpstrnsi)
3569 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3570 else
3571 #endif
3572 return 0;
3574 /* If we don't have POINTER_TYPE, call the function. */
3575 if (arg1_align == 0 || arg2_align == 0)
3576 return 0;
3578 /* Make a place to write the result of the instruction. */
3579 result = target;
3580 if (! (result != 0
3581 && REG_P (result) && GET_MODE (result) == insn_mode
3582 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3583 result = gen_reg_rtx (insn_mode);
3585 arg1_rtx = get_memory_rtx (arg1, len);
3586 arg2_rtx = get_memory_rtx (arg2, len);
3587 arg3_rtx = expand_normal (len);
3589 /* Set MEM_SIZE as appropriate. */
3590 if (GET_CODE (arg3_rtx) == CONST_INT)
3592 set_mem_size (arg1_rtx, arg3_rtx);
3593 set_mem_size (arg2_rtx, arg3_rtx);
3596 #ifdef HAVE_cmpmemsi
3597 if (HAVE_cmpmemsi)
3598 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3599 GEN_INT (MIN (arg1_align, arg2_align)));
3600 else
3601 #endif
3602 #ifdef HAVE_cmpstrnsi
3603 if (HAVE_cmpstrnsi)
3604 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3605 GEN_INT (MIN (arg1_align, arg2_align)));
3606 else
3607 #endif
3608 gcc_unreachable ();
3610 if (insn)
3611 emit_insn (insn);
3612 else
3613 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3614 TYPE_MODE (integer_type_node), 3,
3615 XEXP (arg1_rtx, 0), Pmode,
3616 XEXP (arg2_rtx, 0), Pmode,
3617 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3618 TYPE_UNSIGNED (sizetype)),
3619 TYPE_MODE (sizetype));
3621 /* Return the value in the proper mode for this function. */
3622 mode = TYPE_MODE (TREE_TYPE (exp));
3623 if (GET_MODE (result) == mode)
3624 return result;
3625 else if (target != 0)
3627 convert_move (target, result, 0);
3628 return target;
3630 else
3631 return convert_to_mode (mode, result, 0);
3633 #endif
3635 return 0;
3638 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3639 if we failed the caller should emit a normal call, otherwise try to get
3640 the result in TARGET, if convenient. */
3642 static rtx
3643 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3645 tree arglist = TREE_OPERAND (exp, 1);
3647 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3648 return 0;
3649 else
3651 tree result = fold_builtin_strcmp (arglist);
3652 if (result)
3653 return expand_expr (result, target, mode, EXPAND_NORMAL);
3656 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3657 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3658 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3660 rtx arg1_rtx, arg2_rtx;
3661 rtx result, insn = NULL_RTX;
3662 tree fndecl, fn;
3664 tree arg1 = TREE_VALUE (arglist);
3665 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3666 int arg1_align
3667 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3668 int arg2_align
3669 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3671 /* If we don't have POINTER_TYPE, call the function. */
3672 if (arg1_align == 0 || arg2_align == 0)
3673 return 0;
3675 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3676 arg1 = builtin_save_expr (arg1);
3677 arg2 = builtin_save_expr (arg2);
3679 arg1_rtx = get_memory_rtx (arg1, NULL);
3680 arg2_rtx = get_memory_rtx (arg2, NULL);
3682 #ifdef HAVE_cmpstrsi
3683 /* Try to call cmpstrsi. */
3684 if (HAVE_cmpstrsi)
3686 enum machine_mode insn_mode
3687 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3689 /* Make a place to write the result of the instruction. */
3690 result = target;
3691 if (! (result != 0
3692 && REG_P (result) && GET_MODE (result) == insn_mode
3693 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3694 result = gen_reg_rtx (insn_mode);
3696 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3697 GEN_INT (MIN (arg1_align, arg2_align)));
3699 #endif
3700 #ifdef HAVE_cmpstrnsi
3701 /* Try to determine at least one length and call cmpstrnsi. */
3702 if (!insn && HAVE_cmpstrnsi)
3704 tree len;
3705 rtx arg3_rtx;
3707 enum machine_mode insn_mode
3708 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3709 tree len1 = c_strlen (arg1, 1);
3710 tree len2 = c_strlen (arg2, 1);
3712 if (len1)
3713 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3714 if (len2)
3715 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3717 /* If we don't have a constant length for the first, use the length
3718 of the second, if we know it. We don't require a constant for
3719 this case; some cost analysis could be done if both are available
3720 but neither is constant. For now, assume they're equally cheap,
3721 unless one has side effects. If both strings have constant lengths,
3722 use the smaller. */
3724 if (!len1)
3725 len = len2;
3726 else if (!len2)
3727 len = len1;
3728 else if (TREE_SIDE_EFFECTS (len1))
3729 len = len2;
3730 else if (TREE_SIDE_EFFECTS (len2))
3731 len = len1;
3732 else if (TREE_CODE (len1) != INTEGER_CST)
3733 len = len2;
3734 else if (TREE_CODE (len2) != INTEGER_CST)
3735 len = len1;
3736 else if (tree_int_cst_lt (len1, len2))
3737 len = len1;
3738 else
3739 len = len2;
3741 /* If both arguments have side effects, we cannot optimize. */
3742 if (!len || TREE_SIDE_EFFECTS (len))
3743 goto do_libcall;
3745 arg3_rtx = expand_normal (len);
3747 /* Make a place to write the result of the instruction. */
3748 result = target;
3749 if (! (result != 0
3750 && REG_P (result) && GET_MODE (result) == insn_mode
3751 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3752 result = gen_reg_rtx (insn_mode);
3754 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3755 GEN_INT (MIN (arg1_align, arg2_align)));
3757 #endif
3759 if (insn)
3761 emit_insn (insn);
3763 /* Return the value in the proper mode for this function. */
3764 mode = TYPE_MODE (TREE_TYPE (exp));
3765 if (GET_MODE (result) == mode)
3766 return result;
3767 if (target == 0)
3768 return convert_to_mode (mode, result, 0);
3769 convert_move (target, result, 0);
3770 return target;
3773 /* Expand the library call ourselves using a stabilized argument
3774 list to avoid re-evaluating the function's arguments twice. */
3775 do_libcall:
3776 arglist = build_tree_list (NULL_TREE, arg2);
3777 arglist = tree_cons (NULL_TREE, arg1, arglist);
3778 fndecl = get_callee_fndecl (exp);
3779 fn = build_function_call_expr (fndecl, arglist);
3780 if (TREE_CODE (fn) == CALL_EXPR)
3781 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3782 return expand_call (fn, target, target == const0_rtx);
3784 #endif
3785 return 0;
3788 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3789 if we failed the caller should emit a normal call, otherwise try to get
3790 the result in TARGET, if convenient. */
3792 static rtx
3793 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3795 tree arglist = TREE_OPERAND (exp, 1);
3797 if (!validate_arglist (arglist,
3798 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3799 return 0;
3800 else
3802 tree result = fold_builtin_strncmp (arglist);
3803 if (result)
3804 return expand_expr (result, target, mode, EXPAND_NORMAL);
3807 /* If c_strlen can determine an expression for one of the string
3808 lengths, and it doesn't have side effects, then emit cmpstrnsi
3809 using length MIN(strlen(string)+1, arg3). */
3810 #ifdef HAVE_cmpstrnsi
3811 if (HAVE_cmpstrnsi)
3813 tree arg1 = TREE_VALUE (arglist);
3814 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3815 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3816 tree len, len1, len2;
3817 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3818 rtx result, insn;
3819 tree fndecl, fn;
3821 int arg1_align
3822 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3823 int arg2_align
3824 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3825 enum machine_mode insn_mode
3826 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3828 len1 = c_strlen (arg1, 1);
3829 len2 = c_strlen (arg2, 1);
3831 if (len1)
3832 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3833 if (len2)
3834 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3836 /* If we don't have a constant length for the first, use the length
3837 of the second, if we know it. We don't require a constant for
3838 this case; some cost analysis could be done if both are available
3839 but neither is constant. For now, assume they're equally cheap,
3840 unless one has side effects. If both strings have constant lengths,
3841 use the smaller. */
3843 if (!len1)
3844 len = len2;
3845 else if (!len2)
3846 len = len1;
3847 else if (TREE_SIDE_EFFECTS (len1))
3848 len = len2;
3849 else if (TREE_SIDE_EFFECTS (len2))
3850 len = len1;
3851 else if (TREE_CODE (len1) != INTEGER_CST)
3852 len = len2;
3853 else if (TREE_CODE (len2) != INTEGER_CST)
3854 len = len1;
3855 else if (tree_int_cst_lt (len1, len2))
3856 len = len1;
3857 else
3858 len = len2;
3860 /* If both arguments have side effects, we cannot optimize. */
3861 if (!len || TREE_SIDE_EFFECTS (len))
3862 return 0;
3864 /* The actual new length parameter is MIN(len,arg3). */
3865 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3866 fold_convert (TREE_TYPE (len), arg3));
3868 /* If we don't have POINTER_TYPE, call the function. */
3869 if (arg1_align == 0 || arg2_align == 0)
3870 return 0;
3872 /* Make a place to write the result of the instruction. */
3873 result = target;
3874 if (! (result != 0
3875 && REG_P (result) && GET_MODE (result) == insn_mode
3876 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3877 result = gen_reg_rtx (insn_mode);
3879 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3880 arg1 = builtin_save_expr (arg1);
3881 arg2 = builtin_save_expr (arg2);
3882 len = builtin_save_expr (len);
3884 arg1_rtx = get_memory_rtx (arg1, len);
3885 arg2_rtx = get_memory_rtx (arg2, len);
3886 arg3_rtx = expand_normal (len);
3887 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3888 GEN_INT (MIN (arg1_align, arg2_align)));
3889 if (insn)
3891 emit_insn (insn);
3893 /* Return the value in the proper mode for this function. */
3894 mode = TYPE_MODE (TREE_TYPE (exp));
3895 if (GET_MODE (result) == mode)
3896 return result;
3897 if (target == 0)
3898 return convert_to_mode (mode, result, 0);
3899 convert_move (target, result, 0);
3900 return target;
3903 /* Expand the library call ourselves using a stabilized argument
3904 list to avoid re-evaluating the function's arguments twice. */
3905 arglist = build_tree_list (NULL_TREE, len);
3906 arglist = tree_cons (NULL_TREE, arg2, arglist);
3907 arglist = tree_cons (NULL_TREE, arg1, arglist);
3908 fndecl = get_callee_fndecl (exp);
3909 fn = build_function_call_expr (fndecl, arglist);
3910 if (TREE_CODE (fn) == CALL_EXPR)
3911 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3912 return expand_call (fn, target, target == const0_rtx);
3914 #endif
3915 return 0;
3918 /* Expand expression EXP, which is a call to the strcat builtin.
3919 Return 0 if we failed the caller should emit a normal call,
3920 otherwise try to get the result in TARGET, if convenient. */
3922 static rtx
3923 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3925 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3926 return 0;
3927 else
3929 tree dst = TREE_VALUE (arglist),
3930 src = TREE_VALUE (TREE_CHAIN (arglist));
3931 const char *p = c_getstr (src);
3933 /* If the string length is zero, return the dst parameter. */
3934 if (p && *p == '\0')
3935 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3937 if (!optimize_size)
3939 /* See if we can store by pieces into (dst + strlen(dst)). */
3940 tree newsrc, newdst,
3941 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3942 rtx insns;
3944 /* Stabilize the argument list. */
3945 newsrc = builtin_save_expr (src);
3946 if (newsrc != src)
3947 arglist = build_tree_list (NULL_TREE, newsrc);
3948 else
3949 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3951 dst = builtin_save_expr (dst);
3953 start_sequence ();
3955 /* Create strlen (dst). */
3956 newdst =
3957 build_function_call_expr (strlen_fn,
3958 build_tree_list (NULL_TREE, dst));
3959 /* Create (dst + (cast) strlen (dst)). */
3960 newdst = fold_convert (TREE_TYPE (dst), newdst);
3961 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3963 newdst = builtin_save_expr (newdst);
3964 arglist = tree_cons (NULL_TREE, newdst, arglist);
3966 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3968 end_sequence (); /* Stop sequence. */
3969 return 0;
3972 /* Output the entire sequence. */
3973 insns = get_insns ();
3974 end_sequence ();
3975 emit_insn (insns);
3977 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3980 return 0;
3984 /* Expand expression EXP, which is a call to the strncat builtin.
3985 Return 0 if we failed the caller should emit a normal call,
3986 otherwise try to get the result in TARGET, if convenient. */
3988 static rtx
3989 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3991 if (validate_arglist (arglist,
3992 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3994 tree result = fold_builtin_strncat (arglist);
3995 if (result)
3996 return expand_expr (result, target, mode, EXPAND_NORMAL);
3998 return 0;
4001 /* Expand expression EXP, which is a call to the strspn builtin.
4002 Return 0 if we failed the caller should emit a normal call,
4003 otherwise try to get the result in TARGET, if convenient. */
4005 static rtx
4006 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4008 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4010 tree result = fold_builtin_strspn (arglist);
4011 if (result)
4012 return expand_expr (result, target, mode, EXPAND_NORMAL);
4014 return 0;
4017 /* Expand expression EXP, which is a call to the strcspn builtin.
4018 Return 0 if we failed the caller should emit a normal call,
4019 otherwise try to get the result in TARGET, if convenient. */
4021 static rtx
4022 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4024 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4026 tree result = fold_builtin_strcspn (arglist);
4027 if (result)
4028 return expand_expr (result, target, mode, EXPAND_NORMAL);
4030 return 0;
4033 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4034 if that's convenient. */
4037 expand_builtin_saveregs (void)
4039 rtx val, seq;
4041 /* Don't do __builtin_saveregs more than once in a function.
4042 Save the result of the first call and reuse it. */
4043 if (saveregs_value != 0)
4044 return saveregs_value;
4046 /* When this function is called, it means that registers must be
4047 saved on entry to this function. So we migrate the call to the
4048 first insn of this function. */
4050 start_sequence ();
4052 /* Do whatever the machine needs done in this case. */
4053 val = targetm.calls.expand_builtin_saveregs ();
4055 seq = get_insns ();
4056 end_sequence ();
4058 saveregs_value = val;
4060 /* Put the insns after the NOTE that starts the function. If this
4061 is inside a start_sequence, make the outer-level insn chain current, so
4062 the code is placed at the start of the function. */
4063 push_topmost_sequence ();
4064 emit_insn_after (seq, entry_of_function ());
4065 pop_topmost_sequence ();
4067 return val;
4070 /* __builtin_args_info (N) returns word N of the arg space info
4071 for the current function. The number and meanings of words
4072 is controlled by the definition of CUMULATIVE_ARGS. */
4074 static rtx
4075 expand_builtin_args_info (tree arglist)
4077 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4078 int *word_ptr = (int *) &current_function_args_info;
4080 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4082 if (arglist != 0)
4084 if (!host_integerp (TREE_VALUE (arglist), 0))
4085 error ("argument of %<__builtin_args_info%> must be constant");
4086 else
4088 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4090 if (wordnum < 0 || wordnum >= nwords)
4091 error ("argument of %<__builtin_args_info%> out of range");
4092 else
4093 return GEN_INT (word_ptr[wordnum]);
4096 else
4097 error ("missing argument in %<__builtin_args_info%>");
4099 return const0_rtx;
4102 /* Expand a call to __builtin_next_arg. */
4104 static rtx
4105 expand_builtin_next_arg (void)
4107 /* Checking arguments is already done in fold_builtin_next_arg
4108 that must be called before this function. */
4109 return expand_binop (Pmode, add_optab,
4110 current_function_internal_arg_pointer,
4111 current_function_arg_offset_rtx,
4112 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4115 /* Make it easier for the backends by protecting the valist argument
4116 from multiple evaluations. */
4118 static tree
4119 stabilize_va_list (tree valist, int needs_lvalue)
4121 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4123 if (TREE_SIDE_EFFECTS (valist))
4124 valist = save_expr (valist);
4126 /* For this case, the backends will be expecting a pointer to
4127 TREE_TYPE (va_list_type_node), but it's possible we've
4128 actually been given an array (an actual va_list_type_node).
4129 So fix it. */
4130 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4132 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4133 valist = build_fold_addr_expr_with_type (valist, p1);
4136 else
4138 tree pt;
4140 if (! needs_lvalue)
4142 if (! TREE_SIDE_EFFECTS (valist))
4143 return valist;
4145 pt = build_pointer_type (va_list_type_node);
4146 valist = fold_build1 (ADDR_EXPR, pt, valist);
4147 TREE_SIDE_EFFECTS (valist) = 1;
4150 if (TREE_SIDE_EFFECTS (valist))
4151 valist = save_expr (valist);
4152 valist = build_fold_indirect_ref (valist);
4155 return valist;
4158 /* The "standard" definition of va_list is void*. */
4160 tree
4161 std_build_builtin_va_list (void)
4163 return ptr_type_node;
4166 /* The "standard" implementation of va_start: just assign `nextarg' to
4167 the variable. */
4169 void
4170 std_expand_builtin_va_start (tree valist, rtx nextarg)
4172 tree t;
4174 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4175 make_tree (ptr_type_node, nextarg));
4176 TREE_SIDE_EFFECTS (t) = 1;
4178 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4181 /* Expand ARGLIST, from a call to __builtin_va_start. */
4183 static rtx
4184 expand_builtin_va_start (tree arglist)
4186 rtx nextarg;
4187 tree chain, valist;
4189 chain = TREE_CHAIN (arglist);
4191 if (!chain)
4193 error ("too few arguments to function %<va_start%>");
4194 return const0_rtx;
4197 if (fold_builtin_next_arg (chain))
4198 return const0_rtx;
4200 nextarg = expand_builtin_next_arg ();
4201 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4203 #ifdef EXPAND_BUILTIN_VA_START
4204 EXPAND_BUILTIN_VA_START (valist, nextarg);
4205 #else
4206 std_expand_builtin_va_start (valist, nextarg);
4207 #endif
4209 return const0_rtx;
4212 /* The "standard" implementation of va_arg: read the value from the
4213 current (padded) address and increment by the (padded) size. */
4215 tree
4216 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4218 tree addr, t, type_size, rounded_size, valist_tmp;
4219 unsigned HOST_WIDE_INT align, boundary;
4220 bool indirect;
4222 #ifdef ARGS_GROW_DOWNWARD
4223 /* All of the alignment and movement below is for args-grow-up machines.
4224 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4225 implement their own specialized gimplify_va_arg_expr routines. */
4226 gcc_unreachable ();
4227 #endif
4229 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4230 if (indirect)
4231 type = build_pointer_type (type);
4233 align = PARM_BOUNDARY / BITS_PER_UNIT;
4234 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4236 /* Hoist the valist value into a temporary for the moment. */
4237 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4239 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4240 requires greater alignment, we must perform dynamic alignment. */
4241 if (boundary > align
4242 && !integer_zerop (TYPE_SIZE (type)))
4244 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4245 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4246 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4247 gimplify_and_add (t, pre_p);
4249 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4250 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4251 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4252 gimplify_and_add (t, pre_p);
4254 else
4255 boundary = align;
4257 /* If the actual alignment is less than the alignment of the type,
4258 adjust the type accordingly so that we don't assume strict alignment
4259 when deferencing the pointer. */
4260 boundary *= BITS_PER_UNIT;
4261 if (boundary < TYPE_ALIGN (type))
4263 type = build_variant_type_copy (type);
4264 TYPE_ALIGN (type) = boundary;
4267 /* Compute the rounded size of the type. */
4268 type_size = size_in_bytes (type);
4269 rounded_size = round_up (type_size, align);
4271 /* Reduce rounded_size so it's sharable with the postqueue. */
4272 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4274 /* Get AP. */
4275 addr = valist_tmp;
4276 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4278 /* Small args are padded downward. */
4279 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4280 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4281 size_binop (MINUS_EXPR, rounded_size, type_size));
4282 t = fold_convert (TREE_TYPE (addr), t);
4283 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4286 /* Compute new value for AP. */
4287 t = fold_convert (TREE_TYPE (valist), rounded_size);
4288 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4289 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4290 gimplify_and_add (t, pre_p);
4292 addr = fold_convert (build_pointer_type (type), addr);
4294 if (indirect)
4295 addr = build_va_arg_indirect_ref (addr);
4297 return build_va_arg_indirect_ref (addr);
4300 /* Build an indirect-ref expression over the given TREE, which represents a
4301 piece of a va_arg() expansion. */
4302 tree
4303 build_va_arg_indirect_ref (tree addr)
4305 addr = build_fold_indirect_ref (addr);
4307 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4308 mf_mark (addr);
4310 return addr;
4313 /* Return a dummy expression of type TYPE in order to keep going after an
4314 error. */
4316 static tree
4317 dummy_object (tree type)
4319 tree t = build_int_cst (build_pointer_type (type), 0);
4320 return build1 (INDIRECT_REF, type, t);
4323 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4324 builtin function, but a very special sort of operator. */
4326 enum gimplify_status
4327 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4329 tree promoted_type, want_va_type, have_va_type;
4330 tree valist = TREE_OPERAND (*expr_p, 0);
4331 tree type = TREE_TYPE (*expr_p);
4332 tree t;
4334 /* Verify that valist is of the proper type. */
4335 want_va_type = va_list_type_node;
4336 have_va_type = TREE_TYPE (valist);
4338 if (have_va_type == error_mark_node)
4339 return GS_ERROR;
4341 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4343 /* If va_list is an array type, the argument may have decayed
4344 to a pointer type, e.g. by being passed to another function.
4345 In that case, unwrap both types so that we can compare the
4346 underlying records. */
4347 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4348 || POINTER_TYPE_P (have_va_type))
4350 want_va_type = TREE_TYPE (want_va_type);
4351 have_va_type = TREE_TYPE (have_va_type);
4355 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4357 error ("first argument to %<va_arg%> not of type %<va_list%>");
4358 return GS_ERROR;
4361 /* Generate a diagnostic for requesting data of a type that cannot
4362 be passed through `...' due to type promotion at the call site. */
4363 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4364 != type)
4366 static bool gave_help;
4368 /* Unfortunately, this is merely undefined, rather than a constraint
4369 violation, so we cannot make this an error. If this call is never
4370 executed, the program is still strictly conforming. */
4371 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4372 type, promoted_type);
4373 if (! gave_help)
4375 gave_help = true;
4376 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4377 promoted_type, type);
4380 /* We can, however, treat "undefined" any way we please.
4381 Call abort to encourage the user to fix the program. */
4382 inform ("if this code is reached, the program will abort");
4383 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4384 NULL);
4385 append_to_statement_list (t, pre_p);
4387 /* This is dead code, but go ahead and finish so that the
4388 mode of the result comes out right. */
4389 *expr_p = dummy_object (type);
4390 return GS_ALL_DONE;
4392 else
4394 /* Make it easier for the backends by protecting the valist argument
4395 from multiple evaluations. */
4396 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4398 /* For this case, the backends will be expecting a pointer to
4399 TREE_TYPE (va_list_type_node), but it's possible we've
4400 actually been given an array (an actual va_list_type_node).
4401 So fix it. */
4402 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4404 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4405 valist = build_fold_addr_expr_with_type (valist, p1);
4407 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4409 else
4410 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4412 if (!targetm.gimplify_va_arg_expr)
4413 /* FIXME:Once most targets are converted we should merely
4414 assert this is non-null. */
4415 return GS_ALL_DONE;
4417 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4418 return GS_OK;
4422 /* Expand ARGLIST, from a call to __builtin_va_end. */
4424 static rtx
4425 expand_builtin_va_end (tree arglist)
4427 tree valist = TREE_VALUE (arglist);
4429 /* Evaluate for side effects, if needed. I hate macros that don't
4430 do that. */
4431 if (TREE_SIDE_EFFECTS (valist))
4432 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4434 return const0_rtx;
4437 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4438 builtin rather than just as an assignment in stdarg.h because of the
4439 nastiness of array-type va_list types. */
4441 static rtx
4442 expand_builtin_va_copy (tree arglist)
4444 tree dst, src, t;
4446 dst = TREE_VALUE (arglist);
4447 src = TREE_VALUE (TREE_CHAIN (arglist));
4449 dst = stabilize_va_list (dst, 1);
4450 src = stabilize_va_list (src, 0);
4452 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4454 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4455 TREE_SIDE_EFFECTS (t) = 1;
4456 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4458 else
4460 rtx dstb, srcb, size;
4462 /* Evaluate to pointers. */
4463 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4464 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4465 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4466 VOIDmode, EXPAND_NORMAL);
4468 dstb = convert_memory_address (Pmode, dstb);
4469 srcb = convert_memory_address (Pmode, srcb);
4471 /* "Dereference" to BLKmode memories. */
4472 dstb = gen_rtx_MEM (BLKmode, dstb);
4473 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4474 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4475 srcb = gen_rtx_MEM (BLKmode, srcb);
4476 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4477 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4479 /* Copy. */
4480 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4483 return const0_rtx;
4486 /* Expand a call to one of the builtin functions __builtin_frame_address or
4487 __builtin_return_address. */
4489 static rtx
4490 expand_builtin_frame_address (tree fndecl, tree arglist)
4492 /* The argument must be a nonnegative integer constant.
4493 It counts the number of frames to scan up the stack.
4494 The value is the return address saved in that frame. */
4495 if (arglist == 0)
4496 /* Warning about missing arg was already issued. */
4497 return const0_rtx;
4498 else if (! host_integerp (TREE_VALUE (arglist), 1))
4500 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4501 error ("invalid argument to %<__builtin_frame_address%>");
4502 else
4503 error ("invalid argument to %<__builtin_return_address%>");
4504 return const0_rtx;
4506 else
4508 rtx tem
4509 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4510 tree_low_cst (TREE_VALUE (arglist), 1));
4512 /* Some ports cannot access arbitrary stack frames. */
4513 if (tem == NULL)
4515 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4516 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4517 else
4518 warning (0, "unsupported argument to %<__builtin_return_address%>");
4519 return const0_rtx;
4522 /* For __builtin_frame_address, return what we've got. */
4523 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4524 return tem;
4526 if (!REG_P (tem)
4527 && ! CONSTANT_P (tem))
4528 tem = copy_to_mode_reg (Pmode, tem);
4529 return tem;
4533 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4534 we failed and the caller should emit a normal call, otherwise try to get
4535 the result in TARGET, if convenient. */
4537 static rtx
4538 expand_builtin_alloca (tree arglist, rtx target)
4540 rtx op0;
4541 rtx result;
4543 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4544 should always expand to function calls. These can be intercepted
4545 in libmudflap. */
4546 if (flag_mudflap)
4547 return 0;
4549 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4550 return 0;
4552 /* Compute the argument. */
4553 op0 = expand_normal (TREE_VALUE (arglist));
4555 /* Allocate the desired space. */
4556 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4557 result = convert_memory_address (ptr_mode, result);
4559 return result;
4562 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4563 Return 0 if a normal call should be emitted rather than expanding the
4564 function in-line. If convenient, the result should be placed in TARGET.
4565 SUBTARGET may be used as the target for computing one of EXP's operands. */
4567 static rtx
4568 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4569 rtx subtarget, optab op_optab)
4571 rtx op0;
4572 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4573 return 0;
4575 /* Compute the argument. */
4576 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4577 /* Compute op, into TARGET if possible.
4578 Set TARGET to wherever the result comes back. */
4579 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4580 op_optab, op0, target, 1);
4581 gcc_assert (target);
4583 return convert_to_mode (target_mode, target, 0);
4586 /* If the string passed to fputs is a constant and is one character
4587 long, we attempt to transform this call into __builtin_fputc(). */
4589 static rtx
4590 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4592 /* Verify the arguments in the original call. */
4593 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4595 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4596 unlocked, NULL_TREE);
4597 if (result)
4598 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4600 return 0;
4603 /* Expand a call to __builtin_expect. We return our argument and emit a
4604 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4605 a non-jump context. */
4607 static rtx
4608 expand_builtin_expect (tree arglist, rtx target)
4610 tree exp, c;
4611 rtx note, rtx_c;
4613 if (arglist == NULL_TREE
4614 || TREE_CHAIN (arglist) == NULL_TREE)
4615 return const0_rtx;
4616 exp = TREE_VALUE (arglist);
4617 c = TREE_VALUE (TREE_CHAIN (arglist));
4619 if (TREE_CODE (c) != INTEGER_CST)
4621 error ("second argument to %<__builtin_expect%> must be a constant");
4622 c = integer_zero_node;
4625 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4627 /* Don't bother with expected value notes for integral constants. */
4628 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4630 /* We do need to force this into a register so that we can be
4631 moderately sure to be able to correctly interpret the branch
4632 condition later. */
4633 target = force_reg (GET_MODE (target), target);
4635 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4637 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4638 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4641 return target;
4644 /* Like expand_builtin_expect, except do this in a jump context. This is
4645 called from do_jump if the conditional is a __builtin_expect. Return either
4646 a list of insns to emit the jump or NULL if we cannot optimize
4647 __builtin_expect. We need to optimize this at jump time so that machines
4648 like the PowerPC don't turn the test into a SCC operation, and then jump
4649 based on the test being 0/1. */
4652 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4654 tree arglist = TREE_OPERAND (exp, 1);
4655 tree arg0 = TREE_VALUE (arglist);
4656 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4657 rtx ret = NULL_RTX;
4659 /* Only handle __builtin_expect (test, 0) and
4660 __builtin_expect (test, 1). */
4661 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4662 && (integer_zerop (arg1) || integer_onep (arg1)))
4664 rtx insn, drop_through_label, temp;
4666 /* Expand the jump insns. */
4667 start_sequence ();
4668 do_jump (arg0, if_false_label, if_true_label);
4669 ret = get_insns ();
4671 drop_through_label = get_last_insn ();
4672 if (drop_through_label && NOTE_P (drop_through_label))
4673 drop_through_label = prev_nonnote_insn (drop_through_label);
4674 if (drop_through_label && !LABEL_P (drop_through_label))
4675 drop_through_label = NULL_RTX;
4676 end_sequence ();
4678 if (! if_true_label)
4679 if_true_label = drop_through_label;
4680 if (! if_false_label)
4681 if_false_label = drop_through_label;
4683 /* Go through and add the expect's to each of the conditional jumps. */
4684 insn = ret;
4685 while (insn != NULL_RTX)
4687 rtx next = NEXT_INSN (insn);
4689 if (JUMP_P (insn) && any_condjump_p (insn))
4691 rtx ifelse = SET_SRC (pc_set (insn));
4692 rtx then_dest = XEXP (ifelse, 1);
4693 rtx else_dest = XEXP (ifelse, 2);
4694 int taken = -1;
4696 /* First check if we recognize any of the labels. */
4697 if (GET_CODE (then_dest) == LABEL_REF
4698 && XEXP (then_dest, 0) == if_true_label)
4699 taken = 1;
4700 else if (GET_CODE (then_dest) == LABEL_REF
4701 && XEXP (then_dest, 0) == if_false_label)
4702 taken = 0;
4703 else if (GET_CODE (else_dest) == LABEL_REF
4704 && XEXP (else_dest, 0) == if_false_label)
4705 taken = 1;
4706 else if (GET_CODE (else_dest) == LABEL_REF
4707 && XEXP (else_dest, 0) == if_true_label)
4708 taken = 0;
4709 /* Otherwise check where we drop through. */
4710 else if (else_dest == pc_rtx)
4712 if (next && NOTE_P (next))
4713 next = next_nonnote_insn (next);
4715 if (next && JUMP_P (next)
4716 && any_uncondjump_p (next))
4717 temp = XEXP (SET_SRC (pc_set (next)), 0);
4718 else
4719 temp = next;
4721 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4722 else that can't possibly match either target label. */
4723 if (temp == if_false_label)
4724 taken = 1;
4725 else if (temp == if_true_label)
4726 taken = 0;
4728 else if (then_dest == pc_rtx)
4730 if (next && NOTE_P (next))
4731 next = next_nonnote_insn (next);
4733 if (next && JUMP_P (next)
4734 && any_uncondjump_p (next))
4735 temp = XEXP (SET_SRC (pc_set (next)), 0);
4736 else
4737 temp = next;
4739 if (temp == if_false_label)
4740 taken = 0;
4741 else if (temp == if_true_label)
4742 taken = 1;
4745 if (taken != -1)
4747 /* If the test is expected to fail, reverse the
4748 probabilities. */
4749 if (integer_zerop (arg1))
4750 taken = 1 - taken;
4751 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4755 insn = next;
4759 return ret;
4762 void
4763 expand_builtin_trap (void)
4765 #ifdef HAVE_trap
4766 if (HAVE_trap)
4767 emit_insn (gen_trap ());
4768 else
4769 #endif
4770 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4771 emit_barrier ();
4774 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4775 Return 0 if a normal call should be emitted rather than expanding
4776 the function inline. If convenient, the result should be placed
4777 in TARGET. SUBTARGET may be used as the target for computing
4778 the operand. */
4780 static rtx
4781 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4783 enum machine_mode mode;
4784 tree arg;
4785 rtx op0;
4787 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4788 return 0;
4790 arg = TREE_VALUE (arglist);
4791 mode = TYPE_MODE (TREE_TYPE (arg));
4792 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4793 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4796 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4797 Return NULL is a normal call should be emitted rather than expanding the
4798 function inline. If convenient, the result should be placed in TARGET.
4799 SUBTARGET may be used as the target for computing the operand. */
4801 static rtx
4802 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4804 rtx op0, op1;
4805 tree arg;
4807 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4808 return 0;
4810 arg = TREE_VALUE (arglist);
4811 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4813 arg = TREE_VALUE (TREE_CHAIN (arglist));
4814 op1 = expand_normal (arg);
4816 return expand_copysign (op0, op1, target);
4819 /* Create a new constant string literal and return a char* pointer to it.
4820 The STRING_CST value is the LEN characters at STR. */
4821 tree
4822 build_string_literal (int len, const char *str)
4824 tree t, elem, index, type;
4826 t = build_string (len, str);
4827 elem = build_type_variant (char_type_node, 1, 0);
4828 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4829 type = build_array_type (elem, index);
4830 TREE_TYPE (t) = type;
4831 TREE_CONSTANT (t) = 1;
4832 TREE_INVARIANT (t) = 1;
4833 TREE_READONLY (t) = 1;
4834 TREE_STATIC (t) = 1;
4836 type = build_pointer_type (type);
4837 t = build1 (ADDR_EXPR, type, t);
4839 type = build_pointer_type (elem);
4840 t = build1 (NOP_EXPR, type, t);
4841 return t;
4844 /* Expand EXP, a call to printf or printf_unlocked.
4845 Return 0 if a normal call should be emitted rather than transforming
4846 the function inline. If convenient, the result should be placed in
4847 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4848 call. */
4849 static rtx
4850 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4851 bool unlocked)
4853 tree arglist = TREE_OPERAND (exp, 1);
4854 /* If we're using an unlocked function, assume the other unlocked
4855 functions exist explicitly. */
4856 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4857 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4858 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4859 : implicit_built_in_decls[BUILT_IN_PUTS];
4860 const char *fmt_str;
4861 tree fn, fmt, arg;
4863 /* If the return value is used, don't do the transformation. */
4864 if (target != const0_rtx)
4865 return 0;
4867 /* Verify the required arguments in the original call. */
4868 if (! arglist)
4869 return 0;
4870 fmt = TREE_VALUE (arglist);
4871 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4872 return 0;
4873 arglist = TREE_CHAIN (arglist);
4875 /* Check whether the format is a literal string constant. */
4876 fmt_str = c_getstr (fmt);
4877 if (fmt_str == NULL)
4878 return 0;
4880 if (!init_target_chars())
4881 return 0;
4883 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4884 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4886 if (! arglist
4887 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4888 || TREE_CHAIN (arglist))
4889 return 0;
4890 fn = fn_puts;
4892 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4893 else if (strcmp (fmt_str, target_percent_c) == 0)
4895 if (! arglist
4896 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4897 || TREE_CHAIN (arglist))
4898 return 0;
4899 fn = fn_putchar;
4901 else
4903 /* We can't handle anything else with % args or %% ... yet. */
4904 if (strchr (fmt_str, target_percent))
4905 return 0;
4907 if (arglist)
4908 return 0;
4910 /* If the format specifier was "", printf does nothing. */
4911 if (fmt_str[0] == '\0')
4912 return const0_rtx;
4913 /* If the format specifier has length of 1, call putchar. */
4914 if (fmt_str[1] == '\0')
4916 /* Given printf("c"), (where c is any one character,)
4917 convert "c"[0] to an int and pass that to the replacement
4918 function. */
4919 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4920 arglist = build_tree_list (NULL_TREE, arg);
4921 fn = fn_putchar;
4923 else
4925 /* If the format specifier was "string\n", call puts("string"). */
4926 size_t len = strlen (fmt_str);
4927 if ((unsigned char)fmt_str[len - 1] == target_newline)
4929 /* Create a NUL-terminated string that's one char shorter
4930 than the original, stripping off the trailing '\n'. */
4931 char *newstr = alloca (len);
4932 memcpy (newstr, fmt_str, len - 1);
4933 newstr[len - 1] = 0;
4935 arg = build_string_literal (len, newstr);
4936 arglist = build_tree_list (NULL_TREE, arg);
4937 fn = fn_puts;
4939 else
4940 /* We'd like to arrange to call fputs(string,stdout) here,
4941 but we need stdout and don't have a way to get it yet. */
4942 return 0;
4946 if (!fn)
4947 return 0;
4948 fn = build_function_call_expr (fn, arglist);
4949 if (TREE_CODE (fn) == CALL_EXPR)
4950 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4951 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4954 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4955 Return 0 if a normal call should be emitted rather than transforming
4956 the function inline. If convenient, the result should be placed in
4957 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4958 call. */
4959 static rtx
4960 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4961 bool unlocked)
4963 tree arglist = TREE_OPERAND (exp, 1);
4964 /* If we're using an unlocked function, assume the other unlocked
4965 functions exist explicitly. */
4966 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4967 : implicit_built_in_decls[BUILT_IN_FPUTC];
4968 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4969 : implicit_built_in_decls[BUILT_IN_FPUTS];
4970 const char *fmt_str;
4971 tree fn, fmt, fp, arg;
4973 /* If the return value is used, don't do the transformation. */
4974 if (target != const0_rtx)
4975 return 0;
4977 /* Verify the required arguments in the original call. */
4978 if (! arglist)
4979 return 0;
4980 fp = TREE_VALUE (arglist);
4981 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4982 return 0;
4983 arglist = TREE_CHAIN (arglist);
4984 if (! arglist)
4985 return 0;
4986 fmt = TREE_VALUE (arglist);
4987 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4988 return 0;
4989 arglist = TREE_CHAIN (arglist);
4991 /* Check whether the format is a literal string constant. */
4992 fmt_str = c_getstr (fmt);
4993 if (fmt_str == NULL)
4994 return 0;
4996 if (!init_target_chars())
4997 return 0;
4999 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5000 if (strcmp (fmt_str, target_percent_s) == 0)
5002 if (! arglist
5003 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5004 || TREE_CHAIN (arglist))
5005 return 0;
5006 arg = TREE_VALUE (arglist);
5007 arglist = build_tree_list (NULL_TREE, fp);
5008 arglist = tree_cons (NULL_TREE, arg, arglist);
5009 fn = fn_fputs;
5011 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5012 else if (strcmp (fmt_str, target_percent_c) == 0)
5014 if (! arglist
5015 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5016 || TREE_CHAIN (arglist))
5017 return 0;
5018 arg = TREE_VALUE (arglist);
5019 arglist = build_tree_list (NULL_TREE, fp);
5020 arglist = tree_cons (NULL_TREE, arg, arglist);
5021 fn = fn_fputc;
5023 else
5025 /* We can't handle anything else with % args or %% ... yet. */
5026 if (strchr (fmt_str, target_percent))
5027 return 0;
5029 if (arglist)
5030 return 0;
5032 /* If the format specifier was "", fprintf does nothing. */
5033 if (fmt_str[0] == '\0')
5035 /* Evaluate and ignore FILE* argument for side-effects. */
5036 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5037 return const0_rtx;
5040 /* When "string" doesn't contain %, replace all cases of
5041 fprintf(stream,string) with fputs(string,stream). The fputs
5042 builtin will take care of special cases like length == 1. */
5043 arglist = build_tree_list (NULL_TREE, fp);
5044 arglist = tree_cons (NULL_TREE, fmt, arglist);
5045 fn = fn_fputs;
5048 if (!fn)
5049 return 0;
5050 fn = build_function_call_expr (fn, arglist);
5051 if (TREE_CODE (fn) == CALL_EXPR)
5052 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5053 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5056 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5057 a normal call should be emitted rather than expanding the function
5058 inline. If convenient, the result should be placed in TARGET with
5059 mode MODE. */
5061 static rtx
5062 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5064 tree orig_arglist, dest, fmt;
5065 const char *fmt_str;
5067 orig_arglist = arglist;
5069 /* Verify the required arguments in the original call. */
5070 if (! arglist)
5071 return 0;
5072 dest = TREE_VALUE (arglist);
5073 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5074 return 0;
5075 arglist = TREE_CHAIN (arglist);
5076 if (! arglist)
5077 return 0;
5078 fmt = TREE_VALUE (arglist);
5079 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5080 return 0;
5081 arglist = TREE_CHAIN (arglist);
5083 /* Check whether the format is a literal string constant. */
5084 fmt_str = c_getstr (fmt);
5085 if (fmt_str == NULL)
5086 return 0;
5088 if (!init_target_chars())
5089 return 0;
5091 /* If the format doesn't contain % args or %%, use strcpy. */
5092 if (strchr (fmt_str, target_percent) == 0)
5094 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5095 tree exp;
5097 if (arglist || ! fn)
5098 return 0;
5099 expand_expr (build_function_call_expr (fn, orig_arglist),
5100 const0_rtx, VOIDmode, EXPAND_NORMAL);
5101 if (target == const0_rtx)
5102 return const0_rtx;
5103 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5104 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5106 /* If the format is "%s", use strcpy if the result isn't used. */
5107 else if (strcmp (fmt_str, target_percent_s) == 0)
5109 tree fn, arg, len;
5110 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5112 if (! fn)
5113 return 0;
5115 if (! arglist || TREE_CHAIN (arglist))
5116 return 0;
5117 arg = TREE_VALUE (arglist);
5118 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5119 return 0;
5121 if (target != const0_rtx)
5123 len = c_strlen (arg, 1);
5124 if (! len || TREE_CODE (len) != INTEGER_CST)
5125 return 0;
5127 else
5128 len = NULL_TREE;
5130 arglist = build_tree_list (NULL_TREE, arg);
5131 arglist = tree_cons (NULL_TREE, dest, arglist);
5132 expand_expr (build_function_call_expr (fn, arglist),
5133 const0_rtx, VOIDmode, EXPAND_NORMAL);
5135 if (target == const0_rtx)
5136 return const0_rtx;
5137 return expand_expr (len, target, mode, EXPAND_NORMAL);
5140 return 0;
5143 /* Expand a call to either the entry or exit function profiler. */
5145 static rtx
5146 expand_builtin_profile_func (bool exitp)
5148 rtx this, which;
5150 this = DECL_RTL (current_function_decl);
5151 gcc_assert (MEM_P (this));
5152 this = XEXP (this, 0);
5154 if (exitp)
5155 which = profile_function_exit_libfunc;
5156 else
5157 which = profile_function_entry_libfunc;
5159 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5160 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5162 Pmode);
5164 return const0_rtx;
5167 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5169 static rtx
5170 round_trampoline_addr (rtx tramp)
5172 rtx temp, addend, mask;
5174 /* If we don't need too much alignment, we'll have been guaranteed
5175 proper alignment by get_trampoline_type. */
5176 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5177 return tramp;
5179 /* Round address up to desired boundary. */
5180 temp = gen_reg_rtx (Pmode);
5181 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5182 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5184 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5185 temp, 0, OPTAB_LIB_WIDEN);
5186 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5187 temp, 0, OPTAB_LIB_WIDEN);
5189 return tramp;
5192 static rtx
5193 expand_builtin_init_trampoline (tree arglist)
5195 tree t_tramp, t_func, t_chain;
5196 rtx r_tramp, r_func, r_chain;
5197 #ifdef TRAMPOLINE_TEMPLATE
5198 rtx blktramp;
5199 #endif
5201 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5202 POINTER_TYPE, VOID_TYPE))
5203 return NULL_RTX;
5205 t_tramp = TREE_VALUE (arglist);
5206 arglist = TREE_CHAIN (arglist);
5207 t_func = TREE_VALUE (arglist);
5208 arglist = TREE_CHAIN (arglist);
5209 t_chain = TREE_VALUE (arglist);
5211 r_tramp = expand_normal (t_tramp);
5212 r_func = expand_normal (t_func);
5213 r_chain = expand_normal (t_chain);
5215 /* Generate insns to initialize the trampoline. */
5216 r_tramp = round_trampoline_addr (r_tramp);
5217 #ifdef TRAMPOLINE_TEMPLATE
5218 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5219 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5220 emit_block_move (blktramp, assemble_trampoline_template (),
5221 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5222 #endif
5223 trampolines_created = 1;
5224 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5226 return const0_rtx;
5229 static rtx
5230 expand_builtin_adjust_trampoline (tree arglist)
5232 rtx tramp;
5234 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5235 return NULL_RTX;
5237 tramp = expand_normal (TREE_VALUE (arglist));
5238 tramp = round_trampoline_addr (tramp);
5239 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5240 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5241 #endif
5243 return tramp;
5246 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5247 Return NULL_RTX if a normal call should be emitted rather than expanding
5248 the function in-line. EXP is the expression that is a call to the builtin
5249 function; if convenient, the result should be placed in TARGET. */
5251 static rtx
5252 expand_builtin_signbit (tree exp, rtx target)
5254 const struct real_format *fmt;
5255 enum machine_mode fmode, imode, rmode;
5256 HOST_WIDE_INT hi, lo;
5257 tree arg, arglist;
5258 int word, bitpos;
5259 rtx temp;
5261 arglist = TREE_OPERAND (exp, 1);
5262 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5263 return 0;
5265 arg = TREE_VALUE (arglist);
5266 fmode = TYPE_MODE (TREE_TYPE (arg));
5267 rmode = TYPE_MODE (TREE_TYPE (exp));
5268 fmt = REAL_MODE_FORMAT (fmode);
5270 /* For floating point formats without a sign bit, implement signbit
5271 as "ARG < 0.0". */
5272 bitpos = fmt->signbit_ro;
5273 if (bitpos < 0)
5275 /* But we can't do this if the format supports signed zero. */
5276 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5277 return 0;
5279 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5280 build_real (TREE_TYPE (arg), dconst0));
5281 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5284 temp = expand_normal (arg);
5285 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5287 imode = int_mode_for_mode (fmode);
5288 if (imode == BLKmode)
5289 return 0;
5290 temp = gen_lowpart (imode, temp);
5292 else
5294 imode = word_mode;
5295 /* Handle targets with different FP word orders. */
5296 if (FLOAT_WORDS_BIG_ENDIAN)
5297 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5298 else
5299 word = bitpos / BITS_PER_WORD;
5300 temp = operand_subword_force (temp, word, fmode);
5301 bitpos = bitpos % BITS_PER_WORD;
5304 /* Force the intermediate word_mode (or narrower) result into a
5305 register. This avoids attempting to create paradoxical SUBREGs
5306 of floating point modes below. */
5307 temp = force_reg (imode, temp);
5309 /* If the bitpos is within the "result mode" lowpart, the operation
5310 can be implement with a single bitwise AND. Otherwise, we need
5311 a right shift and an AND. */
5313 if (bitpos < GET_MODE_BITSIZE (rmode))
5315 if (bitpos < HOST_BITS_PER_WIDE_INT)
5317 hi = 0;
5318 lo = (HOST_WIDE_INT) 1 << bitpos;
5320 else
5322 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5323 lo = 0;
5326 if (imode != rmode)
5327 temp = gen_lowpart (rmode, temp);
5328 temp = expand_binop (rmode, and_optab, temp,
5329 immed_double_const (lo, hi, rmode),
5330 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5332 else
5334 /* Perform a logical right shift to place the signbit in the least
5335 significant bit, then truncate the result to the desired mode
5336 and mask just this bit. */
5337 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5338 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5339 temp = gen_lowpart (rmode, temp);
5340 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5341 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5344 return temp;
5347 /* Expand fork or exec calls. TARGET is the desired target of the
5348 call. ARGLIST is the list of arguments of the call. FN is the
5349 identificator of the actual function. IGNORE is nonzero if the
5350 value is to be ignored. */
5352 static rtx
5353 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5355 tree id, decl;
5356 tree call;
5358 /* If we are not profiling, just call the function. */
5359 if (!profile_arc_flag)
5360 return NULL_RTX;
5362 /* Otherwise call the wrapper. This should be equivalent for the rest of
5363 compiler, so the code does not diverge, and the wrapper may run the
5364 code necessary for keeping the profiling sane. */
5366 switch (DECL_FUNCTION_CODE (fn))
5368 case BUILT_IN_FORK:
5369 id = get_identifier ("__gcov_fork");
5370 break;
5372 case BUILT_IN_EXECL:
5373 id = get_identifier ("__gcov_execl");
5374 break;
5376 case BUILT_IN_EXECV:
5377 id = get_identifier ("__gcov_execv");
5378 break;
5380 case BUILT_IN_EXECLP:
5381 id = get_identifier ("__gcov_execlp");
5382 break;
5384 case BUILT_IN_EXECLE:
5385 id = get_identifier ("__gcov_execle");
5386 break;
5388 case BUILT_IN_EXECVP:
5389 id = get_identifier ("__gcov_execvp");
5390 break;
5392 case BUILT_IN_EXECVE:
5393 id = get_identifier ("__gcov_execve");
5394 break;
5396 default:
5397 gcc_unreachable ();
5400 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5401 DECL_EXTERNAL (decl) = 1;
5402 TREE_PUBLIC (decl) = 1;
5403 DECL_ARTIFICIAL (decl) = 1;
5404 TREE_NOTHROW (decl) = 1;
5405 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5406 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5407 call = build_function_call_expr (decl, arglist);
5409 return expand_call (call, target, ignore);
5413 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5414 the pointer in these functions is void*, the tree optimizers may remove
5415 casts. The mode computed in expand_builtin isn't reliable either, due
5416 to __sync_bool_compare_and_swap.
5418 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5419 group of builtins. This gives us log2 of the mode size. */
5421 static inline enum machine_mode
5422 get_builtin_sync_mode (int fcode_diff)
5424 /* The size is not negotiable, so ask not to get BLKmode in return
5425 if the target indicates that a smaller size would be better. */
5426 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5429 /* Expand the memory expression LOC and return the appropriate memory operand
5430 for the builtin_sync operations. */
5432 static rtx
5433 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5435 rtx addr, mem;
5437 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5439 /* Note that we explicitly do not want any alias information for this
5440 memory, so that we kill all other live memories. Otherwise we don't
5441 satisfy the full barrier semantics of the intrinsic. */
5442 mem = validize_mem (gen_rtx_MEM (mode, addr));
5444 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5445 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5446 MEM_VOLATILE_P (mem) = 1;
5448 return mem;
5451 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5452 ARGLIST is the operands list to the function. CODE is the rtx code
5453 that corresponds to the arithmetic or logical operation from the name;
5454 an exception here is that NOT actually means NAND. TARGET is an optional
5455 place for us to store the results; AFTER is true if this is the
5456 fetch_and_xxx form. IGNORE is true if we don't actually care about
5457 the result of the operation at all. */
5459 static rtx
5460 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5461 enum rtx_code code, bool after,
5462 rtx target, bool ignore)
5464 rtx val, mem;
5466 /* Expand the operands. */
5467 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5469 arglist = TREE_CHAIN (arglist);
5470 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5472 if (ignore)
5473 return expand_sync_operation (mem, val, code);
5474 else
5475 return expand_sync_fetch_operation (mem, val, code, after, target);
5478 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5479 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5480 true if this is the boolean form. TARGET is a place for us to store the
5481 results; this is NOT optional if IS_BOOL is true. */
5483 static rtx
5484 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5485 bool is_bool, rtx target)
5487 rtx old_val, new_val, mem;
5489 /* Expand the operands. */
5490 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5492 arglist = TREE_CHAIN (arglist);
5493 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5495 arglist = TREE_CHAIN (arglist);
5496 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5498 if (is_bool)
5499 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5500 else
5501 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5504 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5505 general form is actually an atomic exchange, and some targets only
5506 support a reduced form with the second argument being a constant 1.
5507 ARGLIST is the operands list to the function; TARGET is an optional
5508 place for us to store the results. */
5510 static rtx
5511 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5512 rtx target)
5514 rtx val, mem;
5516 /* Expand the operands. */
5517 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5519 arglist = TREE_CHAIN (arglist);
5520 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5522 return expand_sync_lock_test_and_set (mem, val, target);
5525 /* Expand the __sync_synchronize intrinsic. */
5527 static void
5528 expand_builtin_synchronize (void)
5530 tree x;
5532 #ifdef HAVE_memory_barrier
5533 if (HAVE_memory_barrier)
5535 emit_insn (gen_memory_barrier ());
5536 return;
5538 #endif
5540 /* If no explicit memory barrier instruction is available, create an
5541 empty asm stmt with a memory clobber. */
5542 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5543 tree_cons (NULL, build_string (6, "memory"), NULL));
5544 ASM_VOLATILE_P (x) = 1;
5545 expand_asm_expr (x);
5548 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5549 to the function. */
5551 static void
5552 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5554 enum insn_code icode;
5555 rtx mem, insn;
5556 rtx val = const0_rtx;
5558 /* Expand the operands. */
5559 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5561 /* If there is an explicit operation in the md file, use it. */
5562 icode = sync_lock_release[mode];
5563 if (icode != CODE_FOR_nothing)
5565 if (!insn_data[icode].operand[1].predicate (val, mode))
5566 val = force_reg (mode, val);
5568 insn = GEN_FCN (icode) (mem, val);
5569 if (insn)
5571 emit_insn (insn);
5572 return;
5576 /* Otherwise we can implement this operation by emitting a barrier
5577 followed by a store of zero. */
5578 expand_builtin_synchronize ();
5579 emit_move_insn (mem, val);
5582 /* Expand an expression EXP that calls a built-in function,
5583 with result going to TARGET if that's convenient
5584 (and in mode MODE if that's convenient).
5585 SUBTARGET may be used as the target for computing one of EXP's operands.
5586 IGNORE is nonzero if the value is to be ignored. */
5589 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5590 int ignore)
5592 tree fndecl = get_callee_fndecl (exp);
5593 tree arglist = TREE_OPERAND (exp, 1);
5594 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5595 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5597 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5598 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5599 else
5601 /* Try expanding the builtin via the generic target hook. */
5602 rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
5603 mode, ignore);
5604 if (tmp != NULL_RTX)
5605 return tmp;
5608 /* When not optimizing, generate calls to library functions for a certain
5609 set of builtins. */
5610 if (!optimize
5611 && !called_as_built_in (fndecl)
5612 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5613 && fcode != BUILT_IN_ALLOCA)
5614 return expand_call (exp, target, ignore);
5616 /* The built-in function expanders test for target == const0_rtx
5617 to determine whether the function's result will be ignored. */
5618 if (ignore)
5619 target = const0_rtx;
5621 /* If the result of a pure or const built-in function is ignored, and
5622 none of its arguments are volatile, we can avoid expanding the
5623 built-in call and just evaluate the arguments for side-effects. */
5624 if (target == const0_rtx
5625 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5627 bool volatilep = false;
5628 tree arg;
5630 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5631 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5633 volatilep = true;
5634 break;
5637 if (! volatilep)
5639 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5640 expand_expr (TREE_VALUE (arg), const0_rtx,
5641 VOIDmode, EXPAND_NORMAL);
5642 return const0_rtx;
5646 switch (fcode)
5648 CASE_FLT_FN (BUILT_IN_FABS):
5649 target = expand_builtin_fabs (arglist, target, subtarget);
5650 if (target)
5651 return target;
5652 break;
5654 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5655 target = expand_builtin_copysign (arglist, target, subtarget);
5656 if (target)
5657 return target;
5658 break;
5660 /* Just do a normal library call if we were unable to fold
5661 the values. */
5662 CASE_FLT_FN (BUILT_IN_CABS):
5663 break;
5665 CASE_FLT_FN (BUILT_IN_EXP):
5666 CASE_FLT_FN (BUILT_IN_EXP10):
5667 CASE_FLT_FN (BUILT_IN_POW10):
5668 CASE_FLT_FN (BUILT_IN_EXP2):
5669 CASE_FLT_FN (BUILT_IN_EXPM1):
5670 CASE_FLT_FN (BUILT_IN_LOGB):
5671 CASE_FLT_FN (BUILT_IN_ILOGB):
5672 CASE_FLT_FN (BUILT_IN_LOG):
5673 CASE_FLT_FN (BUILT_IN_LOG10):
5674 CASE_FLT_FN (BUILT_IN_LOG2):
5675 CASE_FLT_FN (BUILT_IN_LOG1P):
5676 CASE_FLT_FN (BUILT_IN_TAN):
5677 CASE_FLT_FN (BUILT_IN_ASIN):
5678 CASE_FLT_FN (BUILT_IN_ACOS):
5679 CASE_FLT_FN (BUILT_IN_ATAN):
5680 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5681 because of possible accuracy problems. */
5682 if (! flag_unsafe_math_optimizations)
5683 break;
5684 CASE_FLT_FN (BUILT_IN_SQRT):
5685 CASE_FLT_FN (BUILT_IN_FLOOR):
5686 CASE_FLT_FN (BUILT_IN_CEIL):
5687 CASE_FLT_FN (BUILT_IN_TRUNC):
5688 CASE_FLT_FN (BUILT_IN_ROUND):
5689 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5690 CASE_FLT_FN (BUILT_IN_RINT):
5691 CASE_FLT_FN (BUILT_IN_LRINT):
5692 CASE_FLT_FN (BUILT_IN_LLRINT):
5693 target = expand_builtin_mathfn (exp, target, subtarget);
5694 if (target)
5695 return target;
5696 break;
5698 CASE_FLT_FN (BUILT_IN_LCEIL):
5699 CASE_FLT_FN (BUILT_IN_LLCEIL):
5700 CASE_FLT_FN (BUILT_IN_LFLOOR):
5701 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5702 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5703 if (target)
5704 return target;
5705 break;
5707 CASE_FLT_FN (BUILT_IN_POW):
5708 target = expand_builtin_pow (exp, target, subtarget);
5709 if (target)
5710 return target;
5711 break;
5713 CASE_FLT_FN (BUILT_IN_POWI):
5714 target = expand_builtin_powi (exp, target, subtarget);
5715 if (target)
5716 return target;
5717 break;
5719 CASE_FLT_FN (BUILT_IN_ATAN2):
5720 CASE_FLT_FN (BUILT_IN_LDEXP):
5721 CASE_FLT_FN (BUILT_IN_FMOD):
5722 CASE_FLT_FN (BUILT_IN_DREM):
5723 if (! flag_unsafe_math_optimizations)
5724 break;
5725 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5726 if (target)
5727 return target;
5728 break;
5730 CASE_FLT_FN (BUILT_IN_SIN):
5731 CASE_FLT_FN (BUILT_IN_COS):
5732 if (! flag_unsafe_math_optimizations)
5733 break;
5734 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5735 if (target)
5736 return target;
5737 break;
5739 CASE_FLT_FN (BUILT_IN_SINCOS):
5740 if (! flag_unsafe_math_optimizations)
5741 break;
5742 target = expand_builtin_sincos (exp);
5743 if (target)
5744 return target;
5745 break;
5747 case BUILT_IN_APPLY_ARGS:
5748 return expand_builtin_apply_args ();
5750 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5751 FUNCTION with a copy of the parameters described by
5752 ARGUMENTS, and ARGSIZE. It returns a block of memory
5753 allocated on the stack into which is stored all the registers
5754 that might possibly be used for returning the result of a
5755 function. ARGUMENTS is the value returned by
5756 __builtin_apply_args. ARGSIZE is the number of bytes of
5757 arguments that must be copied. ??? How should this value be
5758 computed? We'll also need a safe worst case value for varargs
5759 functions. */
5760 case BUILT_IN_APPLY:
5761 if (!validate_arglist (arglist, POINTER_TYPE,
5762 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5763 && !validate_arglist (arglist, REFERENCE_TYPE,
5764 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5765 return const0_rtx;
5766 else
5768 int i;
5769 tree t;
5770 rtx ops[3];
5772 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5773 ops[i] = expand_normal (TREE_VALUE (t));
5775 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5778 /* __builtin_return (RESULT) causes the function to return the
5779 value described by RESULT. RESULT is address of the block of
5780 memory returned by __builtin_apply. */
5781 case BUILT_IN_RETURN:
5782 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5783 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5784 return const0_rtx;
5786 case BUILT_IN_SAVEREGS:
5787 return expand_builtin_saveregs ();
5789 case BUILT_IN_ARGS_INFO:
5790 return expand_builtin_args_info (arglist);
5792 /* Return the address of the first anonymous stack arg. */
5793 case BUILT_IN_NEXT_ARG:
5794 if (fold_builtin_next_arg (arglist))
5795 return const0_rtx;
5796 return expand_builtin_next_arg ();
5798 case BUILT_IN_CLASSIFY_TYPE:
5799 return expand_builtin_classify_type (arglist);
5801 case BUILT_IN_CONSTANT_P:
5802 return const0_rtx;
5804 case BUILT_IN_FRAME_ADDRESS:
5805 case BUILT_IN_RETURN_ADDRESS:
5806 return expand_builtin_frame_address (fndecl, arglist);
5808 /* Returns the address of the area where the structure is returned.
5809 0 otherwise. */
5810 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5811 if (arglist != 0
5812 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5813 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5814 return const0_rtx;
5815 else
5816 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5818 case BUILT_IN_ALLOCA:
5819 target = expand_builtin_alloca (arglist, target);
5820 if (target)
5821 return target;
5822 break;
5824 case BUILT_IN_STACK_SAVE:
5825 return expand_stack_save ();
5827 case BUILT_IN_STACK_RESTORE:
5828 expand_stack_restore (TREE_VALUE (arglist));
5829 return const0_rtx;
5831 CASE_INT_FN (BUILT_IN_FFS):
5832 case BUILT_IN_FFSIMAX:
5833 target = expand_builtin_unop (target_mode, arglist, target,
5834 subtarget, ffs_optab);
5835 if (target)
5836 return target;
5837 break;
5839 CASE_INT_FN (BUILT_IN_CLZ):
5840 case BUILT_IN_CLZIMAX:
5841 target = expand_builtin_unop (target_mode, arglist, target,
5842 subtarget, clz_optab);
5843 if (target)
5844 return target;
5845 break;
5847 CASE_INT_FN (BUILT_IN_CTZ):
5848 case BUILT_IN_CTZIMAX:
5849 target = expand_builtin_unop (target_mode, arglist, target,
5850 subtarget, ctz_optab);
5851 if (target)
5852 return target;
5853 break;
5855 CASE_INT_FN (BUILT_IN_POPCOUNT):
5856 case BUILT_IN_POPCOUNTIMAX:
5857 target = expand_builtin_unop (target_mode, arglist, target,
5858 subtarget, popcount_optab);
5859 if (target)
5860 return target;
5861 break;
5863 CASE_INT_FN (BUILT_IN_PARITY):
5864 case BUILT_IN_PARITYIMAX:
5865 target = expand_builtin_unop (target_mode, arglist, target,
5866 subtarget, parity_optab);
5867 if (target)
5868 return target;
5869 break;
5871 case BUILT_IN_STRLEN:
5872 target = expand_builtin_strlen (arglist, target, target_mode);
5873 if (target)
5874 return target;
5875 break;
5877 case BUILT_IN_STRCPY:
5878 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5879 if (target)
5880 return target;
5881 break;
5883 case BUILT_IN_STRNCPY:
5884 target = expand_builtin_strncpy (exp, target, mode);
5885 if (target)
5886 return target;
5887 break;
5889 case BUILT_IN_STPCPY:
5890 target = expand_builtin_stpcpy (exp, target, mode);
5891 if (target)
5892 return target;
5893 break;
5895 case BUILT_IN_STRCAT:
5896 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5897 if (target)
5898 return target;
5899 break;
5901 case BUILT_IN_STRNCAT:
5902 target = expand_builtin_strncat (arglist, target, mode);
5903 if (target)
5904 return target;
5905 break;
5907 case BUILT_IN_STRSPN:
5908 target = expand_builtin_strspn (arglist, target, mode);
5909 if (target)
5910 return target;
5911 break;
5913 case BUILT_IN_STRCSPN:
5914 target = expand_builtin_strcspn (arglist, target, mode);
5915 if (target)
5916 return target;
5917 break;
5919 case BUILT_IN_STRSTR:
5920 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5921 if (target)
5922 return target;
5923 break;
5925 case BUILT_IN_STRPBRK:
5926 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5927 if (target)
5928 return target;
5929 break;
5931 case BUILT_IN_INDEX:
5932 case BUILT_IN_STRCHR:
5933 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5934 if (target)
5935 return target;
5936 break;
5938 case BUILT_IN_RINDEX:
5939 case BUILT_IN_STRRCHR:
5940 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5941 if (target)
5942 return target;
5943 break;
5945 case BUILT_IN_MEMCPY:
5946 target = expand_builtin_memcpy (exp, target, mode);
5947 if (target)
5948 return target;
5949 break;
5951 case BUILT_IN_MEMPCPY:
5952 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_MEMMOVE:
5958 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5959 mode, exp);
5960 if (target)
5961 return target;
5962 break;
5964 case BUILT_IN_BCOPY:
5965 target = expand_builtin_bcopy (exp);
5966 if (target)
5967 return target;
5968 break;
5970 case BUILT_IN_MEMSET:
5971 target = expand_builtin_memset (arglist, target, mode, exp);
5972 if (target)
5973 return target;
5974 break;
5976 case BUILT_IN_BZERO:
5977 target = expand_builtin_bzero (exp);
5978 if (target)
5979 return target;
5980 break;
5982 case BUILT_IN_STRCMP:
5983 target = expand_builtin_strcmp (exp, target, mode);
5984 if (target)
5985 return target;
5986 break;
5988 case BUILT_IN_STRNCMP:
5989 target = expand_builtin_strncmp (exp, target, mode);
5990 if (target)
5991 return target;
5992 break;
5994 case BUILT_IN_BCMP:
5995 case BUILT_IN_MEMCMP:
5996 target = expand_builtin_memcmp (exp, arglist, target, mode);
5997 if (target)
5998 return target;
5999 break;
6001 case BUILT_IN_SETJMP:
6002 target = expand_builtin_setjmp (arglist, target);
6003 if (target)
6004 return target;
6005 break;
6007 /* __builtin_longjmp is passed a pointer to an array of five words.
6008 It's similar to the C library longjmp function but works with
6009 __builtin_setjmp above. */
6010 case BUILT_IN_LONGJMP:
6011 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6012 break;
6013 else
6015 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6016 VOIDmode, EXPAND_NORMAL);
6017 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6019 if (value != const1_rtx)
6021 error ("%<__builtin_longjmp%> second argument must be 1");
6022 return const0_rtx;
6025 expand_builtin_longjmp (buf_addr, value);
6026 return const0_rtx;
6029 case BUILT_IN_NONLOCAL_GOTO:
6030 target = expand_builtin_nonlocal_goto (arglist);
6031 if (target)
6032 return target;
6033 break;
6035 /* This updates the setjmp buffer that is its argument with the value
6036 of the current stack pointer. */
6037 case BUILT_IN_UPDATE_SETJMP_BUF:
6038 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6040 rtx buf_addr
6041 = expand_normal (TREE_VALUE (arglist));
6043 expand_builtin_update_setjmp_buf (buf_addr);
6044 return const0_rtx;
6046 break;
6048 case BUILT_IN_TRAP:
6049 expand_builtin_trap ();
6050 return const0_rtx;
6052 case BUILT_IN_PRINTF:
6053 target = expand_builtin_printf (exp, target, mode, false);
6054 if (target)
6055 return target;
6056 break;
6058 case BUILT_IN_PRINTF_UNLOCKED:
6059 target = expand_builtin_printf (exp, target, mode, true);
6060 if (target)
6061 return target;
6062 break;
6064 case BUILT_IN_FPUTS:
6065 target = expand_builtin_fputs (arglist, target, false);
6066 if (target)
6067 return target;
6068 break;
6069 case BUILT_IN_FPUTS_UNLOCKED:
6070 target = expand_builtin_fputs (arglist, target, true);
6071 if (target)
6072 return target;
6073 break;
6075 case BUILT_IN_FPRINTF:
6076 target = expand_builtin_fprintf (exp, target, mode, false);
6077 if (target)
6078 return target;
6079 break;
6081 case BUILT_IN_FPRINTF_UNLOCKED:
6082 target = expand_builtin_fprintf (exp, target, mode, true);
6083 if (target)
6084 return target;
6085 break;
6087 case BUILT_IN_SPRINTF:
6088 target = expand_builtin_sprintf (arglist, target, mode);
6089 if (target)
6090 return target;
6091 break;
6093 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6094 target = expand_builtin_signbit (exp, target);
6095 if (target)
6096 return target;
6097 break;
6099 /* Various hooks for the DWARF 2 __throw routine. */
6100 case BUILT_IN_UNWIND_INIT:
6101 expand_builtin_unwind_init ();
6102 return const0_rtx;
6103 case BUILT_IN_DWARF_CFA:
6104 return virtual_cfa_rtx;
6105 #ifdef DWARF2_UNWIND_INFO
6106 case BUILT_IN_DWARF_SP_COLUMN:
6107 return expand_builtin_dwarf_sp_column ();
6108 case BUILT_IN_INIT_DWARF_REG_SIZES:
6109 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6110 return const0_rtx;
6111 #endif
6112 case BUILT_IN_FROB_RETURN_ADDR:
6113 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6114 case BUILT_IN_EXTRACT_RETURN_ADDR:
6115 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6116 case BUILT_IN_EH_RETURN:
6117 expand_builtin_eh_return (TREE_VALUE (arglist),
6118 TREE_VALUE (TREE_CHAIN (arglist)));
6119 return const0_rtx;
6120 #ifdef EH_RETURN_DATA_REGNO
6121 case BUILT_IN_EH_RETURN_DATA_REGNO:
6122 return expand_builtin_eh_return_data_regno (arglist);
6123 #endif
6124 case BUILT_IN_EXTEND_POINTER:
6125 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6127 case BUILT_IN_VA_START:
6128 case BUILT_IN_STDARG_START:
6129 return expand_builtin_va_start (arglist);
6130 case BUILT_IN_VA_END:
6131 return expand_builtin_va_end (arglist);
6132 case BUILT_IN_VA_COPY:
6133 return expand_builtin_va_copy (arglist);
6134 case BUILT_IN_EXPECT:
6135 return expand_builtin_expect (arglist, target);
6136 case BUILT_IN_PREFETCH:
6137 expand_builtin_prefetch (arglist);
6138 return const0_rtx;
6140 case BUILT_IN_PROFILE_FUNC_ENTER:
6141 return expand_builtin_profile_func (false);
6142 case BUILT_IN_PROFILE_FUNC_EXIT:
6143 return expand_builtin_profile_func (true);
6145 case BUILT_IN_INIT_TRAMPOLINE:
6146 return expand_builtin_init_trampoline (arglist);
6147 case BUILT_IN_ADJUST_TRAMPOLINE:
6148 return expand_builtin_adjust_trampoline (arglist);
6150 case BUILT_IN_FORK:
6151 case BUILT_IN_EXECL:
6152 case BUILT_IN_EXECV:
6153 case BUILT_IN_EXECLP:
6154 case BUILT_IN_EXECLE:
6155 case BUILT_IN_EXECVP:
6156 case BUILT_IN_EXECVE:
6157 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6158 if (target)
6159 return target;
6160 break;
6162 case BUILT_IN_FETCH_AND_ADD_1:
6163 case BUILT_IN_FETCH_AND_ADD_2:
6164 case BUILT_IN_FETCH_AND_ADD_4:
6165 case BUILT_IN_FETCH_AND_ADD_8:
6166 case BUILT_IN_FETCH_AND_ADD_16:
6167 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6168 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6169 false, target, ignore);
6170 if (target)
6171 return target;
6172 break;
6174 case BUILT_IN_FETCH_AND_SUB_1:
6175 case BUILT_IN_FETCH_AND_SUB_2:
6176 case BUILT_IN_FETCH_AND_SUB_4:
6177 case BUILT_IN_FETCH_AND_SUB_8:
6178 case BUILT_IN_FETCH_AND_SUB_16:
6179 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6180 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6181 false, target, ignore);
6182 if (target)
6183 return target;
6184 break;
6186 case BUILT_IN_FETCH_AND_OR_1:
6187 case BUILT_IN_FETCH_AND_OR_2:
6188 case BUILT_IN_FETCH_AND_OR_4:
6189 case BUILT_IN_FETCH_AND_OR_8:
6190 case BUILT_IN_FETCH_AND_OR_16:
6191 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6192 target = expand_builtin_sync_operation (mode, arglist, IOR,
6193 false, target, ignore);
6194 if (target)
6195 return target;
6196 break;
6198 case BUILT_IN_FETCH_AND_AND_1:
6199 case BUILT_IN_FETCH_AND_AND_2:
6200 case BUILT_IN_FETCH_AND_AND_4:
6201 case BUILT_IN_FETCH_AND_AND_8:
6202 case BUILT_IN_FETCH_AND_AND_16:
6203 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6204 target = expand_builtin_sync_operation (mode, arglist, AND,
6205 false, target, ignore);
6206 if (target)
6207 return target;
6208 break;
6210 case BUILT_IN_FETCH_AND_XOR_1:
6211 case BUILT_IN_FETCH_AND_XOR_2:
6212 case BUILT_IN_FETCH_AND_XOR_4:
6213 case BUILT_IN_FETCH_AND_XOR_8:
6214 case BUILT_IN_FETCH_AND_XOR_16:
6215 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6216 target = expand_builtin_sync_operation (mode, arglist, XOR,
6217 false, target, ignore);
6218 if (target)
6219 return target;
6220 break;
6222 case BUILT_IN_FETCH_AND_NAND_1:
6223 case BUILT_IN_FETCH_AND_NAND_2:
6224 case BUILT_IN_FETCH_AND_NAND_4:
6225 case BUILT_IN_FETCH_AND_NAND_8:
6226 case BUILT_IN_FETCH_AND_NAND_16:
6227 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6228 target = expand_builtin_sync_operation (mode, arglist, NOT,
6229 false, target, ignore);
6230 if (target)
6231 return target;
6232 break;
6234 case BUILT_IN_ADD_AND_FETCH_1:
6235 case BUILT_IN_ADD_AND_FETCH_2:
6236 case BUILT_IN_ADD_AND_FETCH_4:
6237 case BUILT_IN_ADD_AND_FETCH_8:
6238 case BUILT_IN_ADD_AND_FETCH_16:
6239 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6240 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6241 true, target, ignore);
6242 if (target)
6243 return target;
6244 break;
6246 case BUILT_IN_SUB_AND_FETCH_1:
6247 case BUILT_IN_SUB_AND_FETCH_2:
6248 case BUILT_IN_SUB_AND_FETCH_4:
6249 case BUILT_IN_SUB_AND_FETCH_8:
6250 case BUILT_IN_SUB_AND_FETCH_16:
6251 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6252 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6253 true, target, ignore);
6254 if (target)
6255 return target;
6256 break;
6258 case BUILT_IN_OR_AND_FETCH_1:
6259 case BUILT_IN_OR_AND_FETCH_2:
6260 case BUILT_IN_OR_AND_FETCH_4:
6261 case BUILT_IN_OR_AND_FETCH_8:
6262 case BUILT_IN_OR_AND_FETCH_16:
6263 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6264 target = expand_builtin_sync_operation (mode, arglist, IOR,
6265 true, target, ignore);
6266 if (target)
6267 return target;
6268 break;
6270 case BUILT_IN_AND_AND_FETCH_1:
6271 case BUILT_IN_AND_AND_FETCH_2:
6272 case BUILT_IN_AND_AND_FETCH_4:
6273 case BUILT_IN_AND_AND_FETCH_8:
6274 case BUILT_IN_AND_AND_FETCH_16:
6275 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6276 target = expand_builtin_sync_operation (mode, arglist, AND,
6277 true, target, ignore);
6278 if (target)
6279 return target;
6280 break;
6282 case BUILT_IN_XOR_AND_FETCH_1:
6283 case BUILT_IN_XOR_AND_FETCH_2:
6284 case BUILT_IN_XOR_AND_FETCH_4:
6285 case BUILT_IN_XOR_AND_FETCH_8:
6286 case BUILT_IN_XOR_AND_FETCH_16:
6287 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6288 target = expand_builtin_sync_operation (mode, arglist, XOR,
6289 true, target, ignore);
6290 if (target)
6291 return target;
6292 break;
6294 case BUILT_IN_NAND_AND_FETCH_1:
6295 case BUILT_IN_NAND_AND_FETCH_2:
6296 case BUILT_IN_NAND_AND_FETCH_4:
6297 case BUILT_IN_NAND_AND_FETCH_8:
6298 case BUILT_IN_NAND_AND_FETCH_16:
6299 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6300 target = expand_builtin_sync_operation (mode, arglist, NOT,
6301 true, target, ignore);
6302 if (target)
6303 return target;
6304 break;
6306 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6307 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6308 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6309 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6310 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6311 if (mode == VOIDmode)
6312 mode = TYPE_MODE (boolean_type_node);
6313 if (!target || !register_operand (target, mode))
6314 target = gen_reg_rtx (mode);
6316 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6317 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6318 if (target)
6319 return target;
6320 break;
6322 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6323 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6324 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6325 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6326 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6327 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6328 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6329 if (target)
6330 return target;
6331 break;
6333 case BUILT_IN_LOCK_TEST_AND_SET_1:
6334 case BUILT_IN_LOCK_TEST_AND_SET_2:
6335 case BUILT_IN_LOCK_TEST_AND_SET_4:
6336 case BUILT_IN_LOCK_TEST_AND_SET_8:
6337 case BUILT_IN_LOCK_TEST_AND_SET_16:
6338 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6339 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6340 if (target)
6341 return target;
6342 break;
6344 case BUILT_IN_LOCK_RELEASE_1:
6345 case BUILT_IN_LOCK_RELEASE_2:
6346 case BUILT_IN_LOCK_RELEASE_4:
6347 case BUILT_IN_LOCK_RELEASE_8:
6348 case BUILT_IN_LOCK_RELEASE_16:
6349 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6350 expand_builtin_lock_release (mode, arglist);
6351 return const0_rtx;
6353 case BUILT_IN_SYNCHRONIZE:
6354 expand_builtin_synchronize ();
6355 return const0_rtx;
6357 case BUILT_IN_OBJECT_SIZE:
6358 return expand_builtin_object_size (exp);
6360 case BUILT_IN_MEMCPY_CHK:
6361 case BUILT_IN_MEMPCPY_CHK:
6362 case BUILT_IN_MEMMOVE_CHK:
6363 case BUILT_IN_MEMSET_CHK:
6364 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6365 if (target)
6366 return target;
6367 break;
6369 case BUILT_IN_STRCPY_CHK:
6370 case BUILT_IN_STPCPY_CHK:
6371 case BUILT_IN_STRNCPY_CHK:
6372 case BUILT_IN_STRCAT_CHK:
6373 case BUILT_IN_SNPRINTF_CHK:
6374 case BUILT_IN_VSNPRINTF_CHK:
6375 maybe_emit_chk_warning (exp, fcode);
6376 break;
6378 case BUILT_IN_SPRINTF_CHK:
6379 case BUILT_IN_VSPRINTF_CHK:
6380 maybe_emit_sprintf_chk_warning (exp, fcode);
6381 break;
6383 default: /* just do library call, if unknown builtin */
6384 break;
6387 /* The switch statement above can drop through to cause the function
6388 to be called normally. */
6389 return expand_call (exp, target, ignore);
6392 /* Determine whether a tree node represents a call to a built-in
6393 function. If the tree T is a call to a built-in function with
6394 the right number of arguments of the appropriate types, return
6395 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6396 Otherwise the return value is END_BUILTINS. */
6398 enum built_in_function
6399 builtin_mathfn_code (tree t)
6401 tree fndecl, arglist, parmlist;
6402 tree argtype, parmtype;
6404 if (TREE_CODE (t) != CALL_EXPR
6405 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6406 return END_BUILTINS;
6408 fndecl = get_callee_fndecl (t);
6409 if (fndecl == NULL_TREE
6410 || TREE_CODE (fndecl) != FUNCTION_DECL
6411 || ! DECL_BUILT_IN (fndecl)
6412 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6413 return END_BUILTINS;
6415 arglist = TREE_OPERAND (t, 1);
6416 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6417 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6419 /* If a function doesn't take a variable number of arguments,
6420 the last element in the list will have type `void'. */
6421 parmtype = TREE_VALUE (parmlist);
6422 if (VOID_TYPE_P (parmtype))
6424 if (arglist)
6425 return END_BUILTINS;
6426 return DECL_FUNCTION_CODE (fndecl);
6429 if (! arglist)
6430 return END_BUILTINS;
6432 argtype = TREE_TYPE (TREE_VALUE (arglist));
6434 if (SCALAR_FLOAT_TYPE_P (parmtype))
6436 if (! SCALAR_FLOAT_TYPE_P (argtype))
6437 return END_BUILTINS;
6439 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6441 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6442 return END_BUILTINS;
6444 else if (POINTER_TYPE_P (parmtype))
6446 if (! POINTER_TYPE_P (argtype))
6447 return END_BUILTINS;
6449 else if (INTEGRAL_TYPE_P (parmtype))
6451 if (! INTEGRAL_TYPE_P (argtype))
6452 return END_BUILTINS;
6454 else
6455 return END_BUILTINS;
6457 arglist = TREE_CHAIN (arglist);
6460 /* Variable-length argument list. */
6461 return DECL_FUNCTION_CODE (fndecl);
6464 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6465 constant. ARGLIST is the argument list of the call. */
6467 static tree
6468 fold_builtin_constant_p (tree arglist)
6470 if (arglist == 0)
6471 return 0;
6473 arglist = TREE_VALUE (arglist);
6475 /* We return 1 for a numeric type that's known to be a constant
6476 value at compile-time or for an aggregate type that's a
6477 literal constant. */
6478 STRIP_NOPS (arglist);
6480 /* If we know this is a constant, emit the constant of one. */
6481 if (CONSTANT_CLASS_P (arglist)
6482 || (TREE_CODE (arglist) == CONSTRUCTOR
6483 && TREE_CONSTANT (arglist)))
6484 return integer_one_node;
6485 if (TREE_CODE (arglist) == ADDR_EXPR)
6487 tree op = TREE_OPERAND (arglist, 0);
6488 if (TREE_CODE (op) == STRING_CST
6489 || (TREE_CODE (op) == ARRAY_REF
6490 && integer_zerop (TREE_OPERAND (op, 1))
6491 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6492 return integer_one_node;
6495 /* If this expression has side effects, show we don't know it to be a
6496 constant. Likewise if it's a pointer or aggregate type since in
6497 those case we only want literals, since those are only optimized
6498 when generating RTL, not later.
6499 And finally, if we are compiling an initializer, not code, we
6500 need to return a definite result now; there's not going to be any
6501 more optimization done. */
6502 if (TREE_SIDE_EFFECTS (arglist)
6503 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6504 || POINTER_TYPE_P (TREE_TYPE (arglist))
6505 || cfun == 0)
6506 return integer_zero_node;
6508 return 0;
6511 /* Fold a call to __builtin_expect, if we expect that a comparison against
6512 the argument will fold to a constant. In practice, this means a true
6513 constant or the address of a non-weak symbol. ARGLIST is the argument
6514 list of the call. */
6516 static tree
6517 fold_builtin_expect (tree arglist)
6519 tree arg, inner;
6521 if (arglist == 0)
6522 return 0;
6524 arg = TREE_VALUE (arglist);
6526 /* If the argument isn't invariant, then there's nothing we can do. */
6527 if (!TREE_INVARIANT (arg))
6528 return 0;
6530 /* If we're looking at an address of a weak decl, then do not fold. */
6531 inner = arg;
6532 STRIP_NOPS (inner);
6533 if (TREE_CODE (inner) == ADDR_EXPR)
6537 inner = TREE_OPERAND (inner, 0);
6539 while (TREE_CODE (inner) == COMPONENT_REF
6540 || TREE_CODE (inner) == ARRAY_REF);
6541 if (DECL_P (inner) && DECL_WEAK (inner))
6542 return 0;
6545 /* Otherwise, ARG already has the proper type for the return value. */
6546 return arg;
6549 /* Fold a call to __builtin_classify_type. */
6551 static tree
6552 fold_builtin_classify_type (tree arglist)
6554 if (arglist == 0)
6555 return build_int_cst (NULL_TREE, no_type_class);
6557 return build_int_cst (NULL_TREE,
6558 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6561 /* Fold a call to __builtin_strlen. */
6563 static tree
6564 fold_builtin_strlen (tree arglist)
6566 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6567 return NULL_TREE;
6568 else
6570 tree len = c_strlen (TREE_VALUE (arglist), 0);
6572 if (len)
6574 /* Convert from the internal "sizetype" type to "size_t". */
6575 if (size_type_node)
6576 len = fold_convert (size_type_node, len);
6577 return len;
6580 return NULL_TREE;
6584 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6586 static tree
6587 fold_builtin_inf (tree type, int warn)
6589 REAL_VALUE_TYPE real;
6591 /* __builtin_inff is intended to be usable to define INFINITY on all
6592 targets. If an infinity is not available, INFINITY expands "to a
6593 positive constant of type float that overflows at translation
6594 time", footnote "In this case, using INFINITY will violate the
6595 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6596 Thus we pedwarn to ensure this constraint violation is
6597 diagnosed. */
6598 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6599 pedwarn ("target format does not support infinity");
6601 real_inf (&real);
6602 return build_real (type, real);
6605 /* Fold a call to __builtin_nan or __builtin_nans. */
6607 static tree
6608 fold_builtin_nan (tree arglist, tree type, int quiet)
6610 REAL_VALUE_TYPE real;
6611 const char *str;
6613 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6614 return 0;
6615 str = c_getstr (TREE_VALUE (arglist));
6616 if (!str)
6617 return 0;
6619 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6620 return 0;
6622 return build_real (type, real);
6625 /* Return true if the floating point expression T has an integer value.
6626 We also allow +Inf, -Inf and NaN to be considered integer values. */
6628 static bool
6629 integer_valued_real_p (tree t)
6631 switch (TREE_CODE (t))
6633 case FLOAT_EXPR:
6634 return true;
6636 case ABS_EXPR:
6637 case SAVE_EXPR:
6638 case NON_LVALUE_EXPR:
6639 return integer_valued_real_p (TREE_OPERAND (t, 0));
6641 case COMPOUND_EXPR:
6642 case MODIFY_EXPR:
6643 case BIND_EXPR:
6644 return integer_valued_real_p (TREE_OPERAND (t, 1));
6646 case PLUS_EXPR:
6647 case MINUS_EXPR:
6648 case MULT_EXPR:
6649 case MIN_EXPR:
6650 case MAX_EXPR:
6651 return integer_valued_real_p (TREE_OPERAND (t, 0))
6652 && integer_valued_real_p (TREE_OPERAND (t, 1));
6654 case COND_EXPR:
6655 return integer_valued_real_p (TREE_OPERAND (t, 1))
6656 && integer_valued_real_p (TREE_OPERAND (t, 2));
6658 case REAL_CST:
6659 if (! TREE_CONSTANT_OVERFLOW (t))
6661 REAL_VALUE_TYPE c, cint;
6663 c = TREE_REAL_CST (t);
6664 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6665 return real_identical (&c, &cint);
6667 break;
6669 case NOP_EXPR:
6671 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6672 if (TREE_CODE (type) == INTEGER_TYPE)
6673 return true;
6674 if (TREE_CODE (type) == REAL_TYPE)
6675 return integer_valued_real_p (TREE_OPERAND (t, 0));
6676 break;
6679 case CALL_EXPR:
6680 switch (builtin_mathfn_code (t))
6682 CASE_FLT_FN (BUILT_IN_CEIL):
6683 CASE_FLT_FN (BUILT_IN_FLOOR):
6684 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6685 CASE_FLT_FN (BUILT_IN_RINT):
6686 CASE_FLT_FN (BUILT_IN_ROUND):
6687 CASE_FLT_FN (BUILT_IN_TRUNC):
6688 return true;
6690 default:
6691 break;
6693 break;
6695 default:
6696 break;
6698 return false;
6701 /* EXP is assumed to be builtin call where truncation can be propagated
6702 across (for instance floor((double)f) == (double)floorf (f).
6703 Do the transformation. */
6705 static tree
6706 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6708 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6709 tree arg;
6711 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6712 return 0;
6714 arg = TREE_VALUE (arglist);
6715 /* Integer rounding functions are idempotent. */
6716 if (fcode == builtin_mathfn_code (arg))
6717 return arg;
6719 /* If argument is already integer valued, and we don't need to worry
6720 about setting errno, there's no need to perform rounding. */
6721 if (! flag_errno_math && integer_valued_real_p (arg))
6722 return arg;
6724 if (optimize)
6726 tree arg0 = strip_float_extensions (arg);
6727 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6728 tree newtype = TREE_TYPE (arg0);
6729 tree decl;
6731 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6732 && (decl = mathfn_built_in (newtype, fcode)))
6734 arglist =
6735 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6736 return fold_convert (ftype,
6737 build_function_call_expr (decl, arglist));
6740 return 0;
6743 /* EXP is assumed to be builtin call which can narrow the FP type of
6744 the argument, for instance lround((double)f) -> lroundf (f). */
6746 static tree
6747 fold_fixed_mathfn (tree fndecl, tree arglist)
6749 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6750 tree arg;
6752 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6753 return 0;
6755 arg = TREE_VALUE (arglist);
6757 /* If argument is already integer valued, and we don't need to worry
6758 about setting errno, there's no need to perform rounding. */
6759 if (! flag_errno_math && integer_valued_real_p (arg))
6760 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6762 if (optimize)
6764 tree ftype = TREE_TYPE (arg);
6765 tree arg0 = strip_float_extensions (arg);
6766 tree newtype = TREE_TYPE (arg0);
6767 tree decl;
6769 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6770 && (decl = mathfn_built_in (newtype, fcode)))
6772 arglist =
6773 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6774 return build_function_call_expr (decl, arglist);
6777 return 0;
6780 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6781 is the argument list and TYPE is the return type. Return
6782 NULL_TREE if no if no simplification can be made. */
6784 static tree
6785 fold_builtin_cabs (tree arglist, tree type)
6787 tree arg;
6789 if (!arglist || TREE_CHAIN (arglist))
6790 return NULL_TREE;
6792 arg = TREE_VALUE (arglist);
6793 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6794 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6795 return NULL_TREE;
6797 /* Evaluate cabs of a constant at compile-time. */
6798 if (flag_unsafe_math_optimizations
6799 && TREE_CODE (arg) == COMPLEX_CST
6800 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6801 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6802 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6803 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6805 REAL_VALUE_TYPE r, i;
6807 r = TREE_REAL_CST (TREE_REALPART (arg));
6808 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6810 real_arithmetic (&r, MULT_EXPR, &r, &r);
6811 real_arithmetic (&i, MULT_EXPR, &i, &i);
6812 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6813 if (real_sqrt (&r, TYPE_MODE (type), &r)
6814 || ! flag_trapping_math)
6815 return build_real (type, r);
6818 /* If either part is zero, cabs is fabs of the other. */
6819 if (TREE_CODE (arg) == COMPLEX_EXPR
6820 && real_zerop (TREE_OPERAND (arg, 0)))
6821 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6822 if (TREE_CODE (arg) == COMPLEX_EXPR
6823 && real_zerop (TREE_OPERAND (arg, 1)))
6824 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6826 /* Don't do this when optimizing for size. */
6827 if (flag_unsafe_math_optimizations
6828 && optimize && !optimize_size)
6830 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6832 if (sqrtfn != NULL_TREE)
6834 tree rpart, ipart, result, arglist;
6836 arg = builtin_save_expr (arg);
6838 rpart = fold_build1 (REALPART_EXPR, type, arg);
6839 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6841 rpart = builtin_save_expr (rpart);
6842 ipart = builtin_save_expr (ipart);
6844 result = fold_build2 (PLUS_EXPR, type,
6845 fold_build2 (MULT_EXPR, type,
6846 rpart, rpart),
6847 fold_build2 (MULT_EXPR, type,
6848 ipart, ipart));
6850 arglist = build_tree_list (NULL_TREE, result);
6851 return build_function_call_expr (sqrtfn, arglist);
6855 return NULL_TREE;
6858 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6859 NULL_TREE if no simplification can be made. */
6861 static tree
6862 fold_builtin_sqrt (tree arglist, tree type)
6865 enum built_in_function fcode;
6866 tree arg = TREE_VALUE (arglist);
6868 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6869 return NULL_TREE;
6871 /* Optimize sqrt of constant value. */
6872 if (TREE_CODE (arg) == REAL_CST
6873 && ! TREE_CONSTANT_OVERFLOW (arg))
6875 REAL_VALUE_TYPE r, x;
6877 x = TREE_REAL_CST (arg);
6878 if (real_sqrt (&r, TYPE_MODE (type), &x)
6879 || (!flag_trapping_math && !flag_errno_math))
6880 return build_real (type, r);
6883 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6884 fcode = builtin_mathfn_code (arg);
6885 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6887 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6888 arg = fold_build2 (MULT_EXPR, type,
6889 TREE_VALUE (TREE_OPERAND (arg, 1)),
6890 build_real (type, dconsthalf));
6891 arglist = build_tree_list (NULL_TREE, arg);
6892 return build_function_call_expr (expfn, arglist);
6895 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6896 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6898 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6900 if (powfn)
6902 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6903 tree tree_root;
6904 /* The inner root was either sqrt or cbrt. */
6905 REAL_VALUE_TYPE dconstroot =
6906 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6908 /* Adjust for the outer root. */
6909 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6910 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6911 tree_root = build_real (type, dconstroot);
6912 arglist = tree_cons (NULL_TREE, arg0,
6913 build_tree_list (NULL_TREE, tree_root));
6914 return build_function_call_expr (powfn, arglist);
6918 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6919 if (flag_unsafe_math_optimizations
6920 && (fcode == BUILT_IN_POW
6921 || fcode == BUILT_IN_POWF
6922 || fcode == BUILT_IN_POWL))
6924 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6925 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6926 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6927 tree narg1;
6928 if (!tree_expr_nonnegative_p (arg0))
6929 arg0 = build1 (ABS_EXPR, type, arg0);
6930 narg1 = fold_build2 (MULT_EXPR, type, arg1,
6931 build_real (type, dconsthalf));
6932 arglist = tree_cons (NULL_TREE, arg0,
6933 build_tree_list (NULL_TREE, narg1));
6934 return build_function_call_expr (powfn, arglist);
6937 return NULL_TREE;
6940 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6941 NULL_TREE if no simplification can be made. */
6942 static tree
6943 fold_builtin_cbrt (tree arglist, tree type)
6945 tree arg = TREE_VALUE (arglist);
6946 const enum built_in_function fcode = builtin_mathfn_code (arg);
6948 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6949 return NULL_TREE;
6951 /* Optimize cbrt of constant value. */
6952 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6953 return arg;
6955 if (flag_unsafe_math_optimizations)
6957 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6958 if (BUILTIN_EXPONENT_P (fcode))
6960 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6961 const REAL_VALUE_TYPE third_trunc =
6962 real_value_truncate (TYPE_MODE (type), dconstthird);
6963 arg = fold_build2 (MULT_EXPR, type,
6964 TREE_VALUE (TREE_OPERAND (arg, 1)),
6965 build_real (type, third_trunc));
6966 arglist = build_tree_list (NULL_TREE, arg);
6967 return build_function_call_expr (expfn, arglist);
6970 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6971 if (BUILTIN_SQRT_P (fcode))
6973 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6975 if (powfn)
6977 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6978 tree tree_root;
6979 REAL_VALUE_TYPE dconstroot = dconstthird;
6981 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6982 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6983 tree_root = build_real (type, dconstroot);
6984 arglist = tree_cons (NULL_TREE, arg0,
6985 build_tree_list (NULL_TREE, tree_root));
6986 return build_function_call_expr (powfn, arglist);
6990 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6991 if (BUILTIN_CBRT_P (fcode))
6993 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6994 if (tree_expr_nonnegative_p (arg0))
6996 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6998 if (powfn)
7000 tree tree_root;
7001 REAL_VALUE_TYPE dconstroot;
7003 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7004 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7005 tree_root = build_real (type, dconstroot);
7006 arglist = tree_cons (NULL_TREE, arg0,
7007 build_tree_list (NULL_TREE, tree_root));
7008 return build_function_call_expr (powfn, arglist);
7013 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7014 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7015 || fcode == BUILT_IN_POWL)
7017 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7018 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7019 if (tree_expr_nonnegative_p (arg00))
7021 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7022 const REAL_VALUE_TYPE dconstroot
7023 = real_value_truncate (TYPE_MODE (type), dconstthird);
7024 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7025 build_real (type, dconstroot));
7026 arglist = tree_cons (NULL_TREE, arg00,
7027 build_tree_list (NULL_TREE, narg01));
7028 return build_function_call_expr (powfn, arglist);
7032 return NULL_TREE;
7035 /* Fold function call to builtin sin, sinf, or sinl. Return
7036 NULL_TREE if no simplification can be made. */
7037 static tree
7038 fold_builtin_sin (tree arglist)
7040 tree arg = TREE_VALUE (arglist);
7042 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7043 return NULL_TREE;
7045 /* Optimize sin (0.0) = 0.0. */
7046 if (real_zerop (arg))
7047 return arg;
7049 return NULL_TREE;
7052 /* Fold function call to builtin cos, cosf, or cosl. Return
7053 NULL_TREE if no simplification can be made. */
7054 static tree
7055 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7057 tree arg = TREE_VALUE (arglist);
7059 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7060 return NULL_TREE;
7062 /* Optimize cos (0.0) = 1.0. */
7063 if (real_zerop (arg))
7064 return build_real (type, dconst1);
7066 /* Optimize cos(-x) into cos (x). */
7067 if (TREE_CODE (arg) == NEGATE_EXPR)
7069 tree args = build_tree_list (NULL_TREE,
7070 TREE_OPERAND (arg, 0));
7071 return build_function_call_expr (fndecl, args);
7074 return NULL_TREE;
7077 /* Fold function call to builtin tan, tanf, or tanl. Return
7078 NULL_TREE if no simplification can be made. */
7079 static tree
7080 fold_builtin_tan (tree arglist)
7082 enum built_in_function fcode;
7083 tree arg = TREE_VALUE (arglist);
7085 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7086 return NULL_TREE;
7088 /* Optimize tan(0.0) = 0.0. */
7089 if (real_zerop (arg))
7090 return arg;
7092 /* Optimize tan(atan(x)) = x. */
7093 fcode = builtin_mathfn_code (arg);
7094 if (flag_unsafe_math_optimizations
7095 && (fcode == BUILT_IN_ATAN
7096 || fcode == BUILT_IN_ATANF
7097 || fcode == BUILT_IN_ATANL))
7098 return TREE_VALUE (TREE_OPERAND (arg, 1));
7100 return NULL_TREE;
7103 /* Fold function call to builtin atan, atanf, or atanl. Return
7104 NULL_TREE if no simplification can be made. */
7106 static tree
7107 fold_builtin_atan (tree arglist, tree type)
7110 tree arg = TREE_VALUE (arglist);
7112 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7113 return NULL_TREE;
7115 /* Optimize atan(0.0) = 0.0. */
7116 if (real_zerop (arg))
7117 return arg;
7119 /* Optimize atan(1.0) = pi/4. */
7120 if (real_onep (arg))
7122 REAL_VALUE_TYPE cst;
7124 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7125 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7126 return build_real (type, cst);
7129 return NULL_TREE;
7132 /* Fold function call to builtin trunc, truncf or truncl. Return
7133 NULL_TREE if no simplification can be made. */
7135 static tree
7136 fold_builtin_trunc (tree fndecl, tree arglist)
7138 tree arg;
7140 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7141 return 0;
7143 /* Optimize trunc of constant value. */
7144 arg = TREE_VALUE (arglist);
7145 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7147 REAL_VALUE_TYPE r, x;
7148 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7150 x = TREE_REAL_CST (arg);
7151 real_trunc (&r, TYPE_MODE (type), &x);
7152 return build_real (type, r);
7155 return fold_trunc_transparent_mathfn (fndecl, arglist);
7158 /* Fold function call to builtin floor, floorf or floorl. Return
7159 NULL_TREE if no simplification can be made. */
7161 static tree
7162 fold_builtin_floor (tree fndecl, tree arglist)
7164 tree arg;
7166 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7167 return 0;
7169 /* Optimize floor of constant value. */
7170 arg = TREE_VALUE (arglist);
7171 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7173 REAL_VALUE_TYPE x;
7175 x = TREE_REAL_CST (arg);
7176 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7178 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7179 REAL_VALUE_TYPE r;
7181 real_floor (&r, TYPE_MODE (type), &x);
7182 return build_real (type, r);
7186 return fold_trunc_transparent_mathfn (fndecl, arglist);
7189 /* Fold function call to builtin ceil, ceilf or ceill. Return
7190 NULL_TREE if no simplification can be made. */
7192 static tree
7193 fold_builtin_ceil (tree fndecl, tree arglist)
7195 tree arg;
7197 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7198 return 0;
7200 /* Optimize ceil of constant value. */
7201 arg = TREE_VALUE (arglist);
7202 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7204 REAL_VALUE_TYPE x;
7206 x = TREE_REAL_CST (arg);
7207 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7209 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7210 REAL_VALUE_TYPE r;
7212 real_ceil (&r, TYPE_MODE (type), &x);
7213 return build_real (type, r);
7217 return fold_trunc_transparent_mathfn (fndecl, arglist);
7220 /* Fold function call to builtin round, roundf or roundl. Return
7221 NULL_TREE if no simplification can be made. */
7223 static tree
7224 fold_builtin_round (tree fndecl, tree arglist)
7226 tree arg;
7228 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7229 return 0;
7231 /* Optimize round of constant value. */
7232 arg = TREE_VALUE (arglist);
7233 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7235 REAL_VALUE_TYPE x;
7237 x = TREE_REAL_CST (arg);
7238 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7240 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7241 REAL_VALUE_TYPE r;
7243 real_round (&r, TYPE_MODE (type), &x);
7244 return build_real (type, r);
7248 return fold_trunc_transparent_mathfn (fndecl, arglist);
7251 /* Fold function call to builtin lround, lroundf or lroundl (or the
7252 corresponding long long versions) and other rounding functions.
7253 Return NULL_TREE if no simplification can be made. */
7255 static tree
7256 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7258 tree arg;
7260 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7261 return 0;
7263 /* Optimize lround of constant value. */
7264 arg = TREE_VALUE (arglist);
7265 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7267 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7269 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7271 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7272 tree ftype = TREE_TYPE (arg), result;
7273 HOST_WIDE_INT hi, lo;
7274 REAL_VALUE_TYPE r;
7276 switch (DECL_FUNCTION_CODE (fndecl))
7278 CASE_FLT_FN (BUILT_IN_LFLOOR):
7279 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7280 real_floor (&r, TYPE_MODE (ftype), &x);
7281 break;
7283 CASE_FLT_FN (BUILT_IN_LCEIL):
7284 CASE_FLT_FN (BUILT_IN_LLCEIL):
7285 real_ceil (&r, TYPE_MODE (ftype), &x);
7286 break;
7288 CASE_FLT_FN (BUILT_IN_LROUND):
7289 CASE_FLT_FN (BUILT_IN_LLROUND):
7290 real_round (&r, TYPE_MODE (ftype), &x);
7291 break;
7293 default:
7294 gcc_unreachable ();
7297 REAL_VALUE_TO_INT (&lo, &hi, r);
7298 result = build_int_cst_wide (NULL_TREE, lo, hi);
7299 if (int_fits_type_p (result, itype))
7300 return fold_convert (itype, result);
7304 return fold_fixed_mathfn (fndecl, arglist);
7307 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7308 and their long and long long variants (i.e. ffsl and ffsll).
7309 Return NULL_TREE if no simplification can be made. */
7311 static tree
7312 fold_builtin_bitop (tree fndecl, tree arglist)
7314 tree arg;
7316 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7317 return NULL_TREE;
7319 /* Optimize for constant argument. */
7320 arg = TREE_VALUE (arglist);
7321 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7323 HOST_WIDE_INT hi, width, result;
7324 unsigned HOST_WIDE_INT lo;
7325 tree type;
7327 type = TREE_TYPE (arg);
7328 width = TYPE_PRECISION (type);
7329 lo = TREE_INT_CST_LOW (arg);
7331 /* Clear all the bits that are beyond the type's precision. */
7332 if (width > HOST_BITS_PER_WIDE_INT)
7334 hi = TREE_INT_CST_HIGH (arg);
7335 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7336 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7338 else
7340 hi = 0;
7341 if (width < HOST_BITS_PER_WIDE_INT)
7342 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7345 switch (DECL_FUNCTION_CODE (fndecl))
7347 CASE_INT_FN (BUILT_IN_FFS):
7348 if (lo != 0)
7349 result = exact_log2 (lo & -lo) + 1;
7350 else if (hi != 0)
7351 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7352 else
7353 result = 0;
7354 break;
7356 CASE_INT_FN (BUILT_IN_CLZ):
7357 if (hi != 0)
7358 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7359 else if (lo != 0)
7360 result = width - floor_log2 (lo) - 1;
7361 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7362 result = width;
7363 break;
7365 CASE_INT_FN (BUILT_IN_CTZ):
7366 if (lo != 0)
7367 result = exact_log2 (lo & -lo);
7368 else if (hi != 0)
7369 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7370 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7371 result = width;
7372 break;
7374 CASE_INT_FN (BUILT_IN_POPCOUNT):
7375 result = 0;
7376 while (lo)
7377 result++, lo &= lo - 1;
7378 while (hi)
7379 result++, hi &= hi - 1;
7380 break;
7382 CASE_INT_FN (BUILT_IN_PARITY):
7383 result = 0;
7384 while (lo)
7385 result++, lo &= lo - 1;
7386 while (hi)
7387 result++, hi &= hi - 1;
7388 result &= 1;
7389 break;
7391 default:
7392 gcc_unreachable ();
7395 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7398 return NULL_TREE;
7401 /* Return true if EXPR is the real constant contained in VALUE. */
7403 static bool
7404 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7406 STRIP_NOPS (expr);
7408 return ((TREE_CODE (expr) == REAL_CST
7409 && ! TREE_CONSTANT_OVERFLOW (expr)
7410 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7411 || (TREE_CODE (expr) == COMPLEX_CST
7412 && real_dconstp (TREE_REALPART (expr), value)
7413 && real_zerop (TREE_IMAGPART (expr))));
7416 /* A subroutine of fold_builtin to fold the various logarithmic
7417 functions. EXP is the CALL_EXPR of a call to a builtin logN
7418 function. VALUE is the base of the logN function. */
7420 static tree
7421 fold_builtin_logarithm (tree fndecl, tree arglist,
7422 const REAL_VALUE_TYPE *value)
7424 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7426 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7427 tree arg = TREE_VALUE (arglist);
7428 const enum built_in_function fcode = builtin_mathfn_code (arg);
7430 /* Optimize logN(1.0) = 0.0. */
7431 if (real_onep (arg))
7432 return build_real (type, dconst0);
7434 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7435 exactly, then only do this if flag_unsafe_math_optimizations. */
7436 if (exact_real_truncate (TYPE_MODE (type), value)
7437 || flag_unsafe_math_optimizations)
7439 const REAL_VALUE_TYPE value_truncate =
7440 real_value_truncate (TYPE_MODE (type), *value);
7441 if (real_dconstp (arg, &value_truncate))
7442 return build_real (type, dconst1);
7445 /* Special case, optimize logN(expN(x)) = x. */
7446 if (flag_unsafe_math_optimizations
7447 && ((value == &dconste
7448 && (fcode == BUILT_IN_EXP
7449 || fcode == BUILT_IN_EXPF
7450 || fcode == BUILT_IN_EXPL))
7451 || (value == &dconst2
7452 && (fcode == BUILT_IN_EXP2
7453 || fcode == BUILT_IN_EXP2F
7454 || fcode == BUILT_IN_EXP2L))
7455 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7456 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7458 /* Optimize logN(func()) for various exponential functions. We
7459 want to determine the value "x" and the power "exponent" in
7460 order to transform logN(x**exponent) into exponent*logN(x). */
7461 if (flag_unsafe_math_optimizations)
7463 tree exponent = 0, x = 0;
7465 switch (fcode)
7467 CASE_FLT_FN (BUILT_IN_EXP):
7468 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7469 x = build_real (type,
7470 real_value_truncate (TYPE_MODE (type), dconste));
7471 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7472 break;
7473 CASE_FLT_FN (BUILT_IN_EXP2):
7474 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7475 x = build_real (type, dconst2);
7476 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7477 break;
7478 CASE_FLT_FN (BUILT_IN_EXP10):
7479 CASE_FLT_FN (BUILT_IN_POW10):
7480 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7481 x = build_real (type, dconst10);
7482 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7483 break;
7484 CASE_FLT_FN (BUILT_IN_SQRT):
7485 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7486 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7487 exponent = build_real (type, dconsthalf);
7488 break;
7489 CASE_FLT_FN (BUILT_IN_CBRT):
7490 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7491 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7492 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7493 dconstthird));
7494 break;
7495 CASE_FLT_FN (BUILT_IN_POW):
7496 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7497 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7498 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7499 break;
7500 default:
7501 break;
7504 /* Now perform the optimization. */
7505 if (x && exponent)
7507 tree logfn;
7508 arglist = build_tree_list (NULL_TREE, x);
7509 logfn = build_function_call_expr (fndecl, arglist);
7510 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7515 return 0;
7518 /* Fold a builtin function call to pow, powf, or powl. Return
7519 NULL_TREE if no simplification can be made. */
7520 static tree
7521 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7523 tree arg0 = TREE_VALUE (arglist);
7524 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7526 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7527 return NULL_TREE;
7529 /* Optimize pow(1.0,y) = 1.0. */
7530 if (real_onep (arg0))
7531 return omit_one_operand (type, build_real (type, dconst1), arg1);
7533 if (TREE_CODE (arg1) == REAL_CST
7534 && ! TREE_CONSTANT_OVERFLOW (arg1))
7536 REAL_VALUE_TYPE cint;
7537 REAL_VALUE_TYPE c;
7538 HOST_WIDE_INT n;
7540 c = TREE_REAL_CST (arg1);
7542 /* Optimize pow(x,0.0) = 1.0. */
7543 if (REAL_VALUES_EQUAL (c, dconst0))
7544 return omit_one_operand (type, build_real (type, dconst1),
7545 arg0);
7547 /* Optimize pow(x,1.0) = x. */
7548 if (REAL_VALUES_EQUAL (c, dconst1))
7549 return arg0;
7551 /* Optimize pow(x,-1.0) = 1.0/x. */
7552 if (REAL_VALUES_EQUAL (c, dconstm1))
7553 return fold_build2 (RDIV_EXPR, type,
7554 build_real (type, dconst1), arg0);
7556 /* Optimize pow(x,0.5) = sqrt(x). */
7557 if (flag_unsafe_math_optimizations
7558 && REAL_VALUES_EQUAL (c, dconsthalf))
7560 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7562 if (sqrtfn != NULL_TREE)
7564 tree arglist = build_tree_list (NULL_TREE, arg0);
7565 return build_function_call_expr (sqrtfn, arglist);
7569 /* Check for an integer exponent. */
7570 n = real_to_integer (&c);
7571 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7572 if (real_identical (&c, &cint))
7574 /* Attempt to evaluate pow at compile-time. */
7575 if (TREE_CODE (arg0) == REAL_CST
7576 && ! TREE_CONSTANT_OVERFLOW (arg0))
7578 REAL_VALUE_TYPE x;
7579 bool inexact;
7581 x = TREE_REAL_CST (arg0);
7582 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7583 if (flag_unsafe_math_optimizations || !inexact)
7584 return build_real (type, x);
7587 /* Strip sign ops from even integer powers. */
7588 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7590 tree narg0 = fold_strip_sign_ops (arg0);
7591 if (narg0)
7593 arglist = build_tree_list (NULL_TREE, arg1);
7594 arglist = tree_cons (NULL_TREE, narg0, arglist);
7595 return build_function_call_expr (fndecl, arglist);
7601 if (flag_unsafe_math_optimizations)
7603 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7605 /* Optimize pow(expN(x),y) = expN(x*y). */
7606 if (BUILTIN_EXPONENT_P (fcode))
7608 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7609 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7610 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7611 arglist = build_tree_list (NULL_TREE, arg);
7612 return build_function_call_expr (expfn, arglist);
7615 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7616 if (BUILTIN_SQRT_P (fcode))
7618 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7619 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7620 build_real (type, dconsthalf));
7622 arglist = tree_cons (NULL_TREE, narg0,
7623 build_tree_list (NULL_TREE, narg1));
7624 return build_function_call_expr (fndecl, arglist);
7627 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7628 if (BUILTIN_CBRT_P (fcode))
7630 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7631 if (tree_expr_nonnegative_p (arg))
7633 const REAL_VALUE_TYPE dconstroot
7634 = real_value_truncate (TYPE_MODE (type), dconstthird);
7635 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7636 build_real (type, dconstroot));
7637 arglist = tree_cons (NULL_TREE, arg,
7638 build_tree_list (NULL_TREE, narg1));
7639 return build_function_call_expr (fndecl, arglist);
7643 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7644 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7645 || fcode == BUILT_IN_POWL)
7647 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7648 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7649 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7650 arglist = tree_cons (NULL_TREE, arg00,
7651 build_tree_list (NULL_TREE, narg1));
7652 return build_function_call_expr (fndecl, arglist);
7656 return NULL_TREE;
7659 /* Fold a builtin function call to powi, powif, or powil. Return
7660 NULL_TREE if no simplification can be made. */
7661 static tree
7662 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7664 tree arg0 = TREE_VALUE (arglist);
7665 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7667 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7668 return NULL_TREE;
7670 /* Optimize pow(1.0,y) = 1.0. */
7671 if (real_onep (arg0))
7672 return omit_one_operand (type, build_real (type, dconst1), arg1);
7674 if (host_integerp (arg1, 0))
7676 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7678 /* Evaluate powi at compile-time. */
7679 if (TREE_CODE (arg0) == REAL_CST
7680 && ! TREE_CONSTANT_OVERFLOW (arg0))
7682 REAL_VALUE_TYPE x;
7683 x = TREE_REAL_CST (arg0);
7684 real_powi (&x, TYPE_MODE (type), &x, c);
7685 return build_real (type, x);
7688 /* Optimize pow(x,0) = 1.0. */
7689 if (c == 0)
7690 return omit_one_operand (type, build_real (type, dconst1),
7691 arg0);
7693 /* Optimize pow(x,1) = x. */
7694 if (c == 1)
7695 return arg0;
7697 /* Optimize pow(x,-1) = 1.0/x. */
7698 if (c == -1)
7699 return fold_build2 (RDIV_EXPR, type,
7700 build_real (type, dconst1), arg0);
7703 return NULL_TREE;
7706 /* A subroutine of fold_builtin to fold the various exponent
7707 functions. EXP is the CALL_EXPR of a call to a builtin function.
7708 VALUE is the value which will be raised to a power. */
7710 static tree
7711 fold_builtin_exponent (tree fndecl, tree arglist,
7712 const REAL_VALUE_TYPE *value)
7714 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7716 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7717 tree arg = TREE_VALUE (arglist);
7719 /* Optimize exp*(0.0) = 1.0. */
7720 if (real_zerop (arg))
7721 return build_real (type, dconst1);
7723 /* Optimize expN(1.0) = N. */
7724 if (real_onep (arg))
7726 REAL_VALUE_TYPE cst;
7728 real_convert (&cst, TYPE_MODE (type), value);
7729 return build_real (type, cst);
7732 /* Attempt to evaluate expN(integer) at compile-time. */
7733 if (flag_unsafe_math_optimizations
7734 && TREE_CODE (arg) == REAL_CST
7735 && ! TREE_CONSTANT_OVERFLOW (arg))
7737 REAL_VALUE_TYPE cint;
7738 REAL_VALUE_TYPE c;
7739 HOST_WIDE_INT n;
7741 c = TREE_REAL_CST (arg);
7742 n = real_to_integer (&c);
7743 real_from_integer (&cint, VOIDmode, n,
7744 n < 0 ? -1 : 0, 0);
7745 if (real_identical (&c, &cint))
7747 REAL_VALUE_TYPE x;
7749 real_powi (&x, TYPE_MODE (type), value, n);
7750 return build_real (type, x);
7754 /* Optimize expN(logN(x)) = x. */
7755 if (flag_unsafe_math_optimizations)
7757 const enum built_in_function fcode = builtin_mathfn_code (arg);
7759 if ((value == &dconste
7760 && (fcode == BUILT_IN_LOG
7761 || fcode == BUILT_IN_LOGF
7762 || fcode == BUILT_IN_LOGL))
7763 || (value == &dconst2
7764 && (fcode == BUILT_IN_LOG2
7765 || fcode == BUILT_IN_LOG2F
7766 || fcode == BUILT_IN_LOG2L))
7767 || (value == &dconst10
7768 && (fcode == BUILT_IN_LOG10
7769 || fcode == BUILT_IN_LOG10F
7770 || fcode == BUILT_IN_LOG10L)))
7771 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7775 return 0;
7778 /* Fold function call to builtin memcpy. Return
7779 NULL_TREE if no simplification can be made. */
7781 static tree
7782 fold_builtin_memcpy (tree fndecl, tree arglist)
7784 tree dest, src, len;
7786 if (!validate_arglist (arglist,
7787 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7788 return 0;
7790 dest = TREE_VALUE (arglist);
7791 src = TREE_VALUE (TREE_CHAIN (arglist));
7792 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7794 /* If the LEN parameter is zero, return DEST. */
7795 if (integer_zerop (len))
7796 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7798 /* If SRC and DEST are the same (and not volatile), return DEST. */
7799 if (operand_equal_p (src, dest, 0))
7800 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7802 return 0;
7805 /* Fold function call to builtin mempcpy. Return
7806 NULL_TREE if no simplification can be made. */
7808 static tree
7809 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7811 if (validate_arglist (arglist,
7812 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7814 tree dest = TREE_VALUE (arglist);
7815 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7816 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7818 /* If the LEN parameter is zero, return DEST. */
7819 if (integer_zerop (len))
7820 return omit_one_operand (type, dest, src);
7822 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7823 if (operand_equal_p (src, dest, 0))
7825 if (endp == 0)
7826 return omit_one_operand (type, dest, len);
7828 if (endp == 2)
7829 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7830 ssize_int (1));
7832 len = fold_convert (TREE_TYPE (dest), len);
7833 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7834 return fold_convert (type, len);
7837 return 0;
7840 /* Fold function call to builtin memmove. Return
7841 NULL_TREE if no simplification can be made. */
7843 static tree
7844 fold_builtin_memmove (tree arglist, tree type)
7846 tree dest, src, len;
7848 if (!validate_arglist (arglist,
7849 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7850 return 0;
7852 dest = TREE_VALUE (arglist);
7853 src = TREE_VALUE (TREE_CHAIN (arglist));
7854 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7856 /* If the LEN parameter is zero, return DEST. */
7857 if (integer_zerop (len))
7858 return omit_one_operand (type, dest, src);
7860 /* If SRC and DEST are the same (and not volatile), return DEST. */
7861 if (operand_equal_p (src, dest, 0))
7862 return omit_one_operand (type, dest, len);
7864 return 0;
7867 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7868 the length of the string to be copied. Return NULL_TREE if no
7869 simplification can be made. */
7871 tree
7872 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7874 tree dest, src, fn;
7876 if (!validate_arglist (arglist,
7877 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7878 return 0;
7880 dest = TREE_VALUE (arglist);
7881 src = TREE_VALUE (TREE_CHAIN (arglist));
7883 /* If SRC and DEST are the same (and not volatile), return DEST. */
7884 if (operand_equal_p (src, dest, 0))
7885 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7887 if (optimize_size)
7888 return 0;
7890 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7891 if (!fn)
7892 return 0;
7894 if (!len)
7896 len = c_strlen (src, 1);
7897 if (! len || TREE_SIDE_EFFECTS (len))
7898 return 0;
7901 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7902 arglist = build_tree_list (NULL_TREE, len);
7903 arglist = tree_cons (NULL_TREE, src, arglist);
7904 arglist = tree_cons (NULL_TREE, dest, arglist);
7905 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7906 build_function_call_expr (fn, arglist));
7909 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7910 the length of the source string. Return NULL_TREE if no simplification
7911 can be made. */
7913 tree
7914 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7916 tree dest, src, len, fn;
7918 if (!validate_arglist (arglist,
7919 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7920 return 0;
7922 dest = TREE_VALUE (arglist);
7923 src = TREE_VALUE (TREE_CHAIN (arglist));
7924 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7926 /* If the LEN parameter is zero, return DEST. */
7927 if (integer_zerop (len))
7928 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7930 /* We can't compare slen with len as constants below if len is not a
7931 constant. */
7932 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7933 return 0;
7935 if (!slen)
7936 slen = c_strlen (src, 1);
7938 /* Now, we must be passed a constant src ptr parameter. */
7939 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7940 return 0;
7942 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7944 /* We do not support simplification of this case, though we do
7945 support it when expanding trees into RTL. */
7946 /* FIXME: generate a call to __builtin_memset. */
7947 if (tree_int_cst_lt (slen, len))
7948 return 0;
7950 /* OK transform into builtin memcpy. */
7951 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7952 if (!fn)
7953 return 0;
7954 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7955 build_function_call_expr (fn, arglist));
7958 /* Fold function call to builtin memcmp. Return
7959 NULL_TREE if no simplification can be made. */
7961 static tree
7962 fold_builtin_memcmp (tree arglist)
7964 tree arg1, arg2, len;
7965 const char *p1, *p2;
7967 if (!validate_arglist (arglist,
7968 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7969 return 0;
7971 arg1 = TREE_VALUE (arglist);
7972 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7973 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7975 /* If the LEN parameter is zero, return zero. */
7976 if (integer_zerop (len))
7977 return omit_two_operands (integer_type_node, integer_zero_node,
7978 arg1, arg2);
7980 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7981 if (operand_equal_p (arg1, arg2, 0))
7982 return omit_one_operand (integer_type_node, integer_zero_node, len);
7984 p1 = c_getstr (arg1);
7985 p2 = c_getstr (arg2);
7987 /* If all arguments are constant, and the value of len is not greater
7988 than the lengths of arg1 and arg2, evaluate at compile-time. */
7989 if (host_integerp (len, 1) && p1 && p2
7990 && compare_tree_int (len, strlen (p1) + 1) <= 0
7991 && compare_tree_int (len, strlen (p2) + 1) <= 0)
7993 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7995 if (r > 0)
7996 return integer_one_node;
7997 else if (r < 0)
7998 return integer_minus_one_node;
7999 else
8000 return integer_zero_node;
8003 /* If len parameter is one, return an expression corresponding to
8004 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8005 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8007 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8008 tree cst_uchar_ptr_node
8009 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8011 tree ind1 = fold_convert (integer_type_node,
8012 build1 (INDIRECT_REF, cst_uchar_node,
8013 fold_convert (cst_uchar_ptr_node,
8014 arg1)));
8015 tree ind2 = fold_convert (integer_type_node,
8016 build1 (INDIRECT_REF, cst_uchar_node,
8017 fold_convert (cst_uchar_ptr_node,
8018 arg2)));
8019 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8022 return 0;
8025 /* Fold function call to builtin strcmp. Return
8026 NULL_TREE if no simplification can be made. */
8028 static tree
8029 fold_builtin_strcmp (tree arglist)
8031 tree arg1, arg2;
8032 const char *p1, *p2;
8034 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8035 return 0;
8037 arg1 = TREE_VALUE (arglist);
8038 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8040 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8041 if (operand_equal_p (arg1, arg2, 0))
8042 return integer_zero_node;
8044 p1 = c_getstr (arg1);
8045 p2 = c_getstr (arg2);
8047 if (p1 && p2)
8049 const int i = strcmp (p1, p2);
8050 if (i < 0)
8051 return integer_minus_one_node;
8052 else if (i > 0)
8053 return integer_one_node;
8054 else
8055 return integer_zero_node;
8058 /* If the second arg is "", return *(const unsigned char*)arg1. */
8059 if (p2 && *p2 == '\0')
8061 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8062 tree cst_uchar_ptr_node
8063 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8065 return fold_convert (integer_type_node,
8066 build1 (INDIRECT_REF, cst_uchar_node,
8067 fold_convert (cst_uchar_ptr_node,
8068 arg1)));
8071 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8072 if (p1 && *p1 == '\0')
8074 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8075 tree cst_uchar_ptr_node
8076 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8078 tree temp = fold_convert (integer_type_node,
8079 build1 (INDIRECT_REF, cst_uchar_node,
8080 fold_convert (cst_uchar_ptr_node,
8081 arg2)));
8082 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8085 return 0;
8088 /* Fold function call to builtin strncmp. Return
8089 NULL_TREE if no simplification can be made. */
8091 static tree
8092 fold_builtin_strncmp (tree arglist)
8094 tree arg1, arg2, len;
8095 const char *p1, *p2;
8097 if (!validate_arglist (arglist,
8098 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8099 return 0;
8101 arg1 = TREE_VALUE (arglist);
8102 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8103 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8105 /* If the LEN parameter is zero, return zero. */
8106 if (integer_zerop (len))
8107 return omit_two_operands (integer_type_node, integer_zero_node,
8108 arg1, arg2);
8110 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8111 if (operand_equal_p (arg1, arg2, 0))
8112 return omit_one_operand (integer_type_node, integer_zero_node, len);
8114 p1 = c_getstr (arg1);
8115 p2 = c_getstr (arg2);
8117 if (host_integerp (len, 1) && p1 && p2)
8119 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8120 if (i > 0)
8121 return integer_one_node;
8122 else if (i < 0)
8123 return integer_minus_one_node;
8124 else
8125 return integer_zero_node;
8128 /* If the second arg is "", and the length is greater than zero,
8129 return *(const unsigned char*)arg1. */
8130 if (p2 && *p2 == '\0'
8131 && TREE_CODE (len) == INTEGER_CST
8132 && tree_int_cst_sgn (len) == 1)
8134 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8135 tree cst_uchar_ptr_node
8136 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8138 return fold_convert (integer_type_node,
8139 build1 (INDIRECT_REF, cst_uchar_node,
8140 fold_convert (cst_uchar_ptr_node,
8141 arg1)));
8144 /* If the first arg is "", and the length is greater than zero,
8145 return -*(const unsigned char*)arg2. */
8146 if (p1 && *p1 == '\0'
8147 && TREE_CODE (len) == INTEGER_CST
8148 && tree_int_cst_sgn (len) == 1)
8150 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8151 tree cst_uchar_ptr_node
8152 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8154 tree temp = fold_convert (integer_type_node,
8155 build1 (INDIRECT_REF, cst_uchar_node,
8156 fold_convert (cst_uchar_ptr_node,
8157 arg2)));
8158 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8161 /* If len parameter is one, return an expression corresponding to
8162 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8163 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8165 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8166 tree cst_uchar_ptr_node
8167 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8169 tree ind1 = fold_convert (integer_type_node,
8170 build1 (INDIRECT_REF, cst_uchar_node,
8171 fold_convert (cst_uchar_ptr_node,
8172 arg1)));
8173 tree ind2 = fold_convert (integer_type_node,
8174 build1 (INDIRECT_REF, cst_uchar_node,
8175 fold_convert (cst_uchar_ptr_node,
8176 arg2)));
8177 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8180 return 0;
8183 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8184 NULL_TREE if no simplification can be made. */
8186 static tree
8187 fold_builtin_signbit (tree fndecl, tree arglist)
8189 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8190 tree arg, temp;
8192 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8193 return NULL_TREE;
8195 arg = TREE_VALUE (arglist);
8197 /* If ARG is a compile-time constant, determine the result. */
8198 if (TREE_CODE (arg) == REAL_CST
8199 && !TREE_CONSTANT_OVERFLOW (arg))
8201 REAL_VALUE_TYPE c;
8203 c = TREE_REAL_CST (arg);
8204 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8205 return fold_convert (type, temp);
8208 /* If ARG is non-negative, the result is always zero. */
8209 if (tree_expr_nonnegative_p (arg))
8210 return omit_one_operand (type, integer_zero_node, arg);
8212 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8213 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8214 return fold_build2 (LT_EXPR, type, arg,
8215 build_real (TREE_TYPE (arg), dconst0));
8217 return NULL_TREE;
8220 /* Fold function call to builtin copysign, copysignf or copysignl.
8221 Return NULL_TREE if no simplification can be made. */
8223 static tree
8224 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8226 tree arg1, arg2, tem;
8228 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8229 return NULL_TREE;
8231 arg1 = TREE_VALUE (arglist);
8232 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8234 /* copysign(X,X) is X. */
8235 if (operand_equal_p (arg1, arg2, 0))
8236 return fold_convert (type, arg1);
8238 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8239 if (TREE_CODE (arg1) == REAL_CST
8240 && TREE_CODE (arg2) == REAL_CST
8241 && !TREE_CONSTANT_OVERFLOW (arg1)
8242 && !TREE_CONSTANT_OVERFLOW (arg2))
8244 REAL_VALUE_TYPE c1, c2;
8246 c1 = TREE_REAL_CST (arg1);
8247 c2 = TREE_REAL_CST (arg2);
8248 /* c1.sign := c2.sign. */
8249 real_copysign (&c1, &c2);
8250 return build_real (type, c1);
8253 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8254 Remember to evaluate Y for side-effects. */
8255 if (tree_expr_nonnegative_p (arg2))
8256 return omit_one_operand (type,
8257 fold_build1 (ABS_EXPR, type, arg1),
8258 arg2);
8260 /* Strip sign changing operations for the first argument. */
8261 tem = fold_strip_sign_ops (arg1);
8262 if (tem)
8264 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8265 return build_function_call_expr (fndecl, arglist);
8268 return NULL_TREE;
8271 /* Fold a call to builtin isascii. */
8273 static tree
8274 fold_builtin_isascii (tree arglist)
8276 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8277 return 0;
8278 else
8280 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8281 tree arg = TREE_VALUE (arglist);
8283 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8284 build_int_cst (NULL_TREE,
8285 ~ (unsigned HOST_WIDE_INT) 0x7f));
8286 arg = fold_build2 (EQ_EXPR, integer_type_node,
8287 arg, integer_zero_node);
8289 if (in_gimple_form && !TREE_CONSTANT (arg))
8290 return NULL_TREE;
8291 else
8292 return arg;
8296 /* Fold a call to builtin toascii. */
8298 static tree
8299 fold_builtin_toascii (tree arglist)
8301 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8302 return 0;
8303 else
8305 /* Transform toascii(c) -> (c & 0x7f). */
8306 tree arg = TREE_VALUE (arglist);
8308 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8309 build_int_cst (NULL_TREE, 0x7f));
8313 /* Fold a call to builtin isdigit. */
8315 static tree
8316 fold_builtin_isdigit (tree arglist)
8318 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8319 return 0;
8320 else
8322 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8323 /* According to the C standard, isdigit is unaffected by locale.
8324 However, it definitely is affected by the target character set. */
8325 tree arg;
8326 unsigned HOST_WIDE_INT target_digit0
8327 = lang_hooks.to_target_charset ('0');
8329 if (target_digit0 == 0)
8330 return NULL_TREE;
8332 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8333 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8334 build_int_cst (unsigned_type_node, target_digit0));
8335 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8336 build_int_cst (unsigned_type_node, 9));
8337 if (in_gimple_form && !TREE_CONSTANT (arg))
8338 return NULL_TREE;
8339 else
8340 return arg;
8344 /* Fold a call to fabs, fabsf or fabsl. */
8346 static tree
8347 fold_builtin_fabs (tree arglist, tree type)
8349 tree arg;
8351 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8352 return 0;
8354 arg = TREE_VALUE (arglist);
8355 arg = fold_convert (type, arg);
8356 if (TREE_CODE (arg) == REAL_CST)
8357 return fold_abs_const (arg, type);
8358 return fold_build1 (ABS_EXPR, type, arg);
8361 /* Fold a call to abs, labs, llabs or imaxabs. */
8363 static tree
8364 fold_builtin_abs (tree arglist, tree type)
8366 tree arg;
8368 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8369 return 0;
8371 arg = TREE_VALUE (arglist);
8372 arg = fold_convert (type, arg);
8373 if (TREE_CODE (arg) == INTEGER_CST)
8374 return fold_abs_const (arg, type);
8375 return fold_build1 (ABS_EXPR, type, arg);
8378 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8379 EXP is the CALL_EXPR for the call. */
8381 static tree
8382 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8384 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8385 tree arg;
8386 REAL_VALUE_TYPE r;
8388 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8390 /* Check that we have exactly one argument. */
8391 if (arglist == 0)
8393 error ("too few arguments to function %qs",
8394 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8395 return error_mark_node;
8397 else if (TREE_CHAIN (arglist) != 0)
8399 error ("too many arguments to function %qs",
8400 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8401 return error_mark_node;
8403 else
8405 error ("non-floating-point argument to function %qs",
8406 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8407 return error_mark_node;
8411 arg = TREE_VALUE (arglist);
8412 switch (builtin_index)
8414 case BUILT_IN_ISINF:
8415 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8416 return omit_one_operand (type, integer_zero_node, arg);
8418 if (TREE_CODE (arg) == REAL_CST)
8420 r = TREE_REAL_CST (arg);
8421 if (real_isinf (&r))
8422 return real_compare (GT_EXPR, &r, &dconst0)
8423 ? integer_one_node : integer_minus_one_node;
8424 else
8425 return integer_zero_node;
8428 return NULL_TREE;
8430 case BUILT_IN_FINITE:
8431 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8432 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8433 return omit_one_operand (type, integer_zero_node, arg);
8435 if (TREE_CODE (arg) == REAL_CST)
8437 r = TREE_REAL_CST (arg);
8438 return real_isinf (&r) || real_isnan (&r)
8439 ? integer_zero_node : integer_one_node;
8442 return NULL_TREE;
8444 case BUILT_IN_ISNAN:
8445 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8446 return omit_one_operand (type, integer_zero_node, arg);
8448 if (TREE_CODE (arg) == REAL_CST)
8450 r = TREE_REAL_CST (arg);
8451 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8454 arg = builtin_save_expr (arg);
8455 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8457 default:
8458 gcc_unreachable ();
8462 /* Fold a call to an unordered comparison function such as
8463 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8464 being called and ARGLIST is the argument list for the call.
8465 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8466 the opposite of the desired result. UNORDERED_CODE is used
8467 for modes that can hold NaNs and ORDERED_CODE is used for
8468 the rest. */
8470 static tree
8471 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8472 enum tree_code unordered_code,
8473 enum tree_code ordered_code)
8475 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8476 enum tree_code code;
8477 tree arg0, arg1;
8478 tree type0, type1;
8479 enum tree_code code0, code1;
8480 tree cmp_type = NULL_TREE;
8482 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8484 /* Check that we have exactly two arguments. */
8485 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8487 error ("too few arguments to function %qs",
8488 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8489 return error_mark_node;
8491 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8493 error ("too many arguments to function %qs",
8494 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8495 return error_mark_node;
8499 arg0 = TREE_VALUE (arglist);
8500 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8502 type0 = TREE_TYPE (arg0);
8503 type1 = TREE_TYPE (arg1);
8505 code0 = TREE_CODE (type0);
8506 code1 = TREE_CODE (type1);
8508 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8509 /* Choose the wider of two real types. */
8510 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8511 ? type0 : type1;
8512 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8513 cmp_type = type0;
8514 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8515 cmp_type = type1;
8516 else
8518 error ("non-floating-point argument to function %qs",
8519 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8520 return error_mark_node;
8523 arg0 = fold_convert (cmp_type, arg0);
8524 arg1 = fold_convert (cmp_type, arg1);
8526 if (unordered_code == UNORDERED_EXPR)
8528 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8529 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8530 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8533 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8534 : ordered_code;
8535 return fold_build1 (TRUTH_NOT_EXPR, type,
8536 fold_build2 (code, type, arg0, arg1));
8539 /* Used by constant folding to simplify calls to builtin functions. EXP is
8540 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8541 result of the function call is ignored. This function returns NULL_TREE
8542 if no simplification was possible. */
8544 static tree
8545 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8547 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8548 enum built_in_function fcode;
8550 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8551 return targetm.fold_builtin (fndecl, arglist, ignore);
8553 fcode = DECL_FUNCTION_CODE (fndecl);
8554 switch (fcode)
8556 case BUILT_IN_FPUTS:
8557 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8559 case BUILT_IN_FPUTS_UNLOCKED:
8560 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8562 case BUILT_IN_STRSTR:
8563 return fold_builtin_strstr (arglist, type);
8565 case BUILT_IN_STRCAT:
8566 return fold_builtin_strcat (arglist);
8568 case BUILT_IN_STRNCAT:
8569 return fold_builtin_strncat (arglist);
8571 case BUILT_IN_STRSPN:
8572 return fold_builtin_strspn (arglist);
8574 case BUILT_IN_STRCSPN:
8575 return fold_builtin_strcspn (arglist);
8577 case BUILT_IN_STRCHR:
8578 case BUILT_IN_INDEX:
8579 return fold_builtin_strchr (arglist, type);
8581 case BUILT_IN_STRRCHR:
8582 case BUILT_IN_RINDEX:
8583 return fold_builtin_strrchr (arglist, type);
8585 case BUILT_IN_STRCPY:
8586 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8588 case BUILT_IN_STRNCPY:
8589 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8591 case BUILT_IN_STRCMP:
8592 return fold_builtin_strcmp (arglist);
8594 case BUILT_IN_STRNCMP:
8595 return fold_builtin_strncmp (arglist);
8597 case BUILT_IN_STRPBRK:
8598 return fold_builtin_strpbrk (arglist, type);
8600 case BUILT_IN_BCMP:
8601 case BUILT_IN_MEMCMP:
8602 return fold_builtin_memcmp (arglist);
8604 case BUILT_IN_SPRINTF:
8605 return fold_builtin_sprintf (arglist, ignore);
8607 case BUILT_IN_CONSTANT_P:
8609 tree val;
8611 val = fold_builtin_constant_p (arglist);
8612 /* Gimplification will pull the CALL_EXPR for the builtin out of
8613 an if condition. When not optimizing, we'll not CSE it back.
8614 To avoid link error types of regressions, return false now. */
8615 if (!val && !optimize)
8616 val = integer_zero_node;
8618 return val;
8621 case BUILT_IN_EXPECT:
8622 return fold_builtin_expect (arglist);
8624 case BUILT_IN_CLASSIFY_TYPE:
8625 return fold_builtin_classify_type (arglist);
8627 case BUILT_IN_STRLEN:
8628 return fold_builtin_strlen (arglist);
8630 CASE_FLT_FN (BUILT_IN_FABS):
8631 return fold_builtin_fabs (arglist, type);
8633 case BUILT_IN_ABS:
8634 case BUILT_IN_LABS:
8635 case BUILT_IN_LLABS:
8636 case BUILT_IN_IMAXABS:
8637 return fold_builtin_abs (arglist, type);
8639 CASE_FLT_FN (BUILT_IN_CONJ):
8640 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8641 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8642 break;
8644 CASE_FLT_FN (BUILT_IN_CREAL):
8645 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8646 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8647 TREE_VALUE (arglist)));
8648 break;
8650 CASE_FLT_FN (BUILT_IN_CIMAG):
8651 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8652 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8653 TREE_VALUE (arglist)));
8654 break;
8656 CASE_FLT_FN (BUILT_IN_CABS):
8657 return fold_builtin_cabs (arglist, type);
8659 CASE_FLT_FN (BUILT_IN_SQRT):
8660 return fold_builtin_sqrt (arglist, type);
8662 CASE_FLT_FN (BUILT_IN_CBRT):
8663 return fold_builtin_cbrt (arglist, type);
8665 CASE_FLT_FN (BUILT_IN_SIN):
8666 return fold_builtin_sin (arglist);
8668 CASE_FLT_FN (BUILT_IN_COS):
8669 return fold_builtin_cos (arglist, type, fndecl);
8671 CASE_FLT_FN (BUILT_IN_EXP):
8672 return fold_builtin_exponent (fndecl, arglist, &dconste);
8674 CASE_FLT_FN (BUILT_IN_EXP2):
8675 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8677 CASE_FLT_FN (BUILT_IN_EXP10):
8678 CASE_FLT_FN (BUILT_IN_POW10):
8679 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8681 CASE_FLT_FN (BUILT_IN_LOG):
8682 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8684 CASE_FLT_FN (BUILT_IN_LOG2):
8685 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8687 CASE_FLT_FN (BUILT_IN_LOG10):
8688 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8690 CASE_FLT_FN (BUILT_IN_TAN):
8691 return fold_builtin_tan (arglist);
8693 CASE_FLT_FN (BUILT_IN_ATAN):
8694 return fold_builtin_atan (arglist, type);
8696 CASE_FLT_FN (BUILT_IN_POW):
8697 return fold_builtin_pow (fndecl, arglist, type);
8699 CASE_FLT_FN (BUILT_IN_POWI):
8700 return fold_builtin_powi (fndecl, arglist, type);
8702 CASE_FLT_FN (BUILT_IN_INF):
8703 case BUILT_IN_INFD32:
8704 case BUILT_IN_INFD64:
8705 case BUILT_IN_INFD128:
8706 return fold_builtin_inf (type, true);
8708 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8709 return fold_builtin_inf (type, false);
8711 CASE_FLT_FN (BUILT_IN_NAN):
8712 case BUILT_IN_NAND32:
8713 case BUILT_IN_NAND64:
8714 case BUILT_IN_NAND128:
8715 return fold_builtin_nan (arglist, type, true);
8717 CASE_FLT_FN (BUILT_IN_NANS):
8718 return fold_builtin_nan (arglist, type, false);
8720 CASE_FLT_FN (BUILT_IN_FLOOR):
8721 return fold_builtin_floor (fndecl, arglist);
8723 CASE_FLT_FN (BUILT_IN_CEIL):
8724 return fold_builtin_ceil (fndecl, arglist);
8726 CASE_FLT_FN (BUILT_IN_TRUNC):
8727 return fold_builtin_trunc (fndecl, arglist);
8729 CASE_FLT_FN (BUILT_IN_ROUND):
8730 return fold_builtin_round (fndecl, arglist);
8732 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8733 CASE_FLT_FN (BUILT_IN_RINT):
8734 return fold_trunc_transparent_mathfn (fndecl, arglist);
8736 CASE_FLT_FN (BUILT_IN_LCEIL):
8737 CASE_FLT_FN (BUILT_IN_LLCEIL):
8738 CASE_FLT_FN (BUILT_IN_LFLOOR):
8739 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8740 CASE_FLT_FN (BUILT_IN_LROUND):
8741 CASE_FLT_FN (BUILT_IN_LLROUND):
8742 return fold_builtin_int_roundingfn (fndecl, arglist);
8744 CASE_FLT_FN (BUILT_IN_LRINT):
8745 CASE_FLT_FN (BUILT_IN_LLRINT):
8746 return fold_fixed_mathfn (fndecl, arglist);
8748 CASE_INT_FN (BUILT_IN_FFS):
8749 CASE_INT_FN (BUILT_IN_CLZ):
8750 CASE_INT_FN (BUILT_IN_CTZ):
8751 CASE_INT_FN (BUILT_IN_POPCOUNT):
8752 CASE_INT_FN (BUILT_IN_PARITY):
8753 return fold_builtin_bitop (fndecl, arglist);
8755 case BUILT_IN_MEMCPY:
8756 return fold_builtin_memcpy (fndecl, arglist);
8758 case BUILT_IN_MEMPCPY:
8759 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8761 case BUILT_IN_MEMMOVE:
8762 return fold_builtin_memmove (arglist, type);
8764 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8765 return fold_builtin_signbit (fndecl, arglist);
8767 case BUILT_IN_ISASCII:
8768 return fold_builtin_isascii (arglist);
8770 case BUILT_IN_TOASCII:
8771 return fold_builtin_toascii (arglist);
8773 case BUILT_IN_ISDIGIT:
8774 return fold_builtin_isdigit (arglist);
8776 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8777 return fold_builtin_copysign (fndecl, arglist, type);
8779 CASE_FLT_FN (BUILT_IN_FINITE):
8780 case BUILT_IN_FINITED32:
8781 case BUILT_IN_FINITED64:
8782 case BUILT_IN_FINITED128:
8783 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8785 CASE_FLT_FN (BUILT_IN_ISINF):
8786 case BUILT_IN_ISINFD32:
8787 case BUILT_IN_ISINFD64:
8788 case BUILT_IN_ISINFD128:
8789 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8791 CASE_FLT_FN (BUILT_IN_ISNAN):
8792 case BUILT_IN_ISNAND32:
8793 case BUILT_IN_ISNAND64:
8794 case BUILT_IN_ISNAND128:
8795 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8797 case BUILT_IN_ISGREATER:
8798 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8799 case BUILT_IN_ISGREATEREQUAL:
8800 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8801 case BUILT_IN_ISLESS:
8802 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8803 case BUILT_IN_ISLESSEQUAL:
8804 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8805 case BUILT_IN_ISLESSGREATER:
8806 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8807 case BUILT_IN_ISUNORDERED:
8808 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8809 NOP_EXPR);
8811 /* We do the folding for va_start in the expander. */
8812 case BUILT_IN_VA_START:
8813 break;
8815 case BUILT_IN_OBJECT_SIZE:
8816 return fold_builtin_object_size (arglist);
8817 case BUILT_IN_MEMCPY_CHK:
8818 case BUILT_IN_MEMPCPY_CHK:
8819 case BUILT_IN_MEMMOVE_CHK:
8820 case BUILT_IN_MEMSET_CHK:
8821 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8822 DECL_FUNCTION_CODE (fndecl));
8823 case BUILT_IN_STRCPY_CHK:
8824 case BUILT_IN_STPCPY_CHK:
8825 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8826 DECL_FUNCTION_CODE (fndecl));
8827 case BUILT_IN_STRNCPY_CHK:
8828 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8829 case BUILT_IN_STRCAT_CHK:
8830 return fold_builtin_strcat_chk (fndecl, arglist);
8831 case BUILT_IN_STRNCAT_CHK:
8832 return fold_builtin_strncat_chk (fndecl, arglist);
8833 case BUILT_IN_SPRINTF_CHK:
8834 case BUILT_IN_VSPRINTF_CHK:
8835 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8836 case BUILT_IN_SNPRINTF_CHK:
8837 case BUILT_IN_VSNPRINTF_CHK:
8838 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8839 DECL_FUNCTION_CODE (fndecl));
8841 case BUILT_IN_PRINTF:
8842 case BUILT_IN_PRINTF_UNLOCKED:
8843 case BUILT_IN_VPRINTF:
8844 case BUILT_IN_PRINTF_CHK:
8845 case BUILT_IN_VPRINTF_CHK:
8846 return fold_builtin_printf (fndecl, arglist, ignore,
8847 DECL_FUNCTION_CODE (fndecl));
8849 case BUILT_IN_FPRINTF:
8850 case BUILT_IN_FPRINTF_UNLOCKED:
8851 case BUILT_IN_VFPRINTF:
8852 case BUILT_IN_FPRINTF_CHK:
8853 case BUILT_IN_VFPRINTF_CHK:
8854 return fold_builtin_fprintf (fndecl, arglist, ignore,
8855 DECL_FUNCTION_CODE (fndecl));
8857 default:
8858 break;
8861 return 0;
8864 /* A wrapper function for builtin folding that prevents warnings for
8865 "statement without effect" and the like, caused by removing the
8866 call node earlier than the warning is generated. */
8868 tree
8869 fold_builtin (tree fndecl, tree arglist, bool ignore)
8871 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8872 if (exp)
8874 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8875 TREE_NO_WARNING (exp) = 1;
8878 return exp;
8881 /* Conveniently construct a function call expression. */
8883 tree
8884 build_function_call_expr (tree fn, tree arglist)
8886 tree call_expr;
8888 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8889 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8890 call_expr, arglist, NULL_TREE);
8893 /* This function validates the types of a function call argument list
8894 represented as a tree chain of parameters against a specified list
8895 of tree_codes. If the last specifier is a 0, that represents an
8896 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8898 static int
8899 validate_arglist (tree arglist, ...)
8901 enum tree_code code;
8902 int res = 0;
8903 va_list ap;
8905 va_start (ap, arglist);
8909 code = va_arg (ap, enum tree_code);
8910 switch (code)
8912 case 0:
8913 /* This signifies an ellipses, any further arguments are all ok. */
8914 res = 1;
8915 goto end;
8916 case VOID_TYPE:
8917 /* This signifies an endlink, if no arguments remain, return
8918 true, otherwise return false. */
8919 res = arglist == 0;
8920 goto end;
8921 default:
8922 /* If no parameters remain or the parameter's code does not
8923 match the specified code, return false. Otherwise continue
8924 checking any remaining arguments. */
8925 if (arglist == 0)
8926 goto end;
8927 if (code == POINTER_TYPE)
8929 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8930 goto end;
8932 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8933 goto end;
8934 break;
8936 arglist = TREE_CHAIN (arglist);
8938 while (1);
8940 /* We need gotos here since we can only have one VA_CLOSE in a
8941 function. */
8942 end: ;
8943 va_end (ap);
8945 return res;
8948 /* Default target-specific builtin expander that does nothing. */
8951 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8952 rtx target ATTRIBUTE_UNUSED,
8953 rtx subtarget ATTRIBUTE_UNUSED,
8954 enum machine_mode mode ATTRIBUTE_UNUSED,
8955 int ignore ATTRIBUTE_UNUSED)
8957 return NULL_RTX;
8960 /* Default target-specific library builtin expander that does nothing. */
8963 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
8964 rtx target ATTRIBUTE_UNUSED,
8965 rtx subtarget ATTRIBUTE_UNUSED,
8966 enum machine_mode mode ATTRIBUTE_UNUSED,
8967 int ignore ATTRIBUTE_UNUSED)
8969 return NULL_RTX;
8972 /* Returns true is EXP represents data that would potentially reside
8973 in a readonly section. */
8975 static bool
8976 readonly_data_expr (tree exp)
8978 STRIP_NOPS (exp);
8980 if (TREE_CODE (exp) != ADDR_EXPR)
8981 return false;
8983 exp = get_base_address (TREE_OPERAND (exp, 0));
8984 if (!exp)
8985 return false;
8987 /* Make sure we call decl_readonly_section only for trees it
8988 can handle (since it returns true for everything it doesn't
8989 understand). */
8990 if (TREE_CODE (exp) == STRING_CST
8991 || TREE_CODE (exp) == CONSTRUCTOR
8992 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8993 return decl_readonly_section (exp, 0);
8994 else
8995 return false;
8998 /* Simplify a call to the strstr builtin.
9000 Return 0 if no simplification was possible, otherwise return the
9001 simplified form of the call as a tree.
9003 The simplified form may be a constant or other expression which
9004 computes the same value, but in a more efficient manner (including
9005 calls to other builtin functions).
9007 The call may contain arguments which need to be evaluated, but
9008 which are not useful to determine the result of the call. In
9009 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9010 COMPOUND_EXPR will be an argument which must be evaluated.
9011 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9012 COMPOUND_EXPR in the chain will contain the tree for the simplified
9013 form of the builtin function call. */
9015 static tree
9016 fold_builtin_strstr (tree arglist, tree type)
9018 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9019 return 0;
9020 else
9022 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9023 tree fn;
9024 const char *p1, *p2;
9026 p2 = c_getstr (s2);
9027 if (p2 == NULL)
9028 return 0;
9030 p1 = c_getstr (s1);
9031 if (p1 != NULL)
9033 const char *r = strstr (p1, p2);
9034 tree tem;
9036 if (r == NULL)
9037 return build_int_cst (TREE_TYPE (s1), 0);
9039 /* Return an offset into the constant string argument. */
9040 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9041 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9042 return fold_convert (type, tem);
9045 /* The argument is const char *, and the result is char *, so we need
9046 a type conversion here to avoid a warning. */
9047 if (p2[0] == '\0')
9048 return fold_convert (type, s1);
9050 if (p2[1] != '\0')
9051 return 0;
9053 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9054 if (!fn)
9055 return 0;
9057 /* New argument list transforming strstr(s1, s2) to
9058 strchr(s1, s2[0]). */
9059 arglist = build_tree_list (NULL_TREE,
9060 build_int_cst (NULL_TREE, p2[0]));
9061 arglist = tree_cons (NULL_TREE, s1, arglist);
9062 return build_function_call_expr (fn, arglist);
9066 /* Simplify a call to the strchr builtin.
9068 Return 0 if no simplification was possible, otherwise return the
9069 simplified form of the call as a tree.
9071 The simplified form may be a constant or other expression which
9072 computes the same value, but in a more efficient manner (including
9073 calls to other builtin functions).
9075 The call may contain arguments which need to be evaluated, but
9076 which are not useful to determine the result of the call. In
9077 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9078 COMPOUND_EXPR will be an argument which must be evaluated.
9079 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9080 COMPOUND_EXPR in the chain will contain the tree for the simplified
9081 form of the builtin function call. */
9083 static tree
9084 fold_builtin_strchr (tree arglist, tree type)
9086 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9087 return 0;
9088 else
9090 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9091 const char *p1;
9093 if (TREE_CODE (s2) != INTEGER_CST)
9094 return 0;
9096 p1 = c_getstr (s1);
9097 if (p1 != NULL)
9099 char c;
9100 const char *r;
9101 tree tem;
9103 if (target_char_cast (s2, &c))
9104 return 0;
9106 r = strchr (p1, c);
9108 if (r == NULL)
9109 return build_int_cst (TREE_TYPE (s1), 0);
9111 /* Return an offset into the constant string argument. */
9112 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9113 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9114 return fold_convert (type, tem);
9116 return 0;
9120 /* Simplify a call to the strrchr builtin.
9122 Return 0 if no simplification was possible, otherwise return the
9123 simplified form of the call as a tree.
9125 The simplified form may be a constant or other expression which
9126 computes the same value, but in a more efficient manner (including
9127 calls to other builtin functions).
9129 The call may contain arguments which need to be evaluated, but
9130 which are not useful to determine the result of the call. In
9131 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9132 COMPOUND_EXPR will be an argument which must be evaluated.
9133 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9134 COMPOUND_EXPR in the chain will contain the tree for the simplified
9135 form of the builtin function call. */
9137 static tree
9138 fold_builtin_strrchr (tree arglist, tree type)
9140 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9141 return 0;
9142 else
9144 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9145 tree fn;
9146 const char *p1;
9148 if (TREE_CODE (s2) != INTEGER_CST)
9149 return 0;
9151 p1 = c_getstr (s1);
9152 if (p1 != NULL)
9154 char c;
9155 const char *r;
9156 tree tem;
9158 if (target_char_cast (s2, &c))
9159 return 0;
9161 r = strrchr (p1, c);
9163 if (r == NULL)
9164 return build_int_cst (TREE_TYPE (s1), 0);
9166 /* Return an offset into the constant string argument. */
9167 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9168 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9169 return fold_convert (type, tem);
9172 if (! integer_zerop (s2))
9173 return 0;
9175 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9176 if (!fn)
9177 return 0;
9179 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9180 return build_function_call_expr (fn, arglist);
9184 /* Simplify a call to the strpbrk builtin.
9186 Return 0 if no simplification was possible, otherwise return the
9187 simplified form of the call as a tree.
9189 The simplified form may be a constant or other expression which
9190 computes the same value, but in a more efficient manner (including
9191 calls to other builtin functions).
9193 The call may contain arguments which need to be evaluated, but
9194 which are not useful to determine the result of the call. In
9195 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9196 COMPOUND_EXPR will be an argument which must be evaluated.
9197 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9198 COMPOUND_EXPR in the chain will contain the tree for the simplified
9199 form of the builtin function call. */
9201 static tree
9202 fold_builtin_strpbrk (tree arglist, tree type)
9204 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9205 return 0;
9206 else
9208 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9209 tree fn;
9210 const char *p1, *p2;
9212 p2 = c_getstr (s2);
9213 if (p2 == NULL)
9214 return 0;
9216 p1 = c_getstr (s1);
9217 if (p1 != NULL)
9219 const char *r = strpbrk (p1, p2);
9220 tree tem;
9222 if (r == NULL)
9223 return build_int_cst (TREE_TYPE (s1), 0);
9225 /* Return an offset into the constant string argument. */
9226 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9227 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9228 return fold_convert (type, tem);
9231 if (p2[0] == '\0')
9232 /* strpbrk(x, "") == NULL.
9233 Evaluate and ignore s1 in case it had side-effects. */
9234 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9236 if (p2[1] != '\0')
9237 return 0; /* Really call strpbrk. */
9239 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9240 if (!fn)
9241 return 0;
9243 /* New argument list transforming strpbrk(s1, s2) to
9244 strchr(s1, s2[0]). */
9245 arglist = build_tree_list (NULL_TREE,
9246 build_int_cst (NULL_TREE, p2[0]));
9247 arglist = tree_cons (NULL_TREE, s1, arglist);
9248 return build_function_call_expr (fn, arglist);
9252 /* Simplify a call to the strcat builtin.
9254 Return 0 if no simplification was possible, otherwise return the
9255 simplified form of the call as a tree.
9257 The simplified form may be a constant or other expression which
9258 computes the same value, but in a more efficient manner (including
9259 calls to other builtin functions).
9261 The call may contain arguments which need to be evaluated, but
9262 which are not useful to determine the result of the call. In
9263 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9264 COMPOUND_EXPR will be an argument which must be evaluated.
9265 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9266 COMPOUND_EXPR in the chain will contain the tree for the simplified
9267 form of the builtin function call. */
9269 static tree
9270 fold_builtin_strcat (tree arglist)
9272 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9273 return 0;
9274 else
9276 tree dst = TREE_VALUE (arglist),
9277 src = TREE_VALUE (TREE_CHAIN (arglist));
9278 const char *p = c_getstr (src);
9280 /* If the string length is zero, return the dst parameter. */
9281 if (p && *p == '\0')
9282 return dst;
9284 return 0;
9288 /* Simplify a call to the strncat builtin.
9290 Return 0 if no simplification was possible, otherwise return the
9291 simplified form of the call as a tree.
9293 The simplified form may be a constant or other expression which
9294 computes the same value, but in a more efficient manner (including
9295 calls to other builtin functions).
9297 The call may contain arguments which need to be evaluated, but
9298 which are not useful to determine the result of the call. In
9299 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9300 COMPOUND_EXPR will be an argument which must be evaluated.
9301 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9302 COMPOUND_EXPR in the chain will contain the tree for the simplified
9303 form of the builtin function call. */
9305 static tree
9306 fold_builtin_strncat (tree arglist)
9308 if (!validate_arglist (arglist,
9309 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9310 return 0;
9311 else
9313 tree dst = TREE_VALUE (arglist);
9314 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9315 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9316 const char *p = c_getstr (src);
9318 /* If the requested length is zero, or the src parameter string
9319 length is zero, return the dst parameter. */
9320 if (integer_zerop (len) || (p && *p == '\0'))
9321 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9323 /* If the requested len is greater than or equal to the string
9324 length, call strcat. */
9325 if (TREE_CODE (len) == INTEGER_CST && p
9326 && compare_tree_int (len, strlen (p)) >= 0)
9328 tree newarglist
9329 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9330 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9332 /* If the replacement _DECL isn't initialized, don't do the
9333 transformation. */
9334 if (!fn)
9335 return 0;
9337 return build_function_call_expr (fn, newarglist);
9339 return 0;
9343 /* Simplify a call to the strspn builtin.
9345 Return 0 if no simplification was possible, otherwise return the
9346 simplified form of the call as a tree.
9348 The simplified form may be a constant or other expression which
9349 computes the same value, but in a more efficient manner (including
9350 calls to other builtin functions).
9352 The call may contain arguments which need to be evaluated, but
9353 which are not useful to determine the result of the call. In
9354 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9355 COMPOUND_EXPR will be an argument which must be evaluated.
9356 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9357 COMPOUND_EXPR in the chain will contain the tree for the simplified
9358 form of the builtin function call. */
9360 static tree
9361 fold_builtin_strspn (tree arglist)
9363 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9364 return 0;
9365 else
9367 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9368 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9370 /* If both arguments are constants, evaluate at compile-time. */
9371 if (p1 && p2)
9373 const size_t r = strspn (p1, p2);
9374 return size_int (r);
9377 /* If either argument is "", return 0. */
9378 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9379 /* Evaluate and ignore both arguments in case either one has
9380 side-effects. */
9381 return omit_two_operands (integer_type_node, integer_zero_node,
9382 s1, s2);
9383 return 0;
9387 /* Simplify a call to the strcspn builtin.
9389 Return 0 if no simplification was possible, otherwise return the
9390 simplified form of the call as a tree.
9392 The simplified form may be a constant or other expression which
9393 computes the same value, but in a more efficient manner (including
9394 calls to other builtin functions).
9396 The call may contain arguments which need to be evaluated, but
9397 which are not useful to determine the result of the call. In
9398 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9399 COMPOUND_EXPR will be an argument which must be evaluated.
9400 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9401 COMPOUND_EXPR in the chain will contain the tree for the simplified
9402 form of the builtin function call. */
9404 static tree
9405 fold_builtin_strcspn (tree arglist)
9407 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9408 return 0;
9409 else
9411 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9412 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9414 /* If both arguments are constants, evaluate at compile-time. */
9415 if (p1 && p2)
9417 const size_t r = strcspn (p1, p2);
9418 return size_int (r);
9421 /* If the first argument is "", return 0. */
9422 if (p1 && *p1 == '\0')
9424 /* Evaluate and ignore argument s2 in case it has
9425 side-effects. */
9426 return omit_one_operand (integer_type_node,
9427 integer_zero_node, s2);
9430 /* If the second argument is "", return __builtin_strlen(s1). */
9431 if (p2 && *p2 == '\0')
9433 tree newarglist = build_tree_list (NULL_TREE, s1),
9434 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9436 /* If the replacement _DECL isn't initialized, don't do the
9437 transformation. */
9438 if (!fn)
9439 return 0;
9441 return build_function_call_expr (fn, newarglist);
9443 return 0;
9447 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9448 by the builtin will be ignored. UNLOCKED is true is true if this
9449 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9450 the known length of the string. Return NULL_TREE if no simplification
9451 was possible. */
9453 tree
9454 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9456 tree fn;
9457 /* If we're using an unlocked function, assume the other unlocked
9458 functions exist explicitly. */
9459 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9460 : implicit_built_in_decls[BUILT_IN_FPUTC];
9461 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9462 : implicit_built_in_decls[BUILT_IN_FWRITE];
9464 /* If the return value is used, don't do the transformation. */
9465 if (!ignore)
9466 return 0;
9468 /* Verify the arguments in the original call. */
9469 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9470 return 0;
9472 if (! len)
9473 len = c_strlen (TREE_VALUE (arglist), 0);
9475 /* Get the length of the string passed to fputs. If the length
9476 can't be determined, punt. */
9477 if (!len
9478 || TREE_CODE (len) != INTEGER_CST)
9479 return 0;
9481 switch (compare_tree_int (len, 1))
9483 case -1: /* length is 0, delete the call entirely . */
9484 return omit_one_operand (integer_type_node, integer_zero_node,
9485 TREE_VALUE (TREE_CHAIN (arglist)));
9487 case 0: /* length is 1, call fputc. */
9489 const char *p = c_getstr (TREE_VALUE (arglist));
9491 if (p != NULL)
9493 /* New argument list transforming fputs(string, stream) to
9494 fputc(string[0], stream). */
9495 arglist = build_tree_list (NULL_TREE,
9496 TREE_VALUE (TREE_CHAIN (arglist)));
9497 arglist = tree_cons (NULL_TREE,
9498 build_int_cst (NULL_TREE, p[0]),
9499 arglist);
9500 fn = fn_fputc;
9501 break;
9504 /* FALLTHROUGH */
9505 case 1: /* length is greater than 1, call fwrite. */
9507 tree string_arg;
9509 /* If optimizing for size keep fputs. */
9510 if (optimize_size)
9511 return 0;
9512 string_arg = TREE_VALUE (arglist);
9513 /* New argument list transforming fputs(string, stream) to
9514 fwrite(string, 1, len, stream). */
9515 arglist = build_tree_list (NULL_TREE,
9516 TREE_VALUE (TREE_CHAIN (arglist)));
9517 arglist = tree_cons (NULL_TREE, len, arglist);
9518 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9519 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9520 fn = fn_fwrite;
9521 break;
9523 default:
9524 gcc_unreachable ();
9527 /* If the replacement _DECL isn't initialized, don't do the
9528 transformation. */
9529 if (!fn)
9530 return 0;
9532 /* These optimizations are only performed when the result is ignored,
9533 hence there's no need to cast the result to integer_type_node. */
9534 return build_function_call_expr (fn, arglist);
9537 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9538 produced. False otherwise. This is done so that we don't output the error
9539 or warning twice or three times. */
9540 bool
9541 fold_builtin_next_arg (tree arglist)
9543 tree fntype = TREE_TYPE (current_function_decl);
9545 if (TYPE_ARG_TYPES (fntype) == 0
9546 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9547 == void_type_node))
9549 error ("%<va_start%> used in function with fixed args");
9550 return true;
9552 else if (!arglist)
9554 /* Evidently an out of date version of <stdarg.h>; can't validate
9555 va_start's second argument, but can still work as intended. */
9556 warning (0, "%<__builtin_next_arg%> called without an argument");
9557 return true;
9559 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9560 when we checked the arguments and if needed issued a warning. */
9561 else if (!TREE_CHAIN (arglist)
9562 || !integer_zerop (TREE_VALUE (arglist))
9563 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9564 || TREE_CHAIN (TREE_CHAIN (arglist)))
9566 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9567 tree arg = TREE_VALUE (arglist);
9569 if (TREE_CHAIN (arglist))
9571 error ("%<va_start%> used with too many arguments");
9572 return true;
9575 /* Strip off all nops for the sake of the comparison. This
9576 is not quite the same as STRIP_NOPS. It does more.
9577 We must also strip off INDIRECT_EXPR for C++ reference
9578 parameters. */
9579 while (TREE_CODE (arg) == NOP_EXPR
9580 || TREE_CODE (arg) == CONVERT_EXPR
9581 || TREE_CODE (arg) == NON_LVALUE_EXPR
9582 || TREE_CODE (arg) == INDIRECT_REF)
9583 arg = TREE_OPERAND (arg, 0);
9584 if (arg != last_parm)
9586 /* FIXME: Sometimes with the tree optimizers we can get the
9587 not the last argument even though the user used the last
9588 argument. We just warn and set the arg to be the last
9589 argument so that we will get wrong-code because of
9590 it. */
9591 warning (0, "second parameter of %<va_start%> not last named argument");
9593 /* We want to verify the second parameter just once before the tree
9594 optimizers are run and then avoid keeping it in the tree,
9595 as otherwise we could warn even for correct code like:
9596 void foo (int i, ...)
9597 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9598 TREE_VALUE (arglist) = integer_zero_node;
9599 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9601 return false;
9605 /* Simplify a call to the sprintf builtin.
9607 Return 0 if no simplification was possible, otherwise return the
9608 simplified form of the call as a tree. If IGNORED is true, it means that
9609 the caller does not use the returned value of the function. */
9611 static tree
9612 fold_builtin_sprintf (tree arglist, int ignored)
9614 tree call, retval, dest, fmt;
9615 const char *fmt_str = NULL;
9617 /* Verify the required arguments in the original call. We deal with two
9618 types of sprintf() calls: 'sprintf (str, fmt)' and
9619 'sprintf (dest, "%s", orig)'. */
9620 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9621 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9622 VOID_TYPE))
9623 return NULL_TREE;
9625 /* Get the destination string and the format specifier. */
9626 dest = TREE_VALUE (arglist);
9627 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9629 /* Check whether the format is a literal string constant. */
9630 fmt_str = c_getstr (fmt);
9631 if (fmt_str == NULL)
9632 return NULL_TREE;
9634 call = NULL_TREE;
9635 retval = NULL_TREE;
9637 if (!init_target_chars())
9638 return 0;
9640 /* If the format doesn't contain % args or %%, use strcpy. */
9641 if (strchr (fmt_str, target_percent) == NULL)
9643 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9645 if (!fn)
9646 return NULL_TREE;
9648 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9649 'format' is known to contain no % formats. */
9650 arglist = build_tree_list (NULL_TREE, fmt);
9651 arglist = tree_cons (NULL_TREE, dest, arglist);
9652 call = build_function_call_expr (fn, arglist);
9653 if (!ignored)
9654 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9657 /* If the format is "%s", use strcpy if the result isn't used. */
9658 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9660 tree fn, orig;
9661 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9663 if (!fn)
9664 return NULL_TREE;
9666 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9667 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9668 arglist = build_tree_list (NULL_TREE, orig);
9669 arglist = tree_cons (NULL_TREE, dest, arglist);
9670 if (!ignored)
9672 retval = c_strlen (orig, 1);
9673 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9674 return NULL_TREE;
9676 call = build_function_call_expr (fn, arglist);
9679 if (call && retval)
9681 retval = fold_convert
9682 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9683 retval);
9684 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9686 else
9687 return call;
9690 /* Expand a call to __builtin_object_size. */
9693 expand_builtin_object_size (tree exp)
9695 tree ost;
9696 int object_size_type;
9697 tree fndecl = get_callee_fndecl (exp);
9698 tree arglist = TREE_OPERAND (exp, 1);
9699 location_t locus = EXPR_LOCATION (exp);
9701 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9703 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9704 &locus, fndecl);
9705 expand_builtin_trap ();
9706 return const0_rtx;
9709 ost = TREE_VALUE (TREE_CHAIN (arglist));
9710 STRIP_NOPS (ost);
9712 if (TREE_CODE (ost) != INTEGER_CST
9713 || tree_int_cst_sgn (ost) < 0
9714 || compare_tree_int (ost, 3) > 0)
9716 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9717 &locus, fndecl);
9718 expand_builtin_trap ();
9719 return const0_rtx;
9722 object_size_type = tree_low_cst (ost, 0);
9724 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9727 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9728 FCODE is the BUILT_IN_* to use.
9729 Return 0 if we failed; the caller should emit a normal call,
9730 otherwise try to get the result in TARGET, if convenient (and in
9731 mode MODE if that's convenient). */
9733 static rtx
9734 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9735 enum built_in_function fcode)
9737 tree arglist = TREE_OPERAND (exp, 1);
9738 tree dest, src, len, size;
9740 if (!validate_arglist (arglist,
9741 POINTER_TYPE,
9742 fcode == BUILT_IN_MEMSET_CHK
9743 ? INTEGER_TYPE : POINTER_TYPE,
9744 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9745 return 0;
9747 dest = TREE_VALUE (arglist);
9748 src = TREE_VALUE (TREE_CHAIN (arglist));
9749 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9750 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9752 if (! host_integerp (size, 1))
9753 return 0;
9755 if (host_integerp (len, 1) || integer_all_onesp (size))
9757 tree fn;
9759 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9761 location_t locus = EXPR_LOCATION (exp);
9762 warning (0, "%Hcall to %D will always overflow destination buffer",
9763 &locus, get_callee_fndecl (exp));
9764 return 0;
9767 arglist = build_tree_list (NULL_TREE, len);
9768 arglist = tree_cons (NULL_TREE, src, arglist);
9769 arglist = tree_cons (NULL_TREE, dest, arglist);
9771 fn = NULL_TREE;
9772 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9773 mem{cpy,pcpy,move,set} is available. */
9774 switch (fcode)
9776 case BUILT_IN_MEMCPY_CHK:
9777 fn = built_in_decls[BUILT_IN_MEMCPY];
9778 break;
9779 case BUILT_IN_MEMPCPY_CHK:
9780 fn = built_in_decls[BUILT_IN_MEMPCPY];
9781 break;
9782 case BUILT_IN_MEMMOVE_CHK:
9783 fn = built_in_decls[BUILT_IN_MEMMOVE];
9784 break;
9785 case BUILT_IN_MEMSET_CHK:
9786 fn = built_in_decls[BUILT_IN_MEMSET];
9787 break;
9788 default:
9789 break;
9792 if (! fn)
9793 return 0;
9795 fn = build_function_call_expr (fn, arglist);
9796 if (TREE_CODE (fn) == CALL_EXPR)
9797 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9798 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9800 else if (fcode == BUILT_IN_MEMSET_CHK)
9801 return 0;
9802 else
9804 unsigned int dest_align
9805 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9807 /* If DEST is not a pointer type, call the normal function. */
9808 if (dest_align == 0)
9809 return 0;
9811 /* If SRC and DEST are the same (and not volatile), do nothing. */
9812 if (operand_equal_p (src, dest, 0))
9814 tree expr;
9816 if (fcode != BUILT_IN_MEMPCPY_CHK)
9818 /* Evaluate and ignore LEN in case it has side-effects. */
9819 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9820 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9823 len = fold_convert (TREE_TYPE (dest), len);
9824 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9825 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9828 /* __memmove_chk special case. */
9829 if (fcode == BUILT_IN_MEMMOVE_CHK)
9831 unsigned int src_align
9832 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9834 if (src_align == 0)
9835 return 0;
9837 /* If src is categorized for a readonly section we can use
9838 normal __memcpy_chk. */
9839 if (readonly_data_expr (src))
9841 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9842 if (!fn)
9843 return 0;
9844 fn = build_function_call_expr (fn, arglist);
9845 if (TREE_CODE (fn) == CALL_EXPR)
9846 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9847 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9850 return 0;
9854 /* Emit warning if a buffer overflow is detected at compile time. */
9856 static void
9857 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9859 int arg_mask, is_strlen = 0;
9860 tree arglist = TREE_OPERAND (exp, 1), a;
9861 tree len, size;
9862 location_t locus;
9864 switch (fcode)
9866 case BUILT_IN_STRCPY_CHK:
9867 case BUILT_IN_STPCPY_CHK:
9868 /* For __strcat_chk the warning will be emitted only if overflowing
9869 by at least strlen (dest) + 1 bytes. */
9870 case BUILT_IN_STRCAT_CHK:
9871 arg_mask = 6;
9872 is_strlen = 1;
9873 break;
9874 case BUILT_IN_STRNCPY_CHK:
9875 arg_mask = 12;
9876 break;
9877 case BUILT_IN_SNPRINTF_CHK:
9878 case BUILT_IN_VSNPRINTF_CHK:
9879 arg_mask = 10;
9880 break;
9881 default:
9882 gcc_unreachable ();
9885 len = NULL_TREE;
9886 size = NULL_TREE;
9887 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9888 if (arg_mask & 1)
9890 if (len)
9891 size = a;
9892 else
9893 len = a;
9896 if (!len || !size)
9897 return;
9899 len = TREE_VALUE (len);
9900 size = TREE_VALUE (size);
9902 if (! host_integerp (size, 1) || integer_all_onesp (size))
9903 return;
9905 if (is_strlen)
9907 len = c_strlen (len, 1);
9908 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9909 return;
9911 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9912 return;
9914 locus = EXPR_LOCATION (exp);
9915 warning (0, "%Hcall to %D will always overflow destination buffer",
9916 &locus, get_callee_fndecl (exp));
9919 /* Emit warning if a buffer overflow is detected at compile time
9920 in __sprintf_chk/__vsprintf_chk calls. */
9922 static void
9923 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9925 tree arglist = TREE_OPERAND (exp, 1);
9926 tree dest, size, len, fmt, flag;
9927 const char *fmt_str;
9929 /* Verify the required arguments in the original call. */
9930 if (! arglist)
9931 return;
9932 dest = TREE_VALUE (arglist);
9933 arglist = TREE_CHAIN (arglist);
9934 if (! arglist)
9935 return;
9936 flag = TREE_VALUE (arglist);
9937 arglist = TREE_CHAIN (arglist);
9938 if (! arglist)
9939 return;
9940 size = TREE_VALUE (arglist);
9941 arglist = TREE_CHAIN (arglist);
9942 if (! arglist)
9943 return;
9944 fmt = TREE_VALUE (arglist);
9945 arglist = TREE_CHAIN (arglist);
9947 if (! host_integerp (size, 1) || integer_all_onesp (size))
9948 return;
9950 /* Check whether the format is a literal string constant. */
9951 fmt_str = c_getstr (fmt);
9952 if (fmt_str == NULL)
9953 return;
9955 if (!init_target_chars())
9956 return;
9958 /* If the format doesn't contain % args or %%, we know its size. */
9959 if (strchr (fmt_str, target_percent) == 0)
9960 len = build_int_cstu (size_type_node, strlen (fmt_str));
9961 /* If the format is "%s" and first ... argument is a string literal,
9962 we know it too. */
9963 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9965 tree arg;
9967 if (! arglist)
9968 return;
9969 arg = TREE_VALUE (arglist);
9970 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9971 return;
9973 len = c_strlen (arg, 1);
9974 if (!len || ! host_integerp (len, 1))
9975 return;
9977 else
9978 return;
9980 if (! tree_int_cst_lt (len, size))
9982 location_t locus = EXPR_LOCATION (exp);
9983 warning (0, "%Hcall to %D will always overflow destination buffer",
9984 &locus, get_callee_fndecl (exp));
9988 /* Fold a call to __builtin_object_size, if possible. */
9990 tree
9991 fold_builtin_object_size (tree arglist)
9993 tree ptr, ost, ret = 0;
9994 int object_size_type;
9996 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9997 return 0;
9999 ptr = TREE_VALUE (arglist);
10000 ost = TREE_VALUE (TREE_CHAIN (arglist));
10001 STRIP_NOPS (ost);
10003 if (TREE_CODE (ost) != INTEGER_CST
10004 || tree_int_cst_sgn (ost) < 0
10005 || compare_tree_int (ost, 3) > 0)
10006 return 0;
10008 object_size_type = tree_low_cst (ost, 0);
10010 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10011 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10012 and (size_t) 0 for types 2 and 3. */
10013 if (TREE_SIDE_EFFECTS (ptr))
10014 return fold_convert (size_type_node,
10015 object_size_type < 2
10016 ? integer_minus_one_node : integer_zero_node);
10018 if (TREE_CODE (ptr) == ADDR_EXPR)
10019 ret = build_int_cstu (size_type_node,
10020 compute_builtin_object_size (ptr, object_size_type));
10022 else if (TREE_CODE (ptr) == SSA_NAME)
10024 unsigned HOST_WIDE_INT bytes;
10026 /* If object size is not known yet, delay folding until
10027 later. Maybe subsequent passes will help determining
10028 it. */
10029 bytes = compute_builtin_object_size (ptr, object_size_type);
10030 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10031 ? -1 : 0))
10032 ret = build_int_cstu (size_type_node, bytes);
10035 if (ret)
10037 ret = force_fit_type (ret, -1, false, false);
10038 if (TREE_CONSTANT_OVERFLOW (ret))
10039 ret = 0;
10042 return ret;
10045 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10046 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10047 code of the builtin. If MAXLEN is not NULL, it is maximum length
10048 passed as third argument. */
10050 tree
10051 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10052 enum built_in_function fcode)
10054 tree dest, src, len, size, fn;
10056 if (!validate_arglist (arglist,
10057 POINTER_TYPE,
10058 fcode == BUILT_IN_MEMSET_CHK
10059 ? INTEGER_TYPE : POINTER_TYPE,
10060 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10061 return 0;
10063 dest = TREE_VALUE (arglist);
10064 /* Actually val for __memset_chk, but it doesn't matter. */
10065 src = TREE_VALUE (TREE_CHAIN (arglist));
10066 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10067 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10069 /* If SRC and DEST are the same (and not volatile), return DEST
10070 (resp. DEST+LEN for __mempcpy_chk). */
10071 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10073 if (fcode != BUILT_IN_MEMPCPY_CHK)
10074 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10075 else
10077 tree temp = fold_convert (TREE_TYPE (dest), len);
10078 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10079 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10083 if (! host_integerp (size, 1))
10084 return 0;
10086 if (! integer_all_onesp (size))
10088 if (! host_integerp (len, 1))
10090 /* If LEN is not constant, try MAXLEN too.
10091 For MAXLEN only allow optimizing into non-_ocs function
10092 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10093 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10095 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10097 /* (void) __mempcpy_chk () can be optimized into
10098 (void) __memcpy_chk (). */
10099 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10100 if (!fn)
10101 return 0;
10103 return build_function_call_expr (fn, arglist);
10105 return 0;
10108 else
10109 maxlen = len;
10111 if (tree_int_cst_lt (size, maxlen))
10112 return 0;
10115 arglist = build_tree_list (NULL_TREE, len);
10116 arglist = tree_cons (NULL_TREE, src, arglist);
10117 arglist = tree_cons (NULL_TREE, dest, arglist);
10119 fn = NULL_TREE;
10120 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10121 mem{cpy,pcpy,move,set} is available. */
10122 switch (fcode)
10124 case BUILT_IN_MEMCPY_CHK:
10125 fn = built_in_decls[BUILT_IN_MEMCPY];
10126 break;
10127 case BUILT_IN_MEMPCPY_CHK:
10128 fn = built_in_decls[BUILT_IN_MEMPCPY];
10129 break;
10130 case BUILT_IN_MEMMOVE_CHK:
10131 fn = built_in_decls[BUILT_IN_MEMMOVE];
10132 break;
10133 case BUILT_IN_MEMSET_CHK:
10134 fn = built_in_decls[BUILT_IN_MEMSET];
10135 break;
10136 default:
10137 break;
10140 if (!fn)
10141 return 0;
10143 return build_function_call_expr (fn, arglist);
10146 /* Fold a call to the __st[rp]cpy_chk builtin.
10147 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10148 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10149 strings passed as second argument. */
10151 tree
10152 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10153 enum built_in_function fcode)
10155 tree dest, src, size, len, fn;
10157 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10158 VOID_TYPE))
10159 return 0;
10161 dest = TREE_VALUE (arglist);
10162 src = TREE_VALUE (TREE_CHAIN (arglist));
10163 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10165 /* If SRC and DEST are the same (and not volatile), return DEST. */
10166 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10167 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10169 if (! host_integerp (size, 1))
10170 return 0;
10172 if (! integer_all_onesp (size))
10174 len = c_strlen (src, 1);
10175 if (! len || ! host_integerp (len, 1))
10177 /* If LEN is not constant, try MAXLEN too.
10178 For MAXLEN only allow optimizing into non-_ocs function
10179 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10180 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10182 if (fcode == BUILT_IN_STPCPY_CHK)
10184 if (! ignore)
10185 return 0;
10187 /* If return value of __stpcpy_chk is ignored,
10188 optimize into __strcpy_chk. */
10189 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10190 if (!fn)
10191 return 0;
10193 return build_function_call_expr (fn, arglist);
10196 if (! len || TREE_SIDE_EFFECTS (len))
10197 return 0;
10199 /* If c_strlen returned something, but not a constant,
10200 transform __strcpy_chk into __memcpy_chk. */
10201 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10202 if (!fn)
10203 return 0;
10205 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10206 arglist = build_tree_list (NULL_TREE, size);
10207 arglist = tree_cons (NULL_TREE, len, arglist);
10208 arglist = tree_cons (NULL_TREE, src, arglist);
10209 arglist = tree_cons (NULL_TREE, dest, arglist);
10210 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10211 build_function_call_expr (fn, arglist));
10214 else
10215 maxlen = len;
10217 if (! tree_int_cst_lt (maxlen, size))
10218 return 0;
10221 arglist = build_tree_list (NULL_TREE, src);
10222 arglist = tree_cons (NULL_TREE, dest, arglist);
10224 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10225 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10226 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10227 if (!fn)
10228 return 0;
10230 return build_function_call_expr (fn, arglist);
10233 /* Fold a call to the __strncpy_chk builtin.
10234 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10236 tree
10237 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10239 tree dest, src, size, len, fn;
10241 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10242 INTEGER_TYPE, VOID_TYPE))
10243 return 0;
10245 dest = TREE_VALUE (arglist);
10246 src = TREE_VALUE (TREE_CHAIN (arglist));
10247 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10248 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10250 if (! host_integerp (size, 1))
10251 return 0;
10253 if (! integer_all_onesp (size))
10255 if (! host_integerp (len, 1))
10257 /* If LEN is not constant, try MAXLEN too.
10258 For MAXLEN only allow optimizing into non-_ocs function
10259 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10260 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10261 return 0;
10263 else
10264 maxlen = len;
10266 if (tree_int_cst_lt (size, maxlen))
10267 return 0;
10270 arglist = build_tree_list (NULL_TREE, len);
10271 arglist = tree_cons (NULL_TREE, src, arglist);
10272 arglist = tree_cons (NULL_TREE, dest, arglist);
10274 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10275 fn = built_in_decls[BUILT_IN_STRNCPY];
10276 if (!fn)
10277 return 0;
10279 return build_function_call_expr (fn, arglist);
10282 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10284 static tree
10285 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10287 tree dest, src, size, fn;
10288 const char *p;
10290 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10291 VOID_TYPE))
10292 return 0;
10294 dest = TREE_VALUE (arglist);
10295 src = TREE_VALUE (TREE_CHAIN (arglist));
10296 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10298 p = c_getstr (src);
10299 /* If the SRC parameter is "", return DEST. */
10300 if (p && *p == '\0')
10301 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10303 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10304 return 0;
10306 arglist = build_tree_list (NULL_TREE, src);
10307 arglist = tree_cons (NULL_TREE, dest, arglist);
10309 /* If __builtin_strcat_chk is used, assume strcat is available. */
10310 fn = built_in_decls[BUILT_IN_STRCAT];
10311 if (!fn)
10312 return 0;
10314 return build_function_call_expr (fn, arglist);
10317 /* Fold a call to the __strncat_chk builtin EXP. */
10319 static tree
10320 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10322 tree dest, src, size, len, fn;
10323 const char *p;
10325 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10326 INTEGER_TYPE, VOID_TYPE))
10327 return 0;
10329 dest = TREE_VALUE (arglist);
10330 src = TREE_VALUE (TREE_CHAIN (arglist));
10331 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10332 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10334 p = c_getstr (src);
10335 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10336 if (p && *p == '\0')
10337 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10338 else if (integer_zerop (len))
10339 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10341 if (! host_integerp (size, 1))
10342 return 0;
10344 if (! integer_all_onesp (size))
10346 tree src_len = c_strlen (src, 1);
10347 if (src_len
10348 && host_integerp (src_len, 1)
10349 && host_integerp (len, 1)
10350 && ! tree_int_cst_lt (len, src_len))
10352 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10353 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10354 if (!fn)
10355 return 0;
10357 arglist = build_tree_list (NULL_TREE, size);
10358 arglist = tree_cons (NULL_TREE, src, arglist);
10359 arglist = tree_cons (NULL_TREE, dest, arglist);
10360 return build_function_call_expr (fn, arglist);
10362 return 0;
10365 arglist = build_tree_list (NULL_TREE, len);
10366 arglist = tree_cons (NULL_TREE, src, arglist);
10367 arglist = tree_cons (NULL_TREE, dest, arglist);
10369 /* If __builtin_strncat_chk is used, assume strncat is available. */
10370 fn = built_in_decls[BUILT_IN_STRNCAT];
10371 if (!fn)
10372 return 0;
10374 return build_function_call_expr (fn, arglist);
10377 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10378 a normal call should be emitted rather than expanding the function
10379 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10381 static tree
10382 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10384 tree dest, size, len, fn, fmt, flag;
10385 const char *fmt_str;
10387 /* Verify the required arguments in the original call. */
10388 if (! arglist)
10389 return 0;
10390 dest = TREE_VALUE (arglist);
10391 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10392 return 0;
10393 arglist = TREE_CHAIN (arglist);
10394 if (! arglist)
10395 return 0;
10396 flag = TREE_VALUE (arglist);
10397 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10398 return 0;
10399 arglist = TREE_CHAIN (arglist);
10400 if (! arglist)
10401 return 0;
10402 size = TREE_VALUE (arglist);
10403 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10404 return 0;
10405 arglist = TREE_CHAIN (arglist);
10406 if (! arglist)
10407 return 0;
10408 fmt = TREE_VALUE (arglist);
10409 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10410 return 0;
10411 arglist = TREE_CHAIN (arglist);
10413 if (! host_integerp (size, 1))
10414 return 0;
10416 len = NULL_TREE;
10418 if (!init_target_chars())
10419 return 0;
10421 /* Check whether the format is a literal string constant. */
10422 fmt_str = c_getstr (fmt);
10423 if (fmt_str != NULL)
10425 /* If the format doesn't contain % args or %%, we know the size. */
10426 if (strchr (fmt_str, target_percent) == 0)
10428 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10429 len = build_int_cstu (size_type_node, strlen (fmt_str));
10431 /* If the format is "%s" and first ... argument is a string literal,
10432 we know the size too. */
10433 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10435 tree arg;
10437 if (arglist && !TREE_CHAIN (arglist))
10439 arg = TREE_VALUE (arglist);
10440 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10442 len = c_strlen (arg, 1);
10443 if (! len || ! host_integerp (len, 1))
10444 len = NULL_TREE;
10450 if (! integer_all_onesp (size))
10452 if (! len || ! tree_int_cst_lt (len, size))
10453 return 0;
10456 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10457 or if format doesn't contain % chars or is "%s". */
10458 if (! integer_zerop (flag))
10460 if (fmt_str == NULL)
10461 return 0;
10462 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10463 return 0;
10466 arglist = tree_cons (NULL_TREE, fmt, arglist);
10467 arglist = tree_cons (NULL_TREE, dest, arglist);
10469 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10470 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10471 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10472 if (!fn)
10473 return 0;
10475 return build_function_call_expr (fn, arglist);
10478 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10479 a normal call should be emitted rather than expanding the function
10480 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10481 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10482 passed as second argument. */
10484 tree
10485 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10486 enum built_in_function fcode)
10488 tree dest, size, len, fn, fmt, flag;
10489 const char *fmt_str;
10491 /* Verify the required arguments in the original call. */
10492 if (! arglist)
10493 return 0;
10494 dest = TREE_VALUE (arglist);
10495 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10496 return 0;
10497 arglist = TREE_CHAIN (arglist);
10498 if (! arglist)
10499 return 0;
10500 len = TREE_VALUE (arglist);
10501 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10502 return 0;
10503 arglist = TREE_CHAIN (arglist);
10504 if (! arglist)
10505 return 0;
10506 flag = TREE_VALUE (arglist);
10507 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10508 return 0;
10509 arglist = TREE_CHAIN (arglist);
10510 if (! arglist)
10511 return 0;
10512 size = TREE_VALUE (arglist);
10513 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10514 return 0;
10515 arglist = TREE_CHAIN (arglist);
10516 if (! arglist)
10517 return 0;
10518 fmt = TREE_VALUE (arglist);
10519 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10520 return 0;
10521 arglist = TREE_CHAIN (arglist);
10523 if (! host_integerp (size, 1))
10524 return 0;
10526 if (! integer_all_onesp (size))
10528 if (! host_integerp (len, 1))
10530 /* If LEN is not constant, try MAXLEN too.
10531 For MAXLEN only allow optimizing into non-_ocs function
10532 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10533 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10534 return 0;
10536 else
10537 maxlen = len;
10539 if (tree_int_cst_lt (size, maxlen))
10540 return 0;
10543 if (!init_target_chars())
10544 return 0;
10546 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10547 or if format doesn't contain % chars or is "%s". */
10548 if (! integer_zerop (flag))
10550 fmt_str = c_getstr (fmt);
10551 if (fmt_str == NULL)
10552 return 0;
10553 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10554 return 0;
10557 arglist = tree_cons (NULL_TREE, fmt, arglist);
10558 arglist = tree_cons (NULL_TREE, len, arglist);
10559 arglist = tree_cons (NULL_TREE, dest, arglist);
10561 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10562 available. */
10563 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10564 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10565 if (!fn)
10566 return 0;
10568 return build_function_call_expr (fn, arglist);
10571 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10573 Return 0 if no simplification was possible, otherwise return the
10574 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10575 code of the function to be simplified. */
10577 static tree
10578 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10579 enum built_in_function fcode)
10581 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10582 const char *fmt_str = NULL;
10584 /* If the return value is used, don't do the transformation. */
10585 if (! ignore)
10586 return 0;
10588 /* Verify the required arguments in the original call. */
10589 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10591 tree flag;
10593 if (! arglist)
10594 return 0;
10595 flag = TREE_VALUE (arglist);
10596 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10597 || TREE_SIDE_EFFECTS (flag))
10598 return 0;
10599 arglist = TREE_CHAIN (arglist);
10602 if (! arglist)
10603 return 0;
10604 fmt = TREE_VALUE (arglist);
10605 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10606 return 0;
10607 arglist = TREE_CHAIN (arglist);
10609 /* Check whether the format is a literal string constant. */
10610 fmt_str = c_getstr (fmt);
10611 if (fmt_str == NULL)
10612 return NULL_TREE;
10614 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10616 /* If we're using an unlocked function, assume the other
10617 unlocked functions exist explicitly. */
10618 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10619 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10621 else
10623 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10624 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10627 if (!init_target_chars())
10628 return 0;
10630 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10632 const char *str;
10634 if (strcmp (fmt_str, target_percent_s) == 0)
10636 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10637 return 0;
10639 if (! arglist
10640 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10641 || TREE_CHAIN (arglist))
10642 return 0;
10644 str = c_getstr (TREE_VALUE (arglist));
10645 if (str == NULL)
10646 return 0;
10648 else
10650 /* The format specifier doesn't contain any '%' characters. */
10651 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10652 && arglist)
10653 return 0;
10654 str = fmt_str;
10657 /* If the string was "", printf does nothing. */
10658 if (str[0] == '\0')
10659 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10661 /* If the string has length of 1, call putchar. */
10662 if (str[1] == '\0')
10664 /* Given printf("c"), (where c is any one character,)
10665 convert "c"[0] to an int and pass that to the replacement
10666 function. */
10667 arg = build_int_cst (NULL_TREE, str[0]);
10668 arglist = build_tree_list (NULL_TREE, arg);
10669 fn = fn_putchar;
10671 else
10673 /* If the string was "string\n", call puts("string"). */
10674 size_t len = strlen (str);
10675 if ((unsigned char)str[len - 1] == target_newline)
10677 /* Create a NUL-terminated string that's one char shorter
10678 than the original, stripping off the trailing '\n'. */
10679 char *newstr = alloca (len);
10680 memcpy (newstr, str, len - 1);
10681 newstr[len - 1] = 0;
10683 arg = build_string_literal (len, newstr);
10684 arglist = build_tree_list (NULL_TREE, arg);
10685 fn = fn_puts;
10687 else
10688 /* We'd like to arrange to call fputs(string,stdout) here,
10689 but we need stdout and don't have a way to get it yet. */
10690 return 0;
10694 /* The other optimizations can be done only on the non-va_list variants. */
10695 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10696 return 0;
10698 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10699 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10701 if (! arglist
10702 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10703 || TREE_CHAIN (arglist))
10704 return 0;
10705 fn = fn_puts;
10708 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10709 else if (strcmp (fmt_str, target_percent_c) == 0)
10711 if (! arglist
10712 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10713 || TREE_CHAIN (arglist))
10714 return 0;
10715 fn = fn_putchar;
10718 if (!fn)
10719 return 0;
10721 call = build_function_call_expr (fn, arglist);
10722 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10725 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10727 Return 0 if no simplification was possible, otherwise return the
10728 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10729 code of the function to be simplified. */
10731 static tree
10732 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10733 enum built_in_function fcode)
10735 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10736 const char *fmt_str = NULL;
10738 /* If the return value is used, don't do the transformation. */
10739 if (! ignore)
10740 return 0;
10742 /* Verify the required arguments in the original call. */
10743 if (! arglist)
10744 return 0;
10745 fp = TREE_VALUE (arglist);
10746 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10747 return 0;
10748 arglist = TREE_CHAIN (arglist);
10750 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10752 tree flag;
10754 if (! arglist)
10755 return 0;
10756 flag = TREE_VALUE (arglist);
10757 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10758 || TREE_SIDE_EFFECTS (flag))
10759 return 0;
10760 arglist = TREE_CHAIN (arglist);
10763 if (! arglist)
10764 return 0;
10765 fmt = TREE_VALUE (arglist);
10766 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10767 return 0;
10768 arglist = TREE_CHAIN (arglist);
10770 /* Check whether the format is a literal string constant. */
10771 fmt_str = c_getstr (fmt);
10772 if (fmt_str == NULL)
10773 return NULL_TREE;
10775 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10777 /* If we're using an unlocked function, assume the other
10778 unlocked functions exist explicitly. */
10779 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10780 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10782 else
10784 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10785 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10788 if (!init_target_chars())
10789 return 0;
10791 /* If the format doesn't contain % args or %%, use strcpy. */
10792 if (strchr (fmt_str, target_percent) == NULL)
10794 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10795 && arglist)
10796 return 0;
10798 /* If the format specifier was "", fprintf does nothing. */
10799 if (fmt_str[0] == '\0')
10801 /* If FP has side-effects, just wait until gimplification is
10802 done. */
10803 if (TREE_SIDE_EFFECTS (fp))
10804 return 0;
10806 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10809 /* When "string" doesn't contain %, replace all cases of
10810 fprintf (fp, string) with fputs (string, fp). The fputs
10811 builtin will take care of special cases like length == 1. */
10812 arglist = build_tree_list (NULL_TREE, fp);
10813 arglist = tree_cons (NULL_TREE, fmt, arglist);
10814 fn = fn_fputs;
10817 /* The other optimizations can be done only on the non-va_list variants. */
10818 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10819 return 0;
10821 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10822 else if (strcmp (fmt_str, target_percent_s) == 0)
10824 if (! arglist
10825 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10826 || TREE_CHAIN (arglist))
10827 return 0;
10828 arg = TREE_VALUE (arglist);
10829 arglist = build_tree_list (NULL_TREE, fp);
10830 arglist = tree_cons (NULL_TREE, arg, arglist);
10831 fn = fn_fputs;
10834 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10835 else if (strcmp (fmt_str, target_percent_c) == 0)
10837 if (! arglist
10838 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10839 || TREE_CHAIN (arglist))
10840 return 0;
10841 arg = TREE_VALUE (arglist);
10842 arglist = build_tree_list (NULL_TREE, fp);
10843 arglist = tree_cons (NULL_TREE, arg, arglist);
10844 fn = fn_fputc;
10847 if (!fn)
10848 return 0;
10850 call = build_function_call_expr (fn, arglist);
10851 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10854 /* Initialize format string characters in the target charset. */
10856 static bool
10857 init_target_chars (void)
10859 static bool init;
10860 if (!init)
10862 target_newline = lang_hooks.to_target_charset ('\n');
10863 target_percent = lang_hooks.to_target_charset ('%');
10864 target_c = lang_hooks.to_target_charset ('c');
10865 target_s = lang_hooks.to_target_charset ('s');
10866 if (target_newline == 0 || target_percent == 0 || target_c == 0
10867 || target_s == 0)
10868 return false;
10870 target_percent_c[0] = target_percent;
10871 target_percent_c[1] = target_c;
10872 target_percent_c[2] = '\0';
10874 target_percent_s[0] = target_percent;
10875 target_percent_s[1] = target_s;
10876 target_percent_s[2] = '\0';
10878 target_percent_s_newline[0] = target_percent;
10879 target_percent_s_newline[1] = target_s;
10880 target_percent_s_newline[2] = target_newline;
10881 target_percent_s_newline[3] = '\0';
10883 init = true;
10885 return true;