2004-07-16 Daniel Berlin <dberlin@dberlin.org>
[official-gcc.git] / gcc / builtins.c
blobd83b0de27dea0e57c8eabe702b05bcee4f125ca2
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, 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"
50 #define CALLED_AS_BUILT_IN(NODE) \
51 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
53 #ifndef PAD_VARARGS_DOWN
54 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 #endif
57 /* Define the names of the builtin function types and codes. */
58 const char *const built_in_class_names[4]
59 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
61 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
62 const char *const built_in_names[(int) END_BUILTINS] =
64 #include "builtins.def"
66 #undef DEF_BUILTIN
68 /* Setup an array of _DECL trees, make sure each element is
69 initialized to NULL_TREE. */
70 tree built_in_decls[(int) END_BUILTINS];
71 /* Declarations used when constructing the builtin implicitly in the compiler.
72 It may be NULL_TREE when this is invalid (for instance runtime is not
73 required to implement the function call in all cases). */
74 tree implicit_built_in_decls[(int) END_BUILTINS];
76 static int get_pointer_alignment (tree, unsigned int);
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree);
81 static tree build_string_literal (int, const char *);
82 static int apply_args_size (void);
83 static int apply_result_size (void);
84 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
85 static rtx result_vector (int, rtx);
86 #endif
87 static rtx expand_builtin_setjmp (tree, rtx);
88 static void expand_builtin_update_setjmp_buf (rtx);
89 static void expand_builtin_prefetch (tree);
90 static rtx expand_builtin_apply_args (void);
91 static rtx expand_builtin_apply_args_1 (void);
92 static rtx expand_builtin_apply (rtx, rtx, rtx);
93 static void expand_builtin_return (rtx);
94 static enum type_class type_to_class (tree);
95 static rtx expand_builtin_classify_type (tree);
96 static void expand_errno_check (tree, rtx);
97 static rtx expand_builtin_mathfn (tree, rtx, rtx);
98 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (tree);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_bzero (tree);
125 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_alloca (tree, rtx);
131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
132 static rtx expand_builtin_frame_address (tree, tree);
133 static rtx expand_builtin_fputs (tree, rtx, bool);
134 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
137 static tree stabilize_va_list (tree, int);
138 static rtx expand_builtin_expect (tree, rtx);
139 static tree fold_builtin_constant_p (tree);
140 static tree fold_builtin_classify_type (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);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_cabs (tree, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_cabs (tree, tree);
151 static tree fold_builtin_trunc (tree);
152 static tree fold_builtin_floor (tree);
153 static tree fold_builtin_ceil (tree);
154 static tree fold_builtin_round (tree);
155 static tree fold_builtin_bitop (tree);
156 static tree fold_builtin_memcpy (tree);
157 static tree fold_builtin_mempcpy (tree);
158 static tree fold_builtin_memmove (tree);
159 static tree fold_builtin_strchr (tree, bool);
160 static tree fold_builtin_memcmp (tree);
161 static tree fold_builtin_strcmp (tree);
162 static tree fold_builtin_strncmp (tree);
163 static tree fold_builtin_signbit (tree);
164 static tree fold_builtin_copysign (tree, tree);
165 static tree fold_builtin_isascii (tree);
166 static tree fold_builtin_toascii (tree);
167 static tree fold_builtin_isdigit (tree);
168 static tree fold_builtin_fabs (tree, tree);
169 static tree fold_builtin_abs (tree, tree);
170 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
171 static tree fold_builtin_1 (tree, bool);
173 static tree simplify_builtin_memcmp (tree);
174 static tree simplify_builtin_strcmp (tree);
175 static tree simplify_builtin_strncmp (tree);
176 static tree simplify_builtin_strpbrk (tree);
177 static tree simplify_builtin_strstr (tree);
178 static tree simplify_builtin_strchr (tree);
179 static tree simplify_builtin_strrchr (tree);
180 static tree simplify_builtin_strcat (tree);
181 static tree simplify_builtin_strncat (tree);
182 static tree simplify_builtin_strspn (tree);
183 static tree simplify_builtin_strcspn (tree);
184 static void simplify_builtin_next_arg (tree);
185 static void simplify_builtin_va_start (tree);
186 static tree simplify_builtin_sprintf (tree, int);
189 /* Return the alignment in bits of EXP, a pointer valued expression.
190 But don't return more than MAX_ALIGN no matter what.
191 The alignment returned is, by default, the alignment of the thing that
192 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
194 Otherwise, look at the expression to see if we can do better, i.e., if the
195 expression is actually pointing at an object whose alignment is tighter. */
197 static int
198 get_pointer_alignment (tree exp, unsigned int max_align)
200 unsigned int align, inner;
202 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
203 return 0;
205 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
206 align = MIN (align, max_align);
208 while (1)
210 switch (TREE_CODE (exp))
212 case NOP_EXPR:
213 case CONVERT_EXPR:
214 case NON_LVALUE_EXPR:
215 exp = TREE_OPERAND (exp, 0);
216 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
217 return align;
219 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
220 align = MIN (inner, max_align);
221 break;
223 case PLUS_EXPR:
224 /* If sum of pointer + int, restrict our maximum alignment to that
225 imposed by the integer. If not, we can't do any better than
226 ALIGN. */
227 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
228 return align;
230 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
231 & (max_align / BITS_PER_UNIT - 1))
232 != 0)
233 max_align >>= 1;
235 exp = TREE_OPERAND (exp, 0);
236 break;
238 case ADDR_EXPR:
239 /* See what we are pointing at and look at its alignment. */
240 exp = TREE_OPERAND (exp, 0);
241 if (TREE_CODE (exp) == FUNCTION_DECL)
242 align = FUNCTION_BOUNDARY;
243 else if (DECL_P (exp))
244 align = DECL_ALIGN (exp);
245 #ifdef CONSTANT_ALIGNMENT
246 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
247 align = CONSTANT_ALIGNMENT (exp, align);
248 #endif
249 return MIN (align, max_align);
251 default:
252 return align;
257 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
258 way, because it could contain a zero byte in the middle.
259 TREE_STRING_LENGTH is the size of the character array, not the string.
261 ONLY_VALUE should be nonzero if the result is not going to be emitted
262 into the instruction stream and zero if it is going to be expanded.
263 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
264 is returned, otherwise NULL, since
265 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
266 evaluate the side-effects.
268 The value returned is of type `ssizetype'.
270 Unfortunately, string_constant can't access the values of const char
271 arrays with initializers, so neither can we do so here. */
273 tree
274 c_strlen (tree src, int only_value)
276 tree offset_node;
277 HOST_WIDE_INT offset;
278 int max;
279 const char *ptr;
281 STRIP_NOPS (src);
282 if (TREE_CODE (src) == COND_EXPR
283 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
285 tree len1, len2;
287 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
288 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
289 if (tree_int_cst_equal (len1, len2))
290 return len1;
293 if (TREE_CODE (src) == COMPOUND_EXPR
294 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
295 return c_strlen (TREE_OPERAND (src, 1), only_value);
297 src = string_constant (src, &offset_node);
298 if (src == 0)
299 return 0;
301 max = TREE_STRING_LENGTH (src) - 1;
302 ptr = TREE_STRING_POINTER (src);
304 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
306 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
307 compute the offset to the following null if we don't know where to
308 start searching for it. */
309 int i;
311 for (i = 0; i < max; i++)
312 if (ptr[i] == 0)
313 return 0;
315 /* We don't know the starting offset, but we do know that the string
316 has no internal zero bytes. We can assume that the offset falls
317 within the bounds of the string; otherwise, the programmer deserves
318 what he gets. Subtract the offset from the length of the string,
319 and return that. This would perhaps not be valid if we were dealing
320 with named arrays in addition to literal string constants. */
322 return size_diffop (size_int (max), offset_node);
325 /* We have a known offset into the string. Start searching there for
326 a null character if we can represent it as a single HOST_WIDE_INT. */
327 if (offset_node == 0)
328 offset = 0;
329 else if (! host_integerp (offset_node, 0))
330 offset = -1;
331 else
332 offset = tree_low_cst (offset_node, 0);
334 /* If the offset is known to be out of bounds, warn, and call strlen at
335 runtime. */
336 if (offset < 0 || offset > max)
338 warning ("offset outside bounds of constant string");
339 return 0;
342 /* Use strlen to search for the first zero byte. Since any strings
343 constructed with build_string will have nulls appended, we win even
344 if we get handed something like (char[4])"abcd".
346 Since OFFSET is our starting index into the string, no further
347 calculation is needed. */
348 return ssize_int (strlen (ptr + offset));
351 /* Return a char pointer for a C string if it is a string constant
352 or sum of string constant and integer constant. */
354 static const char *
355 c_getstr (tree src)
357 tree offset_node;
359 src = string_constant (src, &offset_node);
360 if (src == 0)
361 return 0;
363 if (offset_node == 0)
364 return TREE_STRING_POINTER (src);
365 else if (!host_integerp (offset_node, 1)
366 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
367 return 0;
369 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
372 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
373 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
375 static rtx
376 c_readstr (const char *str, enum machine_mode mode)
378 HOST_WIDE_INT c[2];
379 HOST_WIDE_INT ch;
380 unsigned int i, j;
382 if (GET_MODE_CLASS (mode) != MODE_INT)
383 abort ();
384 c[0] = 0;
385 c[1] = 0;
386 ch = 1;
387 for (i = 0; i < GET_MODE_SIZE (mode); i++)
389 j = i;
390 if (WORDS_BIG_ENDIAN)
391 j = GET_MODE_SIZE (mode) - i - 1;
392 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
393 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
394 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
395 j *= BITS_PER_UNIT;
396 if (j > 2 * HOST_BITS_PER_WIDE_INT)
397 abort ();
398 if (ch)
399 ch = (unsigned char) str[i];
400 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
402 return immed_double_const (c[0], c[1], mode);
405 /* Cast a target constant CST to target CHAR and if that value fits into
406 host char type, return zero and put that value into variable pointed by
407 P. */
409 static int
410 target_char_cast (tree cst, char *p)
412 unsigned HOST_WIDE_INT val, hostval;
414 if (!host_integerp (cst, 1)
415 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
416 return 1;
418 val = tree_low_cst (cst, 1);
419 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
420 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
422 hostval = val;
423 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
424 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
426 if (val != hostval)
427 return 1;
429 *p = hostval;
430 return 0;
433 /* Similar to save_expr, but assumes that arbitrary code is not executed
434 in between the multiple evaluations. In particular, we assume that a
435 non-addressable local variable will not be modified. */
437 static tree
438 builtin_save_expr (tree exp)
440 if (TREE_ADDRESSABLE (exp) == 0
441 && (TREE_CODE (exp) == PARM_DECL
442 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
443 return exp;
445 return save_expr (exp);
448 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
449 times to get the address of either a higher stack frame, or a return
450 address located within it (depending on FNDECL_CODE). */
453 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
454 rtx tem)
456 int i;
458 /* Some machines need special handling before we can access
459 arbitrary frames. For example, on the sparc, we must first flush
460 all register windows to the stack. */
461 #ifdef SETUP_FRAME_ADDRESSES
462 if (count > 0)
463 SETUP_FRAME_ADDRESSES ();
464 #endif
466 /* On the sparc, the return address is not in the frame, it is in a
467 register. There is no way to access it off of the current frame
468 pointer, but it can be accessed off the previous frame pointer by
469 reading the value from the register window save area. */
470 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
471 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
472 count--;
473 #endif
475 /* Scan back COUNT frames to the specified frame. */
476 for (i = 0; i < count; i++)
478 /* Assume the dynamic chain pointer is in the word that the
479 frame address points to, unless otherwise specified. */
480 #ifdef DYNAMIC_CHAIN_ADDRESS
481 tem = DYNAMIC_CHAIN_ADDRESS (tem);
482 #endif
483 tem = memory_address (Pmode, tem);
484 tem = gen_rtx_MEM (Pmode, tem);
485 set_mem_alias_set (tem, get_frame_alias_set ());
486 tem = copy_to_reg (tem);
489 /* For __builtin_frame_address, return what we've got. */
490 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
491 return tem;
493 /* For __builtin_return_address, Get the return address from that
494 frame. */
495 #ifdef RETURN_ADDR_RTX
496 tem = RETURN_ADDR_RTX (count, tem);
497 #else
498 tem = memory_address (Pmode,
499 plus_constant (tem, GET_MODE_SIZE (Pmode)));
500 tem = gen_rtx_MEM (Pmode, tem);
501 set_mem_alias_set (tem, get_frame_alias_set ());
502 #endif
503 return tem;
506 /* Alias set used for setjmp buffer. */
507 static HOST_WIDE_INT setjmp_alias_set = -1;
509 /* Construct the leading half of a __builtin_setjmp call. Control will
510 return to RECEIVER_LABEL. This is used directly by sjlj exception
511 handling code. */
513 void
514 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
516 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
517 rtx stack_save;
518 rtx mem;
520 if (setjmp_alias_set == -1)
521 setjmp_alias_set = new_alias_set ();
523 buf_addr = convert_memory_address (Pmode, buf_addr);
525 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
527 /* We store the frame pointer and the address of receiver_label in
528 the buffer and use the rest of it for the stack save area, which
529 is machine-dependent. */
531 mem = gen_rtx_MEM (Pmode, buf_addr);
532 set_mem_alias_set (mem, setjmp_alias_set);
533 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
535 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
536 set_mem_alias_set (mem, setjmp_alias_set);
538 emit_move_insn (validize_mem (mem),
539 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
541 stack_save = gen_rtx_MEM (sa_mode,
542 plus_constant (buf_addr,
543 2 * GET_MODE_SIZE (Pmode)));
544 set_mem_alias_set (stack_save, setjmp_alias_set);
545 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
547 /* If there is further processing to do, do it. */
548 #ifdef HAVE_builtin_setjmp_setup
549 if (HAVE_builtin_setjmp_setup)
550 emit_insn (gen_builtin_setjmp_setup (buf_addr));
551 #endif
553 /* Tell optimize_save_area_alloca that extra work is going to
554 need to go on during alloca. */
555 current_function_calls_setjmp = 1;
557 /* Set this so all the registers get saved in our frame; we need to be
558 able to copy the saved values for any registers from frames we unwind. */
559 current_function_has_nonlocal_label = 1;
562 /* Construct the trailing part of a __builtin_setjmp call.
563 This is used directly by sjlj exception handling code. */
565 void
566 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
568 /* Clobber the FP when we get here, so we have to make sure it's
569 marked as used by this function. */
570 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
572 /* Mark the static chain as clobbered here so life information
573 doesn't get messed up for it. */
574 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
576 /* Now put in the code to restore the frame pointer, and argument
577 pointer, if needed. The code below is from expand_end_bindings
578 in stmt.c; see detailed documentation there. */
579 #ifdef HAVE_nonlocal_goto
580 if (! HAVE_nonlocal_goto)
581 #endif
582 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
584 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
585 if (fixed_regs[ARG_POINTER_REGNUM])
587 #ifdef ELIMINABLE_REGS
588 size_t i;
589 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
591 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
592 if (elim_regs[i].from == ARG_POINTER_REGNUM
593 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
594 break;
596 if (i == ARRAY_SIZE (elim_regs))
597 #endif
599 /* Now restore our arg pointer from the address at which it
600 was saved in our stack frame. */
601 emit_move_insn (virtual_incoming_args_rtx,
602 copy_to_reg (get_arg_pointer_save_area (cfun)));
605 #endif
607 #ifdef HAVE_builtin_setjmp_receiver
608 if (HAVE_builtin_setjmp_receiver)
609 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
610 else
611 #endif
612 #ifdef HAVE_nonlocal_goto_receiver
613 if (HAVE_nonlocal_goto_receiver)
614 emit_insn (gen_nonlocal_goto_receiver ());
615 else
616 #endif
617 { /* Nothing */ }
619 /* @@@ This is a kludge. Not all machine descriptions define a blockage
620 insn, but we must not allow the code we just generated to be reordered
621 by scheduling. Specifically, the update of the frame pointer must
622 happen immediately, not later. So emit an ASM_INPUT to act as blockage
623 insn. */
624 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
627 /* __builtin_setjmp is passed a pointer to an array of five words (not
628 all will be used on all machines). It operates similarly to the C
629 library function of the same name, but is more efficient. Much of
630 the code below (and for longjmp) is copied from the handling of
631 non-local gotos.
633 NOTE: This is intended for use by GNAT and the exception handling
634 scheme in the compiler and will only work in the method used by
635 them. */
637 static rtx
638 expand_builtin_setjmp (tree arglist, rtx target)
640 rtx buf_addr, next_lab, cont_lab;
642 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
643 return NULL_RTX;
645 if (target == 0 || !REG_P (target)
646 || REGNO (target) < FIRST_PSEUDO_REGISTER)
647 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
649 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
651 next_lab = gen_label_rtx ();
652 cont_lab = gen_label_rtx ();
654 expand_builtin_setjmp_setup (buf_addr, next_lab);
656 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
657 ensure that pending stack adjustments are flushed. */
658 emit_move_insn (target, const0_rtx);
659 emit_jump (cont_lab);
661 emit_label (next_lab);
663 expand_builtin_setjmp_receiver (next_lab);
665 /* Set TARGET to one. */
666 emit_move_insn (target, const1_rtx);
667 emit_label (cont_lab);
669 /* Tell flow about the strange goings on. Putting `next_lab' on
670 `nonlocal_goto_handler_labels' to indicates that function
671 calls may traverse the arc back to this label. */
673 current_function_has_nonlocal_label = 1;
674 nonlocal_goto_handler_labels
675 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
677 return target;
680 /* __builtin_longjmp is passed a pointer to an array of five words (not
681 all will be used on all machines). It operates similarly to the C
682 library function of the same name, but is more efficient. Much of
683 the code below is copied from the handling of non-local gotos.
685 NOTE: This is intended for use by GNAT and the exception handling
686 scheme in the compiler and will only work in the method used by
687 them. */
689 void
690 expand_builtin_longjmp (rtx buf_addr, rtx value)
692 rtx fp, lab, stack, insn, last;
693 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
695 if (setjmp_alias_set == -1)
696 setjmp_alias_set = new_alias_set ();
698 buf_addr = convert_memory_address (Pmode, buf_addr);
700 buf_addr = force_reg (Pmode, buf_addr);
702 /* We used to store value in static_chain_rtx, but that fails if pointers
703 are smaller than integers. We instead require that the user must pass
704 a second argument of 1, because that is what builtin_setjmp will
705 return. This also makes EH slightly more efficient, since we are no
706 longer copying around a value that we don't care about. */
707 if (value != const1_rtx)
708 abort ();
710 current_function_calls_longjmp = 1;
712 last = get_last_insn ();
713 #ifdef HAVE_builtin_longjmp
714 if (HAVE_builtin_longjmp)
715 emit_insn (gen_builtin_longjmp (buf_addr));
716 else
717 #endif
719 fp = gen_rtx_MEM (Pmode, buf_addr);
720 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
721 GET_MODE_SIZE (Pmode)));
723 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
724 2 * GET_MODE_SIZE (Pmode)));
725 set_mem_alias_set (fp, setjmp_alias_set);
726 set_mem_alias_set (lab, setjmp_alias_set);
727 set_mem_alias_set (stack, setjmp_alias_set);
729 /* Pick up FP, label, and SP from the block and jump. This code is
730 from expand_goto in stmt.c; see there for detailed comments. */
731 #if HAVE_nonlocal_goto
732 if (HAVE_nonlocal_goto)
733 /* We have to pass a value to the nonlocal_goto pattern that will
734 get copied into the static_chain pointer, but it does not matter
735 what that value is, because builtin_setjmp does not use it. */
736 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
737 else
738 #endif
740 lab = copy_to_reg (lab);
742 emit_insn (gen_rtx_CLOBBER (VOIDmode,
743 gen_rtx_MEM (BLKmode,
744 gen_rtx_SCRATCH (VOIDmode))));
745 emit_insn (gen_rtx_CLOBBER (VOIDmode,
746 gen_rtx_MEM (BLKmode,
747 hard_frame_pointer_rtx)));
749 emit_move_insn (hard_frame_pointer_rtx, fp);
750 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
752 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
753 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
754 emit_indirect_jump (lab);
758 /* Search backwards and mark the jump insn as a non-local goto.
759 Note that this precludes the use of __builtin_longjmp to a
760 __builtin_setjmp target in the same function. However, we've
761 already cautioned the user that these functions are for
762 internal exception handling use only. */
763 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
765 if (insn == last)
766 abort ();
767 if (JUMP_P (insn))
769 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
770 REG_NOTES (insn));
771 break;
773 else if (CALL_P (insn))
774 break;
778 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
779 and the address of the save area. */
781 static rtx
782 expand_builtin_nonlocal_goto (tree arglist)
784 tree t_label, t_save_area;
785 rtx r_label, r_save_area, r_fp, r_sp, insn;
787 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
788 return NULL_RTX;
790 t_label = TREE_VALUE (arglist);
791 arglist = TREE_CHAIN (arglist);
792 t_save_area = TREE_VALUE (arglist);
794 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
795 r_label = convert_memory_address (Pmode, r_label);
796 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
797 r_save_area = convert_memory_address (Pmode, r_save_area);
798 r_fp = gen_rtx_MEM (Pmode, r_save_area);
799 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
800 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
802 current_function_has_nonlocal_goto = 1;
804 #if HAVE_nonlocal_goto
805 /* ??? We no longer need to pass the static chain value, afaik. */
806 if (HAVE_nonlocal_goto)
807 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
808 else
809 #endif
811 r_label = copy_to_reg (r_label);
813 emit_insn (gen_rtx_CLOBBER (VOIDmode,
814 gen_rtx_MEM (BLKmode,
815 gen_rtx_SCRATCH (VOIDmode))));
817 emit_insn (gen_rtx_CLOBBER (VOIDmode,
818 gen_rtx_MEM (BLKmode,
819 hard_frame_pointer_rtx)));
821 /* Restore frame pointer for containing function.
822 This sets the actual hard register used for the frame pointer
823 to the location of the function's incoming static chain info.
824 The non-local goto handler will then adjust it to contain the
825 proper value and reload the argument pointer, if needed. */
826 emit_move_insn (hard_frame_pointer_rtx, r_fp);
827 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
829 /* USE of hard_frame_pointer_rtx added for consistency;
830 not clear if really needed. */
831 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
832 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
833 emit_indirect_jump (r_label);
836 /* Search backwards to the jump insn and mark it as a
837 non-local goto. */
838 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
840 if (JUMP_P (insn))
842 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
843 const0_rtx, REG_NOTES (insn));
844 break;
846 else if (CALL_P (insn))
847 break;
850 return const0_rtx;
853 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
854 (not all will be used on all machines) that was passed to __builtin_setjmp.
855 It updates the stack pointer in that block to correspond to the current
856 stack pointer. */
858 static void
859 expand_builtin_update_setjmp_buf (rtx buf_addr)
861 enum machine_mode sa_mode = Pmode;
862 rtx stack_save;
865 #ifdef HAVE_save_stack_nonlocal
866 if (HAVE_save_stack_nonlocal)
867 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
868 #endif
869 #ifdef STACK_SAVEAREA_MODE
870 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
871 #endif
873 stack_save
874 = gen_rtx_MEM (sa_mode,
875 memory_address
876 (sa_mode,
877 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
879 #ifdef HAVE_setjmp
880 if (HAVE_setjmp)
881 emit_insn (gen_setjmp ());
882 #endif
884 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
887 /* Expand a call to __builtin_prefetch. For a target that does not support
888 data prefetch, evaluate the memory address argument in case it has side
889 effects. */
891 static void
892 expand_builtin_prefetch (tree arglist)
894 tree arg0, arg1, arg2;
895 rtx op0, op1, op2;
897 if (!validate_arglist (arglist, POINTER_TYPE, 0))
898 return;
900 arg0 = TREE_VALUE (arglist);
901 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
902 zero (read) and argument 2 (locality) defaults to 3 (high degree of
903 locality). */
904 if (TREE_CHAIN (arglist))
906 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
907 if (TREE_CHAIN (TREE_CHAIN (arglist)))
908 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
909 else
910 arg2 = build_int_2 (3, 0);
912 else
914 arg1 = integer_zero_node;
915 arg2 = build_int_2 (3, 0);
918 /* Argument 0 is an address. */
919 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
921 /* Argument 1 (read/write flag) must be a compile-time constant int. */
922 if (TREE_CODE (arg1) != INTEGER_CST)
924 error ("second arg to `__builtin_prefetch' must be a constant");
925 arg1 = integer_zero_node;
927 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
928 /* Argument 1 must be either zero or one. */
929 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
931 warning ("invalid second arg to __builtin_prefetch; using zero");
932 op1 = const0_rtx;
935 /* Argument 2 (locality) must be a compile-time constant int. */
936 if (TREE_CODE (arg2) != INTEGER_CST)
938 error ("third arg to `__builtin_prefetch' must be a constant");
939 arg2 = integer_zero_node;
941 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
942 /* Argument 2 must be 0, 1, 2, or 3. */
943 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
945 warning ("invalid third arg to __builtin_prefetch; using zero");
946 op2 = const0_rtx;
949 #ifdef HAVE_prefetch
950 if (HAVE_prefetch)
952 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
953 (op0,
954 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
955 || (GET_MODE (op0) != Pmode))
957 op0 = convert_memory_address (Pmode, op0);
958 op0 = force_reg (Pmode, op0);
960 emit_insn (gen_prefetch (op0, op1, op2));
962 #endif
964 /* Don't do anything with direct references to volatile memory, but
965 generate code to handle other side effects. */
966 if (!MEM_P (op0) && side_effects_p (op0))
967 emit_insn (op0);
970 /* Get a MEM rtx for expression EXP which is the address of an operand
971 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
973 static rtx
974 get_memory_rtx (tree exp)
976 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
977 rtx mem;
979 addr = convert_memory_address (Pmode, addr);
981 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
983 /* Get an expression we can use to find the attributes to assign to MEM.
984 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
985 we can. First remove any nops. */
986 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
987 || TREE_CODE (exp) == NON_LVALUE_EXPR)
988 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
989 exp = TREE_OPERAND (exp, 0);
991 if (TREE_CODE (exp) == ADDR_EXPR)
993 exp = TREE_OPERAND (exp, 0);
994 set_mem_attributes (mem, exp, 0);
996 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
998 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
999 /* memcpy, memset and other builtin stringops can alias with anything. */
1000 set_mem_alias_set (mem, 0);
1003 return mem;
1006 /* Built-in functions to perform an untyped call and return. */
1008 /* For each register that may be used for calling a function, this
1009 gives a mode used to copy the register's value. VOIDmode indicates
1010 the register is not used for calling a function. If the machine
1011 has register windows, this gives only the outbound registers.
1012 INCOMING_REGNO gives the corresponding inbound register. */
1013 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1015 /* For each register that may be used for returning values, this gives
1016 a mode used to copy the register's value. VOIDmode indicates the
1017 register is not used for returning values. If the machine has
1018 register windows, this gives only the outbound registers.
1019 INCOMING_REGNO gives the corresponding inbound register. */
1020 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1022 /* For each register that may be used for calling a function, this
1023 gives the offset of that register into the block returned by
1024 __builtin_apply_args. 0 indicates that the register is not
1025 used for calling a function. */
1026 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1028 /* Return the size required for the block returned by __builtin_apply_args,
1029 and initialize apply_args_mode. */
1031 static int
1032 apply_args_size (void)
1034 static int size = -1;
1035 int align;
1036 unsigned int regno;
1037 enum machine_mode mode;
1039 /* The values computed by this function never change. */
1040 if (size < 0)
1042 /* The first value is the incoming arg-pointer. */
1043 size = GET_MODE_SIZE (Pmode);
1045 /* The second value is the structure value address unless this is
1046 passed as an "invisible" first argument. */
1047 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1048 size += GET_MODE_SIZE (Pmode);
1050 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1051 if (FUNCTION_ARG_REGNO_P (regno))
1053 mode = reg_raw_mode[regno];
1055 if (mode == VOIDmode)
1056 abort ();
1058 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1059 if (size % align != 0)
1060 size = CEIL (size, align) * align;
1061 apply_args_reg_offset[regno] = size;
1062 size += GET_MODE_SIZE (mode);
1063 apply_args_mode[regno] = mode;
1065 else
1067 apply_args_mode[regno] = VOIDmode;
1068 apply_args_reg_offset[regno] = 0;
1071 return size;
1074 /* Return the size required for the block returned by __builtin_apply,
1075 and initialize apply_result_mode. */
1077 static int
1078 apply_result_size (void)
1080 static int size = -1;
1081 int align, regno;
1082 enum machine_mode mode;
1084 /* The values computed by this function never change. */
1085 if (size < 0)
1087 size = 0;
1089 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1090 if (FUNCTION_VALUE_REGNO_P (regno))
1092 mode = reg_raw_mode[regno];
1094 if (mode == VOIDmode)
1095 abort ();
1097 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1098 if (size % align != 0)
1099 size = CEIL (size, align) * align;
1100 size += GET_MODE_SIZE (mode);
1101 apply_result_mode[regno] = mode;
1103 else
1104 apply_result_mode[regno] = VOIDmode;
1106 /* Allow targets that use untyped_call and untyped_return to override
1107 the size so that machine-specific information can be stored here. */
1108 #ifdef APPLY_RESULT_SIZE
1109 size = APPLY_RESULT_SIZE;
1110 #endif
1112 return size;
1115 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1116 /* Create a vector describing the result block RESULT. If SAVEP is true,
1117 the result block is used to save the values; otherwise it is used to
1118 restore the values. */
1120 static rtx
1121 result_vector (int savep, rtx result)
1123 int regno, size, align, nelts;
1124 enum machine_mode mode;
1125 rtx reg, mem;
1126 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1128 size = nelts = 0;
1129 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1130 if ((mode = apply_result_mode[regno]) != VOIDmode)
1132 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1133 if (size % align != 0)
1134 size = CEIL (size, align) * align;
1135 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1136 mem = adjust_address (result, mode, size);
1137 savevec[nelts++] = (savep
1138 ? gen_rtx_SET (VOIDmode, mem, reg)
1139 : gen_rtx_SET (VOIDmode, reg, mem));
1140 size += GET_MODE_SIZE (mode);
1142 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1144 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1146 /* Save the state required to perform an untyped call with the same
1147 arguments as were passed to the current function. */
1149 static rtx
1150 expand_builtin_apply_args_1 (void)
1152 rtx registers, tem;
1153 int size, align, regno;
1154 enum machine_mode mode;
1155 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1157 /* Create a block where the arg-pointer, structure value address,
1158 and argument registers can be saved. */
1159 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1161 /* Walk past the arg-pointer and structure value address. */
1162 size = GET_MODE_SIZE (Pmode);
1163 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1164 size += GET_MODE_SIZE (Pmode);
1166 /* Save each register used in calling a function to the block. */
1167 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1168 if ((mode = apply_args_mode[regno]) != VOIDmode)
1170 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1171 if (size % align != 0)
1172 size = CEIL (size, align) * align;
1174 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1176 emit_move_insn (adjust_address (registers, mode, size), tem);
1177 size += GET_MODE_SIZE (mode);
1180 /* Save the arg pointer to the block. */
1181 tem = copy_to_reg (virtual_incoming_args_rtx);
1182 #ifdef STACK_GROWS_DOWNWARD
1183 /* We need the pointer as the caller actually passed them to us, not
1184 as we might have pretended they were passed. Make sure it's a valid
1185 operand, as emit_move_insn isn't expected to handle a PLUS. */
1187 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1188 NULL_RTX);
1189 #endif
1190 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1192 size = GET_MODE_SIZE (Pmode);
1194 /* Save the structure value address unless this is passed as an
1195 "invisible" first argument. */
1196 if (struct_incoming_value)
1198 emit_move_insn (adjust_address (registers, Pmode, size),
1199 copy_to_reg (struct_incoming_value));
1200 size += GET_MODE_SIZE (Pmode);
1203 /* Return the address of the block. */
1204 return copy_addr_to_reg (XEXP (registers, 0));
1207 /* __builtin_apply_args returns block of memory allocated on
1208 the stack into which is stored the arg pointer, structure
1209 value address, static chain, and all the registers that might
1210 possibly be used in performing a function call. The code is
1211 moved to the start of the function so the incoming values are
1212 saved. */
1214 static rtx
1215 expand_builtin_apply_args (void)
1217 /* Don't do __builtin_apply_args more than once in a function.
1218 Save the result of the first call and reuse it. */
1219 if (apply_args_value != 0)
1220 return apply_args_value;
1222 /* When this function is called, it means that registers must be
1223 saved on entry to this function. So we migrate the
1224 call to the first insn of this function. */
1225 rtx temp;
1226 rtx seq;
1228 start_sequence ();
1229 temp = expand_builtin_apply_args_1 ();
1230 seq = get_insns ();
1231 end_sequence ();
1233 apply_args_value = temp;
1235 /* Put the insns after the NOTE that starts the function.
1236 If this is inside a start_sequence, make the outer-level insn
1237 chain current, so the code is placed at the start of the
1238 function. */
1239 push_topmost_sequence ();
1240 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1241 pop_topmost_sequence ();
1242 return temp;
1246 /* Perform an untyped call and save the state required to perform an
1247 untyped return of whatever value was returned by the given function. */
1249 static rtx
1250 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1252 int size, align, regno;
1253 enum machine_mode mode;
1254 rtx incoming_args, result, reg, dest, src, call_insn;
1255 rtx old_stack_level = 0;
1256 rtx call_fusage = 0;
1257 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1259 arguments = convert_memory_address (Pmode, arguments);
1261 /* Create a block where the return registers can be saved. */
1262 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1264 /* Fetch the arg pointer from the ARGUMENTS block. */
1265 incoming_args = gen_reg_rtx (Pmode);
1266 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1267 #ifndef STACK_GROWS_DOWNWARD
1268 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1269 incoming_args, 0, OPTAB_LIB_WIDEN);
1270 #endif
1272 /* Push a new argument block and copy the arguments. Do not allow
1273 the (potential) memcpy call below to interfere with our stack
1274 manipulations. */
1275 do_pending_stack_adjust ();
1276 NO_DEFER_POP;
1278 /* Save the stack with nonlocal if available. */
1279 #ifdef HAVE_save_stack_nonlocal
1280 if (HAVE_save_stack_nonlocal)
1281 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1282 else
1283 #endif
1284 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1286 /* Allocate a block of memory onto the stack and copy the memory
1287 arguments to the outgoing arguments address. */
1288 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1289 dest = virtual_outgoing_args_rtx;
1290 #ifndef STACK_GROWS_DOWNWARD
1291 if (GET_CODE (argsize) == CONST_INT)
1292 dest = plus_constant (dest, -INTVAL (argsize));
1293 else
1294 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1295 #endif
1296 dest = gen_rtx_MEM (BLKmode, dest);
1297 set_mem_align (dest, PARM_BOUNDARY);
1298 src = gen_rtx_MEM (BLKmode, incoming_args);
1299 set_mem_align (src, PARM_BOUNDARY);
1300 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1302 /* Refer to the argument block. */
1303 apply_args_size ();
1304 arguments = gen_rtx_MEM (BLKmode, arguments);
1305 set_mem_align (arguments, PARM_BOUNDARY);
1307 /* Walk past the arg-pointer and structure value address. */
1308 size = GET_MODE_SIZE (Pmode);
1309 if (struct_value)
1310 size += GET_MODE_SIZE (Pmode);
1312 /* Restore each of the registers previously saved. Make USE insns
1313 for each of these registers for use in making the call. */
1314 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1315 if ((mode = apply_args_mode[regno]) != VOIDmode)
1317 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1318 if (size % align != 0)
1319 size = CEIL (size, align) * align;
1320 reg = gen_rtx_REG (mode, regno);
1321 emit_move_insn (reg, adjust_address (arguments, mode, size));
1322 use_reg (&call_fusage, reg);
1323 size += GET_MODE_SIZE (mode);
1326 /* Restore the structure value address unless this is passed as an
1327 "invisible" first argument. */
1328 size = GET_MODE_SIZE (Pmode);
1329 if (struct_value)
1331 rtx value = gen_reg_rtx (Pmode);
1332 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1333 emit_move_insn (struct_value, value);
1334 if (REG_P (struct_value))
1335 use_reg (&call_fusage, struct_value);
1336 size += GET_MODE_SIZE (Pmode);
1339 /* All arguments and registers used for the call are set up by now! */
1340 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1342 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1343 and we don't want to load it into a register as an optimization,
1344 because prepare_call_address already did it if it should be done. */
1345 if (GET_CODE (function) != SYMBOL_REF)
1346 function = memory_address (FUNCTION_MODE, function);
1348 /* Generate the actual call instruction and save the return value. */
1349 #ifdef HAVE_untyped_call
1350 if (HAVE_untyped_call)
1351 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1352 result, result_vector (1, result)));
1353 else
1354 #endif
1355 #ifdef HAVE_call_value
1356 if (HAVE_call_value)
1358 rtx valreg = 0;
1360 /* Locate the unique return register. It is not possible to
1361 express a call that sets more than one return register using
1362 call_value; use untyped_call for that. In fact, untyped_call
1363 only needs to save the return registers in the given block. */
1364 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1365 if ((mode = apply_result_mode[regno]) != VOIDmode)
1367 if (valreg)
1368 abort (); /* HAVE_untyped_call required. */
1369 valreg = gen_rtx_REG (mode, regno);
1372 emit_call_insn (GEN_CALL_VALUE (valreg,
1373 gen_rtx_MEM (FUNCTION_MODE, function),
1374 const0_rtx, NULL_RTX, const0_rtx));
1376 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1378 else
1379 #endif
1380 abort ();
1382 /* Find the CALL insn we just emitted, and attach the register usage
1383 information. */
1384 call_insn = last_call_insn ();
1385 add_function_usage_to (call_insn, call_fusage);
1387 /* Restore the stack. */
1388 #ifdef HAVE_save_stack_nonlocal
1389 if (HAVE_save_stack_nonlocal)
1390 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1391 else
1392 #endif
1393 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1395 OK_DEFER_POP;
1397 /* Return the address of the result block. */
1398 result = copy_addr_to_reg (XEXP (result, 0));
1399 return convert_memory_address (ptr_mode, result);
1402 /* Perform an untyped return. */
1404 static void
1405 expand_builtin_return (rtx result)
1407 int size, align, regno;
1408 enum machine_mode mode;
1409 rtx reg;
1410 rtx call_fusage = 0;
1412 result = convert_memory_address (Pmode, result);
1414 apply_result_size ();
1415 result = gen_rtx_MEM (BLKmode, result);
1417 #ifdef HAVE_untyped_return
1418 if (HAVE_untyped_return)
1420 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1421 emit_barrier ();
1422 return;
1424 #endif
1426 /* Restore the return value and note that each value is used. */
1427 size = 0;
1428 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1429 if ((mode = apply_result_mode[regno]) != VOIDmode)
1431 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1432 if (size % align != 0)
1433 size = CEIL (size, align) * align;
1434 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1435 emit_move_insn (reg, adjust_address (result, mode, size));
1437 push_to_sequence (call_fusage);
1438 emit_insn (gen_rtx_USE (VOIDmode, reg));
1439 call_fusage = get_insns ();
1440 end_sequence ();
1441 size += GET_MODE_SIZE (mode);
1444 /* Put the USE insns before the return. */
1445 emit_insn (call_fusage);
1447 /* Return whatever values was restored by jumping directly to the end
1448 of the function. */
1449 expand_naked_return ();
1452 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1454 static enum type_class
1455 type_to_class (tree type)
1457 switch (TREE_CODE (type))
1459 case VOID_TYPE: return void_type_class;
1460 case INTEGER_TYPE: return integer_type_class;
1461 case CHAR_TYPE: return char_type_class;
1462 case ENUMERAL_TYPE: return enumeral_type_class;
1463 case BOOLEAN_TYPE: return boolean_type_class;
1464 case POINTER_TYPE: return pointer_type_class;
1465 case REFERENCE_TYPE: return reference_type_class;
1466 case OFFSET_TYPE: return offset_type_class;
1467 case REAL_TYPE: return real_type_class;
1468 case COMPLEX_TYPE: return complex_type_class;
1469 case FUNCTION_TYPE: return function_type_class;
1470 case METHOD_TYPE: return method_type_class;
1471 case RECORD_TYPE: return record_type_class;
1472 case UNION_TYPE:
1473 case QUAL_UNION_TYPE: return union_type_class;
1474 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1475 ? string_type_class : array_type_class);
1476 case SET_TYPE: return set_type_class;
1477 case FILE_TYPE: return file_type_class;
1478 case LANG_TYPE: return lang_type_class;
1479 default: return no_type_class;
1483 /* Expand a call to __builtin_classify_type with arguments found in
1484 ARGLIST. */
1486 static rtx
1487 expand_builtin_classify_type (tree arglist)
1489 if (arglist != 0)
1490 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1491 return GEN_INT (no_type_class);
1494 /* This helper macro, meant to be used in mathfn_built_in below,
1495 determines which among a set of three builtin math functions is
1496 appropriate for a given type mode. The `F' and `L' cases are
1497 automatically generated from the `double' case. */
1498 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1499 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1500 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1501 fcodel = BUILT_IN_MATHFN##L ; break;
1503 /* Return mathematic function equivalent to FN but operating directly
1504 on TYPE, if available. If we can't do the conversion, return zero. */
1505 tree
1506 mathfn_built_in (tree type, enum built_in_function fn)
1508 enum built_in_function fcode, fcodef, fcodel;
1510 switch (fn)
1512 CASE_MATHFN (BUILT_IN_ACOS)
1513 CASE_MATHFN (BUILT_IN_ACOSH)
1514 CASE_MATHFN (BUILT_IN_ASIN)
1515 CASE_MATHFN (BUILT_IN_ASINH)
1516 CASE_MATHFN (BUILT_IN_ATAN)
1517 CASE_MATHFN (BUILT_IN_ATAN2)
1518 CASE_MATHFN (BUILT_IN_ATANH)
1519 CASE_MATHFN (BUILT_IN_CBRT)
1520 CASE_MATHFN (BUILT_IN_CEIL)
1521 CASE_MATHFN (BUILT_IN_COPYSIGN)
1522 CASE_MATHFN (BUILT_IN_COS)
1523 CASE_MATHFN (BUILT_IN_COSH)
1524 CASE_MATHFN (BUILT_IN_DREM)
1525 CASE_MATHFN (BUILT_IN_ERF)
1526 CASE_MATHFN (BUILT_IN_ERFC)
1527 CASE_MATHFN (BUILT_IN_EXP)
1528 CASE_MATHFN (BUILT_IN_EXP10)
1529 CASE_MATHFN (BUILT_IN_EXP2)
1530 CASE_MATHFN (BUILT_IN_EXPM1)
1531 CASE_MATHFN (BUILT_IN_FABS)
1532 CASE_MATHFN (BUILT_IN_FDIM)
1533 CASE_MATHFN (BUILT_IN_FLOOR)
1534 CASE_MATHFN (BUILT_IN_FMA)
1535 CASE_MATHFN (BUILT_IN_FMAX)
1536 CASE_MATHFN (BUILT_IN_FMIN)
1537 CASE_MATHFN (BUILT_IN_FMOD)
1538 CASE_MATHFN (BUILT_IN_FREXP)
1539 CASE_MATHFN (BUILT_IN_GAMMA)
1540 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1541 CASE_MATHFN (BUILT_IN_HYPOT)
1542 CASE_MATHFN (BUILT_IN_ILOGB)
1543 CASE_MATHFN (BUILT_IN_INF)
1544 CASE_MATHFN (BUILT_IN_J0)
1545 CASE_MATHFN (BUILT_IN_J1)
1546 CASE_MATHFN (BUILT_IN_JN)
1547 CASE_MATHFN (BUILT_IN_LDEXP)
1548 CASE_MATHFN (BUILT_IN_LGAMMA)
1549 CASE_MATHFN (BUILT_IN_LLRINT)
1550 CASE_MATHFN (BUILT_IN_LLROUND)
1551 CASE_MATHFN (BUILT_IN_LOG)
1552 CASE_MATHFN (BUILT_IN_LOG10)
1553 CASE_MATHFN (BUILT_IN_LOG1P)
1554 CASE_MATHFN (BUILT_IN_LOG2)
1555 CASE_MATHFN (BUILT_IN_LOGB)
1556 CASE_MATHFN (BUILT_IN_LRINT)
1557 CASE_MATHFN (BUILT_IN_LROUND)
1558 CASE_MATHFN (BUILT_IN_MODF)
1559 CASE_MATHFN (BUILT_IN_NAN)
1560 CASE_MATHFN (BUILT_IN_NANS)
1561 CASE_MATHFN (BUILT_IN_NEARBYINT)
1562 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1563 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1564 CASE_MATHFN (BUILT_IN_POW)
1565 CASE_MATHFN (BUILT_IN_POW10)
1566 CASE_MATHFN (BUILT_IN_REMAINDER)
1567 CASE_MATHFN (BUILT_IN_REMQUO)
1568 CASE_MATHFN (BUILT_IN_RINT)
1569 CASE_MATHFN (BUILT_IN_ROUND)
1570 CASE_MATHFN (BUILT_IN_SCALB)
1571 CASE_MATHFN (BUILT_IN_SCALBLN)
1572 CASE_MATHFN (BUILT_IN_SCALBN)
1573 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1574 CASE_MATHFN (BUILT_IN_SIN)
1575 CASE_MATHFN (BUILT_IN_SINCOS)
1576 CASE_MATHFN (BUILT_IN_SINH)
1577 CASE_MATHFN (BUILT_IN_SQRT)
1578 CASE_MATHFN (BUILT_IN_TAN)
1579 CASE_MATHFN (BUILT_IN_TANH)
1580 CASE_MATHFN (BUILT_IN_TGAMMA)
1581 CASE_MATHFN (BUILT_IN_TRUNC)
1582 CASE_MATHFN (BUILT_IN_Y0)
1583 CASE_MATHFN (BUILT_IN_Y1)
1584 CASE_MATHFN (BUILT_IN_YN)
1586 default:
1587 return 0;
1590 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1591 return implicit_built_in_decls[fcode];
1592 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1593 return implicit_built_in_decls[fcodef];
1594 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1595 return implicit_built_in_decls[fcodel];
1596 else
1597 return 0;
1600 /* If errno must be maintained, expand the RTL to check if the result,
1601 TARGET, of a built-in function call, EXP, is NaN, and if so set
1602 errno to EDOM. */
1604 static void
1605 expand_errno_check (tree exp, rtx target)
1607 rtx lab = gen_label_rtx ();
1609 /* Test the result; if it is NaN, set errno=EDOM because
1610 the argument was not in the domain. */
1611 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1612 0, lab);
1614 #ifdef TARGET_EDOM
1615 /* If this built-in doesn't throw an exception, set errno directly. */
1616 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1618 #ifdef GEN_ERRNO_RTX
1619 rtx errno_rtx = GEN_ERRNO_RTX;
1620 #else
1621 rtx errno_rtx
1622 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1623 #endif
1624 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1625 emit_label (lab);
1626 return;
1628 #endif
1630 /* We can't set errno=EDOM directly; let the library call do it.
1631 Pop the arguments right away in case the call gets deleted. */
1632 NO_DEFER_POP;
1633 expand_call (exp, target, 0);
1634 OK_DEFER_POP;
1635 emit_label (lab);
1639 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1640 Return 0 if a normal call should be emitted rather than expanding the
1641 function in-line. EXP is the expression that is a call to the builtin
1642 function; if convenient, the result should be placed in TARGET.
1643 SUBTARGET may be used as the target for computing one of EXP's operands. */
1645 static rtx
1646 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1648 optab builtin_optab;
1649 rtx op0, insns, before_call;
1650 tree fndecl = get_callee_fndecl (exp);
1651 tree arglist = TREE_OPERAND (exp, 1);
1652 enum machine_mode mode;
1653 bool errno_set = false;
1654 tree arg, narg;
1656 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1657 return 0;
1659 arg = TREE_VALUE (arglist);
1661 switch (DECL_FUNCTION_CODE (fndecl))
1663 case BUILT_IN_SQRT:
1664 case BUILT_IN_SQRTF:
1665 case BUILT_IN_SQRTL:
1666 errno_set = ! tree_expr_nonnegative_p (arg);
1667 builtin_optab = sqrt_optab;
1668 break;
1669 case BUILT_IN_EXP:
1670 case BUILT_IN_EXPF:
1671 case BUILT_IN_EXPL:
1672 errno_set = true; builtin_optab = exp_optab; break;
1673 case BUILT_IN_EXP10:
1674 case BUILT_IN_EXP10F:
1675 case BUILT_IN_EXP10L:
1676 case BUILT_IN_POW10:
1677 case BUILT_IN_POW10F:
1678 case BUILT_IN_POW10L:
1679 errno_set = true; builtin_optab = exp10_optab; break;
1680 case BUILT_IN_EXP2:
1681 case BUILT_IN_EXP2F:
1682 case BUILT_IN_EXP2L:
1683 errno_set = true; builtin_optab = exp2_optab; break;
1684 case BUILT_IN_EXPM1:
1685 case BUILT_IN_EXPM1F:
1686 case BUILT_IN_EXPM1L:
1687 errno_set = true; builtin_optab = expm1_optab; break;
1688 case BUILT_IN_LOGB:
1689 case BUILT_IN_LOGBF:
1690 case BUILT_IN_LOGBL:
1691 errno_set = true; builtin_optab = logb_optab; break;
1692 case BUILT_IN_ILOGB:
1693 case BUILT_IN_ILOGBF:
1694 case BUILT_IN_ILOGBL:
1695 errno_set = true; builtin_optab = ilogb_optab; break;
1696 case BUILT_IN_LOG:
1697 case BUILT_IN_LOGF:
1698 case BUILT_IN_LOGL:
1699 errno_set = true; builtin_optab = log_optab; break;
1700 case BUILT_IN_LOG10:
1701 case BUILT_IN_LOG10F:
1702 case BUILT_IN_LOG10L:
1703 errno_set = true; builtin_optab = log10_optab; break;
1704 case BUILT_IN_LOG2:
1705 case BUILT_IN_LOG2F:
1706 case BUILT_IN_LOG2L:
1707 errno_set = true; builtin_optab = log2_optab; break;
1708 case BUILT_IN_LOG1P:
1709 case BUILT_IN_LOG1PF:
1710 case BUILT_IN_LOG1PL:
1711 errno_set = true; builtin_optab = log1p_optab; break;
1712 case BUILT_IN_ASIN:
1713 case BUILT_IN_ASINF:
1714 case BUILT_IN_ASINL:
1715 builtin_optab = asin_optab; break;
1716 case BUILT_IN_ACOS:
1717 case BUILT_IN_ACOSF:
1718 case BUILT_IN_ACOSL:
1719 builtin_optab = acos_optab; break;
1720 case BUILT_IN_TAN:
1721 case BUILT_IN_TANF:
1722 case BUILT_IN_TANL:
1723 builtin_optab = tan_optab; break;
1724 case BUILT_IN_ATAN:
1725 case BUILT_IN_ATANF:
1726 case BUILT_IN_ATANL:
1727 builtin_optab = atan_optab; break;
1728 case BUILT_IN_FLOOR:
1729 case BUILT_IN_FLOORF:
1730 case BUILT_IN_FLOORL:
1731 builtin_optab = floor_optab; break;
1732 case BUILT_IN_CEIL:
1733 case BUILT_IN_CEILF:
1734 case BUILT_IN_CEILL:
1735 builtin_optab = ceil_optab; break;
1736 case BUILT_IN_TRUNC:
1737 case BUILT_IN_TRUNCF:
1738 case BUILT_IN_TRUNCL:
1739 builtin_optab = btrunc_optab; break;
1740 case BUILT_IN_ROUND:
1741 case BUILT_IN_ROUNDF:
1742 case BUILT_IN_ROUNDL:
1743 builtin_optab = round_optab; break;
1744 case BUILT_IN_NEARBYINT:
1745 case BUILT_IN_NEARBYINTF:
1746 case BUILT_IN_NEARBYINTL:
1747 builtin_optab = nearbyint_optab; break;
1748 default:
1749 abort ();
1752 /* Make a suitable register to place result in. */
1753 mode = TYPE_MODE (TREE_TYPE (exp));
1755 if (! flag_errno_math || ! HONOR_NANS (mode))
1756 errno_set = false;
1758 /* Before working hard, check whether the instruction is available. */
1759 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1761 target = gen_reg_rtx (mode);
1763 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1764 need to expand the argument again. This way, we will not perform
1765 side-effects more the once. */
1766 narg = builtin_save_expr (arg);
1767 if (narg != arg)
1769 arglist = build_tree_list (NULL_TREE, arg);
1770 exp = build_function_call_expr (fndecl, arglist);
1773 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1775 start_sequence ();
1777 /* Compute into TARGET.
1778 Set TARGET to wherever the result comes back. */
1779 target = expand_unop (mode, builtin_optab, op0, target, 0);
1781 if (target != 0)
1783 if (errno_set)
1784 expand_errno_check (exp, target);
1786 /* Output the entire sequence. */
1787 insns = get_insns ();
1788 end_sequence ();
1789 emit_insn (insns);
1790 return target;
1793 /* If we were unable to expand via the builtin, stop the sequence
1794 (without outputting the insns) and call to the library function
1795 with the stabilized argument list. */
1796 end_sequence ();
1799 before_call = get_last_insn ();
1801 target = expand_call (exp, target, target == const0_rtx);
1803 /* If this is a sqrt operation and we don't care about errno, try to
1804 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1805 This allows the semantics of the libcall to be visible to the RTL
1806 optimizers. */
1807 if (builtin_optab == sqrt_optab && !errno_set)
1809 /* Search backwards through the insns emitted by expand_call looking
1810 for the instruction with the REG_RETVAL note. */
1811 rtx last = get_last_insn ();
1812 while (last != before_call)
1814 if (find_reg_note (last, REG_RETVAL, NULL))
1816 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1817 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1818 two elements, i.e. symbol_ref(sqrt) and the operand. */
1819 if (note
1820 && GET_CODE (note) == EXPR_LIST
1821 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1822 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1823 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1825 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1826 /* Check operand is a register with expected mode. */
1827 if (operand
1828 && REG_P (operand)
1829 && GET_MODE (operand) == mode)
1831 /* Replace the REG_EQUAL note with a SQRT rtx. */
1832 rtx equiv = gen_rtx_SQRT (mode, operand);
1833 set_unique_reg_note (last, REG_EQUAL, equiv);
1836 break;
1838 last = PREV_INSN (last);
1842 return target;
1845 /* Expand a call to the builtin binary math functions (pow and atan2).
1846 Return 0 if a normal call should be emitted rather than expanding the
1847 function in-line. EXP is the expression that is a call to the builtin
1848 function; if convenient, the result should be placed in TARGET.
1849 SUBTARGET may be used as the target for computing one of EXP's
1850 operands. */
1852 static rtx
1853 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1855 optab builtin_optab;
1856 rtx op0, op1, insns;
1857 tree fndecl = get_callee_fndecl (exp);
1858 tree arglist = TREE_OPERAND (exp, 1);
1859 tree arg0, arg1, temp, narg;
1860 enum machine_mode mode;
1861 bool errno_set = true;
1862 bool stable = true;
1864 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1865 return 0;
1867 arg0 = TREE_VALUE (arglist);
1868 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1870 switch (DECL_FUNCTION_CODE (fndecl))
1872 case BUILT_IN_POW:
1873 case BUILT_IN_POWF:
1874 case BUILT_IN_POWL:
1875 builtin_optab = pow_optab; break;
1876 case BUILT_IN_ATAN2:
1877 case BUILT_IN_ATAN2F:
1878 case BUILT_IN_ATAN2L:
1879 builtin_optab = atan2_optab; break;
1880 case BUILT_IN_FMOD:
1881 case BUILT_IN_FMODF:
1882 case BUILT_IN_FMODL:
1883 builtin_optab = fmod_optab; break;
1884 case BUILT_IN_DREM:
1885 case BUILT_IN_DREMF:
1886 case BUILT_IN_DREML:
1887 builtin_optab = drem_optab; break;
1888 default:
1889 abort ();
1892 /* Make a suitable register to place result in. */
1893 mode = TYPE_MODE (TREE_TYPE (exp));
1895 /* Before working hard, check whether the instruction is available. */
1896 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1897 return 0;
1899 target = gen_reg_rtx (mode);
1901 if (! flag_errno_math || ! HONOR_NANS (mode))
1902 errno_set = false;
1904 /* Always stabilize the argument list. */
1905 narg = builtin_save_expr (arg1);
1906 if (narg != arg1)
1908 temp = build_tree_list (NULL_TREE, narg);
1909 stable = false;
1911 else
1912 temp = TREE_CHAIN (arglist);
1914 narg = builtin_save_expr (arg0);
1915 if (narg != arg0)
1917 arglist = tree_cons (NULL_TREE, narg, temp);
1918 stable = false;
1920 else if (! stable)
1921 arglist = tree_cons (NULL_TREE, arg0, temp);
1923 if (! stable)
1924 exp = build_function_call_expr (fndecl, arglist);
1926 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1927 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1929 start_sequence ();
1931 /* Compute into TARGET.
1932 Set TARGET to wherever the result comes back. */
1933 target = expand_binop (mode, builtin_optab, op0, op1,
1934 target, 0, OPTAB_DIRECT);
1936 /* If we were unable to expand via the builtin, stop the sequence
1937 (without outputting the insns) and call to the library function
1938 with the stabilized argument list. */
1939 if (target == 0)
1941 end_sequence ();
1942 return expand_call (exp, target, target == const0_rtx);
1945 if (errno_set)
1946 expand_errno_check (exp, target);
1948 /* Output the entire sequence. */
1949 insns = get_insns ();
1950 end_sequence ();
1951 emit_insn (insns);
1953 return target;
1956 /* Expand a call to the builtin sin and cos math functions.
1957 Return 0 if a normal call should be emitted rather than expanding the
1958 function in-line. EXP is the expression that is a call to the builtin
1959 function; if convenient, the result should be placed in TARGET.
1960 SUBTARGET may be used as the target for computing one of EXP's
1961 operands. */
1963 static rtx
1964 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1966 optab builtin_optab;
1967 rtx op0, insns, before_call;
1968 tree fndecl = get_callee_fndecl (exp);
1969 tree arglist = TREE_OPERAND (exp, 1);
1970 enum machine_mode mode;
1971 bool errno_set = false;
1972 tree arg, narg;
1974 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1975 return 0;
1977 arg = TREE_VALUE (arglist);
1979 switch (DECL_FUNCTION_CODE (fndecl))
1981 case BUILT_IN_SIN:
1982 case BUILT_IN_SINF:
1983 case BUILT_IN_SINL:
1984 case BUILT_IN_COS:
1985 case BUILT_IN_COSF:
1986 case BUILT_IN_COSL:
1987 builtin_optab = sincos_optab; break;
1988 default:
1989 abort ();
1992 /* Make a suitable register to place result in. */
1993 mode = TYPE_MODE (TREE_TYPE (exp));
1995 if (! flag_errno_math || ! HONOR_NANS (mode))
1996 errno_set = false;
1998 /* Check if sincos insn is available, otherwise fallback
1999 to sin or cos insn. */
2000 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2001 switch (DECL_FUNCTION_CODE (fndecl))
2003 case BUILT_IN_SIN:
2004 case BUILT_IN_SINF:
2005 case BUILT_IN_SINL:
2006 builtin_optab = sin_optab; break;
2007 case BUILT_IN_COS:
2008 case BUILT_IN_COSF:
2009 case BUILT_IN_COSL:
2010 builtin_optab = cos_optab; break;
2011 default:
2012 abort();
2016 /* Before working hard, check whether the instruction is available. */
2017 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2019 target = gen_reg_rtx (mode);
2021 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2022 need to expand the argument again. This way, we will not perform
2023 side-effects more the once. */
2024 narg = save_expr (arg);
2025 if (narg != arg)
2027 arglist = build_tree_list (NULL_TREE, arg);
2028 exp = build_function_call_expr (fndecl, arglist);
2031 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2033 start_sequence ();
2035 /* Compute into TARGET.
2036 Set TARGET to wherever the result comes back. */
2037 if (builtin_optab == sincos_optab)
2039 switch (DECL_FUNCTION_CODE (fndecl))
2041 case BUILT_IN_SIN:
2042 case BUILT_IN_SINF:
2043 case BUILT_IN_SINL:
2044 if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
2045 abort();
2046 break;
2047 case BUILT_IN_COS:
2048 case BUILT_IN_COSF:
2049 case BUILT_IN_COSL:
2050 if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2051 abort();
2052 break;
2053 default:
2054 abort();
2057 else
2059 target = expand_unop (mode, builtin_optab, op0, target, 0);
2062 if (target != 0)
2064 if (errno_set)
2065 expand_errno_check (exp, target);
2067 /* Output the entire sequence. */
2068 insns = get_insns ();
2069 end_sequence ();
2070 emit_insn (insns);
2071 return target;
2074 /* If we were unable to expand via the builtin, stop the sequence
2075 (without outputting the insns) and call to the library function
2076 with the stabilized argument list. */
2077 end_sequence ();
2080 before_call = get_last_insn ();
2082 target = expand_call (exp, target, target == const0_rtx);
2084 return target;
2087 /* To evaluate powi(x,n), the floating point value x raised to the
2088 constant integer exponent n, we use a hybrid algorithm that
2089 combines the "window method" with look-up tables. For an
2090 introduction to exponentiation algorithms and "addition chains",
2091 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2092 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2093 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2094 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2096 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2097 multiplications to inline before calling the system library's pow
2098 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2099 so this default never requires calling pow, powf or powl. */
2101 #ifndef POWI_MAX_MULTS
2102 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2103 #endif
2105 /* The size of the "optimal power tree" lookup table. All
2106 exponents less than this value are simply looked up in the
2107 powi_table below. This threshold is also used to size the
2108 cache of pseudo registers that hold intermediate results. */
2109 #define POWI_TABLE_SIZE 256
2111 /* The size, in bits of the window, used in the "window method"
2112 exponentiation algorithm. This is equivalent to a radix of
2113 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2114 #define POWI_WINDOW_SIZE 3
2116 /* The following table is an efficient representation of an
2117 "optimal power tree". For each value, i, the corresponding
2118 value, j, in the table states than an optimal evaluation
2119 sequence for calculating pow(x,i) can be found by evaluating
2120 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2121 100 integers is given in Knuth's "Seminumerical algorithms". */
2123 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2125 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2126 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2127 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2128 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2129 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2130 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2131 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2132 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2133 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2134 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2135 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2136 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2137 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2138 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2139 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2140 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2141 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2142 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2143 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2144 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2145 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2146 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2147 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2148 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2149 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2150 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2151 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2152 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2153 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2154 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2155 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2156 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2160 /* Return the number of multiplications required to calculate
2161 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2162 subroutine of powi_cost. CACHE is an array indicating
2163 which exponents have already been calculated. */
2165 static int
2166 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2168 /* If we've already calculated this exponent, then this evaluation
2169 doesn't require any additional multiplications. */
2170 if (cache[n])
2171 return 0;
2173 cache[n] = true;
2174 return powi_lookup_cost (n - powi_table[n], cache)
2175 + powi_lookup_cost (powi_table[n], cache) + 1;
2178 /* Return the number of multiplications required to calculate
2179 powi(x,n) for an arbitrary x, given the exponent N. This
2180 function needs to be kept in sync with expand_powi below. */
2182 static int
2183 powi_cost (HOST_WIDE_INT n)
2185 bool cache[POWI_TABLE_SIZE];
2186 unsigned HOST_WIDE_INT digit;
2187 unsigned HOST_WIDE_INT val;
2188 int result;
2190 if (n == 0)
2191 return 0;
2193 /* Ignore the reciprocal when calculating the cost. */
2194 val = (n < 0) ? -n : n;
2196 /* Initialize the exponent cache. */
2197 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2198 cache[1] = true;
2200 result = 0;
2202 while (val >= POWI_TABLE_SIZE)
2204 if (val & 1)
2206 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2207 result += powi_lookup_cost (digit, cache)
2208 + POWI_WINDOW_SIZE + 1;
2209 val >>= POWI_WINDOW_SIZE;
2211 else
2213 val >>= 1;
2214 result++;
2218 return result + powi_lookup_cost (val, cache);
2221 /* Recursive subroutine of expand_powi. This function takes the array,
2222 CACHE, of already calculated exponents and an exponent N and returns
2223 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2225 static rtx
2226 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2228 unsigned HOST_WIDE_INT digit;
2229 rtx target, result;
2230 rtx op0, op1;
2232 if (n < POWI_TABLE_SIZE)
2234 if (cache[n])
2235 return cache[n];
2237 target = gen_reg_rtx (mode);
2238 cache[n] = target;
2240 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2241 op1 = expand_powi_1 (mode, powi_table[n], cache);
2243 else if (n & 1)
2245 target = gen_reg_rtx (mode);
2246 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2247 op0 = expand_powi_1 (mode, n - digit, cache);
2248 op1 = expand_powi_1 (mode, digit, cache);
2250 else
2252 target = gen_reg_rtx (mode);
2253 op0 = expand_powi_1 (mode, n >> 1, cache);
2254 op1 = op0;
2257 result = expand_mult (mode, op0, op1, target, 0);
2258 if (result != target)
2259 emit_move_insn (target, result);
2260 return target;
2263 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2264 floating point operand in mode MODE, and N is the exponent. This
2265 function needs to be kept in sync with powi_cost above. */
2267 static rtx
2268 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2270 unsigned HOST_WIDE_INT val;
2271 rtx cache[POWI_TABLE_SIZE];
2272 rtx result;
2274 if (n == 0)
2275 return CONST1_RTX (mode);
2277 val = (n < 0) ? -n : n;
2279 memset (cache, 0, sizeof (cache));
2280 cache[1] = x;
2282 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2284 /* If the original exponent was negative, reciprocate the result. */
2285 if (n < 0)
2286 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2287 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2289 return result;
2292 /* Expand a call to the pow built-in mathematical function. Return 0 if
2293 a normal call should be emitted rather than expanding the function
2294 in-line. EXP is the expression that is a call to the builtin
2295 function; if convenient, the result should be placed in TARGET. */
2297 static rtx
2298 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2300 tree arglist = TREE_OPERAND (exp, 1);
2301 tree arg0, arg1;
2303 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2304 return 0;
2306 arg0 = TREE_VALUE (arglist);
2307 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2309 if (TREE_CODE (arg1) == REAL_CST
2310 && ! TREE_CONSTANT_OVERFLOW (arg1))
2312 REAL_VALUE_TYPE cint;
2313 REAL_VALUE_TYPE c;
2314 HOST_WIDE_INT n;
2316 c = TREE_REAL_CST (arg1);
2317 n = real_to_integer (&c);
2318 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2319 if (real_identical (&c, &cint))
2321 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2322 Otherwise, check the number of multiplications required.
2323 Note that pow never sets errno for an integer exponent. */
2324 if ((n >= -1 && n <= 2)
2325 || (flag_unsafe_math_optimizations
2326 && ! optimize_size
2327 && powi_cost (n) <= POWI_MAX_MULTS))
2329 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2330 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2331 op = force_reg (mode, op);
2332 return expand_powi (op, mode, n);
2337 if (! flag_unsafe_math_optimizations)
2338 return NULL_RTX;
2339 return expand_builtin_mathfn_2 (exp, target, subtarget);
2342 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2343 if we failed the caller should emit a normal call, otherwise
2344 try to get the result in TARGET, if convenient. */
2346 static rtx
2347 expand_builtin_strlen (tree arglist, rtx target,
2348 enum machine_mode target_mode)
2350 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2351 return 0;
2352 else
2354 rtx pat;
2355 tree len, src = TREE_VALUE (arglist);
2356 rtx result, src_reg, char_rtx, before_strlen;
2357 enum machine_mode insn_mode = target_mode, char_mode;
2358 enum insn_code icode = CODE_FOR_nothing;
2359 int align;
2361 /* If the length can be computed at compile-time, return it. */
2362 len = c_strlen (src, 0);
2363 if (len)
2364 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2366 /* If the length can be computed at compile-time and is constant
2367 integer, but there are side-effects in src, evaluate
2368 src for side-effects, then return len.
2369 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2370 can be optimized into: i++; x = 3; */
2371 len = c_strlen (src, 1);
2372 if (len && TREE_CODE (len) == INTEGER_CST)
2374 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2375 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2378 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2380 /* If SRC is not a pointer type, don't do this operation inline. */
2381 if (align == 0)
2382 return 0;
2384 /* Bail out if we can't compute strlen in the right mode. */
2385 while (insn_mode != VOIDmode)
2387 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2388 if (icode != CODE_FOR_nothing)
2389 break;
2391 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2393 if (insn_mode == VOIDmode)
2394 return 0;
2396 /* Make a place to write the result of the instruction. */
2397 result = target;
2398 if (! (result != 0
2399 && REG_P (result)
2400 && GET_MODE (result) == insn_mode
2401 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2402 result = gen_reg_rtx (insn_mode);
2404 /* Make a place to hold the source address. We will not expand
2405 the actual source until we are sure that the expansion will
2406 not fail -- there are trees that cannot be expanded twice. */
2407 src_reg = gen_reg_rtx (Pmode);
2409 /* Mark the beginning of the strlen sequence so we can emit the
2410 source operand later. */
2411 before_strlen = get_last_insn ();
2413 char_rtx = const0_rtx;
2414 char_mode = insn_data[(int) icode].operand[2].mode;
2415 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2416 char_mode))
2417 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2419 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2420 char_rtx, GEN_INT (align));
2421 if (! pat)
2422 return 0;
2423 emit_insn (pat);
2425 /* Now that we are assured of success, expand the source. */
2426 start_sequence ();
2427 pat = memory_address (BLKmode,
2428 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2429 if (pat != src_reg)
2430 emit_move_insn (src_reg, pat);
2431 pat = get_insns ();
2432 end_sequence ();
2434 if (before_strlen)
2435 emit_insn_after (pat, before_strlen);
2436 else
2437 emit_insn_before (pat, get_insns ());
2439 /* Return the value in the proper mode for this function. */
2440 if (GET_MODE (result) == target_mode)
2441 target = result;
2442 else if (target != 0)
2443 convert_move (target, result, 0);
2444 else
2445 target = convert_to_mode (target_mode, result, 0);
2447 return target;
2451 /* Expand a call to the strstr builtin. Return 0 if we failed the
2452 caller should emit a normal call, otherwise try to get the result
2453 in TARGET, if convenient (and in mode MODE if that's convenient). */
2455 static rtx
2456 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2458 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2459 return 0;
2460 else
2462 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2463 tree fn, tmp;
2464 const char *p1, *p2;
2466 p2 = c_getstr (s2);
2467 if (p2 == NULL)
2468 return 0;
2470 p1 = c_getstr (s1);
2471 if (p1 != NULL)
2473 const char *r = strstr (p1, p2);
2475 if (r == NULL)
2476 return const0_rtx;
2478 /* Return an offset into the constant string argument. */
2479 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2480 fold_convert (TREE_TYPE (s1),
2481 ssize_int (r - p1))));
2482 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2485 if (p2[0] == '\0')
2486 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2488 if (p2[1] != '\0')
2489 return 0;
2491 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2492 if (!fn)
2493 return 0;
2495 /* New argument list transforming strstr(s1, s2) to
2496 strchr(s1, s2[0]). */
2497 arglist =
2498 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2499 arglist = tree_cons (NULL_TREE, s1, arglist);
2500 return expand_expr (build_function_call_expr (fn, arglist),
2501 target, mode, EXPAND_NORMAL);
2505 /* Expand a call to the strchr builtin. Return 0 if we failed the
2506 caller should emit a normal call, otherwise try to get the result
2507 in TARGET, if convenient (and in mode MODE if that's convenient). */
2509 static rtx
2510 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2512 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2513 return 0;
2514 else
2516 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2517 const char *p1;
2519 if (TREE_CODE (s2) != INTEGER_CST)
2520 return 0;
2522 p1 = c_getstr (s1);
2523 if (p1 != NULL)
2525 char c;
2526 const char *r;
2527 tree tmp;
2529 if (target_char_cast (s2, &c))
2530 return 0;
2532 r = strchr (p1, c);
2534 if (r == NULL)
2535 return const0_rtx;
2537 /* Return an offset into the constant string argument. */
2538 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2539 fold_convert (TREE_TYPE (s1),
2540 ssize_int (r - p1))));
2541 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2544 /* FIXME: Should use here strchrM optab so that ports can optimize
2545 this. */
2546 return 0;
2550 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2551 caller should emit a normal call, otherwise try to get the result
2552 in TARGET, if convenient (and in mode MODE if that's convenient). */
2554 static rtx
2555 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2557 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2558 return 0;
2559 else
2561 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2562 tree fn, tmp;
2563 const char *p1;
2565 if (TREE_CODE (s2) != INTEGER_CST)
2566 return 0;
2568 p1 = c_getstr (s1);
2569 if (p1 != NULL)
2571 char c;
2572 const char *r;
2574 if (target_char_cast (s2, &c))
2575 return 0;
2577 r = strrchr (p1, c);
2579 if (r == NULL)
2580 return const0_rtx;
2582 /* Return an offset into the constant string argument. */
2583 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2584 fold_convert (TREE_TYPE (s1),
2585 ssize_int (r - p1))));
2586 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2589 if (! integer_zerop (s2))
2590 return 0;
2592 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2593 if (!fn)
2594 return 0;
2596 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2597 return expand_expr (build_function_call_expr (fn, arglist),
2598 target, mode, EXPAND_NORMAL);
2602 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2603 caller should emit a normal call, otherwise try to get the result
2604 in TARGET, if convenient (and in mode MODE if that's convenient). */
2606 static rtx
2607 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2609 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2610 return 0;
2611 else
2613 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2614 tree fn, tmp;
2615 const char *p1, *p2;
2617 p2 = c_getstr (s2);
2618 if (p2 == NULL)
2619 return 0;
2621 p1 = c_getstr (s1);
2622 if (p1 != NULL)
2624 const char *r = strpbrk (p1, p2);
2626 if (r == NULL)
2627 return const0_rtx;
2629 /* Return an offset into the constant string argument. */
2630 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2631 fold_convert (TREE_TYPE (s1),
2632 ssize_int (r - p1))));
2633 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2636 if (p2[0] == '\0')
2638 /* strpbrk(x, "") == NULL.
2639 Evaluate and ignore the arguments in case they had
2640 side-effects. */
2641 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2642 return const0_rtx;
2645 if (p2[1] != '\0')
2646 return 0; /* Really call strpbrk. */
2648 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2649 if (!fn)
2650 return 0;
2652 /* New argument list transforming strpbrk(s1, s2) to
2653 strchr(s1, s2[0]). */
2654 arglist =
2655 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2656 arglist = tree_cons (NULL_TREE, s1, arglist);
2657 return expand_expr (build_function_call_expr (fn, arglist),
2658 target, mode, EXPAND_NORMAL);
2662 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2663 bytes from constant string DATA + OFFSET and return it as target
2664 constant. */
2666 static rtx
2667 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2668 enum machine_mode mode)
2670 const char *str = (const char *) data;
2672 if (offset < 0
2673 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2674 > strlen (str) + 1))
2675 abort (); /* Attempt to read past the end of constant string. */
2677 return c_readstr (str + offset, mode);
2680 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2681 Return 0 if we failed, the caller should emit a normal call,
2682 otherwise try to get the result in TARGET, if convenient (and in
2683 mode MODE if that's convenient). */
2684 static rtx
2685 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2687 if (!validate_arglist (arglist,
2688 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2689 return 0;
2690 else
2692 tree dest = TREE_VALUE (arglist);
2693 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2694 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2695 const char *src_str;
2696 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2697 unsigned int dest_align
2698 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2699 rtx dest_mem, src_mem, dest_addr, len_rtx;
2701 /* If DEST is not a pointer type, call the normal function. */
2702 if (dest_align == 0)
2703 return 0;
2705 /* If the LEN parameter is zero, return DEST. */
2706 if (integer_zerop (len))
2708 /* Evaluate and ignore SRC in case it has side-effects. */
2709 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2710 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2713 /* If SRC and DEST are the same (and not volatile), return DEST. */
2714 if (operand_equal_p (src, dest, 0))
2716 /* Evaluate and ignore LEN in case it has side-effects. */
2717 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2718 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2721 /* If either SRC is not a pointer type, don't do this
2722 operation in-line. */
2723 if (src_align == 0)
2724 return 0;
2726 dest_mem = get_memory_rtx (dest);
2727 set_mem_align (dest_mem, dest_align);
2728 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2729 src_str = c_getstr (src);
2731 /* If SRC is a string constant and block move would be done
2732 by pieces, we can avoid loading the string from memory
2733 and only stored the computed constants. */
2734 if (src_str
2735 && GET_CODE (len_rtx) == CONST_INT
2736 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2737 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2738 (void *) src_str, dest_align))
2740 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2741 builtin_memcpy_read_str,
2742 (void *) src_str, dest_align, 0);
2743 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2744 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2745 return dest_mem;
2748 src_mem = get_memory_rtx (src);
2749 set_mem_align (src_mem, src_align);
2751 /* Copy word part most expediently. */
2752 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2753 BLOCK_OP_NORMAL);
2755 if (dest_addr == 0)
2757 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2758 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2760 return dest_addr;
2764 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2765 Return 0 if we failed the caller should emit a normal call,
2766 otherwise try to get the result in TARGET, if convenient (and in
2767 mode MODE if that's convenient). If ENDP is 0 return the
2768 destination pointer, if ENDP is 1 return the end pointer ala
2769 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2770 stpcpy. */
2772 static rtx
2773 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2774 int endp)
2776 if (!validate_arglist (arglist,
2777 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2778 return 0;
2779 /* If return value is ignored, transform mempcpy into memcpy. */
2780 else if (target == const0_rtx)
2782 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2784 if (!fn)
2785 return 0;
2787 return expand_expr (build_function_call_expr (fn, arglist),
2788 target, mode, EXPAND_NORMAL);
2790 else
2792 tree dest = TREE_VALUE (arglist);
2793 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2794 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2795 const char *src_str;
2796 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2797 unsigned int dest_align
2798 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2799 rtx dest_mem, src_mem, len_rtx;
2801 /* If DEST is not a pointer type, call the normal function. */
2802 if (dest_align == 0)
2803 return 0;
2805 /* If SRC and DEST are the same (and not volatile), do nothing. */
2806 if (operand_equal_p (src, dest, 0))
2808 tree expr;
2810 if (endp == 0)
2812 /* Evaluate and ignore LEN in case it has side-effects. */
2813 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2814 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2817 if (endp == 2)
2818 len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2819 integer_one_node));
2820 len = fold_convert (TREE_TYPE (dest), len);
2821 expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2822 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2825 /* If LEN is not constant, call the normal function. */
2826 if (! host_integerp (len, 1))
2827 return 0;
2829 /* If the LEN parameter is zero, return DEST. */
2830 if (tree_low_cst (len, 1) == 0)
2832 /* Evaluate and ignore SRC in case it has side-effects. */
2833 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2834 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2837 /* If either SRC is not a pointer type, don't do this
2838 operation in-line. */
2839 if (src_align == 0)
2840 return 0;
2842 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2843 src_str = c_getstr (src);
2845 /* If SRC is a string constant and block move would be done
2846 by pieces, we can avoid loading the string from memory
2847 and only stored the computed constants. */
2848 if (src_str
2849 && GET_CODE (len_rtx) == CONST_INT
2850 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2851 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2852 (void *) src_str, dest_align))
2854 dest_mem = get_memory_rtx (dest);
2855 set_mem_align (dest_mem, dest_align);
2856 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2857 builtin_memcpy_read_str,
2858 (void *) src_str, dest_align, endp);
2859 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2860 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2861 return dest_mem;
2864 if (GET_CODE (len_rtx) == CONST_INT
2865 && can_move_by_pieces (INTVAL (len_rtx),
2866 MIN (dest_align, src_align)))
2868 dest_mem = get_memory_rtx (dest);
2869 set_mem_align (dest_mem, dest_align);
2870 src_mem = get_memory_rtx (src);
2871 set_mem_align (src_mem, src_align);
2872 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2873 MIN (dest_align, src_align), endp);
2874 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2875 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2876 return dest_mem;
2879 return 0;
2883 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2884 if we failed the caller should emit a normal call. */
2886 static rtx
2887 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2889 if (!validate_arglist (arglist,
2890 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2891 return 0;
2892 else
2894 tree dest = TREE_VALUE (arglist);
2895 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2896 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2898 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2899 unsigned int dest_align
2900 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2902 /* If DEST is not a pointer type, call the normal function. */
2903 if (dest_align == 0)
2904 return 0;
2906 /* If the LEN parameter is zero, return DEST. */
2907 if (integer_zerop (len))
2909 /* Evaluate and ignore SRC in case it has side-effects. */
2910 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2911 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2914 /* If SRC and DEST are the same (and not volatile), return DEST. */
2915 if (operand_equal_p (src, dest, 0))
2917 /* Evaluate and ignore LEN in case it has side-effects. */
2918 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2919 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2922 /* If either SRC is not a pointer type, don't do this
2923 operation in-line. */
2924 if (src_align == 0)
2925 return 0;
2927 /* If src is categorized for a readonly section we can use
2928 normal memcpy. */
2929 if (readonly_data_expr (src))
2931 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2932 if (!fn)
2933 return 0;
2934 return expand_expr (build_function_call_expr (fn, arglist),
2935 target, mode, EXPAND_NORMAL);
2938 /* Otherwise, call the normal function. */
2939 return 0;
2943 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2944 if we failed the caller should emit a normal call. */
2946 static rtx
2947 expand_builtin_bcopy (tree arglist)
2949 tree src, dest, size, newarglist;
2951 if (!validate_arglist (arglist,
2952 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2953 return NULL_RTX;
2955 src = TREE_VALUE (arglist);
2956 dest = TREE_VALUE (TREE_CHAIN (arglist));
2957 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2959 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2960 memmove(ptr y, ptr x, size_t z). This is done this way
2961 so that if it isn't expanded inline, we fallback to
2962 calling bcopy instead of memmove. */
2964 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2965 newarglist = tree_cons (NULL_TREE, src, newarglist);
2966 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2968 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2971 #ifndef HAVE_movstr
2972 # define HAVE_movstr 0
2973 # define CODE_FOR_movstr CODE_FOR_nothing
2974 #endif
2976 /* Expand into a movstr instruction, if one is available. Return 0 if
2977 we failed, the caller should emit a normal call, otherwise try to
2978 get the result in TARGET, if convenient. If ENDP is 0 return the
2979 destination pointer, if ENDP is 1 return the end pointer ala
2980 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2981 stpcpy. */
2983 static rtx
2984 expand_movstr (tree dest, tree src, rtx target, int endp)
2986 rtx end;
2987 rtx dest_mem;
2988 rtx src_mem;
2989 rtx insn;
2990 const struct insn_data * data;
2992 if (!HAVE_movstr)
2993 return 0;
2995 dest_mem = get_memory_rtx (dest);
2996 src_mem = get_memory_rtx (src);
2997 if (!endp)
2999 target = force_reg (Pmode, XEXP (dest_mem, 0));
3000 dest_mem = replace_equiv_address (dest_mem, target);
3001 end = gen_reg_rtx (Pmode);
3003 else
3005 if (target == 0 || target == const0_rtx)
3007 end = gen_reg_rtx (Pmode);
3008 if (target == 0)
3009 target = end;
3011 else
3012 end = target;
3015 data = insn_data + CODE_FOR_movstr;
3017 if (data->operand[0].mode != VOIDmode)
3018 end = gen_lowpart (data->operand[0].mode, end);
3020 insn = data->genfun (end, dest_mem, src_mem);
3022 if (insn == 0)
3023 abort ();
3025 emit_insn (insn);
3027 /* movstr is supposed to set end to the address of the NUL
3028 terminator. If the caller requested a mempcpy-like return value,
3029 adjust it. */
3030 if (endp == 1 && target != const0_rtx)
3031 emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3032 end), 1));
3034 return target;
3037 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3038 if we failed the caller should emit a normal call, otherwise try to get
3039 the result in TARGET, if convenient (and in mode MODE if that's
3040 convenient). */
3042 static rtx
3043 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3045 tree fn, len, src, dst;
3047 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3048 return 0;
3050 src = TREE_VALUE (TREE_CHAIN (arglist));
3051 dst = TREE_VALUE (arglist);
3053 /* If SRC and DST are equal (and not volatile), return DST. */
3054 if (operand_equal_p (src, dst, 0))
3055 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3057 len = c_strlen (src, 1);
3058 if (len == 0 || TREE_SIDE_EFFECTS (len))
3059 return expand_movstr (TREE_VALUE (arglist),
3060 TREE_VALUE (TREE_CHAIN (arglist)),
3061 target, /*endp=*/0);
3063 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3064 if (!fn)
3065 return 0;
3067 len = size_binop (PLUS_EXPR, len, ssize_int (1));
3068 arglist = build_tree_list (NULL_TREE, len);
3069 arglist = tree_cons (NULL_TREE, src, arglist);
3070 arglist = tree_cons (NULL_TREE, dst, arglist);
3071 return expand_expr (build_function_call_expr (fn, arglist),
3072 target, mode, EXPAND_NORMAL);
3075 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3076 Return 0 if we failed the caller should emit a normal call,
3077 otherwise try to get the result in TARGET, if convenient (and in
3078 mode MODE if that's convenient). */
3080 static rtx
3081 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3083 /* If return value is ignored, transform stpcpy into strcpy. */
3084 if (target == const0_rtx)
3086 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3087 if (!fn)
3088 return 0;
3090 return expand_expr (build_function_call_expr (fn, arglist),
3091 target, mode, EXPAND_NORMAL);
3094 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3095 return 0;
3096 else
3098 tree dst, src, len, lenp1;
3099 tree narglist;
3100 rtx ret;
3102 /* Ensure we get an actual string whose length can be evaluated at
3103 compile-time, not an expression containing a string. This is
3104 because the latter will potentially produce pessimized code
3105 when used to produce the return value. */
3106 src = TREE_VALUE (TREE_CHAIN (arglist));
3107 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3108 return expand_movstr (TREE_VALUE (arglist),
3109 TREE_VALUE (TREE_CHAIN (arglist)),
3110 target, /*endp=*/2);
3112 dst = TREE_VALUE (arglist);
3113 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3114 narglist = build_tree_list (NULL_TREE, lenp1);
3115 narglist = tree_cons (NULL_TREE, src, narglist);
3116 narglist = tree_cons (NULL_TREE, dst, narglist);
3117 ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3119 if (ret)
3120 return ret;
3122 if (TREE_CODE (len) == INTEGER_CST)
3124 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3126 if (GET_CODE (len_rtx) == CONST_INT)
3128 ret = expand_builtin_strcpy (arglist, target, mode);
3130 if (ret)
3132 if (! target)
3134 if (mode != VOIDmode)
3135 target = gen_reg_rtx (mode);
3136 else
3137 target = gen_reg_rtx (GET_MODE (ret));
3139 if (GET_MODE (target) != GET_MODE (ret))
3140 ret = gen_lowpart (GET_MODE (target), ret);
3142 ret = emit_move_insn (target,
3143 plus_constant (ret,
3144 INTVAL (len_rtx)));
3145 if (! ret)
3146 abort ();
3148 return target;
3153 return expand_movstr (TREE_VALUE (arglist),
3154 TREE_VALUE (TREE_CHAIN (arglist)),
3155 target, /*endp=*/2);
3159 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3160 bytes from constant string DATA + OFFSET and return it as target
3161 constant. */
3163 static rtx
3164 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3165 enum machine_mode mode)
3167 const char *str = (const char *) data;
3169 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3170 return const0_rtx;
3172 return c_readstr (str + offset, mode);
3175 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3176 if we failed the caller should emit a normal call. */
3178 static rtx
3179 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3181 if (!validate_arglist (arglist,
3182 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3183 return 0;
3184 else
3186 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3187 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3188 tree fn;
3190 /* We must be passed a constant len parameter. */
3191 if (TREE_CODE (len) != INTEGER_CST)
3192 return 0;
3194 /* If the len parameter is zero, return the dst parameter. */
3195 if (integer_zerop (len))
3197 /* Evaluate and ignore the src argument in case it has
3198 side-effects. */
3199 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3200 VOIDmode, EXPAND_NORMAL);
3201 /* Return the dst parameter. */
3202 return expand_expr (TREE_VALUE (arglist), target, mode,
3203 EXPAND_NORMAL);
3206 /* Now, we must be passed a constant src ptr parameter. */
3207 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3208 return 0;
3210 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3212 /* We're required to pad with trailing zeros if the requested
3213 len is greater than strlen(s2)+1. In that case try to
3214 use store_by_pieces, if it fails, punt. */
3215 if (tree_int_cst_lt (slen, len))
3217 tree dest = TREE_VALUE (arglist);
3218 unsigned int dest_align
3219 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3220 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3221 rtx dest_mem;
3223 if (!p || dest_align == 0 || !host_integerp (len, 1)
3224 || !can_store_by_pieces (tree_low_cst (len, 1),
3225 builtin_strncpy_read_str,
3226 (void *) p, dest_align))
3227 return 0;
3229 dest_mem = get_memory_rtx (dest);
3230 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3231 builtin_strncpy_read_str,
3232 (void *) p, dest_align, 0);
3233 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3234 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3235 return dest_mem;
3238 /* OK transform into builtin memcpy. */
3239 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3240 if (!fn)
3241 return 0;
3242 return expand_expr (build_function_call_expr (fn, arglist),
3243 target, mode, EXPAND_NORMAL);
3247 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3248 bytes from constant string DATA + OFFSET and return it as target
3249 constant. */
3251 static rtx
3252 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3253 enum machine_mode mode)
3255 const char *c = (const char *) data;
3256 char *p = alloca (GET_MODE_SIZE (mode));
3258 memset (p, *c, GET_MODE_SIZE (mode));
3260 return c_readstr (p, mode);
3263 /* Callback routine for store_by_pieces. Return the RTL of a register
3264 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3265 char value given in the RTL register data. For example, if mode is
3266 4 bytes wide, return the RTL for 0x01010101*data. */
3268 static rtx
3269 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3270 enum machine_mode mode)
3272 rtx target, coeff;
3273 size_t size;
3274 char *p;
3276 size = GET_MODE_SIZE (mode);
3277 if (size == 1)
3278 return (rtx) data;
3280 p = alloca (size);
3281 memset (p, 1, size);
3282 coeff = c_readstr (p, mode);
3284 target = convert_to_mode (mode, (rtx) data, 1);
3285 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3286 return force_reg (mode, target);
3289 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3290 if we failed the caller should emit a normal call, otherwise try to get
3291 the result in TARGET, if convenient (and in mode MODE if that's
3292 convenient). */
3294 static rtx
3295 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3297 if (!validate_arglist (arglist,
3298 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3299 return 0;
3300 else
3302 tree dest = TREE_VALUE (arglist);
3303 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3304 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3305 char c;
3307 unsigned int dest_align
3308 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3309 rtx dest_mem, dest_addr, len_rtx;
3311 /* If DEST is not a pointer type, don't do this
3312 operation in-line. */
3313 if (dest_align == 0)
3314 return 0;
3316 /* If the LEN parameter is zero, return DEST. */
3317 if (integer_zerop (len))
3319 /* Evaluate and ignore VAL in case it has side-effects. */
3320 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3321 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3324 if (TREE_CODE (val) != INTEGER_CST)
3326 rtx val_rtx;
3328 if (!host_integerp (len, 1))
3329 return 0;
3331 if (optimize_size && tree_low_cst (len, 1) > 1)
3332 return 0;
3334 /* Assume that we can memset by pieces if we can store the
3335 * the coefficients by pieces (in the required modes).
3336 * We can't pass builtin_memset_gen_str as that emits RTL. */
3337 c = 1;
3338 if (!can_store_by_pieces (tree_low_cst (len, 1),
3339 builtin_memset_read_str,
3340 &c, dest_align))
3341 return 0;
3343 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3344 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3345 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3346 val_rtx);
3347 dest_mem = get_memory_rtx (dest);
3348 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3349 builtin_memset_gen_str,
3350 val_rtx, dest_align, 0);
3351 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3352 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3353 return dest_mem;
3356 if (target_char_cast (val, &c))
3357 return 0;
3359 if (c)
3361 if (!host_integerp (len, 1))
3362 return 0;
3363 if (!can_store_by_pieces (tree_low_cst (len, 1),
3364 builtin_memset_read_str, &c,
3365 dest_align))
3366 return 0;
3368 dest_mem = get_memory_rtx (dest);
3369 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3370 builtin_memset_read_str,
3371 &c, dest_align, 0);
3372 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3373 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3374 return dest_mem;
3377 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3379 dest_mem = get_memory_rtx (dest);
3380 set_mem_align (dest_mem, dest_align);
3381 dest_addr = clear_storage (dest_mem, len_rtx);
3383 if (dest_addr == 0)
3385 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3386 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3389 return dest_addr;
3393 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3394 if we failed the caller should emit a normal call. */
3396 static rtx
3397 expand_builtin_bzero (tree arglist)
3399 tree dest, size, newarglist;
3401 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3402 return NULL_RTX;
3404 dest = TREE_VALUE (arglist);
3405 size = TREE_VALUE (TREE_CHAIN (arglist));
3407 /* New argument list transforming bzero(ptr x, int y) to
3408 memset(ptr x, int 0, size_t y). This is done this way
3409 so that if it isn't expanded inline, we fallback to
3410 calling bzero instead of memset. */
3412 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3413 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3414 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3416 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3419 /* Expand expression EXP, which is a call to the memcmp built-in function.
3420 ARGLIST is the argument list for this call. Return 0 if we failed and the
3421 caller should emit a normal call, otherwise try to get the result in
3422 TARGET, if convenient (and in mode MODE, if that's convenient). */
3424 static rtx
3425 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3426 enum machine_mode mode)
3428 tree arg1, arg2, len;
3429 const char *p1, *p2;
3431 if (!validate_arglist (arglist,
3432 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3433 return 0;
3435 arg1 = TREE_VALUE (arglist);
3436 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3437 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3439 /* If the len parameter is zero, return zero. */
3440 if (integer_zerop (len))
3442 /* Evaluate and ignore arg1 and arg2 in case they have
3443 side-effects. */
3444 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3445 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3446 return const0_rtx;
3449 /* If both arguments are equal (and not volatile), return zero. */
3450 if (operand_equal_p (arg1, arg2, 0))
3452 /* Evaluate and ignore len in case it has side-effects. */
3453 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3454 return const0_rtx;
3457 p1 = c_getstr (arg1);
3458 p2 = c_getstr (arg2);
3460 /* If all arguments are constant, and the value of len is not greater
3461 than the lengths of arg1 and arg2, evaluate at compile-time. */
3462 if (host_integerp (len, 1) && p1 && p2
3463 && compare_tree_int (len, strlen (p1) + 1) <= 0
3464 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3466 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3468 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3471 /* If len parameter is one, return an expression corresponding to
3472 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3473 if (integer_onep (len))
3475 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3476 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3477 tree ind1 =
3478 fold (build1 (CONVERT_EXPR, integer_type_node,
3479 build1 (INDIRECT_REF, cst_uchar_node,
3480 fold_convert (cst_uchar_ptr_node, arg1))));
3481 tree ind2 =
3482 fold (build1 (CONVERT_EXPR, integer_type_node,
3483 build1 (INDIRECT_REF, cst_uchar_node,
3484 fold_convert (cst_uchar_ptr_node, arg2))));
3485 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3486 return expand_expr (result, target, mode, EXPAND_NORMAL);
3489 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3491 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3492 rtx result;
3493 rtx insn;
3495 int arg1_align
3496 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3497 int arg2_align
3498 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3499 enum machine_mode insn_mode;
3501 #ifdef HAVE_cmpmemsi
3502 if (HAVE_cmpmemsi)
3503 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3504 else
3505 #endif
3506 #ifdef HAVE_cmpstrsi
3507 if (HAVE_cmpstrsi)
3508 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3509 else
3510 #endif
3511 return 0;
3513 /* If we don't have POINTER_TYPE, call the function. */
3514 if (arg1_align == 0 || arg2_align == 0)
3515 return 0;
3517 /* Make a place to write the result of the instruction. */
3518 result = target;
3519 if (! (result != 0
3520 && REG_P (result) && GET_MODE (result) == insn_mode
3521 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3522 result = gen_reg_rtx (insn_mode);
3524 arg1_rtx = get_memory_rtx (arg1);
3525 arg2_rtx = get_memory_rtx (arg2);
3526 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3527 #ifdef HAVE_cmpmemsi
3528 if (HAVE_cmpmemsi)
3529 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3530 GEN_INT (MIN (arg1_align, arg2_align)));
3531 else
3532 #endif
3533 #ifdef HAVE_cmpstrsi
3534 if (HAVE_cmpstrsi)
3535 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3536 GEN_INT (MIN (arg1_align, arg2_align)));
3537 else
3538 #endif
3539 abort ();
3541 if (insn)
3542 emit_insn (insn);
3543 else
3544 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3545 TYPE_MODE (integer_type_node), 3,
3546 XEXP (arg1_rtx, 0), Pmode,
3547 XEXP (arg2_rtx, 0), Pmode,
3548 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3549 TYPE_UNSIGNED (sizetype)),
3550 TYPE_MODE (sizetype));
3552 /* Return the value in the proper mode for this function. */
3553 mode = TYPE_MODE (TREE_TYPE (exp));
3554 if (GET_MODE (result) == mode)
3555 return result;
3556 else if (target != 0)
3558 convert_move (target, result, 0);
3559 return target;
3561 else
3562 return convert_to_mode (mode, result, 0);
3564 #endif
3566 return 0;
3569 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3570 if we failed the caller should emit a normal call, otherwise try to get
3571 the result in TARGET, if convenient. */
3573 static rtx
3574 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3576 tree arglist = TREE_OPERAND (exp, 1);
3577 tree arg1, arg2;
3578 const char *p1, *p2;
3580 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3581 return 0;
3583 arg1 = TREE_VALUE (arglist);
3584 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3586 /* If both arguments are equal (and not volatile), return zero. */
3587 if (operand_equal_p (arg1, arg2, 0))
3588 return const0_rtx;
3590 p1 = c_getstr (arg1);
3591 p2 = c_getstr (arg2);
3593 if (p1 && p2)
3595 const int i = strcmp (p1, p2);
3596 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3599 /* If either arg is "", return an expression corresponding to
3600 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3601 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3603 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3604 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3605 tree ind1 =
3606 fold (build1 (CONVERT_EXPR, integer_type_node,
3607 build1 (INDIRECT_REF, cst_uchar_node,
3608 fold_convert (cst_uchar_ptr_node, arg1))));
3609 tree ind2 =
3610 fold (build1 (CONVERT_EXPR, integer_type_node,
3611 build1 (INDIRECT_REF, cst_uchar_node,
3612 fold_convert (cst_uchar_ptr_node, arg2))));
3613 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3614 return expand_expr (result, target, mode, EXPAND_NORMAL);
3617 #ifdef HAVE_cmpstrsi
3618 if (HAVE_cmpstrsi)
3620 tree len, len1, len2;
3621 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3622 rtx result, insn;
3623 tree fndecl;
3625 int arg1_align
3626 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3627 int arg2_align
3628 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3629 enum machine_mode insn_mode
3630 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3632 len1 = c_strlen (arg1, 1);
3633 len2 = c_strlen (arg2, 1);
3635 if (len1)
3636 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3637 if (len2)
3638 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3640 /* If we don't have a constant length for the first, use the length
3641 of the second, if we know it. We don't require a constant for
3642 this case; some cost analysis could be done if both are available
3643 but neither is constant. For now, assume they're equally cheap,
3644 unless one has side effects. If both strings have constant lengths,
3645 use the smaller. */
3647 if (!len1)
3648 len = len2;
3649 else if (!len2)
3650 len = len1;
3651 else if (TREE_SIDE_EFFECTS (len1))
3652 len = len2;
3653 else if (TREE_SIDE_EFFECTS (len2))
3654 len = len1;
3655 else if (TREE_CODE (len1) != INTEGER_CST)
3656 len = len2;
3657 else if (TREE_CODE (len2) != INTEGER_CST)
3658 len = len1;
3659 else if (tree_int_cst_lt (len1, len2))
3660 len = len1;
3661 else
3662 len = len2;
3664 /* If both arguments have side effects, we cannot optimize. */
3665 if (!len || TREE_SIDE_EFFECTS (len))
3666 return 0;
3668 /* If we don't have POINTER_TYPE, call the function. */
3669 if (arg1_align == 0 || arg2_align == 0)
3670 return 0;
3672 /* Make a place to write the result of the instruction. */
3673 result = target;
3674 if (! (result != 0
3675 && REG_P (result) && GET_MODE (result) == insn_mode
3676 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3677 result = gen_reg_rtx (insn_mode);
3679 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3680 arg1 = builtin_save_expr (arg1);
3681 arg2 = builtin_save_expr (arg2);
3683 arg1_rtx = get_memory_rtx (arg1);
3684 arg2_rtx = get_memory_rtx (arg2);
3685 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3686 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3687 GEN_INT (MIN (arg1_align, arg2_align)));
3688 if (insn)
3690 emit_insn (insn);
3692 /* Return the value in the proper mode for this function. */
3693 mode = TYPE_MODE (TREE_TYPE (exp));
3694 if (GET_MODE (result) == mode)
3695 return result;
3696 if (target == 0)
3697 return convert_to_mode (mode, result, 0);
3698 convert_move (target, result, 0);
3699 return target;
3702 /* Expand the library call ourselves using a stabilized argument
3703 list to avoid re-evaluating the function's arguments twice. */
3704 arglist = build_tree_list (NULL_TREE, arg2);
3705 arglist = tree_cons (NULL_TREE, arg1, arglist);
3706 fndecl = get_callee_fndecl (exp);
3707 exp = build_function_call_expr (fndecl, arglist);
3708 return expand_call (exp, target, target == const0_rtx);
3710 #endif
3711 return 0;
3714 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3715 if we failed the caller should emit a normal call, otherwise try to get
3716 the result in TARGET, if convenient. */
3718 static rtx
3719 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3721 tree arglist = TREE_OPERAND (exp, 1);
3722 tree arg1, arg2, arg3;
3723 const char *p1, *p2;
3725 if (!validate_arglist (arglist,
3726 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3727 return 0;
3729 arg1 = TREE_VALUE (arglist);
3730 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3731 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3733 /* If the len parameter is zero, return zero. */
3734 if (integer_zerop (arg3))
3736 /* Evaluate and ignore arg1 and arg2 in case they have
3737 side-effects. */
3738 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3739 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3740 return const0_rtx;
3743 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3744 if (operand_equal_p (arg1, arg2, 0))
3746 /* Evaluate and ignore arg3 in case it has side-effects. */
3747 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3748 return const0_rtx;
3751 p1 = c_getstr (arg1);
3752 p2 = c_getstr (arg2);
3754 /* If all arguments are constant, evaluate at compile-time. */
3755 if (host_integerp (arg3, 1) && p1 && p2)
3757 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3758 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3761 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3762 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3763 if (host_integerp (arg3, 1)
3764 && (tree_low_cst (arg3, 1) == 1
3765 || (tree_low_cst (arg3, 1) > 1
3766 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3768 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3769 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3770 tree ind1 =
3771 fold (build1 (CONVERT_EXPR, integer_type_node,
3772 build1 (INDIRECT_REF, cst_uchar_node,
3773 fold_convert (cst_uchar_ptr_node, arg1))));
3774 tree ind2 =
3775 fold (build1 (CONVERT_EXPR, integer_type_node,
3776 build1 (INDIRECT_REF, cst_uchar_node,
3777 fold_convert (cst_uchar_ptr_node, arg2))));
3778 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3779 return expand_expr (result, target, mode, EXPAND_NORMAL);
3782 /* If c_strlen can determine an expression for one of the string
3783 lengths, and it doesn't have side effects, then emit cmpstrsi
3784 using length MIN(strlen(string)+1, arg3). */
3785 #ifdef HAVE_cmpstrsi
3786 if (HAVE_cmpstrsi)
3788 tree len, len1, len2;
3789 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3790 rtx result, insn;
3791 tree fndecl;
3793 int arg1_align
3794 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3795 int arg2_align
3796 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3797 enum machine_mode insn_mode
3798 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3800 len1 = c_strlen (arg1, 1);
3801 len2 = c_strlen (arg2, 1);
3803 if (len1)
3804 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3805 if (len2)
3806 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3808 /* If we don't have a constant length for the first, use the length
3809 of the second, if we know it. We don't require a constant for
3810 this case; some cost analysis could be done if both are available
3811 but neither is constant. For now, assume they're equally cheap,
3812 unless one has side effects. If both strings have constant lengths,
3813 use the smaller. */
3815 if (!len1)
3816 len = len2;
3817 else if (!len2)
3818 len = len1;
3819 else if (TREE_SIDE_EFFECTS (len1))
3820 len = len2;
3821 else if (TREE_SIDE_EFFECTS (len2))
3822 len = len1;
3823 else if (TREE_CODE (len1) != INTEGER_CST)
3824 len = len2;
3825 else if (TREE_CODE (len2) != INTEGER_CST)
3826 len = len1;
3827 else if (tree_int_cst_lt (len1, len2))
3828 len = len1;
3829 else
3830 len = len2;
3832 /* If both arguments have side effects, we cannot optimize. */
3833 if (!len || TREE_SIDE_EFFECTS (len))
3834 return 0;
3836 /* The actual new length parameter is MIN(len,arg3). */
3837 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len, arg3));
3839 /* If we don't have POINTER_TYPE, call the function. */
3840 if (arg1_align == 0 || arg2_align == 0)
3841 return 0;
3843 /* Make a place to write the result of the instruction. */
3844 result = target;
3845 if (! (result != 0
3846 && REG_P (result) && GET_MODE (result) == insn_mode
3847 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3848 result = gen_reg_rtx (insn_mode);
3850 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3851 arg1 = builtin_save_expr (arg1);
3852 arg2 = builtin_save_expr (arg2);
3853 len = builtin_save_expr (len);
3855 arg1_rtx = get_memory_rtx (arg1);
3856 arg2_rtx = get_memory_rtx (arg2);
3857 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3858 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3859 GEN_INT (MIN (arg1_align, arg2_align)));
3860 if (insn)
3862 emit_insn (insn);
3864 /* Return the value in the proper mode for this function. */
3865 mode = TYPE_MODE (TREE_TYPE (exp));
3866 if (GET_MODE (result) == mode)
3867 return result;
3868 if (target == 0)
3869 return convert_to_mode (mode, result, 0);
3870 convert_move (target, result, 0);
3871 return target;
3874 /* Expand the library call ourselves using a stabilized argument
3875 list to avoid re-evaluating the function's arguments twice. */
3876 arglist = build_tree_list (NULL_TREE, len);
3877 arglist = tree_cons (NULL_TREE, arg2, arglist);
3878 arglist = tree_cons (NULL_TREE, arg1, arglist);
3879 fndecl = get_callee_fndecl (exp);
3880 exp = build_function_call_expr (fndecl, arglist);
3881 return expand_call (exp, target, target == const0_rtx);
3883 #endif
3884 return 0;
3887 /* Expand expression EXP, which is a call to the strcat builtin.
3888 Return 0 if we failed the caller should emit a normal call,
3889 otherwise try to get the result in TARGET, if convenient. */
3891 static rtx
3892 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3894 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3895 return 0;
3896 else
3898 tree dst = TREE_VALUE (arglist),
3899 src = TREE_VALUE (TREE_CHAIN (arglist));
3900 const char *p = c_getstr (src);
3902 if (p)
3904 /* If the string length is zero, return the dst parameter. */
3905 if (*p == '\0')
3906 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3907 else if (!optimize_size)
3909 /* Otherwise if !optimize_size, see if we can store by
3910 pieces into (dst + strlen(dst)). */
3911 tree newdst, arglist,
3912 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3914 /* This is the length argument. */
3915 arglist = build_tree_list (NULL_TREE,
3916 fold (size_binop (PLUS_EXPR,
3917 c_strlen (src, 0),
3918 ssize_int (1))));
3919 /* Prepend src argument. */
3920 arglist = tree_cons (NULL_TREE, src, arglist);
3922 /* We're going to use dst more than once. */
3923 dst = builtin_save_expr (dst);
3925 /* Create strlen (dst). */
3926 newdst =
3927 fold (build_function_call_expr (strlen_fn,
3928 build_tree_list (NULL_TREE,
3929 dst)));
3930 /* Create (dst + strlen (dst)). */
3931 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3933 /* Prepend the new dst argument. */
3934 arglist = tree_cons (NULL_TREE, newdst, arglist);
3936 /* We don't want to get turned into a memcpy if the
3937 target is const0_rtx, i.e. when the return value
3938 isn't used. That would produce pessimized code so
3939 pass in a target of zero, it should never actually be
3940 used. If this was successful return the original
3941 dst, not the result of mempcpy. */
3942 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3943 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3944 else
3945 return 0;
3949 return 0;
3953 /* Expand expression EXP, which is a call to the strncat builtin.
3954 Return 0 if we failed the caller should emit a normal call,
3955 otherwise try to get the result in TARGET, if convenient. */
3957 static rtx
3958 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3960 if (!validate_arglist (arglist,
3961 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3962 return 0;
3963 else
3965 tree dst = TREE_VALUE (arglist),
3966 src = TREE_VALUE (TREE_CHAIN (arglist)),
3967 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3968 const char *p = c_getstr (src);
3970 /* If the requested length is zero, or the src parameter string
3971 length is zero, return the dst parameter. */
3972 if (integer_zerop (len) || (p && *p == '\0'))
3974 /* Evaluate and ignore the src and len parameters in case
3975 they have side-effects. */
3976 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3977 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3978 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3981 /* If the requested len is greater than or equal to the string
3982 length, call strcat. */
3983 if (TREE_CODE (len) == INTEGER_CST && p
3984 && compare_tree_int (len, strlen (p)) >= 0)
3986 tree newarglist
3987 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3988 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3990 /* If the replacement _DECL isn't initialized, don't do the
3991 transformation. */
3992 if (!fn)
3993 return 0;
3995 return expand_expr (build_function_call_expr (fn, newarglist),
3996 target, mode, EXPAND_NORMAL);
3998 return 0;
4002 /* Expand expression EXP, which is a call to the strspn builtin.
4003 Return 0 if we failed the caller should emit a normal call,
4004 otherwise try to get the result in TARGET, if convenient. */
4006 static rtx
4007 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4009 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4010 return 0;
4011 else
4013 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4014 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4016 /* If both arguments are constants, evaluate at compile-time. */
4017 if (p1 && p2)
4019 const size_t r = strspn (p1, p2);
4020 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4023 /* If either argument is "", return 0. */
4024 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4026 /* Evaluate and ignore both arguments in case either one has
4027 side-effects. */
4028 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4029 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4030 return const0_rtx;
4032 return 0;
4036 /* Expand expression EXP, which is a call to the strcspn builtin.
4037 Return 0 if we failed the caller should emit a normal call,
4038 otherwise try to get the result in TARGET, if convenient. */
4040 static rtx
4041 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4043 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4044 return 0;
4045 else
4047 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4048 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4050 /* If both arguments are constants, evaluate at compile-time. */
4051 if (p1 && p2)
4053 const size_t r = strcspn (p1, p2);
4054 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4057 /* If the first argument is "", return 0. */
4058 if (p1 && *p1 == '\0')
4060 /* Evaluate and ignore argument s2 in case it has
4061 side-effects. */
4062 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4063 return const0_rtx;
4066 /* If the second argument is "", return __builtin_strlen(s1). */
4067 if (p2 && *p2 == '\0')
4069 tree newarglist = build_tree_list (NULL_TREE, s1),
4070 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4072 /* If the replacement _DECL isn't initialized, don't do the
4073 transformation. */
4074 if (!fn)
4075 return 0;
4077 return expand_expr (build_function_call_expr (fn, newarglist),
4078 target, mode, EXPAND_NORMAL);
4080 return 0;
4084 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4085 if that's convenient. */
4088 expand_builtin_saveregs (void)
4090 rtx val, seq;
4092 /* Don't do __builtin_saveregs more than once in a function.
4093 Save the result of the first call and reuse it. */
4094 if (saveregs_value != 0)
4095 return saveregs_value;
4097 /* When this function is called, it means that registers must be
4098 saved on entry to this function. So we migrate the call to the
4099 first insn of this function. */
4101 start_sequence ();
4103 /* Do whatever the machine needs done in this case. */
4104 val = targetm.calls.expand_builtin_saveregs ();
4106 seq = get_insns ();
4107 end_sequence ();
4109 saveregs_value = val;
4111 /* Put the insns after the NOTE that starts the function. If this
4112 is inside a start_sequence, make the outer-level insn chain current, so
4113 the code is placed at the start of the function. */
4114 push_topmost_sequence ();
4115 emit_insn_after (seq, entry_of_function ());
4116 pop_topmost_sequence ();
4118 return val;
4121 /* __builtin_args_info (N) returns word N of the arg space info
4122 for the current function. The number and meanings of words
4123 is controlled by the definition of CUMULATIVE_ARGS. */
4125 static rtx
4126 expand_builtin_args_info (tree arglist)
4128 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4129 int *word_ptr = (int *) &current_function_args_info;
4131 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4132 abort ();
4134 if (arglist != 0)
4136 if (!host_integerp (TREE_VALUE (arglist), 0))
4137 error ("argument of `__builtin_args_info' must be constant");
4138 else
4140 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4142 if (wordnum < 0 || wordnum >= nwords)
4143 error ("argument of `__builtin_args_info' out of range");
4144 else
4145 return GEN_INT (word_ptr[wordnum]);
4148 else
4149 error ("missing argument in `__builtin_args_info'");
4151 return const0_rtx;
4154 /* Expand ARGLIST, from a call to __builtin_next_arg. */
4156 static rtx
4157 expand_builtin_next_arg (tree arglist)
4159 tree fntype = TREE_TYPE (current_function_decl);
4161 if (TYPE_ARG_TYPES (fntype) == 0
4162 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4163 == void_type_node))
4165 error ("`va_start' used in function with fixed args");
4166 return const0_rtx;
4169 if (arglist)
4171 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4172 tree arg = TREE_VALUE (arglist);
4174 /* Strip off all nops for the sake of the comparison. This
4175 is not quite the same as STRIP_NOPS. It does more.
4176 We must also strip off INDIRECT_EXPR for C++ reference
4177 parameters. */
4178 while (TREE_CODE (arg) == NOP_EXPR
4179 || TREE_CODE (arg) == CONVERT_EXPR
4180 || TREE_CODE (arg) == NON_LVALUE_EXPR
4181 || TREE_CODE (arg) == INDIRECT_REF)
4182 arg = TREE_OPERAND (arg, 0);
4183 if (arg != last_parm)
4184 warning ("second parameter of `va_start' not last named argument");
4186 else
4187 /* Evidently an out of date version of <stdarg.h>; can't validate
4188 va_start's second argument, but can still work as intended. */
4189 warning ("`__builtin_next_arg' called without an argument");
4191 return expand_binop (Pmode, add_optab,
4192 current_function_internal_arg_pointer,
4193 current_function_arg_offset_rtx,
4194 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4197 /* Make it easier for the backends by protecting the valist argument
4198 from multiple evaluations. */
4200 static tree
4201 stabilize_va_list (tree valist, int needs_lvalue)
4203 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4205 if (TREE_SIDE_EFFECTS (valist))
4206 valist = save_expr (valist);
4208 /* For this case, the backends will be expecting a pointer to
4209 TREE_TYPE (va_list_type_node), but it's possible we've
4210 actually been given an array (an actual va_list_type_node).
4211 So fix it. */
4212 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4214 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4215 valist = build_fold_addr_expr_with_type (valist, p1);
4218 else
4220 tree pt;
4222 if (! needs_lvalue)
4224 if (! TREE_SIDE_EFFECTS (valist))
4225 return valist;
4227 pt = build_pointer_type (va_list_type_node);
4228 valist = fold (build1 (ADDR_EXPR, pt, valist));
4229 TREE_SIDE_EFFECTS (valist) = 1;
4232 if (TREE_SIDE_EFFECTS (valist))
4233 valist = save_expr (valist);
4234 valist = build_fold_indirect_ref (valist);
4237 return valist;
4240 /* The "standard" definition of va_list is void*. */
4242 tree
4243 std_build_builtin_va_list (void)
4245 return ptr_type_node;
4248 /* The "standard" implementation of va_start: just assign `nextarg' to
4249 the variable. */
4251 void
4252 std_expand_builtin_va_start (tree valist, rtx nextarg)
4254 tree t;
4256 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4257 make_tree (ptr_type_node, nextarg));
4258 TREE_SIDE_EFFECTS (t) = 1;
4260 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4263 /* Expand ARGLIST, from a call to __builtin_va_start. */
4265 static rtx
4266 expand_builtin_va_start (tree arglist)
4268 rtx nextarg;
4269 tree chain, valist;
4271 chain = TREE_CHAIN (arglist);
4273 if (TREE_CHAIN (chain))
4274 error ("too many arguments to function `va_start'");
4276 nextarg = expand_builtin_next_arg (chain);
4277 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4279 #ifdef EXPAND_BUILTIN_VA_START
4280 EXPAND_BUILTIN_VA_START (valist, nextarg);
4281 #else
4282 std_expand_builtin_va_start (valist, nextarg);
4283 #endif
4285 return const0_rtx;
4288 /* The "standard" implementation of va_arg: read the value from the
4289 current (padded) address and increment by the (padded) size. */
4292 std_expand_builtin_va_arg (tree valist, tree type)
4294 tree addr_tree, t, type_size = NULL;
4295 tree align, alignm1;
4296 tree rounded_size;
4297 rtx addr;
4298 HOST_WIDE_INT boundary;
4300 /* Compute the rounded size of the type. */
4301 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4302 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4303 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4305 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4306 requires greater alignment, we must perform dynamic alignment. */
4308 if (boundary > PARM_BOUNDARY)
4310 if (!PAD_VARARGS_DOWN)
4312 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4313 build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4314 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4315 TREE_SIDE_EFFECTS (t) = 1;
4316 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4318 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4319 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4320 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4321 TREE_SIDE_EFFECTS (t) = 1;
4322 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4324 if (type == error_mark_node
4325 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4326 || TREE_OVERFLOW (type_size))
4327 rounded_size = size_zero_node;
4328 else
4330 rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
4331 rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype,
4332 rounded_size, align));
4333 rounded_size = fold (build2 (MULT_EXPR, sizetype,
4334 rounded_size, align));
4337 /* Get AP. */
4338 addr_tree = valist;
4339 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4341 /* Small args are padded downward. */
4342 addr_tree = fold (build2 (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4343 fold (build3 (COND_EXPR, sizetype,
4344 fold (build2 (GT_EXPR, sizetype,
4345 rounded_size,
4346 align)),
4347 size_zero_node,
4348 fold (build2 (MINUS_EXPR,
4349 sizetype,
4350 rounded_size,
4351 type_size))))));
4354 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4355 addr = copy_to_reg (addr);
4357 /* Compute new value for AP. */
4358 if (! integer_zerop (rounded_size))
4360 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4361 build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4362 rounded_size));
4363 TREE_SIDE_EFFECTS (t) = 1;
4364 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4367 return addr;
4370 /* Expand __builtin_va_arg, which is not really a builtin function, but
4371 a very special sort of operator. */
4374 expand_builtin_va_arg (tree valist, tree type)
4376 rtx addr, result;
4377 tree promoted_type, want_va_type, have_va_type;
4379 /* Verify that valist is of the proper type. */
4381 want_va_type = va_list_type_node;
4382 have_va_type = TREE_TYPE (valist);
4383 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4385 /* If va_list is an array type, the argument may have decayed
4386 to a pointer type, e.g. by being passed to another function.
4387 In that case, unwrap both types so that we can compare the
4388 underlying records. */
4389 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4390 || TREE_CODE (have_va_type) == POINTER_TYPE)
4392 want_va_type = TREE_TYPE (want_va_type);
4393 have_va_type = TREE_TYPE (have_va_type);
4396 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4398 error ("first argument to `va_arg' not of type `va_list'");
4399 addr = const0_rtx;
4402 /* Generate a diagnostic for requesting data of a type that cannot
4403 be passed through `...' due to type promotion at the call site. */
4404 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4405 != type)
4407 const char *name = "<anonymous type>", *pname = 0;
4408 static bool gave_help;
4410 if (TYPE_NAME (type))
4412 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4413 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4414 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4415 && DECL_NAME (TYPE_NAME (type)))
4416 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4418 if (TYPE_NAME (promoted_type))
4420 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4421 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4422 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4423 && DECL_NAME (TYPE_NAME (promoted_type)))
4424 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4427 /* Unfortunately, this is merely undefined, rather than a constraint
4428 violation, so we cannot make this an error. If this call is never
4429 executed, the program is still strictly conforming. */
4430 warning ("`%s' is promoted to `%s' when passed through `...'",
4431 name, pname);
4432 if (! gave_help)
4434 gave_help = true;
4435 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4436 pname, name);
4439 /* We can, however, treat "undefined" any way we please.
4440 Call abort to encourage the user to fix the program. */
4441 inform ("if this code is reached, the program will abort");
4442 expand_builtin_trap ();
4444 /* This is dead code, but go ahead and finish so that the
4445 mode of the result comes out right. */
4446 addr = const0_rtx;
4448 else
4450 /* Make it easier for the backends by protecting the valist argument
4451 from multiple evaluations. */
4452 valist = stabilize_va_list (valist, 0);
4454 #ifdef EXPAND_BUILTIN_VA_ARG
4455 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4456 #else
4457 addr = std_expand_builtin_va_arg (valist, type);
4458 #endif
4461 addr = convert_memory_address (Pmode, addr);
4463 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4464 set_mem_alias_set (result, get_varargs_alias_set ());
4466 return result;
4469 /* Like std_expand_builtin_va_arg, but gimplify instead of expanding. */
4471 tree
4472 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4474 tree addr, t, type_size, rounded_size, valist_tmp;
4475 unsigned HOST_WIDE_INT align, boundary;
4476 bool indirect;
4478 #ifdef ARGS_GROW_DOWNWARD
4479 /* All of the alignment and movement below is for args-grow-up machines.
4480 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4481 implement their own specialized gimplify_va_arg_expr routines. */
4482 abort ();
4483 #endif
4485 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4486 if (indirect)
4487 type = build_pointer_type (type);
4489 align = PARM_BOUNDARY / BITS_PER_UNIT;
4490 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4492 /* Hoist the valist value into a temporary for the moment. */
4493 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4495 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4496 requires greater alignment, we must perform dynamic alignment. */
4497 if (boundary > align)
4499 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4500 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4501 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4502 gimplify_and_add (t, pre_p);
4504 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4505 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4506 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4507 gimplify_and_add (t, pre_p);
4510 /* Compute the rounded size of the type. */
4511 type_size = size_in_bytes (type);
4512 rounded_size = round_up (type_size, align);
4514 /* Reduce rounded_size so it's sharable with the postqueue. */
4515 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4517 /* Get AP. */
4518 addr = valist_tmp;
4519 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4521 /* Small args are padded downward. */
4522 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4523 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4524 size_binop (MINUS_EXPR, rounded_size, type_size)));
4525 t = fold_convert (TREE_TYPE (addr), t);
4526 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4529 /* Compute new value for AP. */
4530 t = fold_convert (TREE_TYPE (valist), rounded_size);
4531 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4532 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4533 gimplify_and_add (t, pre_p);
4535 addr = fold_convert (build_pointer_type (type), addr);
4537 if (indirect)
4538 addr = build_fold_indirect_ref (addr);
4540 return build_fold_indirect_ref (addr);
4543 /* Return a dummy expression of type TYPE in order to keep going after an
4544 error. */
4546 static tree
4547 dummy_object (tree type)
4549 tree t = convert (build_pointer_type (type), null_pointer_node);
4550 return build1 (INDIRECT_REF, type, t);
4553 /* Like expand_builtin_va_arg, but gimplify instead of expanding. */
4555 enum gimplify_status
4556 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4558 tree promoted_type, want_va_type, have_va_type;
4559 tree valist = TREE_OPERAND (*expr_p, 0);
4560 tree type = TREE_TYPE (*expr_p);
4561 tree t;
4563 /* Verify that valist is of the proper type. */
4564 want_va_type = va_list_type_node;
4565 have_va_type = TREE_TYPE (valist);
4567 if (have_va_type == error_mark_node)
4568 return GS_ERROR;
4570 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4572 /* If va_list is an array type, the argument may have decayed
4573 to a pointer type, e.g. by being passed to another function.
4574 In that case, unwrap both types so that we can compare the
4575 underlying records. */
4576 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4577 || TREE_CODE (have_va_type) == POINTER_TYPE)
4579 want_va_type = TREE_TYPE (want_va_type);
4580 have_va_type = TREE_TYPE (have_va_type);
4584 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4586 error ("first argument to `va_arg' not of type `va_list'");
4587 return GS_ERROR;
4590 /* Generate a diagnostic for requesting data of a type that cannot
4591 be passed through `...' due to type promotion at the call site. */
4592 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4593 != type)
4595 static bool gave_help;
4597 /* Unfortunately, this is merely undefined, rather than a constraint
4598 violation, so we cannot make this an error. If this call is never
4599 executed, the program is still strictly conforming. */
4600 warning ("`%T' is promoted to `%T' when passed through `...'",
4601 type, promoted_type);
4602 if (! gave_help)
4604 gave_help = true;
4605 warning ("(so you should pass `%T' not `%T' to `va_arg')",
4606 promoted_type, type);
4609 /* We can, however, treat "undefined" any way we please.
4610 Call abort to encourage the user to fix the program. */
4611 inform ("if this code is reached, the program will abort");
4612 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4613 NULL);
4614 append_to_statement_list (t, pre_p);
4616 /* This is dead code, but go ahead and finish so that the
4617 mode of the result comes out right. */
4618 *expr_p = dummy_object (type);
4619 return GS_ALL_DONE;
4621 else
4623 /* Make it easier for the backends by protecting the valist argument
4624 from multiple evaluations. */
4625 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4627 /* For this case, the backends will be expecting a pointer to
4628 TREE_TYPE (va_list_type_node), but it's possible we've
4629 actually been given an array (an actual va_list_type_node).
4630 So fix it. */
4631 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4633 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4634 valist = build_fold_addr_expr_with_type (valist, p1);
4636 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4638 else
4639 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4641 if (!targetm.gimplify_va_arg_expr)
4642 /* Once most targets are converted this should abort. */
4643 return GS_ALL_DONE;
4645 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4646 return GS_OK;
4650 /* Expand ARGLIST, from a call to __builtin_va_end. */
4652 static rtx
4653 expand_builtin_va_end (tree arglist)
4655 tree valist = TREE_VALUE (arglist);
4657 /* Evaluate for side effects, if needed. I hate macros that don't
4658 do that. */
4659 if (TREE_SIDE_EFFECTS (valist))
4660 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4662 return const0_rtx;
4665 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4666 builtin rather than just as an assignment in stdarg.h because of the
4667 nastiness of array-type va_list types. */
4669 static rtx
4670 expand_builtin_va_copy (tree arglist)
4672 tree dst, src, t;
4674 dst = TREE_VALUE (arglist);
4675 src = TREE_VALUE (TREE_CHAIN (arglist));
4677 dst = stabilize_va_list (dst, 1);
4678 src = stabilize_va_list (src, 0);
4680 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4682 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4683 TREE_SIDE_EFFECTS (t) = 1;
4684 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4686 else
4688 rtx dstb, srcb, size;
4690 /* Evaluate to pointers. */
4691 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4692 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4693 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4694 VOIDmode, EXPAND_NORMAL);
4696 dstb = convert_memory_address (Pmode, dstb);
4697 srcb = convert_memory_address (Pmode, srcb);
4699 /* "Dereference" to BLKmode memories. */
4700 dstb = gen_rtx_MEM (BLKmode, dstb);
4701 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4702 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4703 srcb = gen_rtx_MEM (BLKmode, srcb);
4704 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4705 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4707 /* Copy. */
4708 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4711 return const0_rtx;
4714 /* Expand a call to one of the builtin functions __builtin_frame_address or
4715 __builtin_return_address. */
4717 static rtx
4718 expand_builtin_frame_address (tree fndecl, tree arglist)
4720 /* The argument must be a nonnegative integer constant.
4721 It counts the number of frames to scan up the stack.
4722 The value is the return address saved in that frame. */
4723 if (arglist == 0)
4724 /* Warning about missing arg was already issued. */
4725 return const0_rtx;
4726 else if (! host_integerp (TREE_VALUE (arglist), 1))
4728 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4729 error ("invalid arg to `__builtin_frame_address'");
4730 else
4731 error ("invalid arg to `__builtin_return_address'");
4732 return const0_rtx;
4734 else
4736 rtx tem
4737 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4738 tree_low_cst (TREE_VALUE (arglist), 1),
4739 hard_frame_pointer_rtx);
4741 /* Some ports cannot access arbitrary stack frames. */
4742 if (tem == NULL)
4744 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4745 warning ("unsupported arg to `__builtin_frame_address'");
4746 else
4747 warning ("unsupported arg to `__builtin_return_address'");
4748 return const0_rtx;
4751 /* For __builtin_frame_address, return what we've got. */
4752 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4753 return tem;
4755 if (!REG_P (tem)
4756 && ! CONSTANT_P (tem))
4757 tem = copy_to_mode_reg (Pmode, tem);
4758 return tem;
4762 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4763 we failed and the caller should emit a normal call, otherwise try to get
4764 the result in TARGET, if convenient. */
4766 static rtx
4767 expand_builtin_alloca (tree arglist, rtx target)
4769 rtx op0;
4770 rtx result;
4772 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4773 should always expand to function calls. These can be intercepted
4774 in libmudflap. */
4775 if (flag_mudflap)
4776 return 0;
4778 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4779 return 0;
4781 /* Compute the argument. */
4782 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4784 /* Allocate the desired space. */
4785 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4786 result = convert_memory_address (ptr_mode, result);
4788 return result;
4791 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4792 Return 0 if a normal call should be emitted rather than expanding the
4793 function in-line. If convenient, the result should be placed in TARGET.
4794 SUBTARGET may be used as the target for computing one of EXP's operands. */
4796 static rtx
4797 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4798 rtx subtarget, optab op_optab)
4800 rtx op0;
4801 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4802 return 0;
4804 /* Compute the argument. */
4805 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4806 /* Compute op, into TARGET if possible.
4807 Set TARGET to wherever the result comes back. */
4808 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4809 op_optab, op0, target, 1);
4810 if (target == 0)
4811 abort ();
4813 return convert_to_mode (target_mode, target, 0);
4816 /* If the string passed to fputs is a constant and is one character
4817 long, we attempt to transform this call into __builtin_fputc(). */
4819 static rtx
4820 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4822 tree len, fn;
4823 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4824 : implicit_built_in_decls[BUILT_IN_FPUTC];
4825 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4826 : implicit_built_in_decls[BUILT_IN_FWRITE];
4828 /* If the return value is used, or the replacement _DECL isn't
4829 initialized, don't do the transformation. */
4830 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4831 return 0;
4833 /* Verify the arguments in the original call. */
4834 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4835 return 0;
4837 /* Get the length of the string passed to fputs. If the length
4838 can't be determined, punt. */
4839 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4840 || TREE_CODE (len) != INTEGER_CST)
4841 return 0;
4843 switch (compare_tree_int (len, 1))
4845 case -1: /* length is 0, delete the call entirely . */
4847 /* Evaluate and ignore the argument in case it has
4848 side-effects. */
4849 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4850 VOIDmode, EXPAND_NORMAL);
4851 return const0_rtx;
4853 case 0: /* length is 1, call fputc. */
4855 const char *p = c_getstr (TREE_VALUE (arglist));
4857 if (p != NULL)
4859 /* New argument list transforming fputs(string, stream) to
4860 fputc(string[0], stream). */
4861 arglist =
4862 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4863 arglist =
4864 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4865 fn = fn_fputc;
4866 break;
4869 /* Fall through. */
4870 case 1: /* length is greater than 1, call fwrite. */
4872 tree string_arg;
4874 /* If optimizing for size keep fputs. */
4875 if (optimize_size)
4876 return 0;
4877 string_arg = TREE_VALUE (arglist);
4878 /* New argument list transforming fputs(string, stream) to
4879 fwrite(string, 1, len, stream). */
4880 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4881 arglist = tree_cons (NULL_TREE, len, arglist);
4882 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4883 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4884 fn = fn_fwrite;
4885 break;
4887 default:
4888 abort ();
4891 return expand_expr (build_function_call_expr (fn, arglist),
4892 const0_rtx, VOIDmode, EXPAND_NORMAL);
4895 /* Expand a call to __builtin_expect. We return our argument and emit a
4896 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4897 a non-jump context. */
4899 static rtx
4900 expand_builtin_expect (tree arglist, rtx target)
4902 tree exp, c;
4903 rtx note, rtx_c;
4905 if (arglist == NULL_TREE
4906 || TREE_CHAIN (arglist) == NULL_TREE)
4907 return const0_rtx;
4908 exp = TREE_VALUE (arglist);
4909 c = TREE_VALUE (TREE_CHAIN (arglist));
4911 if (TREE_CODE (c) != INTEGER_CST)
4913 error ("second arg to `__builtin_expect' must be a constant");
4914 c = integer_zero_node;
4917 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4919 /* Don't bother with expected value notes for integral constants. */
4920 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4922 /* We do need to force this into a register so that we can be
4923 moderately sure to be able to correctly interpret the branch
4924 condition later. */
4925 target = force_reg (GET_MODE (target), target);
4927 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4929 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4930 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4933 return target;
4936 /* Like expand_builtin_expect, except do this in a jump context. This is
4937 called from do_jump if the conditional is a __builtin_expect. Return either
4938 a list of insns to emit the jump or NULL if we cannot optimize
4939 __builtin_expect. We need to optimize this at jump time so that machines
4940 like the PowerPC don't turn the test into a SCC operation, and then jump
4941 based on the test being 0/1. */
4944 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4946 tree arglist = TREE_OPERAND (exp, 1);
4947 tree arg0 = TREE_VALUE (arglist);
4948 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4949 rtx ret = NULL_RTX;
4951 /* Only handle __builtin_expect (test, 0) and
4952 __builtin_expect (test, 1). */
4953 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4954 && (integer_zerop (arg1) || integer_onep (arg1)))
4956 rtx insn, drop_through_label, temp;
4958 /* Expand the jump insns. */
4959 start_sequence ();
4960 do_jump (arg0, if_false_label, if_true_label);
4961 ret = get_insns ();
4963 drop_through_label = get_last_insn ();
4964 if (drop_through_label && NOTE_P (drop_through_label))
4965 drop_through_label = prev_nonnote_insn (drop_through_label);
4966 if (drop_through_label && !LABEL_P (drop_through_label))
4967 drop_through_label = NULL_RTX;
4968 end_sequence ();
4970 if (! if_true_label)
4971 if_true_label = drop_through_label;
4972 if (! if_false_label)
4973 if_false_label = drop_through_label;
4975 /* Go through and add the expect's to each of the conditional jumps. */
4976 insn = ret;
4977 while (insn != NULL_RTX)
4979 rtx next = NEXT_INSN (insn);
4981 if (JUMP_P (insn) && any_condjump_p (insn))
4983 rtx ifelse = SET_SRC (pc_set (insn));
4984 rtx then_dest = XEXP (ifelse, 1);
4985 rtx else_dest = XEXP (ifelse, 2);
4986 int taken = -1;
4988 /* First check if we recognize any of the labels. */
4989 if (GET_CODE (then_dest) == LABEL_REF
4990 && XEXP (then_dest, 0) == if_true_label)
4991 taken = 1;
4992 else if (GET_CODE (then_dest) == LABEL_REF
4993 && XEXP (then_dest, 0) == if_false_label)
4994 taken = 0;
4995 else if (GET_CODE (else_dest) == LABEL_REF
4996 && XEXP (else_dest, 0) == if_false_label)
4997 taken = 1;
4998 else if (GET_CODE (else_dest) == LABEL_REF
4999 && XEXP (else_dest, 0) == if_true_label)
5000 taken = 0;
5001 /* Otherwise check where we drop through. */
5002 else if (else_dest == pc_rtx)
5004 if (next && NOTE_P (next))
5005 next = next_nonnote_insn (next);
5007 if (next && JUMP_P (next)
5008 && any_uncondjump_p (next))
5009 temp = XEXP (SET_SRC (pc_set (next)), 0);
5010 else
5011 temp = next;
5013 /* TEMP is either a CODE_LABEL, NULL_RTX or something
5014 else that can't possibly match either target label. */
5015 if (temp == if_false_label)
5016 taken = 1;
5017 else if (temp == if_true_label)
5018 taken = 0;
5020 else if (then_dest == pc_rtx)
5022 if (next && NOTE_P (next))
5023 next = next_nonnote_insn (next);
5025 if (next && JUMP_P (next)
5026 && any_uncondjump_p (next))
5027 temp = XEXP (SET_SRC (pc_set (next)), 0);
5028 else
5029 temp = next;
5031 if (temp == if_false_label)
5032 taken = 0;
5033 else if (temp == if_true_label)
5034 taken = 1;
5037 if (taken != -1)
5039 /* If the test is expected to fail, reverse the
5040 probabilities. */
5041 if (integer_zerop (arg1))
5042 taken = 1 - taken;
5043 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
5047 insn = next;
5051 return ret;
5054 void
5055 expand_builtin_trap (void)
5057 #ifdef HAVE_trap
5058 if (HAVE_trap)
5059 emit_insn (gen_trap ());
5060 else
5061 #endif
5062 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5063 emit_barrier ();
5066 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
5067 Return 0 if a normal call should be emitted rather than expanding
5068 the function inline. If convenient, the result should be placed
5069 in TARGET. SUBTARGET may be used as the target for computing
5070 the operand. */
5072 static rtx
5073 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
5075 enum machine_mode mode;
5076 tree arg;
5077 rtx op0;
5079 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5080 return 0;
5082 arg = TREE_VALUE (arglist);
5083 mode = TYPE_MODE (TREE_TYPE (arg));
5084 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
5085 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5088 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
5089 Return 0 if a normal call should be emitted rather than expanding
5090 the function inline. If convenient, the result should be placed
5091 in target. */
5093 static rtx
5094 expand_builtin_cabs (tree arglist, rtx target)
5096 enum machine_mode mode;
5097 tree arg;
5098 rtx op0;
5100 if (arglist == 0 || TREE_CHAIN (arglist))
5101 return 0;
5102 arg = TREE_VALUE (arglist);
5103 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5104 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5105 return 0;
5107 mode = TYPE_MODE (TREE_TYPE (arg));
5108 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5109 return expand_complex_abs (mode, op0, target, 0);
5112 /* Create a new constant string literal and return a char* pointer to it.
5113 The STRING_CST value is the LEN characters at STR. */
5114 static tree
5115 build_string_literal (int len, const char *str)
5117 tree t, elem, index, type;
5119 t = build_string (len, str);
5120 elem = build_type_variant (char_type_node, 1, 0);
5121 index = build_index_type (build_int_2 (len - 1, 0));
5122 type = build_array_type (elem, index);
5123 TREE_TYPE (t) = type;
5124 TREE_CONSTANT (t) = 1;
5125 TREE_INVARIANT (t) = 1;
5126 TREE_READONLY (t) = 1;
5127 TREE_STATIC (t) = 1;
5129 type = build_pointer_type (type);
5130 t = build1 (ADDR_EXPR, type, t);
5132 type = build_pointer_type (elem);
5133 t = build1 (NOP_EXPR, type, t);
5134 return t;
5137 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
5138 Return 0 if a normal call should be emitted rather than transforming
5139 the function inline. If convenient, the result should be placed in
5140 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
5141 call. */
5142 static rtx
5143 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
5144 bool unlocked)
5146 tree fn_putchar = unlocked
5147 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5148 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5149 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5150 : implicit_built_in_decls[BUILT_IN_PUTS];
5151 const char *fmt_str;
5152 tree fn, fmt, arg;
5154 /* If the return value is used, don't do the transformation. */
5155 if (target != const0_rtx)
5156 return 0;
5158 /* Verify the required arguments in the original call. */
5159 if (! arglist)
5160 return 0;
5161 fmt = TREE_VALUE (arglist);
5162 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5163 return 0;
5164 arglist = TREE_CHAIN (arglist);
5166 /* Check whether the format is a literal string constant. */
5167 fmt_str = c_getstr (fmt);
5168 if (fmt_str == NULL)
5169 return 0;
5171 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
5172 if (strcmp (fmt_str, "%s\n") == 0)
5174 if (! arglist
5175 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5176 || TREE_CHAIN (arglist))
5177 return 0;
5178 fn = fn_puts;
5180 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5181 else if (strcmp (fmt_str, "%c") == 0)
5183 if (! arglist
5184 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5185 || TREE_CHAIN (arglist))
5186 return 0;
5187 fn = fn_putchar;
5189 else
5191 /* We can't handle anything else with % args or %% ... yet. */
5192 if (strchr (fmt_str, '%'))
5193 return 0;
5195 if (arglist)
5196 return 0;
5198 /* If the format specifier was "", printf does nothing. */
5199 if (fmt_str[0] == '\0')
5200 return const0_rtx;
5201 /* If the format specifier has length of 1, call putchar. */
5202 if (fmt_str[1] == '\0')
5204 /* Given printf("c"), (where c is any one character,)
5205 convert "c"[0] to an int and pass that to the replacement
5206 function. */
5207 arg = build_int_2 (fmt_str[0], 0);
5208 arglist = build_tree_list (NULL_TREE, arg);
5209 fn = fn_putchar;
5211 else
5213 /* If the format specifier was "string\n", call puts("string"). */
5214 size_t len = strlen (fmt_str);
5215 if (fmt_str[len - 1] == '\n')
5217 /* Create a NUL-terminated string that's one char shorter
5218 than the original, stripping off the trailing '\n'. */
5219 char *newstr = alloca (len);
5220 memcpy (newstr, fmt_str, len - 1);
5221 newstr[len - 1] = 0;
5223 arg = build_string_literal (len, newstr);
5224 arglist = build_tree_list (NULL_TREE, arg);
5225 fn = fn_puts;
5227 else
5228 /* We'd like to arrange to call fputs(string,stdout) here,
5229 but we need stdout and don't have a way to get it yet. */
5230 return 0;
5234 if (!fn)
5235 return 0;
5236 return expand_expr (build_function_call_expr (fn, arglist),
5237 target, mode, EXPAND_NORMAL);
5240 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5241 Return 0 if a normal call should be emitted rather than transforming
5242 the function inline. If convenient, the result should be placed in
5243 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5244 call. */
5245 static rtx
5246 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5247 bool unlocked)
5249 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5250 : implicit_built_in_decls[BUILT_IN_FPUTC];
5251 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5252 : implicit_built_in_decls[BUILT_IN_FPUTS];
5253 const char *fmt_str;
5254 tree fn, fmt, fp, arg;
5256 /* If the return value is used, don't do the transformation. */
5257 if (target != const0_rtx)
5258 return 0;
5260 /* Verify the required arguments in the original call. */
5261 if (! arglist)
5262 return 0;
5263 fp = TREE_VALUE (arglist);
5264 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5265 return 0;
5266 arglist = TREE_CHAIN (arglist);
5267 if (! arglist)
5268 return 0;
5269 fmt = TREE_VALUE (arglist);
5270 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5271 return 0;
5272 arglist = TREE_CHAIN (arglist);
5274 /* Check whether the format is a literal string constant. */
5275 fmt_str = c_getstr (fmt);
5276 if (fmt_str == NULL)
5277 return 0;
5279 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5280 if (strcmp (fmt_str, "%s") == 0)
5282 if (! arglist
5283 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5284 || TREE_CHAIN (arglist))
5285 return 0;
5286 arg = TREE_VALUE (arglist);
5287 arglist = build_tree_list (NULL_TREE, fp);
5288 arglist = tree_cons (NULL_TREE, arg, arglist);
5289 fn = fn_fputs;
5291 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5292 else if (strcmp (fmt_str, "%c") == 0)
5294 if (! arglist
5295 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5296 || TREE_CHAIN (arglist))
5297 return 0;
5298 arg = TREE_VALUE (arglist);
5299 arglist = build_tree_list (NULL_TREE, fp);
5300 arglist = tree_cons (NULL_TREE, arg, arglist);
5301 fn = fn_fputc;
5303 else
5305 /* We can't handle anything else with % args or %% ... yet. */
5306 if (strchr (fmt_str, '%'))
5307 return 0;
5309 if (arglist)
5310 return 0;
5312 /* If the format specifier was "", fprintf does nothing. */
5313 if (fmt_str[0] == '\0')
5315 /* Evaluate and ignore FILE* argument for side-effects. */
5316 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5317 return const0_rtx;
5320 /* When "string" doesn't contain %, replace all cases of
5321 fprintf(stream,string) with fputs(string,stream). The fputs
5322 builtin will take care of special cases like length == 1. */
5323 arglist = build_tree_list (NULL_TREE, fp);
5324 arglist = tree_cons (NULL_TREE, fmt, arglist);
5325 fn = fn_fputs;
5328 if (!fn)
5329 return 0;
5330 return expand_expr (build_function_call_expr (fn, arglist),
5331 target, mode, EXPAND_NORMAL);
5334 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5335 a normal call should be emitted rather than expanding the function
5336 inline. If convenient, the result should be placed in TARGET with
5337 mode MODE. */
5339 static rtx
5340 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5342 tree orig_arglist, dest, fmt;
5343 const char *fmt_str;
5345 orig_arglist = arglist;
5347 /* Verify the required arguments in the original call. */
5348 if (! arglist)
5349 return 0;
5350 dest = TREE_VALUE (arglist);
5351 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5352 return 0;
5353 arglist = TREE_CHAIN (arglist);
5354 if (! arglist)
5355 return 0;
5356 fmt = TREE_VALUE (arglist);
5357 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5358 return 0;
5359 arglist = TREE_CHAIN (arglist);
5361 /* Check whether the format is a literal string constant. */
5362 fmt_str = c_getstr (fmt);
5363 if (fmt_str == NULL)
5364 return 0;
5366 /* If the format doesn't contain % args or %%, use strcpy. */
5367 if (strchr (fmt_str, '%') == 0)
5369 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5370 tree exp;
5372 if (arglist || ! fn)
5373 return 0;
5374 expand_expr (build_function_call_expr (fn, orig_arglist),
5375 const0_rtx, VOIDmode, EXPAND_NORMAL);
5376 if (target == const0_rtx)
5377 return const0_rtx;
5378 exp = build_int_2 (strlen (fmt_str), 0);
5379 exp = fold_convert (integer_type_node, exp);
5380 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5382 /* If the format is "%s", use strcpy if the result isn't used. */
5383 else if (strcmp (fmt_str, "%s") == 0)
5385 tree fn, arg, len;
5386 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5388 if (! fn)
5389 return 0;
5391 if (! arglist || TREE_CHAIN (arglist))
5392 return 0;
5393 arg = TREE_VALUE (arglist);
5394 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5395 return 0;
5397 if (target != const0_rtx)
5399 len = c_strlen (arg, 1);
5400 if (! len || TREE_CODE (len) != INTEGER_CST)
5401 return 0;
5403 else
5404 len = NULL_TREE;
5406 arglist = build_tree_list (NULL_TREE, arg);
5407 arglist = tree_cons (NULL_TREE, dest, arglist);
5408 expand_expr (build_function_call_expr (fn, arglist),
5409 const0_rtx, VOIDmode, EXPAND_NORMAL);
5411 if (target == const0_rtx)
5412 return const0_rtx;
5413 return expand_expr (len, target, mode, EXPAND_NORMAL);
5416 return 0;
5419 /* Expand a call to either the entry or exit function profiler. */
5421 static rtx
5422 expand_builtin_profile_func (bool exitp)
5424 rtx this, which;
5426 this = DECL_RTL (current_function_decl);
5427 if (MEM_P (this))
5428 this = XEXP (this, 0);
5429 else
5430 abort ();
5432 if (exitp)
5433 which = profile_function_exit_libfunc;
5434 else
5435 which = profile_function_entry_libfunc;
5437 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5438 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5439 0, hard_frame_pointer_rtx),
5440 Pmode);
5442 return const0_rtx;
5445 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5447 static rtx
5448 round_trampoline_addr (rtx tramp)
5450 rtx temp, addend, mask;
5452 /* If we don't need too much alignment, we'll have been guaranteed
5453 proper alignment by get_trampoline_type. */
5454 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5455 return tramp;
5457 /* Round address up to desired boundary. */
5458 temp = gen_reg_rtx (Pmode);
5459 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5460 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5462 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5463 temp, 0, OPTAB_LIB_WIDEN);
5464 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5465 temp, 0, OPTAB_LIB_WIDEN);
5467 return tramp;
5470 static rtx
5471 expand_builtin_init_trampoline (tree arglist)
5473 tree t_tramp, t_func, t_chain;
5474 rtx r_tramp, r_func, r_chain;
5475 #ifdef TRAMPOLINE_TEMPLATE
5476 rtx blktramp;
5477 #endif
5479 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5480 POINTER_TYPE, VOID_TYPE))
5481 return NULL_RTX;
5483 t_tramp = TREE_VALUE (arglist);
5484 arglist = TREE_CHAIN (arglist);
5485 t_func = TREE_VALUE (arglist);
5486 arglist = TREE_CHAIN (arglist);
5487 t_chain = TREE_VALUE (arglist);
5489 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5490 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5491 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5493 /* Generate insns to initialize the trampoline. */
5494 r_tramp = round_trampoline_addr (r_tramp);
5495 #ifdef TRAMPOLINE_TEMPLATE
5496 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5497 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5498 emit_block_move (blktramp, assemble_trampoline_template (),
5499 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5500 #endif
5501 trampolines_created = 1;
5502 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5504 return const0_rtx;
5507 static rtx
5508 expand_builtin_adjust_trampoline (tree arglist)
5510 rtx tramp;
5512 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5513 return NULL_RTX;
5515 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5516 tramp = round_trampoline_addr (tramp);
5517 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5518 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5519 #endif
5521 return tramp;
5524 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5525 Return NULL_RTX if a normal call should be emitted rather than expanding
5526 the function in-line. EXP is the expression that is a call to the builtin
5527 function; if convenient, the result should be placed in TARGET. */
5529 static rtx
5530 expand_builtin_signbit (tree exp, rtx target)
5532 const struct real_format *fmt;
5533 enum machine_mode fmode, imode, rmode;
5534 HOST_WIDE_INT hi, lo;
5535 tree arg, arglist;
5536 int bitpos;
5537 rtx temp;
5539 arglist = TREE_OPERAND (exp, 1);
5540 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5541 return 0;
5543 arg = TREE_VALUE (arglist);
5544 fmode = TYPE_MODE (TREE_TYPE (arg));
5545 rmode = TYPE_MODE (TREE_TYPE (exp));
5546 fmt = REAL_MODE_FORMAT (fmode);
5548 /* For floating point formats without a sign bit, implement signbit
5549 as "ARG < 0.0". */
5550 if (fmt->signbit < 0)
5552 /* But we can't do this if the format supports signed zero. */
5553 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5554 return 0;
5556 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5557 build_real (TREE_TYPE (arg), dconst0)));
5558 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5561 imode = int_mode_for_mode (fmode);
5562 if (imode == BLKmode)
5563 return 0;
5565 bitpos = fmt->signbit;
5566 /* Handle targets with different FP word orders. */
5567 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5569 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5570 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5571 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5574 /* If the sign bit is not in the lowpart and the floating point format
5575 is wider than an integer, check that is twice the size of an integer
5576 so that we can use gen_highpart below. */
5577 if (bitpos >= GET_MODE_BITSIZE (rmode)
5578 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5579 return 0;
5581 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5582 temp = gen_lowpart (imode, temp);
5584 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5586 if (BYTES_BIG_ENDIAN)
5587 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5588 temp = copy_to_mode_reg (imode, temp);
5589 temp = extract_bit_field (temp, 1, bitpos, 1,
5590 NULL_RTX, rmode, rmode);
5592 else
5594 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5595 temp = gen_lowpart (rmode, temp);
5596 if (bitpos < HOST_BITS_PER_WIDE_INT)
5598 hi = 0;
5599 lo = (HOST_WIDE_INT) 1 << bitpos;
5601 else
5603 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5604 lo = 0;
5607 temp = force_reg (rmode, temp);
5608 temp = expand_binop (rmode, and_optab, temp,
5609 immed_double_const (lo, hi, rmode),
5610 target, 1, OPTAB_LIB_WIDEN);
5612 return temp;
5615 /* Expand fork or exec calls. TARGET is the desired target of the
5616 call. ARGLIST is the list of arguments of the call. FN is the
5617 identificator of the actual function. IGNORE is nonzero if the
5618 value is to be ignored. */
5620 static rtx
5621 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5623 tree id, decl;
5624 tree call;
5626 /* If we are not profiling, just call the function. */
5627 if (!profile_arc_flag)
5628 return NULL_RTX;
5630 /* Otherwise call the wrapper. This should be equivalent for the rest of
5631 compiler, so the code does not diverge, and the wrapper may run the
5632 code necessary for keeping the profiling sane. */
5634 switch (DECL_FUNCTION_CODE (fn))
5636 case BUILT_IN_FORK:
5637 id = get_identifier ("__gcov_fork");
5638 break;
5640 case BUILT_IN_EXECL:
5641 id = get_identifier ("__gcov_execl");
5642 break;
5644 case BUILT_IN_EXECV:
5645 id = get_identifier ("__gcov_execv");
5646 break;
5648 case BUILT_IN_EXECLP:
5649 id = get_identifier ("__gcov_execlp");
5650 break;
5652 case BUILT_IN_EXECLE:
5653 id = get_identifier ("__gcov_execle");
5654 break;
5656 case BUILT_IN_EXECVP:
5657 id = get_identifier ("__gcov_execvp");
5658 break;
5660 case BUILT_IN_EXECVE:
5661 id = get_identifier ("__gcov_execve");
5662 break;
5664 default:
5665 abort ();
5668 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5669 DECL_EXTERNAL (decl) = 1;
5670 TREE_PUBLIC (decl) = 1;
5671 DECL_ARTIFICIAL (decl) = 1;
5672 TREE_NOTHROW (decl) = 1;
5673 call = build_function_call_expr (decl, arglist);
5675 return expand_call (call, target, ignore);
5678 /* Expand an expression EXP that calls a built-in function,
5679 with result going to TARGET if that's convenient
5680 (and in mode MODE if that's convenient).
5681 SUBTARGET may be used as the target for computing one of EXP's operands.
5682 IGNORE is nonzero if the value is to be ignored. */
5685 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5686 int ignore)
5688 tree fndecl = get_callee_fndecl (exp);
5689 tree arglist = TREE_OPERAND (exp, 1);
5690 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5691 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5693 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5694 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5696 /* When not optimizing, generate calls to library functions for a certain
5697 set of builtins. */
5698 if (!optimize
5699 && !CALLED_AS_BUILT_IN (fndecl)
5700 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5701 && fcode != BUILT_IN_ALLOCA)
5702 return expand_call (exp, target, ignore);
5704 /* The built-in function expanders test for target == const0_rtx
5705 to determine whether the function's result will be ignored. */
5706 if (ignore)
5707 target = const0_rtx;
5709 /* If the result of a pure or const built-in function is ignored, and
5710 none of its arguments are volatile, we can avoid expanding the
5711 built-in call and just evaluate the arguments for side-effects. */
5712 if (target == const0_rtx
5713 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5715 bool volatilep = false;
5716 tree arg;
5718 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5719 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5721 volatilep = true;
5722 break;
5725 if (! volatilep)
5727 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5728 expand_expr (TREE_VALUE (arg), const0_rtx,
5729 VOIDmode, EXPAND_NORMAL);
5730 return const0_rtx;
5734 switch (fcode)
5736 case BUILT_IN_FABS:
5737 case BUILT_IN_FABSF:
5738 case BUILT_IN_FABSL:
5739 target = expand_builtin_fabs (arglist, target, subtarget);
5740 if (target)
5741 return target;
5742 break;
5744 case BUILT_IN_CABS:
5745 case BUILT_IN_CABSF:
5746 case BUILT_IN_CABSL:
5747 if (flag_unsafe_math_optimizations)
5749 target = expand_builtin_cabs (arglist, target);
5750 if (target)
5751 return target;
5753 break;
5755 case BUILT_IN_EXP:
5756 case BUILT_IN_EXPF:
5757 case BUILT_IN_EXPL:
5758 case BUILT_IN_EXP10:
5759 case BUILT_IN_EXP10F:
5760 case BUILT_IN_EXP10L:
5761 case BUILT_IN_POW10:
5762 case BUILT_IN_POW10F:
5763 case BUILT_IN_POW10L:
5764 case BUILT_IN_EXP2:
5765 case BUILT_IN_EXP2F:
5766 case BUILT_IN_EXP2L:
5767 case BUILT_IN_EXPM1:
5768 case BUILT_IN_EXPM1F:
5769 case BUILT_IN_EXPM1L:
5770 case BUILT_IN_LOGB:
5771 case BUILT_IN_LOGBF:
5772 case BUILT_IN_LOGBL:
5773 case BUILT_IN_ILOGB:
5774 case BUILT_IN_ILOGBF:
5775 case BUILT_IN_ILOGBL:
5776 case BUILT_IN_LOG:
5777 case BUILT_IN_LOGF:
5778 case BUILT_IN_LOGL:
5779 case BUILT_IN_LOG10:
5780 case BUILT_IN_LOG10F:
5781 case BUILT_IN_LOG10L:
5782 case BUILT_IN_LOG2:
5783 case BUILT_IN_LOG2F:
5784 case BUILT_IN_LOG2L:
5785 case BUILT_IN_LOG1P:
5786 case BUILT_IN_LOG1PF:
5787 case BUILT_IN_LOG1PL:
5788 case BUILT_IN_TAN:
5789 case BUILT_IN_TANF:
5790 case BUILT_IN_TANL:
5791 case BUILT_IN_ASIN:
5792 case BUILT_IN_ASINF:
5793 case BUILT_IN_ASINL:
5794 case BUILT_IN_ACOS:
5795 case BUILT_IN_ACOSF:
5796 case BUILT_IN_ACOSL:
5797 case BUILT_IN_ATAN:
5798 case BUILT_IN_ATANF:
5799 case BUILT_IN_ATANL:
5800 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5801 because of possible accuracy problems. */
5802 if (! flag_unsafe_math_optimizations)
5803 break;
5804 case BUILT_IN_SQRT:
5805 case BUILT_IN_SQRTF:
5806 case BUILT_IN_SQRTL:
5807 case BUILT_IN_FLOOR:
5808 case BUILT_IN_FLOORF:
5809 case BUILT_IN_FLOORL:
5810 case BUILT_IN_CEIL:
5811 case BUILT_IN_CEILF:
5812 case BUILT_IN_CEILL:
5813 case BUILT_IN_TRUNC:
5814 case BUILT_IN_TRUNCF:
5815 case BUILT_IN_TRUNCL:
5816 case BUILT_IN_ROUND:
5817 case BUILT_IN_ROUNDF:
5818 case BUILT_IN_ROUNDL:
5819 case BUILT_IN_NEARBYINT:
5820 case BUILT_IN_NEARBYINTF:
5821 case BUILT_IN_NEARBYINTL:
5822 target = expand_builtin_mathfn (exp, target, subtarget);
5823 if (target)
5824 return target;
5825 break;
5827 case BUILT_IN_POW:
5828 case BUILT_IN_POWF:
5829 case BUILT_IN_POWL:
5830 target = expand_builtin_pow (exp, target, subtarget);
5831 if (target)
5832 return target;
5833 break;
5835 case BUILT_IN_ATAN2:
5836 case BUILT_IN_ATAN2F:
5837 case BUILT_IN_ATAN2L:
5838 case BUILT_IN_FMOD:
5839 case BUILT_IN_FMODF:
5840 case BUILT_IN_FMODL:
5841 case BUILT_IN_DREM:
5842 case BUILT_IN_DREMF:
5843 case BUILT_IN_DREML:
5844 if (! flag_unsafe_math_optimizations)
5845 break;
5846 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5847 if (target)
5848 return target;
5849 break;
5851 case BUILT_IN_SIN:
5852 case BUILT_IN_SINF:
5853 case BUILT_IN_SINL:
5854 case BUILT_IN_COS:
5855 case BUILT_IN_COSF:
5856 case BUILT_IN_COSL:
5857 if (! flag_unsafe_math_optimizations)
5858 break;
5859 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5860 if (target)
5861 return target;
5862 break;
5864 case BUILT_IN_APPLY_ARGS:
5865 return expand_builtin_apply_args ();
5867 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5868 FUNCTION with a copy of the parameters described by
5869 ARGUMENTS, and ARGSIZE. It returns a block of memory
5870 allocated on the stack into which is stored all the registers
5871 that might possibly be used for returning the result of a
5872 function. ARGUMENTS is the value returned by
5873 __builtin_apply_args. ARGSIZE is the number of bytes of
5874 arguments that must be copied. ??? How should this value be
5875 computed? We'll also need a safe worst case value for varargs
5876 functions. */
5877 case BUILT_IN_APPLY:
5878 if (!validate_arglist (arglist, POINTER_TYPE,
5879 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5880 && !validate_arglist (arglist, REFERENCE_TYPE,
5881 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5882 return const0_rtx;
5883 else
5885 int i;
5886 tree t;
5887 rtx ops[3];
5889 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5890 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5892 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5895 /* __builtin_return (RESULT) causes the function to return the
5896 value described by RESULT. RESULT is address of the block of
5897 memory returned by __builtin_apply. */
5898 case BUILT_IN_RETURN:
5899 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5900 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5901 NULL_RTX, VOIDmode, 0));
5902 return const0_rtx;
5904 case BUILT_IN_SAVEREGS:
5905 return expand_builtin_saveregs ();
5907 case BUILT_IN_ARGS_INFO:
5908 return expand_builtin_args_info (arglist);
5910 /* Return the address of the first anonymous stack arg. */
5911 case BUILT_IN_NEXT_ARG:
5912 simplify_builtin_next_arg (arglist);
5913 return expand_builtin_next_arg (arglist);
5915 case BUILT_IN_CLASSIFY_TYPE:
5916 return expand_builtin_classify_type (arglist);
5918 case BUILT_IN_CONSTANT_P:
5919 return const0_rtx;
5921 case BUILT_IN_FRAME_ADDRESS:
5922 case BUILT_IN_RETURN_ADDRESS:
5923 return expand_builtin_frame_address (fndecl, arglist);
5925 /* Returns the address of the area where the structure is returned.
5926 0 otherwise. */
5927 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5928 if (arglist != 0
5929 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5930 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5931 return const0_rtx;
5932 else
5933 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5935 case BUILT_IN_ALLOCA:
5936 target = expand_builtin_alloca (arglist, target);
5937 if (target)
5938 return target;
5939 break;
5941 case BUILT_IN_STACK_ALLOC:
5942 expand_stack_alloc (TREE_VALUE (arglist),
5943 TREE_VALUE (TREE_CHAIN (arglist)));
5944 return const0_rtx;
5946 case BUILT_IN_STACK_SAVE:
5947 return expand_stack_save ();
5949 case BUILT_IN_STACK_RESTORE:
5950 expand_stack_restore (TREE_VALUE (arglist));
5951 return const0_rtx;
5953 case BUILT_IN_FFS:
5954 case BUILT_IN_FFSL:
5955 case BUILT_IN_FFSLL:
5956 case BUILT_IN_FFSIMAX:
5957 target = expand_builtin_unop (target_mode, arglist, target,
5958 subtarget, ffs_optab);
5959 if (target)
5960 return target;
5961 break;
5963 case BUILT_IN_CLZ:
5964 case BUILT_IN_CLZL:
5965 case BUILT_IN_CLZLL:
5966 case BUILT_IN_CLZIMAX:
5967 target = expand_builtin_unop (target_mode, arglist, target,
5968 subtarget, clz_optab);
5969 if (target)
5970 return target;
5971 break;
5973 case BUILT_IN_CTZ:
5974 case BUILT_IN_CTZL:
5975 case BUILT_IN_CTZLL:
5976 case BUILT_IN_CTZIMAX:
5977 target = expand_builtin_unop (target_mode, arglist, target,
5978 subtarget, ctz_optab);
5979 if (target)
5980 return target;
5981 break;
5983 case BUILT_IN_POPCOUNT:
5984 case BUILT_IN_POPCOUNTL:
5985 case BUILT_IN_POPCOUNTLL:
5986 case BUILT_IN_POPCOUNTIMAX:
5987 target = expand_builtin_unop (target_mode, arglist, target,
5988 subtarget, popcount_optab);
5989 if (target)
5990 return target;
5991 break;
5993 case BUILT_IN_PARITY:
5994 case BUILT_IN_PARITYL:
5995 case BUILT_IN_PARITYLL:
5996 case BUILT_IN_PARITYIMAX:
5997 target = expand_builtin_unop (target_mode, arglist, target,
5998 subtarget, parity_optab);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_STRLEN:
6004 target = expand_builtin_strlen (arglist, target, target_mode);
6005 if (target)
6006 return target;
6007 break;
6009 case BUILT_IN_STRCPY:
6010 target = expand_builtin_strcpy (arglist, target, mode);
6011 if (target)
6012 return target;
6013 break;
6015 case BUILT_IN_STRNCPY:
6016 target = expand_builtin_strncpy (arglist, target, mode);
6017 if (target)
6018 return target;
6019 break;
6021 case BUILT_IN_STPCPY:
6022 target = expand_builtin_stpcpy (arglist, target, mode);
6023 if (target)
6024 return target;
6025 break;
6027 case BUILT_IN_STRCAT:
6028 target = expand_builtin_strcat (arglist, target, mode);
6029 if (target)
6030 return target;
6031 break;
6033 case BUILT_IN_STRNCAT:
6034 target = expand_builtin_strncat (arglist, target, mode);
6035 if (target)
6036 return target;
6037 break;
6039 case BUILT_IN_STRSPN:
6040 target = expand_builtin_strspn (arglist, target, mode);
6041 if (target)
6042 return target;
6043 break;
6045 case BUILT_IN_STRCSPN:
6046 target = expand_builtin_strcspn (arglist, target, mode);
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_STRSTR:
6052 target = expand_builtin_strstr (arglist, target, mode);
6053 if (target)
6054 return target;
6055 break;
6057 case BUILT_IN_STRPBRK:
6058 target = expand_builtin_strpbrk (arglist, target, mode);
6059 if (target)
6060 return target;
6061 break;
6063 case BUILT_IN_INDEX:
6064 case BUILT_IN_STRCHR:
6065 target = expand_builtin_strchr (arglist, target, mode);
6066 if (target)
6067 return target;
6068 break;
6070 case BUILT_IN_RINDEX:
6071 case BUILT_IN_STRRCHR:
6072 target = expand_builtin_strrchr (arglist, target, mode);
6073 if (target)
6074 return target;
6075 break;
6077 case BUILT_IN_MEMCPY:
6078 target = expand_builtin_memcpy (arglist, target, mode);
6079 if (target)
6080 return target;
6081 break;
6083 case BUILT_IN_MEMPCPY:
6084 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
6085 if (target)
6086 return target;
6087 break;
6089 case BUILT_IN_MEMMOVE:
6090 target = expand_builtin_memmove (arglist, target, mode);
6091 if (target)
6092 return target;
6093 break;
6095 case BUILT_IN_BCOPY:
6096 target = expand_builtin_bcopy (arglist);
6097 if (target)
6098 return target;
6099 break;
6101 case BUILT_IN_MEMSET:
6102 target = expand_builtin_memset (arglist, target, mode);
6103 if (target)
6104 return target;
6105 break;
6107 case BUILT_IN_BZERO:
6108 target = expand_builtin_bzero (arglist);
6109 if (target)
6110 return target;
6111 break;
6113 case BUILT_IN_STRCMP:
6114 target = expand_builtin_strcmp (exp, target, mode);
6115 if (target)
6116 return target;
6117 break;
6119 case BUILT_IN_STRNCMP:
6120 target = expand_builtin_strncmp (exp, target, mode);
6121 if (target)
6122 return target;
6123 break;
6125 case BUILT_IN_BCMP:
6126 case BUILT_IN_MEMCMP:
6127 target = expand_builtin_memcmp (exp, arglist, target, mode);
6128 if (target)
6129 return target;
6130 break;
6132 case BUILT_IN_SETJMP:
6133 target = expand_builtin_setjmp (arglist, target);
6134 if (target)
6135 return target;
6136 break;
6138 /* __builtin_longjmp is passed a pointer to an array of five words.
6139 It's similar to the C library longjmp function but works with
6140 __builtin_setjmp above. */
6141 case BUILT_IN_LONGJMP:
6142 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6143 break;
6144 else
6146 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6147 VOIDmode, 0);
6148 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6149 NULL_RTX, VOIDmode, 0);
6151 if (value != const1_rtx)
6153 error ("__builtin_longjmp second argument must be 1");
6154 return const0_rtx;
6157 expand_builtin_longjmp (buf_addr, value);
6158 return const0_rtx;
6161 case BUILT_IN_NONLOCAL_GOTO:
6162 target = expand_builtin_nonlocal_goto (arglist);
6163 if (target)
6164 return target;
6165 break;
6167 /* This updates the setjmp buffer that is its argument with the value
6168 of the current stack pointer. */
6169 case BUILT_IN_UPDATE_SETJMP_BUF:
6170 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6172 rtx buf_addr
6173 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6175 expand_builtin_update_setjmp_buf (buf_addr);
6176 return const0_rtx;
6178 break;
6180 case BUILT_IN_TRAP:
6181 expand_builtin_trap ();
6182 return const0_rtx;
6184 case BUILT_IN_PRINTF:
6185 target = expand_builtin_printf (arglist, target, mode, false);
6186 if (target)
6187 return target;
6188 break;
6190 case BUILT_IN_PRINTF_UNLOCKED:
6191 target = expand_builtin_printf (arglist, target, mode, true);
6192 if (target)
6193 return target;
6194 break;
6196 case BUILT_IN_FPUTS:
6197 target = expand_builtin_fputs (arglist, target, false);
6198 if (target)
6199 return target;
6200 break;
6201 case BUILT_IN_FPUTS_UNLOCKED:
6202 target = expand_builtin_fputs (arglist, target, true);
6203 if (target)
6204 return target;
6205 break;
6207 case BUILT_IN_FPRINTF:
6208 target = expand_builtin_fprintf (arglist, target, mode, false);
6209 if (target)
6210 return target;
6211 break;
6213 case BUILT_IN_FPRINTF_UNLOCKED:
6214 target = expand_builtin_fprintf (arglist, target, mode, true);
6215 if (target)
6216 return target;
6217 break;
6219 case BUILT_IN_SPRINTF:
6220 target = expand_builtin_sprintf (arglist, target, mode);
6221 if (target)
6222 return target;
6223 break;
6225 case BUILT_IN_SIGNBIT:
6226 case BUILT_IN_SIGNBITF:
6227 case BUILT_IN_SIGNBITL:
6228 target = expand_builtin_signbit (exp, target);
6229 if (target)
6230 return target;
6231 break;
6233 /* Various hooks for the DWARF 2 __throw routine. */
6234 case BUILT_IN_UNWIND_INIT:
6235 expand_builtin_unwind_init ();
6236 return const0_rtx;
6237 case BUILT_IN_DWARF_CFA:
6238 return virtual_cfa_rtx;
6239 #ifdef DWARF2_UNWIND_INFO
6240 case BUILT_IN_DWARF_SP_COLUMN:
6241 return expand_builtin_dwarf_sp_column ();
6242 case BUILT_IN_INIT_DWARF_REG_SIZES:
6243 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6244 return const0_rtx;
6245 #endif
6246 case BUILT_IN_FROB_RETURN_ADDR:
6247 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6248 case BUILT_IN_EXTRACT_RETURN_ADDR:
6249 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6250 case BUILT_IN_EH_RETURN:
6251 expand_builtin_eh_return (TREE_VALUE (arglist),
6252 TREE_VALUE (TREE_CHAIN (arglist)));
6253 return const0_rtx;
6254 #ifdef EH_RETURN_DATA_REGNO
6255 case BUILT_IN_EH_RETURN_DATA_REGNO:
6256 return expand_builtin_eh_return_data_regno (arglist);
6257 #endif
6258 case BUILT_IN_EXTEND_POINTER:
6259 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6261 case BUILT_IN_VA_START:
6262 case BUILT_IN_STDARG_START:
6263 return expand_builtin_va_start (arglist);
6264 case BUILT_IN_VA_END:
6265 return expand_builtin_va_end (arglist);
6266 case BUILT_IN_VA_COPY:
6267 return expand_builtin_va_copy (arglist);
6268 case BUILT_IN_EXPECT:
6269 return expand_builtin_expect (arglist, target);
6270 case BUILT_IN_PREFETCH:
6271 expand_builtin_prefetch (arglist);
6272 return const0_rtx;
6274 case BUILT_IN_PROFILE_FUNC_ENTER:
6275 return expand_builtin_profile_func (false);
6276 case BUILT_IN_PROFILE_FUNC_EXIT:
6277 return expand_builtin_profile_func (true);
6279 case BUILT_IN_INIT_TRAMPOLINE:
6280 return expand_builtin_init_trampoline (arglist);
6281 case BUILT_IN_ADJUST_TRAMPOLINE:
6282 return expand_builtin_adjust_trampoline (arglist);
6284 case BUILT_IN_FORK:
6285 case BUILT_IN_EXECL:
6286 case BUILT_IN_EXECV:
6287 case BUILT_IN_EXECLP:
6288 case BUILT_IN_EXECLE:
6289 case BUILT_IN_EXECVP:
6290 case BUILT_IN_EXECVE:
6291 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6292 if (target)
6293 return target;
6294 break;
6296 default: /* just do library call, if unknown builtin */
6297 break;
6300 /* The switch statement above can drop through to cause the function
6301 to be called normally. */
6302 return expand_call (exp, target, ignore);
6305 /* Determine whether a tree node represents a call to a built-in
6306 function. If the tree T is a call to a built-in function with
6307 the right number of arguments of the appropriate types, return
6308 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6309 Otherwise the return value is END_BUILTINS. */
6311 enum built_in_function
6312 builtin_mathfn_code (tree t)
6314 tree fndecl, arglist, parmlist;
6315 tree argtype, parmtype;
6317 if (TREE_CODE (t) != CALL_EXPR
6318 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6319 return END_BUILTINS;
6321 fndecl = get_callee_fndecl (t);
6322 if (fndecl == NULL_TREE
6323 || TREE_CODE (fndecl) != FUNCTION_DECL
6324 || ! DECL_BUILT_IN (fndecl)
6325 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6326 return END_BUILTINS;
6328 arglist = TREE_OPERAND (t, 1);
6329 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6330 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6332 /* If a function doesn't take a variable number of arguments,
6333 the last element in the list will have type `void'. */
6334 parmtype = TREE_VALUE (parmlist);
6335 if (VOID_TYPE_P (parmtype))
6337 if (arglist)
6338 return END_BUILTINS;
6339 return DECL_FUNCTION_CODE (fndecl);
6342 if (! arglist)
6343 return END_BUILTINS;
6345 argtype = TREE_TYPE (TREE_VALUE (arglist));
6347 if (SCALAR_FLOAT_TYPE_P (parmtype))
6349 if (! SCALAR_FLOAT_TYPE_P (argtype))
6350 return END_BUILTINS;
6352 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6354 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6355 return END_BUILTINS;
6357 else if (POINTER_TYPE_P (parmtype))
6359 if (! POINTER_TYPE_P (argtype))
6360 return END_BUILTINS;
6362 else if (INTEGRAL_TYPE_P (parmtype))
6364 if (! INTEGRAL_TYPE_P (argtype))
6365 return END_BUILTINS;
6367 else
6368 return END_BUILTINS;
6370 arglist = TREE_CHAIN (arglist);
6373 /* Variable-length argument list. */
6374 return DECL_FUNCTION_CODE (fndecl);
6377 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6378 constant. ARGLIST is the argument list of the call. */
6380 static tree
6381 fold_builtin_constant_p (tree arglist)
6383 if (arglist == 0)
6384 return 0;
6386 arglist = TREE_VALUE (arglist);
6388 /* We return 1 for a numeric type that's known to be a constant
6389 value at compile-time or for an aggregate type that's a
6390 literal constant. */
6391 STRIP_NOPS (arglist);
6393 /* If we know this is a constant, emit the constant of one. */
6394 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6395 || (TREE_CODE (arglist) == CONSTRUCTOR
6396 && TREE_CONSTANT (arglist))
6397 || (TREE_CODE (arglist) == ADDR_EXPR
6398 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6399 return integer_one_node;
6401 /* If this expression has side effects, show we don't know it to be a
6402 constant. Likewise if it's a pointer or aggregate type since in
6403 those case we only want literals, since those are only optimized
6404 when generating RTL, not later.
6405 And finally, if we are compiling an initializer, not code, we
6406 need to return a definite result now; there's not going to be any
6407 more optimization done. */
6408 if (TREE_SIDE_EFFECTS (arglist)
6409 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6410 || POINTER_TYPE_P (TREE_TYPE (arglist))
6411 || cfun == 0)
6412 return integer_zero_node;
6414 return 0;
6417 /* Fold a call to __builtin_expect, if we expect that a comparison against
6418 the argument will fold to a constant. In practice, this means a true
6419 constant or the address of a non-weak symbol. ARGLIST is the argument
6420 list of the call. */
6422 static tree
6423 fold_builtin_expect (tree arglist)
6425 tree arg, inner;
6427 if (arglist == 0)
6428 return 0;
6430 arg = TREE_VALUE (arglist);
6432 /* If the argument isn't invariant, then there's nothing we can do. */
6433 if (!TREE_INVARIANT (arg))
6434 return 0;
6436 /* If we're looking at an address of a weak decl, then do not fold. */
6437 inner = arg;
6438 STRIP_NOPS (inner);
6439 if (TREE_CODE (inner) == ADDR_EXPR)
6443 inner = TREE_OPERAND (inner, 0);
6445 while (TREE_CODE (inner) == COMPONENT_REF
6446 || TREE_CODE (inner) == ARRAY_REF);
6447 if (DECL_P (inner) && DECL_WEAK (inner))
6448 return 0;
6451 /* Otherwise, ARG already has the proper type for the return value. */
6452 return arg;
6455 /* Fold a call to __builtin_classify_type. */
6457 static tree
6458 fold_builtin_classify_type (tree arglist)
6460 if (arglist == 0)
6461 return build_int_2 (no_type_class, 0);
6463 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6466 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6468 static tree
6469 fold_builtin_inf (tree type, int warn)
6471 REAL_VALUE_TYPE real;
6473 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6474 warning ("target format does not support infinity");
6476 real_inf (&real);
6477 return build_real (type, real);
6480 /* Fold a call to __builtin_nan or __builtin_nans. */
6482 static tree
6483 fold_builtin_nan (tree arglist, tree type, int quiet)
6485 REAL_VALUE_TYPE real;
6486 const char *str;
6488 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6489 return 0;
6490 str = c_getstr (TREE_VALUE (arglist));
6491 if (!str)
6492 return 0;
6494 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6495 return 0;
6497 return build_real (type, real);
6500 /* Return true if the floating point expression T has an integer value.
6501 We also allow +Inf, -Inf and NaN to be considered integer values. */
6503 static bool
6504 integer_valued_real_p (tree t)
6506 switch (TREE_CODE (t))
6508 case FLOAT_EXPR:
6509 return true;
6511 case ABS_EXPR:
6512 case SAVE_EXPR:
6513 case NON_LVALUE_EXPR:
6514 return integer_valued_real_p (TREE_OPERAND (t, 0));
6516 case COMPOUND_EXPR:
6517 case MODIFY_EXPR:
6518 case BIND_EXPR:
6519 return integer_valued_real_p (TREE_OPERAND (t, 1));
6521 case PLUS_EXPR:
6522 case MINUS_EXPR:
6523 case MULT_EXPR:
6524 case MIN_EXPR:
6525 case MAX_EXPR:
6526 return integer_valued_real_p (TREE_OPERAND (t, 0))
6527 && integer_valued_real_p (TREE_OPERAND (t, 1));
6529 case COND_EXPR:
6530 return integer_valued_real_p (TREE_OPERAND (t, 1))
6531 && integer_valued_real_p (TREE_OPERAND (t, 2));
6533 case REAL_CST:
6534 if (! TREE_CONSTANT_OVERFLOW (t))
6536 REAL_VALUE_TYPE c, cint;
6538 c = TREE_REAL_CST (t);
6539 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6540 return real_identical (&c, &cint);
6543 case NOP_EXPR:
6545 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6546 if (TREE_CODE (type) == INTEGER_TYPE)
6547 return true;
6548 if (TREE_CODE (type) == REAL_TYPE)
6549 return integer_valued_real_p (TREE_OPERAND (t, 0));
6550 break;
6553 case CALL_EXPR:
6554 switch (builtin_mathfn_code (t))
6556 case BUILT_IN_CEIL:
6557 case BUILT_IN_CEILF:
6558 case BUILT_IN_CEILL:
6559 case BUILT_IN_FLOOR:
6560 case BUILT_IN_FLOORF:
6561 case BUILT_IN_FLOORL:
6562 case BUILT_IN_NEARBYINT:
6563 case BUILT_IN_NEARBYINTF:
6564 case BUILT_IN_NEARBYINTL:
6565 case BUILT_IN_RINT:
6566 case BUILT_IN_RINTF:
6567 case BUILT_IN_RINTL:
6568 case BUILT_IN_ROUND:
6569 case BUILT_IN_ROUNDF:
6570 case BUILT_IN_ROUNDL:
6571 case BUILT_IN_TRUNC:
6572 case BUILT_IN_TRUNCF:
6573 case BUILT_IN_TRUNCL:
6574 return true;
6576 default:
6577 break;
6579 break;
6581 default:
6582 break;
6584 return false;
6587 /* EXP is assumed to be builtin call where truncation can be propagated
6588 across (for instance floor((double)f) == (double)floorf (f).
6589 Do the transformation. */
6591 static tree
6592 fold_trunc_transparent_mathfn (tree exp)
6594 tree fndecl = get_callee_fndecl (exp);
6595 tree arglist = TREE_OPERAND (exp, 1);
6596 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6597 tree arg;
6599 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6600 return 0;
6602 arg = TREE_VALUE (arglist);
6603 /* Integer rounding functions are idempotent. */
6604 if (fcode == builtin_mathfn_code (arg))
6605 return arg;
6607 /* If argument is already integer valued, and we don't need to worry
6608 about setting errno, there's no need to perform rounding. */
6609 if (! flag_errno_math && integer_valued_real_p (arg))
6610 return arg;
6612 if (optimize)
6614 tree arg0 = strip_float_extensions (arg);
6615 tree ftype = TREE_TYPE (exp);
6616 tree newtype = TREE_TYPE (arg0);
6617 tree decl;
6619 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6620 && (decl = mathfn_built_in (newtype, fcode)))
6622 arglist =
6623 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6624 return fold_convert (ftype,
6625 build_function_call_expr (decl, arglist));
6628 return 0;
6631 /* EXP is assumed to be builtin call which can narrow the FP type of
6632 the argument, for instance lround((double)f) -> lroundf (f). */
6634 static tree
6635 fold_fixed_mathfn (tree exp)
6637 tree fndecl = get_callee_fndecl (exp);
6638 tree arglist = TREE_OPERAND (exp, 1);
6639 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6640 tree arg;
6642 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6643 return 0;
6645 arg = TREE_VALUE (arglist);
6647 /* If argument is already integer valued, and we don't need to worry
6648 about setting errno, there's no need to perform rounding. */
6649 if (! flag_errno_math && integer_valued_real_p (arg))
6650 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6652 if (optimize)
6654 tree ftype = TREE_TYPE (arg);
6655 tree arg0 = strip_float_extensions (arg);
6656 tree newtype = TREE_TYPE (arg0);
6657 tree decl;
6659 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6660 && (decl = mathfn_built_in (newtype, fcode)))
6662 arglist =
6663 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6664 return build_function_call_expr (decl, arglist);
6667 return 0;
6670 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6671 is the argument list and TYPE is the return type. Return
6672 NULL_TREE if no if no simplification can be made. */
6674 static tree
6675 fold_builtin_cabs (tree arglist, tree type)
6677 tree arg;
6679 if (!arglist || TREE_CHAIN (arglist))
6680 return NULL_TREE;
6682 arg = TREE_VALUE (arglist);
6683 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6684 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6685 return NULL_TREE;
6687 /* Evaluate cabs of a constant at compile-time. */
6688 if (flag_unsafe_math_optimizations
6689 && TREE_CODE (arg) == COMPLEX_CST
6690 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6691 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6692 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6693 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6695 REAL_VALUE_TYPE r, i;
6697 r = TREE_REAL_CST (TREE_REALPART (arg));
6698 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6700 real_arithmetic (&r, MULT_EXPR, &r, &r);
6701 real_arithmetic (&i, MULT_EXPR, &i, &i);
6702 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6703 if (real_sqrt (&r, TYPE_MODE (type), &r)
6704 || ! flag_trapping_math)
6705 return build_real (type, r);
6708 /* If either part is zero, cabs is fabs of the other. */
6709 if (TREE_CODE (arg) == COMPLEX_EXPR
6710 && real_zerop (TREE_OPERAND (arg, 0)))
6711 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6712 if (TREE_CODE (arg) == COMPLEX_EXPR
6713 && real_zerop (TREE_OPERAND (arg, 1)))
6714 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6716 if (flag_unsafe_math_optimizations)
6718 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6720 if (sqrtfn != NULL_TREE)
6722 tree rpart, ipart, result, arglist;
6724 arg = builtin_save_expr (arg);
6726 rpart = fold (build1 (REALPART_EXPR, type, arg));
6727 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6729 rpart = builtin_save_expr (rpart);
6730 ipart = builtin_save_expr (ipart);
6732 result = fold (build2 (PLUS_EXPR, type,
6733 fold (build2 (MULT_EXPR, type,
6734 rpart, rpart)),
6735 fold (build2 (MULT_EXPR, type,
6736 ipart, ipart))));
6738 arglist = build_tree_list (NULL_TREE, result);
6739 return build_function_call_expr (sqrtfn, arglist);
6743 return NULL_TREE;
6746 /* Fold function call to builtin trunc, truncf or truncl. Return
6747 NULL_TREE if no simplification can be made. */
6749 static tree
6750 fold_builtin_trunc (tree exp)
6752 tree arglist = TREE_OPERAND (exp, 1);
6753 tree arg;
6755 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6756 return 0;
6758 /* Optimize trunc of constant value. */
6759 arg = TREE_VALUE (arglist);
6760 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6762 REAL_VALUE_TYPE r, x;
6763 tree type = TREE_TYPE (exp);
6765 x = TREE_REAL_CST (arg);
6766 real_trunc (&r, TYPE_MODE (type), &x);
6767 return build_real (type, r);
6770 return fold_trunc_transparent_mathfn (exp);
6773 /* Fold function call to builtin floor, floorf or floorl. Return
6774 NULL_TREE if no simplification can be made. */
6776 static tree
6777 fold_builtin_floor (tree exp)
6779 tree arglist = TREE_OPERAND (exp, 1);
6780 tree arg;
6782 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6783 return 0;
6785 /* Optimize floor of constant value. */
6786 arg = TREE_VALUE (arglist);
6787 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6789 REAL_VALUE_TYPE x;
6791 x = TREE_REAL_CST (arg);
6792 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6794 tree type = TREE_TYPE (exp);
6795 REAL_VALUE_TYPE r;
6797 real_floor (&r, TYPE_MODE (type), &x);
6798 return build_real (type, r);
6802 return fold_trunc_transparent_mathfn (exp);
6805 /* Fold function call to builtin ceil, ceilf or ceill. Return
6806 NULL_TREE if no simplification can be made. */
6808 static tree
6809 fold_builtin_ceil (tree exp)
6811 tree arglist = TREE_OPERAND (exp, 1);
6812 tree arg;
6814 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6815 return 0;
6817 /* Optimize ceil of constant value. */
6818 arg = TREE_VALUE (arglist);
6819 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6821 REAL_VALUE_TYPE x;
6823 x = TREE_REAL_CST (arg);
6824 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6826 tree type = TREE_TYPE (exp);
6827 REAL_VALUE_TYPE r;
6829 real_ceil (&r, TYPE_MODE (type), &x);
6830 return build_real (type, r);
6834 return fold_trunc_transparent_mathfn (exp);
6837 /* Fold function call to builtin round, roundf or roundl. Return
6838 NULL_TREE if no simplification can be made. */
6840 static tree
6841 fold_builtin_round (tree exp)
6843 tree arglist = TREE_OPERAND (exp, 1);
6844 tree arg;
6846 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6847 return 0;
6849 /* Optimize round of constant value. */
6850 arg = TREE_VALUE (arglist);
6851 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6853 REAL_VALUE_TYPE x;
6855 x = TREE_REAL_CST (arg);
6856 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6858 tree type = TREE_TYPE (exp);
6859 REAL_VALUE_TYPE r;
6861 real_round (&r, TYPE_MODE (type), &x);
6862 return build_real (type, r);
6866 return fold_trunc_transparent_mathfn (exp);
6869 /* Fold function call to builtin lround, lroundf or lroundl (or the
6870 corresponding long long versions). Return NULL_TREE if no
6871 simplification can be made. */
6873 static tree
6874 fold_builtin_lround (tree exp)
6876 tree arglist = TREE_OPERAND (exp, 1);
6877 tree arg;
6879 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6880 return 0;
6882 /* Optimize lround of constant value. */
6883 arg = TREE_VALUE (arglist);
6884 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6886 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6888 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6890 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6891 HOST_WIDE_INT hi, lo;
6892 REAL_VALUE_TYPE r;
6894 real_round (&r, TYPE_MODE (ftype), &x);
6895 REAL_VALUE_TO_INT (&lo, &hi, r);
6896 result = build_int_2 (lo, hi);
6897 if (int_fits_type_p (result, itype))
6898 return fold_convert (itype, result);
6902 return fold_fixed_mathfn (exp);
6905 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6906 and their long and long long variants (i.e. ffsl and ffsll).
6907 Return NULL_TREE if no simplification can be made. */
6909 static tree
6910 fold_builtin_bitop (tree exp)
6912 tree fndecl = get_callee_fndecl (exp);
6913 tree arglist = TREE_OPERAND (exp, 1);
6914 tree arg;
6916 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6917 return NULL_TREE;
6919 /* Optimize for constant argument. */
6920 arg = TREE_VALUE (arglist);
6921 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6923 HOST_WIDE_INT hi, width, result;
6924 unsigned HOST_WIDE_INT lo;
6925 tree type, t;
6927 type = TREE_TYPE (arg);
6928 width = TYPE_PRECISION (type);
6929 lo = TREE_INT_CST_LOW (arg);
6931 /* Clear all the bits that are beyond the type's precision. */
6932 if (width > HOST_BITS_PER_WIDE_INT)
6934 hi = TREE_INT_CST_HIGH (arg);
6935 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6936 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6938 else
6940 hi = 0;
6941 if (width < HOST_BITS_PER_WIDE_INT)
6942 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6945 switch (DECL_FUNCTION_CODE (fndecl))
6947 case BUILT_IN_FFS:
6948 case BUILT_IN_FFSL:
6949 case BUILT_IN_FFSLL:
6950 if (lo != 0)
6951 result = exact_log2 (lo & -lo) + 1;
6952 else if (hi != 0)
6953 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6954 else
6955 result = 0;
6956 break;
6958 case BUILT_IN_CLZ:
6959 case BUILT_IN_CLZL:
6960 case BUILT_IN_CLZLL:
6961 if (hi != 0)
6962 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6963 else if (lo != 0)
6964 result = width - floor_log2 (lo) - 1;
6965 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6966 result = width;
6967 break;
6969 case BUILT_IN_CTZ:
6970 case BUILT_IN_CTZL:
6971 case BUILT_IN_CTZLL:
6972 if (lo != 0)
6973 result = exact_log2 (lo & -lo);
6974 else if (hi != 0)
6975 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6976 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6977 result = width;
6978 break;
6980 case BUILT_IN_POPCOUNT:
6981 case BUILT_IN_POPCOUNTL:
6982 case BUILT_IN_POPCOUNTLL:
6983 result = 0;
6984 while (lo)
6985 result++, lo &= lo - 1;
6986 while (hi)
6987 result++, hi &= hi - 1;
6988 break;
6990 case BUILT_IN_PARITY:
6991 case BUILT_IN_PARITYL:
6992 case BUILT_IN_PARITYLL:
6993 result = 0;
6994 while (lo)
6995 result++, lo &= lo - 1;
6996 while (hi)
6997 result++, hi &= hi - 1;
6998 result &= 1;
6999 break;
7001 default:
7002 abort();
7005 t = build_int_2 (result, 0);
7006 TREE_TYPE (t) = TREE_TYPE (exp);
7007 return t;
7010 return NULL_TREE;
7013 /* Return true if EXPR is the real constant contained in VALUE. */
7015 static bool
7016 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7018 STRIP_NOPS (expr);
7020 return ((TREE_CODE (expr) == REAL_CST
7021 && ! TREE_CONSTANT_OVERFLOW (expr)
7022 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7023 || (TREE_CODE (expr) == COMPLEX_CST
7024 && real_dconstp (TREE_REALPART (expr), value)
7025 && real_zerop (TREE_IMAGPART (expr))));
7028 /* A subroutine of fold_builtin to fold the various logarithmic
7029 functions. EXP is the CALL_EXPR of a call to a builtin logN
7030 function. VALUE is the base of the logN function. */
7032 static tree
7033 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
7035 tree arglist = TREE_OPERAND (exp, 1);
7037 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7039 tree fndecl = get_callee_fndecl (exp);
7040 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7041 tree arg = TREE_VALUE (arglist);
7042 const enum built_in_function fcode = builtin_mathfn_code (arg);
7044 /* Optimize logN(1.0) = 0.0. */
7045 if (real_onep (arg))
7046 return build_real (type, dconst0);
7048 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7049 exactly, then only do this if flag_unsafe_math_optimizations. */
7050 if (exact_real_truncate (TYPE_MODE (type), value)
7051 || flag_unsafe_math_optimizations)
7053 const REAL_VALUE_TYPE value_truncate =
7054 real_value_truncate (TYPE_MODE (type), *value);
7055 if (real_dconstp (arg, &value_truncate))
7056 return build_real (type, dconst1);
7059 /* Special case, optimize logN(expN(x)) = x. */
7060 if (flag_unsafe_math_optimizations
7061 && ((value == &dconste
7062 && (fcode == BUILT_IN_EXP
7063 || fcode == BUILT_IN_EXPF
7064 || fcode == BUILT_IN_EXPL))
7065 || (value == &dconst2
7066 && (fcode == BUILT_IN_EXP2
7067 || fcode == BUILT_IN_EXP2F
7068 || fcode == BUILT_IN_EXP2L))
7069 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7070 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7072 /* Optimize logN(func()) for various exponential functions. We
7073 want to determine the value "x" and the power "exponent" in
7074 order to transform logN(x**exponent) into exponent*logN(x). */
7075 if (flag_unsafe_math_optimizations)
7077 tree exponent = 0, x = 0;
7079 switch (fcode)
7081 case BUILT_IN_EXP:
7082 case BUILT_IN_EXPF:
7083 case BUILT_IN_EXPL:
7084 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7085 x = build_real (type,
7086 real_value_truncate (TYPE_MODE (type), dconste));
7087 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7088 break;
7089 case BUILT_IN_EXP2:
7090 case BUILT_IN_EXP2F:
7091 case BUILT_IN_EXP2L:
7092 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7093 x = build_real (type, dconst2);
7094 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7095 break;
7096 case BUILT_IN_EXP10:
7097 case BUILT_IN_EXP10F:
7098 case BUILT_IN_EXP10L:
7099 case BUILT_IN_POW10:
7100 case BUILT_IN_POW10F:
7101 case BUILT_IN_POW10L:
7102 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7103 x = build_real (type, dconst10);
7104 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7105 break;
7106 case BUILT_IN_SQRT:
7107 case BUILT_IN_SQRTF:
7108 case BUILT_IN_SQRTL:
7109 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7110 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7111 exponent = build_real (type, dconsthalf);
7112 break;
7113 case BUILT_IN_CBRT:
7114 case BUILT_IN_CBRTF:
7115 case BUILT_IN_CBRTL:
7116 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7117 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7118 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7119 dconstthird));
7120 break;
7121 case BUILT_IN_POW:
7122 case BUILT_IN_POWF:
7123 case BUILT_IN_POWL:
7124 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7125 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7126 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7127 break;
7128 default:
7129 break;
7132 /* Now perform the optimization. */
7133 if (x && exponent)
7135 tree logfn;
7136 arglist = build_tree_list (NULL_TREE, x);
7137 logfn = build_function_call_expr (fndecl, arglist);
7138 return fold (build2 (MULT_EXPR, type, exponent, logfn));
7143 return 0;
7146 /* A subroutine of fold_builtin to fold the various exponent
7147 functions. EXP is the CALL_EXPR of a call to a builtin function.
7148 VALUE is the value which will be raised to a power. */
7150 static tree
7151 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
7153 tree arglist = TREE_OPERAND (exp, 1);
7155 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7157 tree fndecl = get_callee_fndecl (exp);
7158 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7159 tree arg = TREE_VALUE (arglist);
7161 /* Optimize exp*(0.0) = 1.0. */
7162 if (real_zerop (arg))
7163 return build_real (type, dconst1);
7165 /* Optimize expN(1.0) = N. */
7166 if (real_onep (arg))
7168 REAL_VALUE_TYPE cst;
7170 real_convert (&cst, TYPE_MODE (type), value);
7171 return build_real (type, cst);
7174 /* Attempt to evaluate expN(integer) at compile-time. */
7175 if (flag_unsafe_math_optimizations
7176 && TREE_CODE (arg) == REAL_CST
7177 && ! TREE_CONSTANT_OVERFLOW (arg))
7179 REAL_VALUE_TYPE cint;
7180 REAL_VALUE_TYPE c;
7181 HOST_WIDE_INT n;
7183 c = TREE_REAL_CST (arg);
7184 n = real_to_integer (&c);
7185 real_from_integer (&cint, VOIDmode, n,
7186 n < 0 ? -1 : 0, 0);
7187 if (real_identical (&c, &cint))
7189 REAL_VALUE_TYPE x;
7191 real_powi (&x, TYPE_MODE (type), value, n);
7192 return build_real (type, x);
7196 /* Optimize expN(logN(x)) = x. */
7197 if (flag_unsafe_math_optimizations)
7199 const enum built_in_function fcode = builtin_mathfn_code (arg);
7201 if ((value == &dconste
7202 && (fcode == BUILT_IN_LOG
7203 || fcode == BUILT_IN_LOGF
7204 || fcode == BUILT_IN_LOGL))
7205 || (value == &dconst2
7206 && (fcode == BUILT_IN_LOG2
7207 || fcode == BUILT_IN_LOG2F
7208 || fcode == BUILT_IN_LOG2L))
7209 || (value == &dconst10
7210 && (fcode == BUILT_IN_LOG10
7211 || fcode == BUILT_IN_LOG10F
7212 || fcode == BUILT_IN_LOG10L)))
7213 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7217 return 0;
7220 /* Fold function call to builtin memcpy. Return
7221 NULL_TREE if no simplification can be made. */
7223 static tree
7224 fold_builtin_memcpy (tree exp)
7226 tree arglist = TREE_OPERAND (exp, 1);
7227 tree dest, src, len;
7229 if (!validate_arglist (arglist,
7230 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7231 return 0;
7233 dest = TREE_VALUE (arglist);
7234 src = TREE_VALUE (TREE_CHAIN (arglist));
7235 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7237 /* If the LEN parameter is zero, return DEST. */
7238 if (integer_zerop (len))
7239 return omit_one_operand (TREE_TYPE (exp), dest, src);
7241 /* If SRC and DEST are the same (and not volatile), return DEST. */
7242 if (operand_equal_p (src, dest, 0))
7243 return omit_one_operand (TREE_TYPE (exp), dest, len);
7245 return 0;
7248 /* Fold function call to builtin mempcpy. Return
7249 NULL_TREE if no simplification can be made. */
7251 static tree
7252 fold_builtin_mempcpy (tree exp)
7254 tree arglist = TREE_OPERAND (exp, 1);
7255 tree dest, src, len;
7257 if (!validate_arglist (arglist,
7258 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7259 return 0;
7261 dest = TREE_VALUE (arglist);
7262 src = TREE_VALUE (TREE_CHAIN (arglist));
7263 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7265 /* If the LEN parameter is zero, return DEST. */
7266 if (integer_zerop (len))
7267 return omit_one_operand (TREE_TYPE (exp), dest, src);
7269 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7270 if (operand_equal_p (src, dest, 0))
7272 tree temp = fold_convert (TREE_TYPE (dest), len);
7273 temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7274 return fold_convert (TREE_TYPE (exp), temp);
7277 return 0;
7280 /* Fold function call to builtin memmove. Return
7281 NULL_TREE if no simplification can be made. */
7283 static tree
7284 fold_builtin_memmove (tree exp)
7286 tree arglist = TREE_OPERAND (exp, 1);
7287 tree dest, src, len;
7289 if (!validate_arglist (arglist,
7290 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7291 return 0;
7293 dest = TREE_VALUE (arglist);
7294 src = TREE_VALUE (TREE_CHAIN (arglist));
7295 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7297 /* If the LEN parameter is zero, return DEST. */
7298 if (integer_zerop (len))
7299 return omit_one_operand (TREE_TYPE (exp), dest, src);
7301 /* If SRC and DEST are the same (and not volatile), return DEST. */
7302 if (operand_equal_p (src, dest, 0))
7303 return omit_one_operand (TREE_TYPE (exp), dest, len);
7305 return 0;
7308 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7309 the length of the string to be copied. Return NULL_TREE if no
7310 simplification can be made. */
7312 tree
7313 fold_builtin_strcpy (tree exp, tree len)
7315 tree arglist = TREE_OPERAND (exp, 1);
7316 tree dest, src, fn;
7318 if (!validate_arglist (arglist,
7319 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7320 return 0;
7322 dest = TREE_VALUE (arglist);
7323 src = TREE_VALUE (TREE_CHAIN (arglist));
7325 /* If SRC and DEST are the same (and not volatile), return DEST. */
7326 if (operand_equal_p (src, dest, 0))
7327 return fold_convert (TREE_TYPE (exp), dest);
7329 if (optimize_size)
7330 return 0;
7332 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7333 if (!fn)
7334 return 0;
7336 if (!len)
7338 len = c_strlen (src, 1);
7339 if (! len || TREE_SIDE_EFFECTS (len))
7340 return 0;
7343 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7344 arglist = build_tree_list (NULL_TREE, len);
7345 arglist = tree_cons (NULL_TREE, src, arglist);
7346 arglist = tree_cons (NULL_TREE, dest, arglist);
7347 return fold_convert (TREE_TYPE (exp),
7348 build_function_call_expr (fn, arglist));
7351 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7352 the length of the source string. Return NULL_TREE if no simplification
7353 can be made. */
7355 tree
7356 fold_builtin_strncpy (tree exp, tree slen)
7358 tree arglist = TREE_OPERAND (exp, 1);
7359 tree dest, src, len, fn;
7361 if (!validate_arglist (arglist,
7362 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7363 return 0;
7365 dest = TREE_VALUE (arglist);
7366 src = TREE_VALUE (TREE_CHAIN (arglist));
7367 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7369 /* If the LEN parameter is zero, return DEST. */
7370 if (integer_zerop (len))
7371 return omit_one_operand (TREE_TYPE (exp), dest, src);
7373 /* We can't compare slen with len as constants below if len is not a
7374 constant. */
7375 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7376 return 0;
7378 if (!slen)
7379 slen = c_strlen (src, 1);
7381 /* Now, we must be passed a constant src ptr parameter. */
7382 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7383 return 0;
7385 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7387 /* We do not support simplification of this case, though we do
7388 support it when expanding trees into RTL. */
7389 /* FIXME: generate a call to __builtin_memset. */
7390 if (tree_int_cst_lt (slen, len))
7391 return 0;
7393 /* OK transform into builtin memcpy. */
7394 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7395 if (!fn)
7396 return 0;
7397 return fold_convert (TREE_TYPE (exp),
7398 build_function_call_expr (fn, arglist));
7401 /* Fold function call to builtin strchr and strrchr.
7402 Return NULL_TREE if no simplification can be made. */
7404 static tree
7405 fold_builtin_strchr (tree exp, bool actually_strrchr)
7407 tree arglist = TREE_OPERAND (exp, 1);
7408 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7409 return 0;
7410 else
7412 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7413 const char *p1;
7415 if (TREE_CODE (s2) != INTEGER_CST)
7416 return 0;
7418 p1 = c_getstr (s1);
7419 if (p1 != NULL)
7421 char c;
7422 const char *r;
7424 if (target_char_cast (s2, &c))
7425 return 0;
7427 r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7429 if (r == NULL)
7430 return fold_convert (TREE_TYPE (s1), integer_zero_node);
7432 /* Return an offset into the constant string argument. */
7433 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7434 s1, fold_convert (TREE_TYPE (s1),
7435 ssize_int (r - p1))));
7438 if (actually_strrchr)
7440 tree fn;
7442 if (!integer_zerop (s2))
7443 return 0;
7445 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7446 if (!fn)
7447 return 0;
7449 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
7450 return build_function_call_expr (fn, arglist);
7453 return 0;
7457 /* Fold function call to builtin memcmp. Return
7458 NULL_TREE if no simplification can be made. */
7460 static tree
7461 fold_builtin_memcmp (tree exp)
7463 tree arglist = TREE_OPERAND (exp, 1);
7464 tree arg1, arg2, len;
7466 if (!validate_arglist (arglist,
7467 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7468 return 0;
7470 arg1 = TREE_VALUE (arglist);
7471 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7472 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7474 /* If the LEN parameter is zero, return zero. */
7475 if (integer_zerop (len))
7477 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7478 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7481 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7482 if (operand_equal_p (arg1, arg2, 0))
7483 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7485 return 0;
7488 /* Fold function call to builtin strcmp. Return
7489 NULL_TREE if no simplification can be made. */
7491 static tree
7492 fold_builtin_strcmp (tree exp)
7494 tree arglist = TREE_OPERAND (exp, 1);
7495 tree arg1, arg2;
7496 const char *p1, *p2;
7498 if (!validate_arglist (arglist,
7499 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7500 return 0;
7502 arg1 = TREE_VALUE (arglist);
7503 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7505 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7506 if (operand_equal_p (arg1, arg2, 0))
7507 return fold_convert (TREE_TYPE (exp), integer_zero_node);
7509 p1 = c_getstr (arg1);
7510 p2 = c_getstr (arg2);
7512 if (p1 && p2)
7514 tree temp;
7515 const int i = strcmp (p1, p2);
7516 if (i < 0)
7517 temp = integer_minus_one_node;
7518 else if (i > 0)
7519 temp = integer_one_node;
7520 else
7521 temp = integer_zero_node;
7522 return fold_convert (TREE_TYPE (exp), temp);
7525 return 0;
7528 /* Fold function call to builtin strncmp. Return
7529 NULL_TREE if no simplification can be made. */
7531 static tree
7532 fold_builtin_strncmp (tree exp)
7534 tree arglist = TREE_OPERAND (exp, 1);
7535 tree arg1, arg2, len;
7536 const char *p1, *p2;
7538 if (!validate_arglist (arglist,
7539 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7540 return 0;
7542 arg1 = TREE_VALUE (arglist);
7543 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7544 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7546 /* If the LEN parameter is zero, return zero. */
7547 if (integer_zerop (len))
7549 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7550 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7553 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7554 if (operand_equal_p (arg1, arg2, 0))
7555 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7557 p1 = c_getstr (arg1);
7558 p2 = c_getstr (arg2);
7560 if (host_integerp (len, 1) && p1 && p2)
7562 tree temp;
7563 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7564 if (i < 0)
7565 temp = integer_minus_one_node;
7566 else if (i > 0)
7567 temp = integer_one_node;
7568 else
7569 temp = integer_zero_node;
7570 return fold_convert (TREE_TYPE (exp), temp);
7573 return 0;
7576 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7577 NULL_TREE if no simplification can be made. */
7579 static tree
7580 fold_builtin_signbit (tree exp)
7582 tree arglist = TREE_OPERAND (exp, 1);
7583 tree arg, temp;
7585 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7586 return NULL_TREE;
7588 arg = TREE_VALUE (arglist);
7590 /* If ARG is a compile-time constant, determine the result. */
7591 if (TREE_CODE (arg) == REAL_CST
7592 && !TREE_CONSTANT_OVERFLOW (arg))
7594 REAL_VALUE_TYPE c;
7596 c = TREE_REAL_CST (arg);
7597 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7598 return fold_convert (TREE_TYPE (exp), temp);
7601 /* If ARG is non-negative, the result is always zero. */
7602 if (tree_expr_nonnegative_p (arg))
7603 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7605 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7606 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7607 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7608 build_real (TREE_TYPE (arg), dconst0)));
7610 return NULL_TREE;
7613 /* Fold function call to builtin copysign, copysignf or copysignl.
7614 Return NULL_TREE if no simplification can be made. */
7616 static tree
7617 fold_builtin_copysign (tree arglist, tree type)
7619 tree arg1, arg2;
7621 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7622 return NULL_TREE;
7624 arg1 = TREE_VALUE (arglist);
7625 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7627 /* copysign(X,X) is X. */
7628 if (operand_equal_p (arg1, arg2, 0))
7629 return fold_convert (type, arg1);
7631 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7632 if (TREE_CODE (arg1) == REAL_CST
7633 && TREE_CODE (arg2) == REAL_CST
7634 && !TREE_CONSTANT_OVERFLOW (arg1)
7635 && !TREE_CONSTANT_OVERFLOW (arg2))
7637 REAL_VALUE_TYPE c1, c2;
7639 c1 = TREE_REAL_CST (arg1);
7640 c2 = TREE_REAL_CST (arg2);
7641 real_copysign (&c1, &c2);
7642 return build_real (type, c1);
7643 c1.sign = c2.sign;
7646 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7647 Remember to evaluate Y for side-effects. */
7648 if (tree_expr_nonnegative_p (arg2))
7649 return omit_one_operand (type,
7650 fold (build1 (ABS_EXPR, type, arg1)),
7651 arg2);
7653 return NULL_TREE;
7656 /* Fold a call to builtin isascii. */
7658 static tree
7659 fold_builtin_isascii (tree arglist)
7661 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7662 return 0;
7663 else
7665 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7666 tree arg = TREE_VALUE (arglist);
7668 arg = fold (build2 (EQ_EXPR, integer_type_node,
7669 build2 (BIT_AND_EXPR, integer_type_node, arg,
7670 build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7671 ~ (HOST_WIDE_INT) 0)),
7672 integer_zero_node));
7674 if (in_gimple_form && !TREE_CONSTANT (arg))
7675 return NULL_TREE;
7676 else
7677 return arg;
7681 /* Fold a call to builtin toascii. */
7683 static tree
7684 fold_builtin_toascii (tree arglist)
7686 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7687 return 0;
7688 else
7690 /* Transform toascii(c) -> (c & 0x7f). */
7691 tree arg = TREE_VALUE (arglist);
7693 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7694 build_int_2 (0x7f, 0)));
7698 /* Fold a call to builtin isdigit. */
7700 static tree
7701 fold_builtin_isdigit (tree arglist)
7703 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7704 return 0;
7705 else
7707 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7708 /* According to the C standard, isdigit is unaffected by locale. */
7709 tree arg = TREE_VALUE (arglist);
7710 arg = fold_convert (unsigned_type_node, arg);
7711 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7712 fold_convert (unsigned_type_node,
7713 build_int_2 (TARGET_DIGIT0, 0)));
7714 arg = build2 (LE_EXPR, integer_type_node, arg,
7715 fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7716 arg = fold (arg);
7717 if (in_gimple_form && !TREE_CONSTANT (arg))
7718 return NULL_TREE;
7719 else
7720 return arg;
7724 /* Fold a call to fabs, fabsf or fabsl. */
7726 static tree
7727 fold_builtin_fabs (tree arglist, tree type)
7729 tree arg;
7731 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7732 return 0;
7734 arg = TREE_VALUE (arglist);
7735 if (TREE_CODE (arg) == REAL_CST)
7736 return fold_abs_const (arg, type);
7737 return fold (build1 (ABS_EXPR, type, arg));
7740 /* Fold a call to abs, labs, llabs or imaxabs. */
7742 static tree
7743 fold_builtin_abs (tree arglist, tree type)
7745 tree arg;
7747 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7748 return 0;
7750 arg = TREE_VALUE (arglist);
7751 if (TREE_CODE (arg) == INTEGER_CST)
7752 return fold_abs_const (arg, type);
7753 return fold (build1 (ABS_EXPR, type, arg));
7756 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7757 EXP is the CALL_EXPR for the call. */
7759 static tree
7760 fold_builtin_classify (tree exp, int builtin_index)
7762 tree fndecl = get_callee_fndecl (exp);
7763 tree arglist = TREE_OPERAND (exp, 1);
7764 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7765 tree arg;
7766 REAL_VALUE_TYPE r;
7768 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7770 /* Check that we have exactly one argument. */
7771 if (arglist == 0)
7773 error ("too few arguments to function `%s'",
7774 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7775 return error_mark_node;
7777 else if (TREE_CHAIN (arglist) != 0)
7779 error ("too many arguments to function `%s'",
7780 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7781 return error_mark_node;
7783 else
7785 error ("non-floating-point argument to function `%s'",
7786 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7787 return error_mark_node;
7791 arg = TREE_VALUE (arglist);
7792 switch (builtin_index)
7794 case BUILT_IN_ISINF:
7795 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7796 return omit_one_operand (type, integer_zero_node, arg);
7798 if (TREE_CODE (arg) == REAL_CST)
7800 r = TREE_REAL_CST (arg);
7801 if (real_isinf (&r))
7802 return real_compare (GT_EXPR, &r, &dconst0)
7803 ? integer_one_node : integer_minus_one_node;
7804 else
7805 return integer_zero_node;
7808 return NULL_TREE;
7810 case BUILT_IN_FINITE:
7811 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7812 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7813 return omit_one_operand (type, integer_zero_node, arg);
7815 if (TREE_CODE (arg) == REAL_CST)
7817 r = TREE_REAL_CST (arg);
7818 return real_isinf (&r) || real_isnan (&r)
7819 ? integer_zero_node : integer_one_node;
7822 return NULL_TREE;
7824 case BUILT_IN_ISNAN:
7825 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7826 return omit_one_operand (type, integer_zero_node, arg);
7828 if (TREE_CODE (arg) == REAL_CST)
7830 r = TREE_REAL_CST (arg);
7831 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7834 arg = builtin_save_expr (arg);
7835 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7837 default:
7838 abort ();
7842 /* Fold a call to an unordered comparison function such as
7843 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7844 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7845 the opposite of the desired result. UNORDERED_CODE is used
7846 for modes that can hold NaNs and ORDERED_CODE is used for
7847 the rest. */
7849 static tree
7850 fold_builtin_unordered_cmp (tree exp,
7851 enum tree_code unordered_code,
7852 enum tree_code ordered_code)
7854 tree fndecl = get_callee_fndecl (exp);
7855 tree arglist = TREE_OPERAND (exp, 1);
7856 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7857 enum tree_code code;
7858 tree arg0, arg1;
7860 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7862 enum tree_code code0, code1;
7863 tree type0, type1;
7864 tree cmp_type = 0;
7866 /* Check that we have exactly two arguments. */
7867 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7869 error ("too few arguments to function `%s'",
7870 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7871 return error_mark_node;
7873 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7875 error ("too many arguments to function `%s'",
7876 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7877 return error_mark_node;
7880 arg0 = TREE_VALUE (arglist);
7881 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7883 type0 = TREE_TYPE (arg0);
7884 type1 = TREE_TYPE (arg1);
7886 code0 = TREE_CODE (type0);
7887 code1 = TREE_CODE (type1);
7889 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7890 /* Choose the wider of two real types. */
7891 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7892 ? type0 : type1;
7893 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7894 cmp_type = type0;
7895 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7896 cmp_type = type1;
7897 else
7899 error ("non-floating-point argument to function `%s'",
7900 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7901 return error_mark_node;
7904 arg0 = fold_convert (cmp_type, arg0);
7905 arg1 = fold_convert (cmp_type, arg1);
7907 else
7909 arg0 = TREE_VALUE (arglist);
7910 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7913 if (unordered_code == UNORDERED_EXPR)
7915 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7916 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7917 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7920 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7921 : ordered_code;
7922 return fold (build1 (TRUTH_NOT_EXPR, type,
7923 fold (build2 (code, type, arg0, arg1))));
7926 /* Used by constant folding to simplify calls to builtin functions. EXP is
7927 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7928 result of the function call is ignored. This function returns NULL_TREE
7929 if no simplification was possible. */
7931 static tree
7932 fold_builtin_1 (tree exp, bool ignore)
7934 tree fndecl = get_callee_fndecl (exp);
7935 tree arglist = TREE_OPERAND (exp, 1);
7936 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7938 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7939 return 0;
7941 switch (DECL_FUNCTION_CODE (fndecl))
7943 case BUILT_IN_CONSTANT_P:
7944 return fold_builtin_constant_p (arglist);
7946 case BUILT_IN_EXPECT:
7947 return fold_builtin_expect (arglist);
7949 case BUILT_IN_CLASSIFY_TYPE:
7950 return fold_builtin_classify_type (arglist);
7952 case BUILT_IN_STRLEN:
7953 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7955 tree len = c_strlen (TREE_VALUE (arglist), 0);
7956 if (len)
7958 /* Convert from the internal "sizetype" type to "size_t". */
7959 if (size_type_node)
7960 len = fold_convert (size_type_node, len);
7961 return len;
7964 break;
7966 case BUILT_IN_FABS:
7967 case BUILT_IN_FABSF:
7968 case BUILT_IN_FABSL:
7969 return fold_builtin_fabs (arglist, type);
7971 case BUILT_IN_ABS:
7972 case BUILT_IN_LABS:
7973 case BUILT_IN_LLABS:
7974 case BUILT_IN_IMAXABS:
7975 return fold_builtin_abs (arglist, type);
7977 case BUILT_IN_CONJ:
7978 case BUILT_IN_CONJF:
7979 case BUILT_IN_CONJL:
7980 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7981 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7982 break;
7984 case BUILT_IN_CREAL:
7985 case BUILT_IN_CREALF:
7986 case BUILT_IN_CREALL:
7987 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7988 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7989 TREE_VALUE (arglist))));
7990 break;
7992 case BUILT_IN_CIMAG:
7993 case BUILT_IN_CIMAGF:
7994 case BUILT_IN_CIMAGL:
7995 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7996 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7997 TREE_VALUE (arglist))));
7998 break;
8000 case BUILT_IN_CABS:
8001 case BUILT_IN_CABSF:
8002 case BUILT_IN_CABSL:
8003 return fold_builtin_cabs (arglist, type);
8005 case BUILT_IN_SQRT:
8006 case BUILT_IN_SQRTF:
8007 case BUILT_IN_SQRTL:
8008 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8010 enum built_in_function fcode;
8011 tree arg = TREE_VALUE (arglist);
8013 /* Optimize sqrt of constant value. */
8014 if (TREE_CODE (arg) == REAL_CST
8015 && ! TREE_CONSTANT_OVERFLOW (arg))
8017 REAL_VALUE_TYPE r, x;
8019 x = TREE_REAL_CST (arg);
8020 if (real_sqrt (&r, TYPE_MODE (type), &x)
8021 || (!flag_trapping_math && !flag_errno_math))
8022 return build_real (type, r);
8025 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
8026 fcode = builtin_mathfn_code (arg);
8027 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8029 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8030 arg = fold (build2 (MULT_EXPR, type,
8031 TREE_VALUE (TREE_OPERAND (arg, 1)),
8032 build_real (type, dconsthalf)));
8033 arglist = build_tree_list (NULL_TREE, arg);
8034 return build_function_call_expr (expfn, arglist);
8037 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
8038 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
8040 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8042 if (powfn)
8044 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8045 tree tree_root;
8046 /* The inner root was either sqrt or cbrt. */
8047 REAL_VALUE_TYPE dconstroot =
8048 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
8050 /* Adjust for the outer root. */
8051 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8052 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8053 tree_root = build_real (type, dconstroot);
8054 arglist = tree_cons (NULL_TREE, arg0,
8055 build_tree_list (NULL_TREE, tree_root));
8056 return build_function_call_expr (powfn, arglist);
8060 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
8061 if (flag_unsafe_math_optimizations
8062 && (fcode == BUILT_IN_POW
8063 || fcode == BUILT_IN_POWF
8064 || fcode == BUILT_IN_POWL))
8066 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8067 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8068 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
8069 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8070 build_real (type, dconsthalf)));
8071 arglist = tree_cons (NULL_TREE, arg0,
8072 build_tree_list (NULL_TREE, narg1));
8073 return build_function_call_expr (powfn, arglist);
8076 break;
8078 case BUILT_IN_CBRT:
8079 case BUILT_IN_CBRTF:
8080 case BUILT_IN_CBRTL:
8081 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8083 tree arg = TREE_VALUE (arglist);
8084 const enum built_in_function fcode = builtin_mathfn_code (arg);
8086 /* Optimize cbrt of constant value. */
8087 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
8088 return arg;
8090 /* Optimize cbrt(expN(x)) -> expN(x/3). */
8091 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8093 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8094 const REAL_VALUE_TYPE third_trunc =
8095 real_value_truncate (TYPE_MODE (type), dconstthird);
8096 arg = fold (build2 (MULT_EXPR, type,
8097 TREE_VALUE (TREE_OPERAND (arg, 1)),
8098 build_real (type, third_trunc)));
8099 arglist = build_tree_list (NULL_TREE, arg);
8100 return build_function_call_expr (expfn, arglist);
8103 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
8104 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8105 x is negative pow will error but cbrt won't. */
8106 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8108 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8110 if (powfn)
8112 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8113 tree tree_root;
8114 REAL_VALUE_TYPE dconstroot = dconstthird;
8116 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8117 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8118 tree_root = build_real (type, dconstroot);
8119 arglist = tree_cons (NULL_TREE, arg0,
8120 build_tree_list (NULL_TREE, tree_root));
8121 return build_function_call_expr (powfn, arglist);
8126 break;
8128 case BUILT_IN_SIN:
8129 case BUILT_IN_SINF:
8130 case BUILT_IN_SINL:
8131 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8133 tree arg = TREE_VALUE (arglist);
8135 /* Optimize sin(0.0) = 0.0. */
8136 if (real_zerop (arg))
8137 return arg;
8139 break;
8141 case BUILT_IN_COS:
8142 case BUILT_IN_COSF:
8143 case BUILT_IN_COSL:
8144 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8146 tree arg = TREE_VALUE (arglist);
8148 /* Optimize cos(0.0) = 1.0. */
8149 if (real_zerop (arg))
8150 return build_real (type, dconst1);
8152 /* Optimize cos(-x) into cos(x). */
8153 if (TREE_CODE (arg) == NEGATE_EXPR)
8155 tree arglist = build_tree_list (NULL_TREE,
8156 TREE_OPERAND (arg, 0));
8157 return build_function_call_expr (fndecl, arglist);
8160 break;
8162 case BUILT_IN_EXP:
8163 case BUILT_IN_EXPF:
8164 case BUILT_IN_EXPL:
8165 return fold_builtin_exponent (exp, &dconste);
8167 case BUILT_IN_EXP2:
8168 case BUILT_IN_EXP2F:
8169 case BUILT_IN_EXP2L:
8170 return fold_builtin_exponent (exp, &dconst2);
8172 case BUILT_IN_EXP10:
8173 case BUILT_IN_EXP10F:
8174 case BUILT_IN_EXP10L:
8175 case BUILT_IN_POW10:
8176 case BUILT_IN_POW10F:
8177 case BUILT_IN_POW10L:
8178 return fold_builtin_exponent (exp, &dconst10);
8180 case BUILT_IN_LOG:
8181 case BUILT_IN_LOGF:
8182 case BUILT_IN_LOGL:
8183 return fold_builtin_logarithm (exp, &dconste);
8185 case BUILT_IN_LOG2:
8186 case BUILT_IN_LOG2F:
8187 case BUILT_IN_LOG2L:
8188 return fold_builtin_logarithm (exp, &dconst2);
8190 case BUILT_IN_LOG10:
8191 case BUILT_IN_LOG10F:
8192 case BUILT_IN_LOG10L:
8193 return fold_builtin_logarithm (exp, &dconst10);
8195 case BUILT_IN_TAN:
8196 case BUILT_IN_TANF:
8197 case BUILT_IN_TANL:
8198 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8200 enum built_in_function fcode;
8201 tree arg = TREE_VALUE (arglist);
8203 /* Optimize tan(0.0) = 0.0. */
8204 if (real_zerop (arg))
8205 return arg;
8207 /* Optimize tan(atan(x)) = x. */
8208 fcode = builtin_mathfn_code (arg);
8209 if (flag_unsafe_math_optimizations
8210 && (fcode == BUILT_IN_ATAN
8211 || fcode == BUILT_IN_ATANF
8212 || fcode == BUILT_IN_ATANL))
8213 return TREE_VALUE (TREE_OPERAND (arg, 1));
8215 break;
8217 case BUILT_IN_ATAN:
8218 case BUILT_IN_ATANF:
8219 case BUILT_IN_ATANL:
8220 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8222 tree arg = TREE_VALUE (arglist);
8224 /* Optimize atan(0.0) = 0.0. */
8225 if (real_zerop (arg))
8226 return arg;
8228 /* Optimize atan(1.0) = pi/4. */
8229 if (real_onep (arg))
8231 REAL_VALUE_TYPE cst;
8233 real_convert (&cst, TYPE_MODE (type), &dconstpi);
8234 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8235 return build_real (type, cst);
8238 break;
8240 case BUILT_IN_POW:
8241 case BUILT_IN_POWF:
8242 case BUILT_IN_POWL:
8243 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8245 enum built_in_function fcode;
8246 tree arg0 = TREE_VALUE (arglist);
8247 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8249 /* Optimize pow(1.0,y) = 1.0. */
8250 if (real_onep (arg0))
8251 return omit_one_operand (type, build_real (type, dconst1), arg1);
8253 if (TREE_CODE (arg1) == REAL_CST
8254 && ! TREE_CONSTANT_OVERFLOW (arg1))
8256 REAL_VALUE_TYPE c;
8257 c = TREE_REAL_CST (arg1);
8259 /* Optimize pow(x,0.0) = 1.0. */
8260 if (REAL_VALUES_EQUAL (c, dconst0))
8261 return omit_one_operand (type, build_real (type, dconst1),
8262 arg0);
8264 /* Optimize pow(x,1.0) = x. */
8265 if (REAL_VALUES_EQUAL (c, dconst1))
8266 return arg0;
8268 /* Optimize pow(x,-1.0) = 1.0/x. */
8269 if (REAL_VALUES_EQUAL (c, dconstm1))
8270 return fold (build2 (RDIV_EXPR, type,
8271 build_real (type, dconst1), arg0));
8273 /* Optimize pow(x,0.5) = sqrt(x). */
8274 if (flag_unsafe_math_optimizations
8275 && REAL_VALUES_EQUAL (c, dconsthalf))
8277 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8279 if (sqrtfn != NULL_TREE)
8281 tree arglist = build_tree_list (NULL_TREE, arg0);
8282 return build_function_call_expr (sqrtfn, arglist);
8286 /* Attempt to evaluate pow at compile-time. */
8287 if (TREE_CODE (arg0) == REAL_CST
8288 && ! TREE_CONSTANT_OVERFLOW (arg0))
8290 REAL_VALUE_TYPE cint;
8291 HOST_WIDE_INT n;
8293 n = real_to_integer (&c);
8294 real_from_integer (&cint, VOIDmode, n,
8295 n < 0 ? -1 : 0, 0);
8296 if (real_identical (&c, &cint))
8298 REAL_VALUE_TYPE x;
8299 bool inexact;
8301 x = TREE_REAL_CST (arg0);
8302 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8303 if (flag_unsafe_math_optimizations || !inexact)
8304 return build_real (type, x);
8309 /* Optimize pow(expN(x),y) = expN(x*y). */
8310 fcode = builtin_mathfn_code (arg0);
8311 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8313 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8314 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8315 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8316 arglist = build_tree_list (NULL_TREE, arg);
8317 return build_function_call_expr (expfn, arglist);
8320 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8321 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8323 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8324 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8325 build_real (type, dconsthalf)));
8327 arglist = tree_cons (NULL_TREE, narg0,
8328 build_tree_list (NULL_TREE, narg1));
8329 return build_function_call_expr (fndecl, arglist);
8332 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8333 if (flag_unsafe_math_optimizations
8334 && (fcode == BUILT_IN_POW
8335 || fcode == BUILT_IN_POWF
8336 || fcode == BUILT_IN_POWL))
8338 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8339 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8340 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8341 arglist = tree_cons (NULL_TREE, arg00,
8342 build_tree_list (NULL_TREE, narg1));
8343 return build_function_call_expr (fndecl, arglist);
8346 break;
8348 case BUILT_IN_INF:
8349 case BUILT_IN_INFF:
8350 case BUILT_IN_INFL:
8351 return fold_builtin_inf (type, true);
8353 case BUILT_IN_HUGE_VAL:
8354 case BUILT_IN_HUGE_VALF:
8355 case BUILT_IN_HUGE_VALL:
8356 return fold_builtin_inf (type, false);
8358 case BUILT_IN_NAN:
8359 case BUILT_IN_NANF:
8360 case BUILT_IN_NANL:
8361 return fold_builtin_nan (arglist, type, true);
8363 case BUILT_IN_NANS:
8364 case BUILT_IN_NANSF:
8365 case BUILT_IN_NANSL:
8366 return fold_builtin_nan (arglist, type, false);
8368 case BUILT_IN_FLOOR:
8369 case BUILT_IN_FLOORF:
8370 case BUILT_IN_FLOORL:
8371 return fold_builtin_floor (exp);
8373 case BUILT_IN_CEIL:
8374 case BUILT_IN_CEILF:
8375 case BUILT_IN_CEILL:
8376 return fold_builtin_ceil (exp);
8378 case BUILT_IN_TRUNC:
8379 case BUILT_IN_TRUNCF:
8380 case BUILT_IN_TRUNCL:
8381 return fold_builtin_trunc (exp);
8383 case BUILT_IN_ROUND:
8384 case BUILT_IN_ROUNDF:
8385 case BUILT_IN_ROUNDL:
8386 return fold_builtin_round (exp);
8388 case BUILT_IN_NEARBYINT:
8389 case BUILT_IN_NEARBYINTF:
8390 case BUILT_IN_NEARBYINTL:
8391 case BUILT_IN_RINT:
8392 case BUILT_IN_RINTF:
8393 case BUILT_IN_RINTL:
8394 return fold_trunc_transparent_mathfn (exp);
8396 case BUILT_IN_LROUND:
8397 case BUILT_IN_LROUNDF:
8398 case BUILT_IN_LROUNDL:
8399 case BUILT_IN_LLROUND:
8400 case BUILT_IN_LLROUNDF:
8401 case BUILT_IN_LLROUNDL:
8402 return fold_builtin_lround (exp);
8404 case BUILT_IN_LRINT:
8405 case BUILT_IN_LRINTF:
8406 case BUILT_IN_LRINTL:
8407 case BUILT_IN_LLRINT:
8408 case BUILT_IN_LLRINTF:
8409 case BUILT_IN_LLRINTL:
8410 return fold_fixed_mathfn (exp);
8412 case BUILT_IN_FFS:
8413 case BUILT_IN_FFSL:
8414 case BUILT_IN_FFSLL:
8415 case BUILT_IN_CLZ:
8416 case BUILT_IN_CLZL:
8417 case BUILT_IN_CLZLL:
8418 case BUILT_IN_CTZ:
8419 case BUILT_IN_CTZL:
8420 case BUILT_IN_CTZLL:
8421 case BUILT_IN_POPCOUNT:
8422 case BUILT_IN_POPCOUNTL:
8423 case BUILT_IN_POPCOUNTLL:
8424 case BUILT_IN_PARITY:
8425 case BUILT_IN_PARITYL:
8426 case BUILT_IN_PARITYLL:
8427 return fold_builtin_bitop (exp);
8429 case BUILT_IN_MEMCPY:
8430 return fold_builtin_memcpy (exp);
8432 case BUILT_IN_MEMPCPY:
8433 return fold_builtin_mempcpy (exp);
8435 case BUILT_IN_MEMMOVE:
8436 return fold_builtin_memmove (exp);
8438 case BUILT_IN_STRCPY:
8439 return fold_builtin_strcpy (exp, NULL_TREE);
8441 case BUILT_IN_STRNCPY:
8442 return fold_builtin_strncpy (exp, NULL_TREE);
8444 case BUILT_IN_INDEX:
8445 case BUILT_IN_STRCHR:
8446 return fold_builtin_strchr (exp, false);
8448 case BUILT_IN_RINDEX:
8449 case BUILT_IN_STRRCHR:
8450 return fold_builtin_strchr (exp, true);
8452 case BUILT_IN_MEMCMP:
8453 return fold_builtin_memcmp (exp);
8455 case BUILT_IN_STRCMP:
8456 return fold_builtin_strcmp (exp);
8458 case BUILT_IN_STRNCMP:
8459 return fold_builtin_strncmp (exp);
8461 case BUILT_IN_SIGNBIT:
8462 case BUILT_IN_SIGNBITF:
8463 case BUILT_IN_SIGNBITL:
8464 return fold_builtin_signbit (exp);
8466 case BUILT_IN_ISASCII:
8467 return fold_builtin_isascii (arglist);
8469 case BUILT_IN_TOASCII:
8470 return fold_builtin_toascii (arglist);
8472 case BUILT_IN_ISDIGIT:
8473 return fold_builtin_isdigit (arglist);
8475 case BUILT_IN_COPYSIGN:
8476 case BUILT_IN_COPYSIGNF:
8477 case BUILT_IN_COPYSIGNL:
8478 return fold_builtin_copysign (arglist, type);
8480 case BUILT_IN_FINITE:
8481 case BUILT_IN_FINITEF:
8482 case BUILT_IN_FINITEL:
8483 return fold_builtin_classify (exp, BUILT_IN_FINITE);
8485 case BUILT_IN_ISINF:
8486 case BUILT_IN_ISINFF:
8487 case BUILT_IN_ISINFL:
8488 return fold_builtin_classify (exp, BUILT_IN_ISINF);
8490 case BUILT_IN_ISNAN:
8491 case BUILT_IN_ISNANF:
8492 case BUILT_IN_ISNANL:
8493 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8495 case BUILT_IN_ISGREATER:
8496 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8497 case BUILT_IN_ISGREATEREQUAL:
8498 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8499 case BUILT_IN_ISLESS:
8500 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8501 case BUILT_IN_ISLESSEQUAL:
8502 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8503 case BUILT_IN_ISLESSGREATER:
8504 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8505 case BUILT_IN_ISUNORDERED:
8506 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8508 case BUILT_IN_FPUTS:
8509 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8511 case BUILT_IN_FPUTS_UNLOCKED:
8512 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8514 default:
8515 break;
8518 return 0;
8521 /* A wrapper function for builtin folding that prevents warnings for
8522 "statement without effect" and the like, caused by removing the
8523 call node earlier than the warning is generated. */
8525 tree
8526 fold_builtin (tree exp, bool ignore)
8528 exp = fold_builtin_1 (exp, ignore);
8529 if (exp)
8531 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8532 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8533 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8534 TREE_NO_WARNING (exp) = 1;
8536 return exp;
8539 /* Conveniently construct a function call expression. */
8541 tree
8542 build_function_call_expr (tree fn, tree arglist)
8544 tree call_expr;
8546 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8547 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8548 call_expr, arglist, NULL_TREE);
8549 return fold (call_expr);
8552 /* This function validates the types of a function call argument list
8553 represented as a tree chain of parameters against a specified list
8554 of tree_codes. If the last specifier is a 0, that represents an
8555 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8557 static int
8558 validate_arglist (tree arglist, ...)
8560 enum tree_code code;
8561 int res = 0;
8562 va_list ap;
8564 va_start (ap, arglist);
8568 code = va_arg (ap, enum tree_code);
8569 switch (code)
8571 case 0:
8572 /* This signifies an ellipses, any further arguments are all ok. */
8573 res = 1;
8574 goto end;
8575 case VOID_TYPE:
8576 /* This signifies an endlink, if no arguments remain, return
8577 true, otherwise return false. */
8578 res = arglist == 0;
8579 goto end;
8580 default:
8581 /* If no parameters remain or the parameter's code does not
8582 match the specified code, return false. Otherwise continue
8583 checking any remaining arguments. */
8584 if (arglist == 0
8585 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8586 goto end;
8587 break;
8589 arglist = TREE_CHAIN (arglist);
8591 while (1);
8593 /* We need gotos here since we can only have one VA_CLOSE in a
8594 function. */
8595 end: ;
8596 va_end (ap);
8598 return res;
8601 /* Default target-specific builtin expander that does nothing. */
8604 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8605 rtx target ATTRIBUTE_UNUSED,
8606 rtx subtarget ATTRIBUTE_UNUSED,
8607 enum machine_mode mode ATTRIBUTE_UNUSED,
8608 int ignore ATTRIBUTE_UNUSED)
8610 return NULL_RTX;
8613 /* Returns true is EXP represents data that would potentially reside
8614 in a readonly section. */
8616 static bool
8617 readonly_data_expr (tree exp)
8619 STRIP_NOPS (exp);
8621 if (TREE_CODE (exp) != ADDR_EXPR)
8622 return false;
8624 exp = get_base_address (TREE_OPERAND (exp, 0));
8625 if (!exp)
8626 return false;
8628 /* Make sure we call decl_readonly_section only for trees it
8629 can handle (since it returns true for everything it doesn't
8630 understand). */
8631 if (TREE_CODE (exp) == STRING_CST
8632 || TREE_CODE (exp) == CONSTRUCTOR
8633 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8634 return decl_readonly_section (exp, 0);
8635 else
8636 return false;
8639 /* Front-end to the simplify_builtin_XXX routines.
8641 EXP is a call to a builtin function. If possible try to simplify
8642 that into a constant, expression or call to a more efficient
8643 builtin function.
8645 If IGNORE is nonzero, then the result of this builtin function
8646 call is ignored.
8648 If simplification is possible, return the simplified tree, otherwise
8649 return NULL_TREE. */
8651 tree
8652 simplify_builtin (tree exp, int ignore)
8654 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8655 tree arglist = TREE_OPERAND (exp, 1);
8656 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8657 tree val;
8659 switch (fcode)
8661 case BUILT_IN_FPUTS:
8662 val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8663 break;
8664 case BUILT_IN_FPUTS_UNLOCKED:
8665 val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8666 break;
8667 case BUILT_IN_STRSTR:
8668 val = simplify_builtin_strstr (arglist);
8669 break;
8670 case BUILT_IN_STRCAT:
8671 val = simplify_builtin_strcat (arglist);
8672 break;
8673 case BUILT_IN_STRNCAT:
8674 val = simplify_builtin_strncat (arglist);
8675 break;
8676 case BUILT_IN_STRSPN:
8677 val = simplify_builtin_strspn (arglist);
8678 break;
8679 case BUILT_IN_STRCSPN:
8680 val = simplify_builtin_strcspn (arglist);
8681 break;
8682 case BUILT_IN_STRCHR:
8683 case BUILT_IN_INDEX:
8684 val = simplify_builtin_strchr (arglist);
8685 break;
8686 case BUILT_IN_STRRCHR:
8687 case BUILT_IN_RINDEX:
8688 val = simplify_builtin_strrchr (arglist);
8689 break;
8690 case BUILT_IN_STRCPY:
8691 val = fold_builtin_strcpy (exp, NULL_TREE);
8692 break;
8693 case BUILT_IN_STRNCPY:
8694 val = fold_builtin_strncpy (exp, NULL_TREE);
8695 break;
8696 case BUILT_IN_STRCMP:
8697 val = simplify_builtin_strcmp (arglist);
8698 break;
8699 case BUILT_IN_STRNCMP:
8700 val = simplify_builtin_strncmp (arglist);
8701 break;
8702 case BUILT_IN_STRPBRK:
8703 val = simplify_builtin_strpbrk (arglist);
8704 break;
8705 case BUILT_IN_BCMP:
8706 case BUILT_IN_MEMCMP:
8707 val = simplify_builtin_memcmp (arglist);
8708 break;
8709 case BUILT_IN_VA_START:
8710 simplify_builtin_va_start (arglist);
8711 val = NULL_TREE;
8712 break;
8713 case BUILT_IN_SPRINTF:
8714 val = simplify_builtin_sprintf (arglist, ignore);
8715 break;
8716 case BUILT_IN_CONSTANT_P:
8717 val = fold_builtin_constant_p (arglist);
8718 /* Gimplification will pull the CALL_EXPR for the builtin out of
8719 an if condition. When not optimizing, we'll not CSE it back.
8720 To avoid link error types of regressions, return false now. */
8721 if (!val && !optimize)
8722 val = integer_zero_node;
8723 break;
8724 default:
8725 val = NULL_TREE;
8726 break;
8729 if (val)
8730 val = fold_convert (TREE_TYPE (exp), val);
8731 return val;
8734 /* Simplify a call to the strstr builtin.
8736 Return 0 if no simplification was possible, otherwise return the
8737 simplified form of the call as a tree.
8739 The simplified form may be a constant or other expression which
8740 computes the same value, but in a more efficient manner (including
8741 calls to other builtin functions).
8743 The call may contain arguments which need to be evaluated, but
8744 which are not useful to determine the result of the call. In
8745 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8746 COMPOUND_EXPR will be an argument which must be evaluated.
8747 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8748 COMPOUND_EXPR in the chain will contain the tree for the simplified
8749 form of the builtin function call. */
8751 static tree
8752 simplify_builtin_strstr (tree arglist)
8754 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8755 return 0;
8756 else
8758 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8759 tree fn;
8760 const char *p1, *p2;
8762 p2 = c_getstr (s2);
8763 if (p2 == NULL)
8764 return 0;
8766 p1 = c_getstr (s1);
8767 if (p1 != NULL)
8769 const char *r = strstr (p1, p2);
8771 if (r == NULL)
8772 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8774 /* Return an offset into the constant string argument. */
8775 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8776 s1, fold_convert (TREE_TYPE (s1),
8777 ssize_int (r - p1))));
8780 if (p2[0] == '\0')
8781 return s1;
8783 if (p2[1] != '\0')
8784 return 0;
8786 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8787 if (!fn)
8788 return 0;
8790 /* New argument list transforming strstr(s1, s2) to
8791 strchr(s1, s2[0]). */
8792 arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8793 arglist = tree_cons (NULL_TREE, s1, arglist);
8794 return build_function_call_expr (fn, arglist);
8798 /* Simplify a call to the strstr builtin.
8800 Return 0 if no simplification was possible, otherwise return the
8801 simplified form of the call as a tree.
8803 The simplified form may be a constant or other expression which
8804 computes the same value, but in a more efficient manner (including
8805 calls to other builtin functions).
8807 The call may contain arguments which need to be evaluated, but
8808 which are not useful to determine the result of the call. In
8809 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8810 COMPOUND_EXPR will be an argument which must be evaluated.
8811 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8812 COMPOUND_EXPR in the chain will contain the tree for the simplified
8813 form of the builtin function call. */
8815 static tree
8816 simplify_builtin_strchr (tree arglist)
8818 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8819 return 0;
8820 else
8822 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8823 const char *p1;
8825 if (TREE_CODE (s2) != INTEGER_CST)
8826 return 0;
8828 p1 = c_getstr (s1);
8829 if (p1 != NULL)
8831 char c;
8832 const char *r;
8834 if (target_char_cast (s2, &c))
8835 return 0;
8837 r = strchr (p1, c);
8839 if (r == NULL)
8840 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8842 /* Return an offset into the constant string argument. */
8843 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8844 s1, fold_convert (TREE_TYPE (s1),
8845 ssize_int (r - p1))));
8848 /* FIXME: Should use here strchrM optab so that ports can optimize
8849 this. */
8850 return 0;
8854 /* Simplify a call to the strrchr builtin.
8856 Return 0 if no simplification was possible, otherwise return the
8857 simplified form of the call as a tree.
8859 The simplified form may be a constant or other expression which
8860 computes the same value, but in a more efficient manner (including
8861 calls to other builtin functions).
8863 The call may contain arguments which need to be evaluated, but
8864 which are not useful to determine the result of the call. In
8865 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8866 COMPOUND_EXPR will be an argument which must be evaluated.
8867 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8868 COMPOUND_EXPR in the chain will contain the tree for the simplified
8869 form of the builtin function call. */
8871 static tree
8872 simplify_builtin_strrchr (tree arglist)
8874 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8875 return 0;
8876 else
8878 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8879 tree fn;
8880 const char *p1;
8882 if (TREE_CODE (s2) != INTEGER_CST)
8883 return 0;
8885 p1 = c_getstr (s1);
8886 if (p1 != NULL)
8888 char c;
8889 const char *r;
8891 if (target_char_cast (s2, &c))
8892 return 0;
8894 r = strrchr (p1, c);
8896 if (r == NULL)
8897 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8899 /* Return an offset into the constant string argument. */
8900 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8901 s1, fold_convert (TREE_TYPE (s1),
8902 ssize_int (r - p1))));
8905 if (! integer_zerop (s2))
8906 return 0;
8908 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8909 if (!fn)
8910 return 0;
8912 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8913 return build_function_call_expr (fn, arglist);
8917 /* Simplify a call to the strpbrk builtin.
8919 Return 0 if no simplification was possible, otherwise return the
8920 simplified form of the call as a tree.
8922 The simplified form may be a constant or other expression which
8923 computes the same value, but in a more efficient manner (including
8924 calls to other builtin functions).
8926 The call may contain arguments which need to be evaluated, but
8927 which are not useful to determine the result of the call. In
8928 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8929 COMPOUND_EXPR will be an argument which must be evaluated.
8930 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8931 COMPOUND_EXPR in the chain will contain the tree for the simplified
8932 form of the builtin function call. */
8934 static tree
8935 simplify_builtin_strpbrk (tree arglist)
8937 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8938 return 0;
8939 else
8941 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8942 tree fn;
8943 const char *p1, *p2;
8945 p2 = c_getstr (s2);
8946 if (p2 == NULL)
8947 return 0;
8949 p1 = c_getstr (s1);
8950 if (p1 != NULL)
8952 const char *r = strpbrk (p1, p2);
8954 if (r == NULL)
8955 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8957 /* Return an offset into the constant string argument. */
8958 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8959 s1, fold_convert (TREE_TYPE (s1),
8960 ssize_int (r - p1))));
8963 if (p2[0] == '\0')
8964 /* strpbrk(x, "") == NULL.
8965 Evaluate and ignore s1 in case it had side-effects. */
8966 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8968 if (p2[1] != '\0')
8969 return 0; /* Really call strpbrk. */
8971 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8972 if (!fn)
8973 return 0;
8975 /* New argument list transforming strpbrk(s1, s2) to
8976 strchr(s1, s2[0]). */
8977 arglist =
8978 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8979 arglist = tree_cons (NULL_TREE, s1, arglist);
8980 return build_function_call_expr (fn, arglist);
8984 /* Simplify a call to the memcmp builtin.
8986 Return 0 if no simplification was possible, otherwise return the
8987 simplified form of the call as a tree.
8989 The simplified form may be a constant or other expression which
8990 computes the same value, but in a more efficient manner (including
8991 calls to other builtin functions).
8993 The call may contain arguments which need to be evaluated, but
8994 which are not useful to determine the result of the call. In
8995 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8996 COMPOUND_EXPR will be an argument which must be evaluated.
8997 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8998 COMPOUND_EXPR in the chain will contain the tree for the simplified
8999 form of the builtin function call. */
9001 static tree
9002 simplify_builtin_memcmp (tree arglist)
9004 tree arg1, arg2, len;
9005 const char *p1, *p2;
9007 if (!validate_arglist (arglist,
9008 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9009 return 0;
9011 arg1 = TREE_VALUE (arglist);
9012 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9013 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9015 /* If the len parameter is zero, return zero. */
9016 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
9017 /* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
9018 return omit_two_operands (integer_type_node, integer_zero_node,
9019 arg1, arg2);
9021 p1 = c_getstr (arg1);
9022 p2 = c_getstr (arg2);
9024 /* If all arguments are constant, and the value of len is not greater
9025 than the lengths of arg1 and arg2, evaluate at compile-time. */
9026 if (host_integerp (len, 1) && p1 && p2
9027 && compare_tree_int (len, strlen (p1) + 1) <= 0
9028 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9030 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9032 return (r < 0
9033 ? integer_minus_one_node
9034 : (r > 0 ? integer_one_node : integer_zero_node));
9037 /* If len parameter is one, return an expression corresponding to
9038 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9039 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9041 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9042 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9043 tree ind1 =
9044 fold (build1 (CONVERT_EXPR, integer_type_node,
9045 build1 (INDIRECT_REF, cst_uchar_node,
9046 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9047 tree ind2 =
9048 fold (build1 (CONVERT_EXPR, integer_type_node,
9049 build1 (INDIRECT_REF, cst_uchar_node,
9050 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9051 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9054 return 0;
9057 /* Simplify a call to the strcmp builtin.
9059 Return 0 if no simplification was possible, otherwise return the
9060 simplified form of the call as a tree.
9062 The simplified form may be a constant or other expression which
9063 computes the same value, but in a more efficient manner (including
9064 calls to other builtin functions).
9066 The call may contain arguments which need to be evaluated, but
9067 which are not useful to determine the result of the call. In
9068 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9069 COMPOUND_EXPR will be an argument which must be evaluated.
9070 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9071 COMPOUND_EXPR in the chain will contain the tree for the simplified
9072 form of the builtin function call. */
9074 static tree
9075 simplify_builtin_strcmp (tree arglist)
9077 tree arg1, arg2;
9078 const char *p1, *p2;
9080 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9081 return 0;
9083 arg1 = TREE_VALUE (arglist);
9084 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9086 /* If both arguments are equal (and not volatile), return zero. */
9087 if (operand_equal_p (arg1, arg2, 0))
9088 return integer_zero_node;
9090 p1 = c_getstr (arg1);
9091 p2 = c_getstr (arg2);
9093 if (p1 && p2)
9095 const int i = strcmp (p1, p2);
9096 return (i < 0
9097 ? integer_minus_one_node
9098 : (i > 0 ? integer_one_node : integer_zero_node));
9101 /* If either arg is "", return an expression corresponding to
9102 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9103 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9105 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9106 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9107 tree ind1 =
9108 fold (build1 (CONVERT_EXPR, integer_type_node,
9109 build1 (INDIRECT_REF, cst_uchar_node,
9110 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9111 tree ind2 =
9112 fold (build1 (CONVERT_EXPR, integer_type_node,
9113 build1 (INDIRECT_REF, cst_uchar_node,
9114 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9115 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9118 return 0;
9121 /* Simplify a call to the strncmp builtin.
9123 Return 0 if no simplification was possible, otherwise return the
9124 simplified form of the call as a tree.
9126 The simplified form may be a constant or other expression which
9127 computes the same value, but in a more efficient manner (including
9128 calls to other builtin functions).
9130 The call may contain arguments which need to be evaluated, but
9131 which are not useful to determine the result of the call. In
9132 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9133 COMPOUND_EXPR will be an argument which must be evaluated.
9134 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9135 COMPOUND_EXPR in the chain will contain the tree for the simplified
9136 form of the builtin function call. */
9138 static tree
9139 simplify_builtin_strncmp (tree arglist)
9141 tree arg1, arg2, arg3;
9142 const char *p1, *p2;
9144 if (!validate_arglist (arglist,
9145 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9146 return 0;
9148 arg1 = TREE_VALUE (arglist);
9149 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9150 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9152 /* If the len parameter is zero, return zero. */
9153 if (integer_zerop (arg3))
9154 /* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
9155 return omit_two_operands (integer_type_node, integer_zero_node,
9156 arg1, arg2);
9158 /* If arg1 and arg2 are equal (and not volatile), return zero. */
9159 if (operand_equal_p (arg1, arg2, 0))
9160 /* Evaluate and ignore arg3 in case it has side-effects. */
9161 return omit_one_operand (integer_type_node, integer_zero_node, arg3);
9163 p1 = c_getstr (arg1);
9164 p2 = c_getstr (arg2);
9166 /* If all arguments are constant, evaluate at compile-time. */
9167 if (host_integerp (arg3, 1) && p1 && p2)
9169 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
9170 return (r < 0
9171 ? integer_minus_one_node
9172 : (r > 0 ? integer_one_node : integer_zero_node));
9175 /* If len == 1 or (either string parameter is "" and (len >= 1)),
9176 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
9177 if (host_integerp (arg3, 1)
9178 && (tree_low_cst (arg3, 1) == 1
9179 || (tree_low_cst (arg3, 1) > 1
9180 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
9182 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9183 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9184 tree ind1 =
9185 fold (build1 (CONVERT_EXPR, integer_type_node,
9186 build1 (INDIRECT_REF, cst_uchar_node,
9187 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9188 tree ind2 =
9189 fold (build1 (CONVERT_EXPR, integer_type_node,
9190 build1 (INDIRECT_REF, cst_uchar_node,
9191 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9192 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9195 return 0;
9198 /* Simplify a call to the strcat builtin.
9200 Return 0 if no simplification was possible, otherwise return the
9201 simplified form of the call as a tree.
9203 The simplified form may be a constant or other expression which
9204 computes the same value, but in a more efficient manner (including
9205 calls to other builtin functions).
9207 The call may contain arguments which need to be evaluated, but
9208 which are not useful to determine the result of the call. In
9209 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9210 COMPOUND_EXPR will be an argument which must be evaluated.
9211 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9212 COMPOUND_EXPR in the chain will contain the tree for the simplified
9213 form of the builtin function call. */
9215 static tree
9216 simplify_builtin_strcat (tree arglist)
9218 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9219 return 0;
9220 else
9222 tree dst = TREE_VALUE (arglist),
9223 src = TREE_VALUE (TREE_CHAIN (arglist));
9224 const char *p = c_getstr (src);
9226 /* If the string length is zero, return the dst parameter. */
9227 if (p && *p == '\0')
9228 return dst;
9230 return 0;
9234 /* Simplify a call to the strncat builtin.
9236 Return 0 if no simplification was possible, otherwise return the
9237 simplified form of the call as a tree.
9239 The simplified form may be a constant or other expression which
9240 computes the same value, but in a more efficient manner (including
9241 calls to other builtin functions).
9243 The call may contain arguments which need to be evaluated, but
9244 which are not useful to determine the result of the call. In
9245 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9246 COMPOUND_EXPR will be an argument which must be evaluated.
9247 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9248 COMPOUND_EXPR in the chain will contain the tree for the simplified
9249 form of the builtin function call. */
9251 static tree
9252 simplify_builtin_strncat (tree arglist)
9254 if (!validate_arglist (arglist,
9255 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9256 return 0;
9257 else
9259 tree dst = TREE_VALUE (arglist);
9260 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9261 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9262 const char *p = c_getstr (src);
9264 /* If the requested length is zero, or the src parameter string
9265 length is zero, return the dst parameter. */
9266 if (integer_zerop (len) || (p && *p == '\0'))
9267 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9269 /* If the requested len is greater than or equal to the string
9270 length, call strcat. */
9271 if (TREE_CODE (len) == INTEGER_CST && p
9272 && compare_tree_int (len, strlen (p)) >= 0)
9274 tree newarglist
9275 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9276 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9278 /* If the replacement _DECL isn't initialized, don't do the
9279 transformation. */
9280 if (!fn)
9281 return 0;
9283 return build_function_call_expr (fn, newarglist);
9285 return 0;
9289 /* Simplify a call to the strspn builtin.
9291 Return 0 if no simplification was possible, otherwise return the
9292 simplified form of the call as a tree.
9294 The simplified form may be a constant or other expression which
9295 computes the same value, but in a more efficient manner (including
9296 calls to other builtin functions).
9298 The call may contain arguments which need to be evaluated, but
9299 which are not useful to determine the result of the call. In
9300 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9301 COMPOUND_EXPR will be an argument which must be evaluated.
9302 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9303 COMPOUND_EXPR in the chain will contain the tree for the simplified
9304 form of the builtin function call. */
9306 static tree
9307 simplify_builtin_strspn (tree arglist)
9309 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9310 return 0;
9311 else
9313 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9314 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9316 /* If both arguments are constants, evaluate at compile-time. */
9317 if (p1 && p2)
9319 const size_t r = strspn (p1, p2);
9320 return size_int (r);
9323 /* If either argument is "", return 0. */
9324 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9325 /* Evaluate and ignore both arguments in case either one has
9326 side-effects. */
9327 return omit_two_operands (integer_type_node, integer_zero_node,
9328 s1, s2);
9329 return 0;
9333 /* Simplify a call to the strcspn builtin.
9335 Return 0 if no simplification was possible, otherwise return the
9336 simplified form of the call as a tree.
9338 The simplified form may be a constant or other expression which
9339 computes the same value, but in a more efficient manner (including
9340 calls to other builtin functions).
9342 The call may contain arguments which need to be evaluated, but
9343 which are not useful to determine the result of the call. In
9344 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9345 COMPOUND_EXPR will be an argument which must be evaluated.
9346 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9347 COMPOUND_EXPR in the chain will contain the tree for the simplified
9348 form of the builtin function call. */
9350 static tree
9351 simplify_builtin_strcspn (tree arglist)
9353 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9354 return 0;
9355 else
9357 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9358 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9360 /* If both arguments are constants, evaluate at compile-time. */
9361 if (p1 && p2)
9363 const size_t r = strcspn (p1, p2);
9364 return size_int (r);
9367 /* If the first argument is "", return 0. */
9368 if (p1 && *p1 == '\0')
9370 /* Evaluate and ignore argument s2 in case it has
9371 side-effects. */
9372 return omit_one_operand (integer_type_node,
9373 integer_zero_node, s2);
9376 /* If the second argument is "", return __builtin_strlen(s1). */
9377 if (p2 && *p2 == '\0')
9379 tree newarglist = build_tree_list (NULL_TREE, s1),
9380 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9382 /* If the replacement _DECL isn't initialized, don't do the
9383 transformation. */
9384 if (!fn)
9385 return 0;
9387 return build_function_call_expr (fn, newarglist);
9389 return 0;
9393 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9394 by the builtin will be ignored. UNLOCKED is true is true if this
9395 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9396 the known length of the string. Return NULL_TREE if no simplification
9397 was possible. */
9399 tree
9400 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9402 tree fn;
9403 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9404 : implicit_built_in_decls[BUILT_IN_FPUTC];
9405 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9406 : implicit_built_in_decls[BUILT_IN_FWRITE];
9408 /* If the return value is used, or the replacement _DECL isn't
9409 initialized, don't do the transformation. */
9410 if (!ignore || !fn_fputc || !fn_fwrite)
9411 return 0;
9413 /* Verify the arguments in the original call. */
9414 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9415 return 0;
9417 if (! len)
9418 len = c_strlen (TREE_VALUE (arglist), 0);
9420 /* Get the length of the string passed to fputs. If the length
9421 can't be determined, punt. */
9422 if (!len
9423 || TREE_CODE (len) != INTEGER_CST)
9424 return 0;
9426 switch (compare_tree_int (len, 1))
9428 case -1: /* length is 0, delete the call entirely . */
9429 return omit_one_operand (integer_type_node, integer_zero_node,
9430 TREE_VALUE (TREE_CHAIN (arglist)));
9432 case 0: /* length is 1, call fputc. */
9434 const char *p = c_getstr (TREE_VALUE (arglist));
9436 if (p != NULL)
9438 /* New argument list transforming fputs(string, stream) to
9439 fputc(string[0], stream). */
9440 arglist =
9441 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9442 arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9443 fn = fn_fputc;
9444 break;
9447 /* FALLTHROUGH */
9448 case 1: /* length is greater than 1, call fwrite. */
9450 tree string_arg;
9452 /* If optimizing for size keep fputs. */
9453 if (optimize_size)
9454 return 0;
9455 string_arg = TREE_VALUE (arglist);
9456 /* New argument list transforming fputs(string, stream) to
9457 fwrite(string, 1, len, stream). */
9458 arglist = build_tree_list (NULL_TREE,
9459 TREE_VALUE (TREE_CHAIN (arglist)));
9460 arglist = tree_cons (NULL_TREE, len, arglist);
9461 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9462 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9463 fn = fn_fwrite;
9464 break;
9466 default:
9467 abort ();
9470 /* These optimizations are only performed when the result is ignored,
9471 hence there's no need to cast the result to integer_type_node. */
9472 return build_function_call_expr (fn, arglist);
9475 static void
9476 simplify_builtin_va_start (tree arglist)
9478 tree chain = TREE_CHAIN (arglist);
9480 if (TREE_CHAIN (chain))
9481 error ("too many arguments to function `va_start'");
9483 simplify_builtin_next_arg (chain);
9486 static void
9487 simplify_builtin_next_arg (tree arglist)
9489 tree fntype = TREE_TYPE (current_function_decl);
9491 if (TYPE_ARG_TYPES (fntype) == 0
9492 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9493 == void_type_node))
9494 error ("`va_start' used in function with fixed args");
9495 else if (arglist)
9497 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9498 tree arg = TREE_VALUE (arglist);
9500 /* Strip off all nops for the sake of the comparison. This
9501 is not quite the same as STRIP_NOPS. It does more.
9502 We must also strip off INDIRECT_EXPR for C++ reference
9503 parameters. */
9504 while (TREE_CODE (arg) == NOP_EXPR
9505 || TREE_CODE (arg) == CONVERT_EXPR
9506 || TREE_CODE (arg) == NON_LVALUE_EXPR
9507 || TREE_CODE (arg) == INDIRECT_REF)
9508 arg = TREE_OPERAND (arg, 0);
9509 if (arg != last_parm)
9510 warning ("second parameter of `va_start' not last named argument");
9511 TREE_VALUE (arglist) = arg;
9513 else
9514 /* Evidently an out of date version of <stdarg.h>; can't validate
9515 va_start's second argument, but can still work as intended. */
9516 warning ("`__builtin_next_arg' called without an argument");
9520 /* Simplify a call to the sprintf builtin.
9522 Return 0 if no simplification was possible, otherwise return the
9523 simplified form of the call as a tree. If IGNORED is true, it means that
9524 the caller does not use the returned value of the function. */
9526 static tree
9527 simplify_builtin_sprintf (tree arglist, int ignored)
9529 tree call, retval, dest, fmt;
9530 const char *fmt_str = NULL;
9532 /* Verify the required arguments in the original call. We deal with two
9533 types of sprintf() calls: 'sprintf (str, fmt)' and
9534 'sprintf (dest, "%s", orig)'. */
9535 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9536 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9537 VOID_TYPE))
9538 return NULL_TREE;
9540 /* Get the destination string and the format specifier. */
9541 dest = TREE_VALUE (arglist);
9542 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9544 /* Check whether the format is a literal string constant. */
9545 fmt_str = c_getstr (fmt);
9546 if (fmt_str == NULL)
9547 return NULL_TREE;
9549 call = NULL_TREE;
9550 retval = NULL_TREE;
9552 /* If the format doesn't contain % args or %%, use strcpy. */
9553 if (strchr (fmt_str, '%') == NULL)
9555 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9557 if (!fn)
9558 return NULL_TREE;
9560 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9561 'format' is known to contain no % formats. */
9562 arglist = build_tree_list (NULL_TREE, fmt);
9563 arglist = tree_cons (NULL_TREE, dest, arglist);
9564 call = build_function_call_expr (fn, arglist);
9565 if (!ignored)
9566 retval = build_int_2 (strlen (fmt_str), 0);
9569 /* If the format is "%s", use strcpy if the result isn't used. */
9570 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9572 tree fn, orig;
9573 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9575 if (!fn)
9576 return NULL_TREE;
9578 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9579 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9580 arglist = build_tree_list (NULL_TREE, orig);
9581 arglist = tree_cons (NULL_TREE, dest, arglist);
9582 if (!ignored)
9584 retval = c_strlen (orig, 1);
9585 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9586 return NULL_TREE;
9588 call = build_function_call_expr (fn, arglist);
9591 if (call && retval)
9593 retval = convert
9594 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9595 retval);
9596 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9598 else
9599 return call;