* gnu/regexp/CharIndexedReader.java: Removed.
[official-gcc.git] / gcc / builtins.c
blobb0375c377aa70bc87d05ad508a8f17127a53f2f7
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 "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53 #endif
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
60 const char *const built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
64 #undef DEF_BUILTIN
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree);
79 static tree build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx result_vector (int, rtx);
84 #endif
85 static rtx expand_builtin_setjmp (tree, rtx);
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_args_info (tree);
99 static rtx expand_builtin_next_arg (tree);
100 static rtx expand_builtin_va_start (tree);
101 static rtx expand_builtin_va_end (tree);
102 static rtx expand_builtin_va_copy (tree);
103 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
113 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_bcopy (tree);
115 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_bzero (tree);
123 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, rtx);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static rtx expand_builtin_fputs (tree, rtx, bool);
132 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135 static tree stabilize_va_list (tree, int);
136 static rtx expand_builtin_expect (tree, rtx);
137 static tree fold_builtin_constant_p (tree);
138 static tree fold_builtin_classify_type (tree);
139 static tree fold_builtin_inf (tree, int);
140 static tree fold_builtin_nan (tree, tree, int);
141 static int validate_arglist (tree, ...);
142 static bool integer_valued_real_p (tree);
143 static tree fold_trunc_transparent_mathfn (tree);
144 static bool readonly_data_expr (tree);
145 static rtx expand_builtin_fabs (tree, rtx, rtx);
146 static rtx expand_builtin_cabs (tree, rtx);
147 static rtx expand_builtin_signbit (tree, rtx);
148 static tree fold_builtin_cabs (tree, tree);
149 static tree fold_builtin_trunc (tree);
150 static tree fold_builtin_floor (tree);
151 static tree fold_builtin_ceil (tree);
152 static tree fold_builtin_round (tree);
153 static tree fold_builtin_bitop (tree);
154 static tree fold_builtin_memcpy (tree);
155 static tree fold_builtin_mempcpy (tree);
156 static tree fold_builtin_memmove (tree);
157 static tree fold_builtin_strcpy (tree);
158 static tree fold_builtin_strncpy (tree);
159 static tree fold_builtin_memcmp (tree);
160 static tree fold_builtin_strcmp (tree);
161 static tree fold_builtin_strncmp (tree);
162 static tree fold_builtin_signbit (tree);
164 static tree simplify_builtin_memcmp (tree);
165 static tree simplify_builtin_strcmp (tree);
166 static tree simplify_builtin_strncmp (tree);
167 static tree simplify_builtin_strpbrk (tree);
168 static tree simplify_builtin_strstr (tree);
169 static tree simplify_builtin_strchr (tree);
170 static tree simplify_builtin_strrchr (tree);
171 static tree simplify_builtin_strcat (tree);
172 static tree simplify_builtin_strncat (tree);
173 static tree simplify_builtin_strspn (tree);
174 static tree simplify_builtin_strcspn (tree);
175 static void simplify_builtin_next_arg (tree);
176 static void simplify_builtin_va_start (tree);
177 static tree simplify_builtin_sprintf (tree, int);
180 /* Return the alignment in bits of EXP, a pointer valued expression.
181 But don't return more than MAX_ALIGN no matter what.
182 The alignment returned is, by default, the alignment of the thing that
183 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
185 Otherwise, look at the expression to see if we can do better, i.e., if the
186 expression is actually pointing at an object whose alignment is tighter. */
188 static int
189 get_pointer_alignment (tree exp, unsigned int max_align)
191 unsigned int align, inner;
193 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
194 return 0;
196 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
197 align = MIN (align, max_align);
199 while (1)
201 switch (TREE_CODE (exp))
203 case NOP_EXPR:
204 case CONVERT_EXPR:
205 case NON_LVALUE_EXPR:
206 exp = TREE_OPERAND (exp, 0);
207 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
208 return align;
210 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
211 align = MIN (inner, max_align);
212 break;
214 case PLUS_EXPR:
215 /* If sum of pointer + int, restrict our maximum alignment to that
216 imposed by the integer. If not, we can't do any better than
217 ALIGN. */
218 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
219 return align;
221 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
222 & (max_align / BITS_PER_UNIT - 1))
223 != 0)
224 max_align >>= 1;
226 exp = TREE_OPERAND (exp, 0);
227 break;
229 case ADDR_EXPR:
230 /* See what we are pointing at and look at its alignment. */
231 exp = TREE_OPERAND (exp, 0);
232 if (TREE_CODE (exp) == FUNCTION_DECL)
233 align = FUNCTION_BOUNDARY;
234 else if (DECL_P (exp))
235 align = DECL_ALIGN (exp);
236 #ifdef CONSTANT_ALIGNMENT
237 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
238 align = CONSTANT_ALIGNMENT (exp, align);
239 #endif
240 return MIN (align, max_align);
242 default:
243 return align;
248 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
249 way, because it could contain a zero byte in the middle.
250 TREE_STRING_LENGTH is the size of the character array, not the string.
252 ONLY_VALUE should be nonzero if the result is not going to be emitted
253 into the instruction stream and zero if it is going to be expanded.
254 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
255 is returned, otherwise NULL, since
256 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
257 evaluate the side-effects.
259 The value returned is of type `ssizetype'.
261 Unfortunately, string_constant can't access the values of const char
262 arrays with initializers, so neither can we do so here. */
264 tree
265 c_strlen (tree src, int only_value)
267 tree offset_node;
268 HOST_WIDE_INT offset;
269 int max;
270 const char *ptr;
272 STRIP_NOPS (src);
273 if (TREE_CODE (src) == COND_EXPR
274 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
276 tree len1, len2;
278 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
279 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
280 if (tree_int_cst_equal (len1, len2))
281 return len1;
284 if (TREE_CODE (src) == COMPOUND_EXPR
285 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
286 return c_strlen (TREE_OPERAND (src, 1), only_value);
288 src = string_constant (src, &offset_node);
289 if (src == 0)
290 return 0;
292 max = TREE_STRING_LENGTH (src) - 1;
293 ptr = TREE_STRING_POINTER (src);
295 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
297 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
298 compute the offset to the following null if we don't know where to
299 start searching for it. */
300 int i;
302 for (i = 0; i < max; i++)
303 if (ptr[i] == 0)
304 return 0;
306 /* We don't know the starting offset, but we do know that the string
307 has no internal zero bytes. We can assume that the offset falls
308 within the bounds of the string; otherwise, the programmer deserves
309 what he gets. Subtract the offset from the length of the string,
310 and return that. This would perhaps not be valid if we were dealing
311 with named arrays in addition to literal string constants. */
313 return size_diffop (size_int (max), offset_node);
316 /* We have a known offset into the string. Start searching there for
317 a null character if we can represent it as a single HOST_WIDE_INT. */
318 if (offset_node == 0)
319 offset = 0;
320 else if (! host_integerp (offset_node, 0))
321 offset = -1;
322 else
323 offset = tree_low_cst (offset_node, 0);
325 /* If the offset is known to be out of bounds, warn, and call strlen at
326 runtime. */
327 if (offset < 0 || offset > max)
329 warning ("offset outside bounds of constant string");
330 return 0;
333 /* Use strlen to search for the first zero byte. Since any strings
334 constructed with build_string will have nulls appended, we win even
335 if we get handed something like (char[4])"abcd".
337 Since OFFSET is our starting index into the string, no further
338 calculation is needed. */
339 return ssize_int (strlen (ptr + offset));
342 /* Return a char pointer for a C string if it is a string constant
343 or sum of string constant and integer constant. */
345 static const char *
346 c_getstr (tree src)
348 tree offset_node;
350 src = string_constant (src, &offset_node);
351 if (src == 0)
352 return 0;
354 if (offset_node == 0)
355 return TREE_STRING_POINTER (src);
356 else if (!host_integerp (offset_node, 1)
357 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
358 return 0;
360 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
363 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
364 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
366 static rtx
367 c_readstr (const char *str, enum machine_mode mode)
369 HOST_WIDE_INT c[2];
370 HOST_WIDE_INT ch;
371 unsigned int i, j;
373 if (GET_MODE_CLASS (mode) != MODE_INT)
374 abort ();
375 c[0] = 0;
376 c[1] = 0;
377 ch = 1;
378 for (i = 0; i < GET_MODE_SIZE (mode); i++)
380 j = i;
381 if (WORDS_BIG_ENDIAN)
382 j = GET_MODE_SIZE (mode) - i - 1;
383 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
384 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
385 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
386 j *= BITS_PER_UNIT;
387 if (j > 2 * HOST_BITS_PER_WIDE_INT)
388 abort ();
389 if (ch)
390 ch = (unsigned char) str[i];
391 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
393 return immed_double_const (c[0], c[1], mode);
396 /* Cast a target constant CST to target CHAR and if that value fits into
397 host char type, return zero and put that value into variable pointed by
398 P. */
400 static int
401 target_char_cast (tree cst, char *p)
403 unsigned HOST_WIDE_INT val, hostval;
405 if (!host_integerp (cst, 1)
406 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
407 return 1;
409 val = tree_low_cst (cst, 1);
410 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
411 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
413 hostval = val;
414 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
415 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
417 if (val != hostval)
418 return 1;
420 *p = hostval;
421 return 0;
424 /* Similar to save_expr, but assumes that arbitrary code is not executed
425 in between the multiple evaluations. In particular, we assume that a
426 non-addressable local variable will not be modified. */
428 static tree
429 builtin_save_expr (tree exp)
431 if (TREE_ADDRESSABLE (exp) == 0
432 && (TREE_CODE (exp) == PARM_DECL
433 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
434 return exp;
436 return save_expr (exp);
439 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
440 times to get the address of either a higher stack frame, or a return
441 address located within it (depending on FNDECL_CODE). */
444 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
445 rtx tem)
447 int i;
449 /* Some machines need special handling before we can access
450 arbitrary frames. For example, on the sparc, we must first flush
451 all register windows to the stack. */
452 #ifdef SETUP_FRAME_ADDRESSES
453 if (count > 0)
454 SETUP_FRAME_ADDRESSES ();
455 #endif
457 /* On the sparc, the return address is not in the frame, it is in a
458 register. There is no way to access it off of the current frame
459 pointer, but it can be accessed off the previous frame pointer by
460 reading the value from the register window save area. */
461 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
462 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
463 count--;
464 #endif
466 /* Scan back COUNT frames to the specified frame. */
467 for (i = 0; i < count; i++)
469 /* Assume the dynamic chain pointer is in the word that the
470 frame address points to, unless otherwise specified. */
471 #ifdef DYNAMIC_CHAIN_ADDRESS
472 tem = DYNAMIC_CHAIN_ADDRESS (tem);
473 #endif
474 tem = memory_address (Pmode, tem);
475 tem = gen_rtx_MEM (Pmode, tem);
476 set_mem_alias_set (tem, get_frame_alias_set ());
477 tem = copy_to_reg (tem);
480 /* For __builtin_frame_address, return what we've got. */
481 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
482 return tem;
484 /* For __builtin_return_address, Get the return address from that
485 frame. */
486 #ifdef RETURN_ADDR_RTX
487 tem = RETURN_ADDR_RTX (count, tem);
488 #else
489 tem = memory_address (Pmode,
490 plus_constant (tem, GET_MODE_SIZE (Pmode)));
491 tem = gen_rtx_MEM (Pmode, tem);
492 set_mem_alias_set (tem, get_frame_alias_set ());
493 #endif
494 return tem;
497 /* Alias set used for setjmp buffer. */
498 static HOST_WIDE_INT setjmp_alias_set = -1;
500 /* Construct the leading half of a __builtin_setjmp call. Control will
501 return to RECEIVER_LABEL. This is used directly by sjlj exception
502 handling code. */
504 void
505 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
507 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
508 rtx stack_save;
509 rtx mem;
511 if (setjmp_alias_set == -1)
512 setjmp_alias_set = new_alias_set ();
514 buf_addr = convert_memory_address (Pmode, buf_addr);
516 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
518 emit_queue ();
520 /* We store the frame pointer and the address of receiver_label in
521 the buffer and use the rest of it for the stack save area, which
522 is machine-dependent. */
524 mem = gen_rtx_MEM (Pmode, buf_addr);
525 set_mem_alias_set (mem, setjmp_alias_set);
526 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
528 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
529 set_mem_alias_set (mem, setjmp_alias_set);
531 emit_move_insn (validize_mem (mem),
532 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
534 stack_save = gen_rtx_MEM (sa_mode,
535 plus_constant (buf_addr,
536 2 * GET_MODE_SIZE (Pmode)));
537 set_mem_alias_set (stack_save, setjmp_alias_set);
538 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
540 /* If there is further processing to do, do it. */
541 #ifdef HAVE_builtin_setjmp_setup
542 if (HAVE_builtin_setjmp_setup)
543 emit_insn (gen_builtin_setjmp_setup (buf_addr));
544 #endif
546 /* Tell optimize_save_area_alloca that extra work is going to
547 need to go on during alloca. */
548 current_function_calls_setjmp = 1;
550 /* Set this so all the registers get saved in our frame; we need to be
551 able to copy the saved values for any registers from frames we unwind. */
552 current_function_has_nonlocal_label = 1;
555 /* Construct the trailing part of a __builtin_setjmp call.
556 This is used directly by sjlj exception handling code. */
558 void
559 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
561 /* Clobber the FP when we get here, so we have to make sure it's
562 marked as used by this function. */
563 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
565 /* Mark the static chain as clobbered here so life information
566 doesn't get messed up for it. */
567 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
569 /* Now put in the code to restore the frame pointer, and argument
570 pointer, if needed. The code below is from expand_end_bindings
571 in stmt.c; see detailed documentation there. */
572 #ifdef HAVE_nonlocal_goto
573 if (! HAVE_nonlocal_goto)
574 #endif
575 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
577 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
578 if (fixed_regs[ARG_POINTER_REGNUM])
580 #ifdef ELIMINABLE_REGS
581 size_t i;
582 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
584 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
585 if (elim_regs[i].from == ARG_POINTER_REGNUM
586 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
587 break;
589 if (i == ARRAY_SIZE (elim_regs))
590 #endif
592 /* Now restore our arg pointer from the address at which it
593 was saved in our stack frame. */
594 emit_move_insn (virtual_incoming_args_rtx,
595 copy_to_reg (get_arg_pointer_save_area (cfun)));
598 #endif
600 #ifdef HAVE_builtin_setjmp_receiver
601 if (HAVE_builtin_setjmp_receiver)
602 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
603 else
604 #endif
605 #ifdef HAVE_nonlocal_goto_receiver
606 if (HAVE_nonlocal_goto_receiver)
607 emit_insn (gen_nonlocal_goto_receiver ());
608 else
609 #endif
610 { /* Nothing */ }
612 /* @@@ This is a kludge. Not all machine descriptions define a blockage
613 insn, but we must not allow the code we just generated to be reordered
614 by scheduling. Specifically, the update of the frame pointer must
615 happen immediately, not later. So emit an ASM_INPUT to act as blockage
616 insn. */
617 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
620 /* __builtin_setjmp is passed a pointer to an array of five words (not
621 all will be used on all machines). It operates similarly to the C
622 library function of the same name, but is more efficient. Much of
623 the code below (and for longjmp) is copied from the handling of
624 non-local gotos.
626 NOTE: This is intended for use by GNAT and the exception handling
627 scheme in the compiler and will only work in the method used by
628 them. */
630 static rtx
631 expand_builtin_setjmp (tree arglist, rtx target)
633 rtx buf_addr, next_lab, cont_lab;
635 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
636 return NULL_RTX;
638 if (target == 0 || GET_CODE (target) != REG
639 || REGNO (target) < FIRST_PSEUDO_REGISTER)
640 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
642 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
644 next_lab = gen_label_rtx ();
645 cont_lab = gen_label_rtx ();
647 expand_builtin_setjmp_setup (buf_addr, next_lab);
649 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
650 ensure that pending stack adjustments are flushed. */
651 emit_move_insn (target, const0_rtx);
652 emit_jump (cont_lab);
654 emit_label (next_lab);
656 expand_builtin_setjmp_receiver (next_lab);
658 /* Set TARGET to one. */
659 emit_move_insn (target, const1_rtx);
660 emit_label (cont_lab);
662 /* Tell flow about the strange goings on. Putting `next_lab' on
663 `nonlocal_goto_handler_labels' to indicates that function
664 calls may traverse the arc back to this label. */
666 current_function_has_nonlocal_label = 1;
667 nonlocal_goto_handler_labels
668 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
670 return target;
673 /* __builtin_longjmp is passed a pointer to an array of five words (not
674 all will be used on all machines). It operates similarly to the C
675 library function of the same name, but is more efficient. Much of
676 the code below is copied from the handling of non-local gotos.
678 NOTE: This is intended for use by GNAT and the exception handling
679 scheme in the compiler and will only work in the method used by
680 them. */
682 void
683 expand_builtin_longjmp (rtx buf_addr, rtx value)
685 rtx fp, lab, stack, insn, last;
686 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
688 if (setjmp_alias_set == -1)
689 setjmp_alias_set = new_alias_set ();
691 buf_addr = convert_memory_address (Pmode, buf_addr);
693 buf_addr = force_reg (Pmode, buf_addr);
695 /* We used to store value in static_chain_rtx, but that fails if pointers
696 are smaller than integers. We instead require that the user must pass
697 a second argument of 1, because that is what builtin_setjmp will
698 return. This also makes EH slightly more efficient, since we are no
699 longer copying around a value that we don't care about. */
700 if (value != const1_rtx)
701 abort ();
703 current_function_calls_longjmp = 1;
705 last = get_last_insn ();
706 #ifdef HAVE_builtin_longjmp
707 if (HAVE_builtin_longjmp)
708 emit_insn (gen_builtin_longjmp (buf_addr));
709 else
710 #endif
712 fp = gen_rtx_MEM (Pmode, buf_addr);
713 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
714 GET_MODE_SIZE (Pmode)));
716 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
717 2 * GET_MODE_SIZE (Pmode)));
718 set_mem_alias_set (fp, setjmp_alias_set);
719 set_mem_alias_set (lab, setjmp_alias_set);
720 set_mem_alias_set (stack, setjmp_alias_set);
722 /* Pick up FP, label, and SP from the block and jump. This code is
723 from expand_goto in stmt.c; see there for detailed comments. */
724 #if HAVE_nonlocal_goto
725 if (HAVE_nonlocal_goto)
726 /* We have to pass a value to the nonlocal_goto pattern that will
727 get copied into the static_chain pointer, but it does not matter
728 what that value is, because builtin_setjmp does not use it. */
729 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
730 else
731 #endif
733 lab = copy_to_reg (lab);
735 emit_insn (gen_rtx_CLOBBER (VOIDmode,
736 gen_rtx_MEM (BLKmode,
737 gen_rtx_SCRATCH (VOIDmode))));
738 emit_insn (gen_rtx_CLOBBER (VOIDmode,
739 gen_rtx_MEM (BLKmode,
740 hard_frame_pointer_rtx)));
742 emit_move_insn (hard_frame_pointer_rtx, fp);
743 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
745 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
746 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
747 emit_indirect_jump (lab);
751 /* Search backwards and mark the jump insn as a non-local goto.
752 Note that this precludes the use of __builtin_longjmp to a
753 __builtin_setjmp target in the same function. However, we've
754 already cautioned the user that these functions are for
755 internal exception handling use only. */
756 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
758 if (insn == last)
759 abort ();
760 if (GET_CODE (insn) == JUMP_INSN)
762 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
763 REG_NOTES (insn));
764 break;
766 else if (GET_CODE (insn) == CALL_INSN)
767 break;
771 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
772 and the address of the save area. */
774 static rtx
775 expand_builtin_nonlocal_goto (tree arglist)
777 tree t_label, t_save_area;
778 rtx r_label, r_save_area, r_fp, r_sp, insn;
780 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
781 return NULL_RTX;
783 t_label = TREE_VALUE (arglist);
784 arglist = TREE_CHAIN (arglist);
785 t_save_area = TREE_VALUE (arglist);
787 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
788 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
789 r_fp = gen_rtx_MEM (Pmode, r_save_area);
790 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
791 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
793 current_function_has_nonlocal_goto = 1;
795 #if HAVE_nonlocal_goto
796 /* ??? We no longer need to pass the static chain value, afaik. */
797 if (HAVE_nonlocal_goto)
798 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
799 else
800 #endif
802 r_label = copy_to_reg (r_label);
804 emit_insn (gen_rtx_CLOBBER (VOIDmode,
805 gen_rtx_MEM (BLKmode,
806 gen_rtx_SCRATCH (VOIDmode))));
808 emit_insn (gen_rtx_CLOBBER (VOIDmode,
809 gen_rtx_MEM (BLKmode,
810 hard_frame_pointer_rtx)));
812 /* Restore frame pointer for containing function.
813 This sets the actual hard register used for the frame pointer
814 to the location of the function's incoming static chain info.
815 The non-local goto handler will then adjust it to contain the
816 proper value and reload the argument pointer, if needed. */
817 emit_move_insn (hard_frame_pointer_rtx, r_fp);
818 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
820 /* USE of hard_frame_pointer_rtx added for consistency;
821 not clear if really needed. */
822 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
823 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
824 emit_indirect_jump (r_label);
827 /* Search backwards to the jump insn and mark it as a
828 non-local goto. */
829 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
831 if (GET_CODE (insn) == JUMP_INSN)
833 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
834 const0_rtx, REG_NOTES (insn));
835 break;
837 else if (GET_CODE (insn) == CALL_INSN)
838 break;
841 return const0_rtx;
844 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
845 (not all will be used on all machines) that was passed to __builtin_setjmp.
846 It updates the stack pointer in that block to correspond to the current
847 stack pointer. */
849 static void
850 expand_builtin_update_setjmp_buf (rtx buf_addr)
852 enum machine_mode sa_mode = Pmode;
853 rtx stack_save;
856 #ifdef HAVE_save_stack_nonlocal
857 if (HAVE_save_stack_nonlocal)
858 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
859 #endif
860 #ifdef STACK_SAVEAREA_MODE
861 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
862 #endif
864 stack_save
865 = gen_rtx_MEM (sa_mode,
866 memory_address
867 (sa_mode,
868 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
870 #ifdef HAVE_setjmp
871 if (HAVE_setjmp)
872 emit_insn (gen_setjmp ());
873 #endif
875 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
878 /* Expand a call to __builtin_prefetch. For a target that does not support
879 data prefetch, evaluate the memory address argument in case it has side
880 effects. */
882 static void
883 expand_builtin_prefetch (tree arglist)
885 tree arg0, arg1, arg2;
886 rtx op0, op1, op2;
888 if (!validate_arglist (arglist, POINTER_TYPE, 0))
889 return;
891 arg0 = TREE_VALUE (arglist);
892 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
893 zero (read) and argument 2 (locality) defaults to 3 (high degree of
894 locality). */
895 if (TREE_CHAIN (arglist))
897 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
898 if (TREE_CHAIN (TREE_CHAIN (arglist)))
899 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
900 else
901 arg2 = build_int_2 (3, 0);
903 else
905 arg1 = integer_zero_node;
906 arg2 = build_int_2 (3, 0);
909 /* Argument 0 is an address. */
910 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
912 /* Argument 1 (read/write flag) must be a compile-time constant int. */
913 if (TREE_CODE (arg1) != INTEGER_CST)
915 error ("second arg to `__builtin_prefetch' must be a constant");
916 arg1 = integer_zero_node;
918 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
919 /* Argument 1 must be either zero or one. */
920 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
922 warning ("invalid second arg to __builtin_prefetch; using zero");
923 op1 = const0_rtx;
926 /* Argument 2 (locality) must be a compile-time constant int. */
927 if (TREE_CODE (arg2) != INTEGER_CST)
929 error ("third arg to `__builtin_prefetch' must be a constant");
930 arg2 = integer_zero_node;
932 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
933 /* Argument 2 must be 0, 1, 2, or 3. */
934 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
936 warning ("invalid third arg to __builtin_prefetch; using zero");
937 op2 = const0_rtx;
940 #ifdef HAVE_prefetch
941 if (HAVE_prefetch)
943 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
944 (op0,
945 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
946 || (GET_MODE (op0) != Pmode))
948 op0 = convert_memory_address (Pmode, op0);
949 op0 = force_reg (Pmode, op0);
951 emit_insn (gen_prefetch (op0, op1, op2));
953 else
954 #endif
955 op0 = protect_from_queue (op0, 0);
956 /* Don't do anything with direct references to volatile memory, but
957 generate code to handle other side effects. */
958 if (GET_CODE (op0) != MEM && side_effects_p (op0))
959 emit_insn (op0);
962 /* Get a MEM rtx for expression EXP which is the address of an operand
963 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
965 static rtx
966 get_memory_rtx (tree exp)
968 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
969 rtx mem;
971 addr = convert_memory_address (Pmode, addr);
973 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
975 /* Get an expression we can use to find the attributes to assign to MEM.
976 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
977 we can. First remove any nops. */
978 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
979 || TREE_CODE (exp) == NON_LVALUE_EXPR)
980 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
981 exp = TREE_OPERAND (exp, 0);
983 if (TREE_CODE (exp) == ADDR_EXPR)
985 exp = TREE_OPERAND (exp, 0);
986 set_mem_attributes (mem, exp, 0);
988 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
990 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
991 /* memcpy, memset and other builtin stringops can alias with anything. */
992 set_mem_alias_set (mem, 0);
995 return mem;
998 /* Built-in functions to perform an untyped call and return. */
1000 /* For each register that may be used for calling a function, this
1001 gives a mode used to copy the register's value. VOIDmode indicates
1002 the register is not used for calling a function. If the machine
1003 has register windows, this gives only the outbound registers.
1004 INCOMING_REGNO gives the corresponding inbound register. */
1005 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1007 /* For each register that may be used for returning values, this gives
1008 a mode used to copy the register's value. VOIDmode indicates the
1009 register is not used for returning values. If the machine has
1010 register windows, this gives only the outbound registers.
1011 INCOMING_REGNO gives the corresponding inbound register. */
1012 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1014 /* For each register that may be used for calling a function, this
1015 gives the offset of that register into the block returned by
1016 __builtin_apply_args. 0 indicates that the register is not
1017 used for calling a function. */
1018 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1020 /* Return the size required for the block returned by __builtin_apply_args,
1021 and initialize apply_args_mode. */
1023 static int
1024 apply_args_size (void)
1026 static int size = -1;
1027 int align;
1028 unsigned int regno;
1029 enum machine_mode mode;
1031 /* The values computed by this function never change. */
1032 if (size < 0)
1034 /* The first value is the incoming arg-pointer. */
1035 size = GET_MODE_SIZE (Pmode);
1037 /* The second value is the structure value address unless this is
1038 passed as an "invisible" first argument. */
1039 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1040 size += GET_MODE_SIZE (Pmode);
1042 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1043 if (FUNCTION_ARG_REGNO_P (regno))
1045 mode = reg_raw_mode[regno];
1047 if (mode == VOIDmode)
1048 abort ();
1050 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1051 if (size % align != 0)
1052 size = CEIL (size, align) * align;
1053 apply_args_reg_offset[regno] = size;
1054 size += GET_MODE_SIZE (mode);
1055 apply_args_mode[regno] = mode;
1057 else
1059 apply_args_mode[regno] = VOIDmode;
1060 apply_args_reg_offset[regno] = 0;
1063 return size;
1066 /* Return the size required for the block returned by __builtin_apply,
1067 and initialize apply_result_mode. */
1069 static int
1070 apply_result_size (void)
1072 static int size = -1;
1073 int align, regno;
1074 enum machine_mode mode;
1076 /* The values computed by this function never change. */
1077 if (size < 0)
1079 size = 0;
1081 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1082 if (FUNCTION_VALUE_REGNO_P (regno))
1084 mode = reg_raw_mode[regno];
1086 if (mode == VOIDmode)
1087 abort ();
1089 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1090 if (size % align != 0)
1091 size = CEIL (size, align) * align;
1092 size += GET_MODE_SIZE (mode);
1093 apply_result_mode[regno] = mode;
1095 else
1096 apply_result_mode[regno] = VOIDmode;
1098 /* Allow targets that use untyped_call and untyped_return to override
1099 the size so that machine-specific information can be stored here. */
1100 #ifdef APPLY_RESULT_SIZE
1101 size = APPLY_RESULT_SIZE;
1102 #endif
1104 return size;
1107 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1108 /* Create a vector describing the result block RESULT. If SAVEP is true,
1109 the result block is used to save the values; otherwise it is used to
1110 restore the values. */
1112 static rtx
1113 result_vector (int savep, rtx result)
1115 int regno, size, align, nelts;
1116 enum machine_mode mode;
1117 rtx reg, mem;
1118 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1120 size = nelts = 0;
1121 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1122 if ((mode = apply_result_mode[regno]) != VOIDmode)
1124 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1125 if (size % align != 0)
1126 size = CEIL (size, align) * align;
1127 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1128 mem = adjust_address (result, mode, size);
1129 savevec[nelts++] = (savep
1130 ? gen_rtx_SET (VOIDmode, mem, reg)
1131 : gen_rtx_SET (VOIDmode, reg, mem));
1132 size += GET_MODE_SIZE (mode);
1134 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1136 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1138 /* Save the state required to perform an untyped call with the same
1139 arguments as were passed to the current function. */
1141 static rtx
1142 expand_builtin_apply_args_1 (void)
1144 rtx registers, tem;
1145 int size, align, regno;
1146 enum machine_mode mode;
1147 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1149 /* Create a block where the arg-pointer, structure value address,
1150 and argument registers can be saved. */
1151 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1153 /* Walk past the arg-pointer and structure value address. */
1154 size = GET_MODE_SIZE (Pmode);
1155 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1156 size += GET_MODE_SIZE (Pmode);
1158 /* Save each register used in calling a function to the block. */
1159 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1160 if ((mode = apply_args_mode[regno]) != VOIDmode)
1162 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1163 if (size % align != 0)
1164 size = CEIL (size, align) * align;
1166 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1168 emit_move_insn (adjust_address (registers, mode, size), tem);
1169 size += GET_MODE_SIZE (mode);
1172 /* Save the arg pointer to the block. */
1173 tem = copy_to_reg (virtual_incoming_args_rtx);
1174 #ifdef STACK_GROWS_DOWNWARD
1175 /* We need the pointer as the caller actually passed them to us, not
1176 as we might have pretended they were passed. Make sure it's a valid
1177 operand, as emit_move_insn isn't expected to handle a PLUS. */
1179 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1180 NULL_RTX);
1181 #endif
1182 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1184 size = GET_MODE_SIZE (Pmode);
1186 /* Save the structure value address unless this is passed as an
1187 "invisible" first argument. */
1188 if (struct_incoming_value)
1190 emit_move_insn (adjust_address (registers, Pmode, size),
1191 copy_to_reg (struct_incoming_value));
1192 size += GET_MODE_SIZE (Pmode);
1195 /* Return the address of the block. */
1196 return copy_addr_to_reg (XEXP (registers, 0));
1199 /* __builtin_apply_args returns block of memory allocated on
1200 the stack into which is stored the arg pointer, structure
1201 value address, static chain, and all the registers that might
1202 possibly be used in performing a function call. The code is
1203 moved to the start of the function so the incoming values are
1204 saved. */
1206 static rtx
1207 expand_builtin_apply_args (void)
1209 /* Don't do __builtin_apply_args more than once in a function.
1210 Save the result of the first call and reuse it. */
1211 if (apply_args_value != 0)
1212 return apply_args_value;
1214 /* When this function is called, it means that registers must be
1215 saved on entry to this function. So we migrate the
1216 call to the first insn of this function. */
1217 rtx temp;
1218 rtx seq;
1220 start_sequence ();
1221 temp = expand_builtin_apply_args_1 ();
1222 seq = get_insns ();
1223 end_sequence ();
1225 apply_args_value = temp;
1227 /* Put the insns after the NOTE that starts the function.
1228 If this is inside a start_sequence, make the outer-level insn
1229 chain current, so the code is placed at the start of the
1230 function. */
1231 push_topmost_sequence ();
1232 emit_insn_before (seq, NEXT_INSN (get_insns ()));
1233 pop_topmost_sequence ();
1234 return temp;
1238 /* Perform an untyped call and save the state required to perform an
1239 untyped return of whatever value was returned by the given function. */
1241 static rtx
1242 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1244 int size, align, regno;
1245 enum machine_mode mode;
1246 rtx incoming_args, result, reg, dest, src, call_insn;
1247 rtx old_stack_level = 0;
1248 rtx call_fusage = 0;
1249 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1251 arguments = convert_memory_address (Pmode, arguments);
1253 /* Create a block where the return registers can be saved. */
1254 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1256 /* Fetch the arg pointer from the ARGUMENTS block. */
1257 incoming_args = gen_reg_rtx (Pmode);
1258 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1259 #ifndef STACK_GROWS_DOWNWARD
1260 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1261 incoming_args, 0, OPTAB_LIB_WIDEN);
1262 #endif
1264 /* Perform postincrements before actually calling the function. */
1265 emit_queue ();
1267 /* Push a new argument block and copy the arguments. Do not allow
1268 the (potential) memcpy call below to interfere with our stack
1269 manipulations. */
1270 do_pending_stack_adjust ();
1271 NO_DEFER_POP;
1273 /* Save the stack with nonlocal if available. */
1274 #ifdef HAVE_save_stack_nonlocal
1275 if (HAVE_save_stack_nonlocal)
1276 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1277 else
1278 #endif
1279 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1281 /* Allocate a block of memory onto the stack and copy the memory
1282 arguments to the outgoing arguments address. */
1283 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1284 dest = virtual_outgoing_args_rtx;
1285 #ifndef STACK_GROWS_DOWNWARD
1286 if (GET_CODE (argsize) == CONST_INT)
1287 dest = plus_constant (dest, -INTVAL (argsize));
1288 else
1289 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1290 #endif
1291 dest = gen_rtx_MEM (BLKmode, dest);
1292 set_mem_align (dest, PARM_BOUNDARY);
1293 src = gen_rtx_MEM (BLKmode, incoming_args);
1294 set_mem_align (src, PARM_BOUNDARY);
1295 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1297 /* Refer to the argument block. */
1298 apply_args_size ();
1299 arguments = gen_rtx_MEM (BLKmode, arguments);
1300 set_mem_align (arguments, PARM_BOUNDARY);
1302 /* Walk past the arg-pointer and structure value address. */
1303 size = GET_MODE_SIZE (Pmode);
1304 if (struct_value)
1305 size += GET_MODE_SIZE (Pmode);
1307 /* Restore each of the registers previously saved. Make USE insns
1308 for each of these registers for use in making the call. */
1309 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1310 if ((mode = apply_args_mode[regno]) != VOIDmode)
1312 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1313 if (size % align != 0)
1314 size = CEIL (size, align) * align;
1315 reg = gen_rtx_REG (mode, regno);
1316 emit_move_insn (reg, adjust_address (arguments, mode, size));
1317 use_reg (&call_fusage, reg);
1318 size += GET_MODE_SIZE (mode);
1321 /* Restore the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 size = GET_MODE_SIZE (Pmode);
1324 if (struct_value)
1326 rtx value = gen_reg_rtx (Pmode);
1327 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1328 emit_move_insn (struct_value, value);
1329 if (GET_CODE (struct_value) == REG)
1330 use_reg (&call_fusage, struct_value);
1331 size += GET_MODE_SIZE (Pmode);
1334 /* All arguments and registers used for the call are set up by now! */
1335 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1337 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1338 and we don't want to load it into a register as an optimization,
1339 because prepare_call_address already did it if it should be done. */
1340 if (GET_CODE (function) != SYMBOL_REF)
1341 function = memory_address (FUNCTION_MODE, function);
1343 /* Generate the actual call instruction and save the return value. */
1344 #ifdef HAVE_untyped_call
1345 if (HAVE_untyped_call)
1346 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1347 result, result_vector (1, result)));
1348 else
1349 #endif
1350 #ifdef HAVE_call_value
1351 if (HAVE_call_value)
1353 rtx valreg = 0;
1355 /* Locate the unique return register. It is not possible to
1356 express a call that sets more than one return register using
1357 call_value; use untyped_call for that. In fact, untyped_call
1358 only needs to save the return registers in the given block. */
1359 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1360 if ((mode = apply_result_mode[regno]) != VOIDmode)
1362 if (valreg)
1363 abort (); /* HAVE_untyped_call required. */
1364 valreg = gen_rtx_REG (mode, regno);
1367 emit_call_insn (GEN_CALL_VALUE (valreg,
1368 gen_rtx_MEM (FUNCTION_MODE, function),
1369 const0_rtx, NULL_RTX, const0_rtx));
1371 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1373 else
1374 #endif
1375 abort ();
1377 /* Find the CALL insn we just emitted, and attach the register usage
1378 information. */
1379 call_insn = last_call_insn ();
1380 add_function_usage_to (call_insn, call_fusage);
1382 /* Restore the stack. */
1383 #ifdef HAVE_save_stack_nonlocal
1384 if (HAVE_save_stack_nonlocal)
1385 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1386 else
1387 #endif
1388 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1390 OK_DEFER_POP;
1392 /* Return the address of the result block. */
1393 result = copy_addr_to_reg (XEXP (result, 0));
1394 return convert_memory_address (ptr_mode, result);
1397 /* Perform an untyped return. */
1399 static void
1400 expand_builtin_return (rtx result)
1402 int size, align, regno;
1403 enum machine_mode mode;
1404 rtx reg;
1405 rtx call_fusage = 0;
1407 result = convert_memory_address (Pmode, result);
1409 apply_result_size ();
1410 result = gen_rtx_MEM (BLKmode, result);
1412 #ifdef HAVE_untyped_return
1413 if (HAVE_untyped_return)
1415 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1416 emit_barrier ();
1417 return;
1419 #endif
1421 /* Restore the return value and note that each value is used. */
1422 size = 0;
1423 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1424 if ((mode = apply_result_mode[regno]) != VOIDmode)
1426 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1427 if (size % align != 0)
1428 size = CEIL (size, align) * align;
1429 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1430 emit_move_insn (reg, adjust_address (result, mode, size));
1432 push_to_sequence (call_fusage);
1433 emit_insn (gen_rtx_USE (VOIDmode, reg));
1434 call_fusage = get_insns ();
1435 end_sequence ();
1436 size += GET_MODE_SIZE (mode);
1439 /* Put the USE insns before the return. */
1440 emit_insn (call_fusage);
1442 /* Return whatever values was restored by jumping directly to the end
1443 of the function. */
1444 expand_naked_return ();
1447 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1449 static enum type_class
1450 type_to_class (tree type)
1452 switch (TREE_CODE (type))
1454 case VOID_TYPE: return void_type_class;
1455 case INTEGER_TYPE: return integer_type_class;
1456 case CHAR_TYPE: return char_type_class;
1457 case ENUMERAL_TYPE: return enumeral_type_class;
1458 case BOOLEAN_TYPE: return boolean_type_class;
1459 case POINTER_TYPE: return pointer_type_class;
1460 case REFERENCE_TYPE: return reference_type_class;
1461 case OFFSET_TYPE: return offset_type_class;
1462 case REAL_TYPE: return real_type_class;
1463 case COMPLEX_TYPE: return complex_type_class;
1464 case FUNCTION_TYPE: return function_type_class;
1465 case METHOD_TYPE: return method_type_class;
1466 case RECORD_TYPE: return record_type_class;
1467 case UNION_TYPE:
1468 case QUAL_UNION_TYPE: return union_type_class;
1469 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1470 ? string_type_class : array_type_class);
1471 case SET_TYPE: return set_type_class;
1472 case FILE_TYPE: return file_type_class;
1473 case LANG_TYPE: return lang_type_class;
1474 default: return no_type_class;
1478 /* Expand a call to __builtin_classify_type with arguments found in
1479 ARGLIST. */
1481 static rtx
1482 expand_builtin_classify_type (tree arglist)
1484 if (arglist != 0)
1485 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1486 return GEN_INT (no_type_class);
1489 /* This helper macro, meant to be used in mathfn_built_in below,
1490 determines which among a set of three builtin math functions is
1491 appropriate for a given type mode. The `F' and `L' cases are
1492 automatically generated from the `double' case. */
1493 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1494 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1495 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1496 fcodel = BUILT_IN_MATHFN##L ; break;
1498 /* Return mathematic function equivalent to FN but operating directly
1499 on TYPE, if available. If we can't do the conversion, return zero. */
1500 tree
1501 mathfn_built_in (tree type, enum built_in_function fn)
1503 enum built_in_function fcode, fcodef, fcodel;
1505 switch (fn)
1507 CASE_MATHFN (BUILT_IN_ACOS)
1508 CASE_MATHFN (BUILT_IN_ACOSH)
1509 CASE_MATHFN (BUILT_IN_ASIN)
1510 CASE_MATHFN (BUILT_IN_ASINH)
1511 CASE_MATHFN (BUILT_IN_ATAN)
1512 CASE_MATHFN (BUILT_IN_ATAN2)
1513 CASE_MATHFN (BUILT_IN_ATANH)
1514 CASE_MATHFN (BUILT_IN_CBRT)
1515 CASE_MATHFN (BUILT_IN_CEIL)
1516 CASE_MATHFN (BUILT_IN_COPYSIGN)
1517 CASE_MATHFN (BUILT_IN_COS)
1518 CASE_MATHFN (BUILT_IN_COSH)
1519 CASE_MATHFN (BUILT_IN_DREM)
1520 CASE_MATHFN (BUILT_IN_ERF)
1521 CASE_MATHFN (BUILT_IN_ERFC)
1522 CASE_MATHFN (BUILT_IN_EXP)
1523 CASE_MATHFN (BUILT_IN_EXP10)
1524 CASE_MATHFN (BUILT_IN_EXP2)
1525 CASE_MATHFN (BUILT_IN_EXPM1)
1526 CASE_MATHFN (BUILT_IN_FABS)
1527 CASE_MATHFN (BUILT_IN_FDIM)
1528 CASE_MATHFN (BUILT_IN_FLOOR)
1529 CASE_MATHFN (BUILT_IN_FMA)
1530 CASE_MATHFN (BUILT_IN_FMAX)
1531 CASE_MATHFN (BUILT_IN_FMIN)
1532 CASE_MATHFN (BUILT_IN_FMOD)
1533 CASE_MATHFN (BUILT_IN_FREXP)
1534 CASE_MATHFN (BUILT_IN_GAMMA)
1535 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1536 CASE_MATHFN (BUILT_IN_HYPOT)
1537 CASE_MATHFN (BUILT_IN_ILOGB)
1538 CASE_MATHFN (BUILT_IN_INF)
1539 CASE_MATHFN (BUILT_IN_J0)
1540 CASE_MATHFN (BUILT_IN_J1)
1541 CASE_MATHFN (BUILT_IN_JN)
1542 CASE_MATHFN (BUILT_IN_LDEXP)
1543 CASE_MATHFN (BUILT_IN_LGAMMA)
1544 CASE_MATHFN (BUILT_IN_LLRINT)
1545 CASE_MATHFN (BUILT_IN_LLROUND)
1546 CASE_MATHFN (BUILT_IN_LOG)
1547 CASE_MATHFN (BUILT_IN_LOG10)
1548 CASE_MATHFN (BUILT_IN_LOG1P)
1549 CASE_MATHFN (BUILT_IN_LOG2)
1550 CASE_MATHFN (BUILT_IN_LOGB)
1551 CASE_MATHFN (BUILT_IN_LRINT)
1552 CASE_MATHFN (BUILT_IN_LROUND)
1553 CASE_MATHFN (BUILT_IN_MODF)
1554 CASE_MATHFN (BUILT_IN_NAN)
1555 CASE_MATHFN (BUILT_IN_NANS)
1556 CASE_MATHFN (BUILT_IN_NEARBYINT)
1557 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1558 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1559 CASE_MATHFN (BUILT_IN_POW)
1560 CASE_MATHFN (BUILT_IN_POW10)
1561 CASE_MATHFN (BUILT_IN_REMAINDER)
1562 CASE_MATHFN (BUILT_IN_REMQUO)
1563 CASE_MATHFN (BUILT_IN_RINT)
1564 CASE_MATHFN (BUILT_IN_ROUND)
1565 CASE_MATHFN (BUILT_IN_SCALB)
1566 CASE_MATHFN (BUILT_IN_SCALBLN)
1567 CASE_MATHFN (BUILT_IN_SCALBN)
1568 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1569 CASE_MATHFN (BUILT_IN_SIN)
1570 CASE_MATHFN (BUILT_IN_SINCOS)
1571 CASE_MATHFN (BUILT_IN_SINH)
1572 CASE_MATHFN (BUILT_IN_SQRT)
1573 CASE_MATHFN (BUILT_IN_TAN)
1574 CASE_MATHFN (BUILT_IN_TANH)
1575 CASE_MATHFN (BUILT_IN_TGAMMA)
1576 CASE_MATHFN (BUILT_IN_TRUNC)
1577 CASE_MATHFN (BUILT_IN_Y0)
1578 CASE_MATHFN (BUILT_IN_Y1)
1579 CASE_MATHFN (BUILT_IN_YN)
1581 default:
1582 return 0;
1585 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1586 return implicit_built_in_decls[fcode];
1587 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1588 return implicit_built_in_decls[fcodef];
1589 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1590 return implicit_built_in_decls[fcodel];
1591 else
1592 return 0;
1595 /* If errno must be maintained, expand the RTL to check if the result,
1596 TARGET, of a built-in function call, EXP, is NaN, and if so set
1597 errno to EDOM. */
1599 static void
1600 expand_errno_check (tree exp, rtx target)
1602 rtx lab = gen_label_rtx ();
1604 /* Test the result; if it is NaN, set errno=EDOM because
1605 the argument was not in the domain. */
1606 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1607 0, lab);
1609 #ifdef TARGET_EDOM
1610 /* If this built-in doesn't throw an exception, set errno directly. */
1611 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1613 #ifdef GEN_ERRNO_RTX
1614 rtx errno_rtx = GEN_ERRNO_RTX;
1615 #else
1616 rtx errno_rtx
1617 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1618 #endif
1619 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1620 emit_label (lab);
1621 return;
1623 #endif
1625 /* We can't set errno=EDOM directly; let the library call do it.
1626 Pop the arguments right away in case the call gets deleted. */
1627 NO_DEFER_POP;
1628 expand_call (exp, target, 0);
1629 OK_DEFER_POP;
1630 emit_label (lab);
1634 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1635 Return 0 if a normal call should be emitted rather than expanding the
1636 function in-line. EXP is the expression that is a call to the builtin
1637 function; if convenient, the result should be placed in TARGET.
1638 SUBTARGET may be used as the target for computing one of EXP's operands. */
1640 static rtx
1641 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1643 optab builtin_optab;
1644 rtx op0, insns, before_call;
1645 tree fndecl = get_callee_fndecl (exp);
1646 tree arglist = TREE_OPERAND (exp, 1);
1647 enum machine_mode mode;
1648 bool errno_set = false;
1649 tree arg, narg;
1651 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1652 return 0;
1654 arg = TREE_VALUE (arglist);
1656 switch (DECL_FUNCTION_CODE (fndecl))
1658 case BUILT_IN_SQRT:
1659 case BUILT_IN_SQRTF:
1660 case BUILT_IN_SQRTL:
1661 errno_set = ! tree_expr_nonnegative_p (arg);
1662 builtin_optab = sqrt_optab;
1663 break;
1664 case BUILT_IN_EXP:
1665 case BUILT_IN_EXPF:
1666 case BUILT_IN_EXPL:
1667 errno_set = true; builtin_optab = exp_optab; break;
1668 case BUILT_IN_EXP10:
1669 case BUILT_IN_EXP10F:
1670 case BUILT_IN_EXP10L:
1671 case BUILT_IN_POW10:
1672 case BUILT_IN_POW10F:
1673 case BUILT_IN_POW10L:
1674 errno_set = true; builtin_optab = exp10_optab; break;
1675 case BUILT_IN_EXP2:
1676 case BUILT_IN_EXP2F:
1677 case BUILT_IN_EXP2L:
1678 errno_set = true; builtin_optab = exp2_optab; break;
1679 case BUILT_IN_EXPM1:
1680 case BUILT_IN_EXPM1F:
1681 case BUILT_IN_EXPM1L:
1682 errno_set = true; builtin_optab = expm1_optab; break;
1683 case BUILT_IN_LOGB:
1684 case BUILT_IN_LOGBF:
1685 case BUILT_IN_LOGBL:
1686 errno_set = true; builtin_optab = logb_optab; break;
1687 case BUILT_IN_ILOGB:
1688 case BUILT_IN_ILOGBF:
1689 case BUILT_IN_ILOGBL:
1690 errno_set = true; builtin_optab = ilogb_optab; break;
1691 case BUILT_IN_LOG:
1692 case BUILT_IN_LOGF:
1693 case BUILT_IN_LOGL:
1694 errno_set = true; builtin_optab = log_optab; break;
1695 case BUILT_IN_LOG10:
1696 case BUILT_IN_LOG10F:
1697 case BUILT_IN_LOG10L:
1698 errno_set = true; builtin_optab = log10_optab; break;
1699 case BUILT_IN_LOG2:
1700 case BUILT_IN_LOG2F:
1701 case BUILT_IN_LOG2L:
1702 errno_set = true; builtin_optab = log2_optab; break;
1703 case BUILT_IN_LOG1P:
1704 case BUILT_IN_LOG1PF:
1705 case BUILT_IN_LOG1PL:
1706 errno_set = true; builtin_optab = log1p_optab; break;
1707 case BUILT_IN_ASIN:
1708 case BUILT_IN_ASINF:
1709 case BUILT_IN_ASINL:
1710 builtin_optab = asin_optab; break;
1711 case BUILT_IN_ACOS:
1712 case BUILT_IN_ACOSF:
1713 case BUILT_IN_ACOSL:
1714 builtin_optab = acos_optab; break;
1715 case BUILT_IN_TAN:
1716 case BUILT_IN_TANF:
1717 case BUILT_IN_TANL:
1718 builtin_optab = tan_optab; break;
1719 case BUILT_IN_ATAN:
1720 case BUILT_IN_ATANF:
1721 case BUILT_IN_ATANL:
1722 builtin_optab = atan_optab; break;
1723 case BUILT_IN_FLOOR:
1724 case BUILT_IN_FLOORF:
1725 case BUILT_IN_FLOORL:
1726 builtin_optab = floor_optab; break;
1727 case BUILT_IN_CEIL:
1728 case BUILT_IN_CEILF:
1729 case BUILT_IN_CEILL:
1730 builtin_optab = ceil_optab; break;
1731 case BUILT_IN_TRUNC:
1732 case BUILT_IN_TRUNCF:
1733 case BUILT_IN_TRUNCL:
1734 builtin_optab = btrunc_optab; break;
1735 case BUILT_IN_ROUND:
1736 case BUILT_IN_ROUNDF:
1737 case BUILT_IN_ROUNDL:
1738 builtin_optab = round_optab; break;
1739 case BUILT_IN_NEARBYINT:
1740 case BUILT_IN_NEARBYINTF:
1741 case BUILT_IN_NEARBYINTL:
1742 builtin_optab = nearbyint_optab; break;
1743 default:
1744 abort ();
1747 /* Make a suitable register to place result in. */
1748 mode = TYPE_MODE (TREE_TYPE (exp));
1750 if (! flag_errno_math || ! HONOR_NANS (mode))
1751 errno_set = false;
1753 /* Before working hard, check whether the instruction is available. */
1754 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1756 target = gen_reg_rtx (mode);
1758 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1759 need to expand the argument again. This way, we will not perform
1760 side-effects more the once. */
1761 narg = builtin_save_expr (arg);
1762 if (narg != arg)
1764 arglist = build_tree_list (NULL_TREE, arg);
1765 exp = build_function_call_expr (fndecl, arglist);
1768 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1770 emit_queue ();
1771 start_sequence ();
1773 /* Compute into TARGET.
1774 Set TARGET to wherever the result comes back. */
1775 target = expand_unop (mode, builtin_optab, op0, target, 0);
1777 if (target != 0)
1779 if (errno_set)
1780 expand_errno_check (exp, target);
1782 /* Output the entire sequence. */
1783 insns = get_insns ();
1784 end_sequence ();
1785 emit_insn (insns);
1786 return target;
1789 /* If we were unable to expand via the builtin, stop the sequence
1790 (without outputting the insns) and call to the library function
1791 with the stabilized argument list. */
1792 end_sequence ();
1795 before_call = get_last_insn ();
1797 target = expand_call (exp, target, target == const0_rtx);
1799 /* If this is a sqrt operation and we don't care about errno, try to
1800 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1801 This allows the semantics of the libcall to be visible to the RTL
1802 optimizers. */
1803 if (builtin_optab == sqrt_optab && !errno_set)
1805 /* Search backwards through the insns emitted by expand_call looking
1806 for the instruction with the REG_RETVAL note. */
1807 rtx last = get_last_insn ();
1808 while (last != before_call)
1810 if (find_reg_note (last, REG_RETVAL, NULL))
1812 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1813 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1814 two elements, i.e. symbol_ref(sqrt) and the operand. */
1815 if (note
1816 && GET_CODE (note) == EXPR_LIST
1817 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1818 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1819 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1821 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1822 /* Check operand is a register with expected mode. */
1823 if (operand
1824 && GET_CODE (operand) == REG
1825 && GET_MODE (operand) == mode)
1827 /* Replace the REG_EQUAL note with a SQRT rtx. */
1828 rtx equiv = gen_rtx_SQRT (mode, operand);
1829 set_unique_reg_note (last, REG_EQUAL, equiv);
1832 break;
1834 last = PREV_INSN (last);
1838 return target;
1841 /* Expand a call to the builtin binary math functions (pow and atan2).
1842 Return 0 if a normal call should be emitted rather than expanding the
1843 function in-line. EXP is the expression that is a call to the builtin
1844 function; if convenient, the result should be placed in TARGET.
1845 SUBTARGET may be used as the target for computing one of EXP's
1846 operands. */
1848 static rtx
1849 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1851 optab builtin_optab;
1852 rtx op0, op1, insns;
1853 tree fndecl = get_callee_fndecl (exp);
1854 tree arglist = TREE_OPERAND (exp, 1);
1855 tree arg0, arg1, temp, narg;
1856 enum machine_mode mode;
1857 bool errno_set = true;
1858 bool stable = true;
1860 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1861 return 0;
1863 arg0 = TREE_VALUE (arglist);
1864 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1866 switch (DECL_FUNCTION_CODE (fndecl))
1868 case BUILT_IN_POW:
1869 case BUILT_IN_POWF:
1870 case BUILT_IN_POWL:
1871 builtin_optab = pow_optab; break;
1872 case BUILT_IN_ATAN2:
1873 case BUILT_IN_ATAN2F:
1874 case BUILT_IN_ATAN2L:
1875 builtin_optab = atan2_optab; break;
1876 case BUILT_IN_FMOD:
1877 case BUILT_IN_FMODF:
1878 case BUILT_IN_FMODL:
1879 builtin_optab = fmod_optab; break;
1880 case BUILT_IN_DREM:
1881 case BUILT_IN_DREMF:
1882 case BUILT_IN_DREML:
1883 builtin_optab = drem_optab; break;
1884 default:
1885 abort ();
1888 /* Make a suitable register to place result in. */
1889 mode = TYPE_MODE (TREE_TYPE (exp));
1891 /* Before working hard, check whether the instruction is available. */
1892 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1893 return 0;
1895 target = gen_reg_rtx (mode);
1897 if (! flag_errno_math || ! HONOR_NANS (mode))
1898 errno_set = false;
1900 /* Always stabilize the argument list. */
1901 narg = builtin_save_expr (arg1);
1902 if (narg != arg1)
1904 temp = build_tree_list (NULL_TREE, narg);
1905 stable = false;
1907 else
1908 temp = TREE_CHAIN (arglist);
1910 narg = builtin_save_expr (arg0);
1911 if (narg != arg0)
1913 arglist = tree_cons (NULL_TREE, narg, temp);
1914 stable = false;
1916 else if (! stable)
1917 arglist = tree_cons (NULL_TREE, arg0, temp);
1919 if (! stable)
1920 exp = build_function_call_expr (fndecl, arglist);
1922 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1923 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1925 emit_queue ();
1926 start_sequence ();
1928 /* Compute into TARGET.
1929 Set TARGET to wherever the result comes back. */
1930 target = expand_binop (mode, builtin_optab, op0, op1,
1931 target, 0, OPTAB_DIRECT);
1933 /* If we were unable to expand via the builtin, stop the sequence
1934 (without outputting the insns) and call to the library function
1935 with the stabilized argument list. */
1936 if (target == 0)
1938 end_sequence ();
1939 return expand_call (exp, target, target == const0_rtx);
1942 if (errno_set)
1943 expand_errno_check (exp, target);
1945 /* Output the entire sequence. */
1946 insns = get_insns ();
1947 end_sequence ();
1948 emit_insn (insns);
1950 return target;
1953 /* Expand a call to the builtin sin and cos math functions.
1954 Return 0 if a normal call should be emitted rather than expanding the
1955 function in-line. EXP is the expression that is a call to the builtin
1956 function; if convenient, the result should be placed in TARGET.
1957 SUBTARGET may be used as the target for computing one of EXP's
1958 operands. */
1960 static rtx
1961 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1963 optab builtin_optab;
1964 rtx op0, insns, before_call;
1965 tree fndecl = get_callee_fndecl (exp);
1966 tree arglist = TREE_OPERAND (exp, 1);
1967 enum machine_mode mode;
1968 bool errno_set = false;
1969 tree arg, narg;
1971 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1972 return 0;
1974 arg = TREE_VALUE (arglist);
1976 switch (DECL_FUNCTION_CODE (fndecl))
1978 case BUILT_IN_SIN:
1979 case BUILT_IN_SINF:
1980 case BUILT_IN_SINL:
1981 case BUILT_IN_COS:
1982 case BUILT_IN_COSF:
1983 case BUILT_IN_COSL:
1984 builtin_optab = sincos_optab; break;
1985 default:
1986 abort ();
1989 /* Make a suitable register to place result in. */
1990 mode = TYPE_MODE (TREE_TYPE (exp));
1992 if (! flag_errno_math || ! HONOR_NANS (mode))
1993 errno_set = false;
1995 /* Check if sincos insn is available, otherwise fallback
1996 to sin or cos insn. */
1997 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1998 switch (DECL_FUNCTION_CODE (fndecl))
2000 case BUILT_IN_SIN:
2001 case BUILT_IN_SINF:
2002 case BUILT_IN_SINL:
2003 builtin_optab = sin_optab; break;
2004 case BUILT_IN_COS:
2005 case BUILT_IN_COSF:
2006 case BUILT_IN_COSL:
2007 builtin_optab = cos_optab; break;
2008 default:
2009 abort();
2013 /* Before working hard, check whether the instruction is available. */
2014 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2016 target = gen_reg_rtx (mode);
2018 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2019 need to expand the argument again. This way, we will not perform
2020 side-effects more the once. */
2021 narg = save_expr (arg);
2022 if (narg != arg)
2024 arglist = build_tree_list (NULL_TREE, arg);
2025 exp = build_function_call_expr (fndecl, arglist);
2028 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2030 emit_queue ();
2031 start_sequence ();
2033 /* Compute into TARGET.
2034 Set TARGET to wherever the result comes back. */
2035 if (builtin_optab == sincos_optab)
2037 switch (DECL_FUNCTION_CODE (fndecl))
2039 case BUILT_IN_SIN:
2040 case BUILT_IN_SINF:
2041 case BUILT_IN_SINL:
2042 if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
2043 abort();
2044 break;
2045 case BUILT_IN_COS:
2046 case BUILT_IN_COSF:
2047 case BUILT_IN_COSL:
2048 if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2049 abort();
2050 break;
2051 default:
2052 abort();
2055 else
2057 target = expand_unop (mode, builtin_optab, op0, target, 0);
2060 if (target != 0)
2062 if (errno_set)
2063 expand_errno_check (exp, target);
2065 /* Output the entire sequence. */
2066 insns = get_insns ();
2067 end_sequence ();
2068 emit_insn (insns);
2069 return target;
2072 /* If we were unable to expand via the builtin, stop the sequence
2073 (without outputting the insns) and call to the library function
2074 with the stabilized argument list. */
2075 end_sequence ();
2078 before_call = get_last_insn ();
2080 target = expand_call (exp, target, target == const0_rtx);
2082 return target;
2085 /* To evaluate powi(x,n), the floating point value x raised to the
2086 constant integer exponent n, we use a hybrid algorithm that
2087 combines the "window method" with look-up tables. For an
2088 introduction to exponentiation algorithms and "addition chains",
2089 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2090 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2091 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2092 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2094 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2095 multiplications to inline before calling the system library's pow
2096 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2097 so this default never requires calling pow, powf or powl. */
2099 #ifndef POWI_MAX_MULTS
2100 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2101 #endif
2103 /* The size of the "optimal power tree" lookup table. All
2104 exponents less than this value are simply looked up in the
2105 powi_table below. This threshold is also used to size the
2106 cache of pseudo registers that hold intermediate results. */
2107 #define POWI_TABLE_SIZE 256
2109 /* The size, in bits of the window, used in the "window method"
2110 exponentiation algorithm. This is equivalent to a radix of
2111 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2112 #define POWI_WINDOW_SIZE 3
2114 /* The following table is an efficient representation of an
2115 "optimal power tree". For each value, i, the corresponding
2116 value, j, in the table states than an optimal evaluation
2117 sequence for calculating pow(x,i) can be found by evaluating
2118 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2119 100 integers is given in Knuth's "Seminumerical algorithms". */
2121 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2123 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2124 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2125 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2126 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2127 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2128 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2129 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2130 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2131 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2132 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2133 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2134 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2135 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2136 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2137 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2138 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2139 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2140 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2141 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2142 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2143 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2144 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2145 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2146 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2147 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2148 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2149 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2150 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2151 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2152 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2153 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2154 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2158 /* Return the number of multiplications required to calculate
2159 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2160 subroutine of powi_cost. CACHE is an array indicating
2161 which exponents have already been calculated. */
2163 static int
2164 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2166 /* If we've already calculated this exponent, then this evaluation
2167 doesn't require any additional multiplications. */
2168 if (cache[n])
2169 return 0;
2171 cache[n] = true;
2172 return powi_lookup_cost (n - powi_table[n], cache)
2173 + powi_lookup_cost (powi_table[n], cache) + 1;
2176 /* Return the number of multiplications required to calculate
2177 powi(x,n) for an arbitrary x, given the exponent N. This
2178 function needs to be kept in sync with expand_powi below. */
2180 static int
2181 powi_cost (HOST_WIDE_INT n)
2183 bool cache[POWI_TABLE_SIZE];
2184 unsigned HOST_WIDE_INT digit;
2185 unsigned HOST_WIDE_INT val;
2186 int result;
2188 if (n == 0)
2189 return 0;
2191 /* Ignore the reciprocal when calculating the cost. */
2192 val = (n < 0) ? -n : n;
2194 /* Initialize the exponent cache. */
2195 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2196 cache[1] = true;
2198 result = 0;
2200 while (val >= POWI_TABLE_SIZE)
2202 if (val & 1)
2204 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2205 result += powi_lookup_cost (digit, cache)
2206 + POWI_WINDOW_SIZE + 1;
2207 val >>= POWI_WINDOW_SIZE;
2209 else
2211 val >>= 1;
2212 result++;
2216 return result + powi_lookup_cost (val, cache);
2219 /* Recursive subroutine of expand_powi. This function takes the array,
2220 CACHE, of already calculated exponents and an exponent N and returns
2221 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2223 static rtx
2224 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2226 unsigned HOST_WIDE_INT digit;
2227 rtx target, result;
2228 rtx op0, op1;
2230 if (n < POWI_TABLE_SIZE)
2232 if (cache[n])
2233 return cache[n];
2235 target = gen_reg_rtx (mode);
2236 cache[n] = target;
2238 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2239 op1 = expand_powi_1 (mode, powi_table[n], cache);
2241 else if (n & 1)
2243 target = gen_reg_rtx (mode);
2244 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2245 op0 = expand_powi_1 (mode, n - digit, cache);
2246 op1 = expand_powi_1 (mode, digit, cache);
2248 else
2250 target = gen_reg_rtx (mode);
2251 op0 = expand_powi_1 (mode, n >> 1, cache);
2252 op1 = op0;
2255 result = expand_mult (mode, op0, op1, target, 0);
2256 if (result != target)
2257 emit_move_insn (target, result);
2258 return target;
2261 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2262 floating point operand in mode MODE, and N is the exponent. This
2263 function needs to be kept in sync with powi_cost above. */
2265 static rtx
2266 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2268 unsigned HOST_WIDE_INT val;
2269 rtx cache[POWI_TABLE_SIZE];
2270 rtx result;
2272 if (n == 0)
2273 return CONST1_RTX (mode);
2275 val = (n < 0) ? -n : n;
2277 memset (cache, 0, sizeof (cache));
2278 cache[1] = x;
2280 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2282 /* If the original exponent was negative, reciprocate the result. */
2283 if (n < 0)
2284 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2285 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2287 return result;
2290 /* Expand a call to the pow built-in mathematical function. Return 0 if
2291 a normal call should be emitted rather than expanding the function
2292 in-line. EXP is the expression that is a call to the builtin
2293 function; if convenient, the result should be placed in TARGET. */
2295 static rtx
2296 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2298 tree arglist = TREE_OPERAND (exp, 1);
2299 tree arg0, arg1;
2301 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2302 return 0;
2304 arg0 = TREE_VALUE (arglist);
2305 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2307 if (TREE_CODE (arg1) == REAL_CST
2308 && ! TREE_CONSTANT_OVERFLOW (arg1))
2310 REAL_VALUE_TYPE cint;
2311 REAL_VALUE_TYPE c;
2312 HOST_WIDE_INT n;
2314 c = TREE_REAL_CST (arg1);
2315 n = real_to_integer (&c);
2316 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2317 if (real_identical (&c, &cint))
2319 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2320 Otherwise, check the number of multiplications required.
2321 Note that pow never sets errno for an integer exponent. */
2322 if ((n >= -1 && n <= 2)
2323 || (flag_unsafe_math_optimizations
2324 && ! optimize_size
2325 && powi_cost (n) <= POWI_MAX_MULTS))
2327 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2328 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2329 op = force_reg (mode, op);
2330 return expand_powi (op, mode, n);
2335 if (! flag_unsafe_math_optimizations)
2336 return NULL_RTX;
2337 return expand_builtin_mathfn_2 (exp, target, subtarget);
2340 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2341 if we failed the caller should emit a normal call, otherwise
2342 try to get the result in TARGET, if convenient. */
2344 static rtx
2345 expand_builtin_strlen (tree arglist, rtx target,
2346 enum machine_mode target_mode)
2348 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2349 return 0;
2350 else
2352 rtx pat;
2353 tree len, src = TREE_VALUE (arglist);
2354 rtx result, src_reg, char_rtx, before_strlen;
2355 enum machine_mode insn_mode = target_mode, char_mode;
2356 enum insn_code icode = CODE_FOR_nothing;
2357 int align;
2359 /* If the length can be computed at compile-time, return it. */
2360 len = c_strlen (src, 0);
2361 if (len)
2362 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2364 /* If the length can be computed at compile-time and is constant
2365 integer, but there are side-effects in src, evaluate
2366 src for side-effects, then return len.
2367 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2368 can be optimized into: i++; x = 3; */
2369 len = c_strlen (src, 1);
2370 if (len && TREE_CODE (len) == INTEGER_CST)
2372 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2373 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2376 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2378 /* If SRC is not a pointer type, don't do this operation inline. */
2379 if (align == 0)
2380 return 0;
2382 /* Bail out if we can't compute strlen in the right mode. */
2383 while (insn_mode != VOIDmode)
2385 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2386 if (icode != CODE_FOR_nothing)
2387 break;
2389 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2391 if (insn_mode == VOIDmode)
2392 return 0;
2394 /* Make a place to write the result of the instruction. */
2395 result = target;
2396 if (! (result != 0
2397 && GET_CODE (result) == REG
2398 && GET_MODE (result) == insn_mode
2399 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2400 result = gen_reg_rtx (insn_mode);
2402 /* Make a place to hold the source address. We will not expand
2403 the actual source until we are sure that the expansion will
2404 not fail -- there are trees that cannot be expanded twice. */
2405 src_reg = gen_reg_rtx (Pmode);
2407 /* Mark the beginning of the strlen sequence so we can emit the
2408 source operand later. */
2409 before_strlen = get_last_insn ();
2411 char_rtx = const0_rtx;
2412 char_mode = insn_data[(int) icode].operand[2].mode;
2413 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2414 char_mode))
2415 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2417 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2418 char_rtx, GEN_INT (align));
2419 if (! pat)
2420 return 0;
2421 emit_insn (pat);
2423 /* Now that we are assured of success, expand the source. */
2424 start_sequence ();
2425 pat = memory_address (BLKmode,
2426 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2427 if (pat != src_reg)
2428 emit_move_insn (src_reg, pat);
2429 pat = get_insns ();
2430 end_sequence ();
2432 if (before_strlen)
2433 emit_insn_after (pat, before_strlen);
2434 else
2435 emit_insn_before (pat, get_insns ());
2437 /* Return the value in the proper mode for this function. */
2438 if (GET_MODE (result) == target_mode)
2439 target = result;
2440 else if (target != 0)
2441 convert_move (target, result, 0);
2442 else
2443 target = convert_to_mode (target_mode, result, 0);
2445 return target;
2449 /* Expand a call to the strstr builtin. Return 0 if we failed the
2450 caller should emit a normal call, otherwise try to get the result
2451 in TARGET, if convenient (and in mode MODE if that's convenient). */
2453 static rtx
2454 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2456 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2457 return 0;
2458 else
2460 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2461 tree fn;
2462 const char *p1, *p2;
2464 p2 = c_getstr (s2);
2465 if (p2 == NULL)
2466 return 0;
2468 p1 = c_getstr (s1);
2469 if (p1 != NULL)
2471 const char *r = strstr (p1, p2);
2473 if (r == NULL)
2474 return const0_rtx;
2476 /* Return an offset into the constant string argument. */
2477 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2478 fold_convert (TREE_TYPE (s1),
2479 ssize_int (r - p1)))),
2480 target, mode, EXPAND_NORMAL);
2483 if (p2[0] == '\0')
2484 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2486 if (p2[1] != '\0')
2487 return 0;
2489 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2490 if (!fn)
2491 return 0;
2493 /* New argument list transforming strstr(s1, s2) to
2494 strchr(s1, s2[0]). */
2495 arglist =
2496 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2497 arglist = tree_cons (NULL_TREE, s1, arglist);
2498 return expand_expr (build_function_call_expr (fn, arglist),
2499 target, mode, EXPAND_NORMAL);
2503 /* Expand a call to the strchr builtin. Return 0 if we failed the
2504 caller should emit a normal call, otherwise try to get the result
2505 in TARGET, if convenient (and in mode MODE if that's convenient). */
2507 static rtx
2508 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2510 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2511 return 0;
2512 else
2514 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2515 const char *p1;
2517 if (TREE_CODE (s2) != INTEGER_CST)
2518 return 0;
2520 p1 = c_getstr (s1);
2521 if (p1 != NULL)
2523 char c;
2524 const char *r;
2526 if (target_char_cast (s2, &c))
2527 return 0;
2529 r = strchr (p1, c);
2531 if (r == NULL)
2532 return const0_rtx;
2534 /* Return an offset into the constant string argument. */
2535 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2536 fold_convert (TREE_TYPE (s1),
2537 ssize_int (r - p1)))),
2538 target, mode, EXPAND_NORMAL);
2541 /* FIXME: Should use here strchrM optab so that ports can optimize
2542 this. */
2543 return 0;
2547 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2548 caller should emit a normal call, otherwise try to get the result
2549 in TARGET, if convenient (and in mode MODE if that's convenient). */
2551 static rtx
2552 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2554 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2555 return 0;
2556 else
2558 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2559 tree fn;
2560 const char *p1;
2562 if (TREE_CODE (s2) != INTEGER_CST)
2563 return 0;
2565 p1 = c_getstr (s1);
2566 if (p1 != NULL)
2568 char c;
2569 const char *r;
2571 if (target_char_cast (s2, &c))
2572 return 0;
2574 r = strrchr (p1, c);
2576 if (r == NULL)
2577 return const0_rtx;
2579 /* Return an offset into the constant string argument. */
2580 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2581 fold_convert (TREE_TYPE (s1),
2582 ssize_int (r - p1)))),
2583 target, mode, EXPAND_NORMAL);
2586 if (! integer_zerop (s2))
2587 return 0;
2589 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2590 if (!fn)
2591 return 0;
2593 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2594 return expand_expr (build_function_call_expr (fn, arglist),
2595 target, mode, EXPAND_NORMAL);
2599 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2600 caller should emit a normal call, otherwise try to get the result
2601 in TARGET, if convenient (and in mode MODE if that's convenient). */
2603 static rtx
2604 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2606 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2607 return 0;
2608 else
2610 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2611 tree fn;
2612 const char *p1, *p2;
2614 p2 = c_getstr (s2);
2615 if (p2 == NULL)
2616 return 0;
2618 p1 = c_getstr (s1);
2619 if (p1 != NULL)
2621 const char *r = strpbrk (p1, p2);
2623 if (r == NULL)
2624 return const0_rtx;
2626 /* Return an offset into the constant string argument. */
2627 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2628 fold_convert (TREE_TYPE (s1),
2629 ssize_int (r - p1)))),
2630 target, mode, EXPAND_NORMAL);
2633 if (p2[0] == '\0')
2635 /* strpbrk(x, "") == NULL.
2636 Evaluate and ignore the arguments in case they had
2637 side-effects. */
2638 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2639 return const0_rtx;
2642 if (p2[1] != '\0')
2643 return 0; /* Really call strpbrk. */
2645 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2646 if (!fn)
2647 return 0;
2649 /* New argument list transforming strpbrk(s1, s2) to
2650 strchr(s1, s2[0]). */
2651 arglist =
2652 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2653 arglist = tree_cons (NULL_TREE, s1, arglist);
2654 return expand_expr (build_function_call_expr (fn, arglist),
2655 target, mode, EXPAND_NORMAL);
2659 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2660 bytes from constant string DATA + OFFSET and return it as target
2661 constant. */
2663 static rtx
2664 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2665 enum machine_mode mode)
2667 const char *str = (const char *) data;
2669 if (offset < 0
2670 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2671 > strlen (str) + 1))
2672 abort (); /* Attempt to read past the end of constant string. */
2674 return c_readstr (str + offset, mode);
2677 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2678 Return 0 if we failed, the caller should emit a normal call,
2679 otherwise try to get the result in TARGET, if convenient (and in
2680 mode MODE if that's convenient). */
2681 static rtx
2682 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2684 if (!validate_arglist (arglist,
2685 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2686 return 0;
2687 else
2689 tree dest = TREE_VALUE (arglist);
2690 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2691 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2692 const char *src_str;
2693 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2694 unsigned int dest_align
2695 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2696 rtx dest_mem, src_mem, dest_addr, len_rtx;
2698 /* If DEST is not a pointer type, call the normal function. */
2699 if (dest_align == 0)
2700 return 0;
2702 /* If the LEN parameter is zero, return DEST. */
2703 if (integer_zerop (len))
2705 /* Evaluate and ignore SRC in case it has side-effects. */
2706 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2707 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2710 /* If SRC and DEST are the same (and not volatile), return DEST. */
2711 if (operand_equal_p (src, dest, 0))
2713 /* Evaluate and ignore LEN in case it has side-effects. */
2714 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2715 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2718 /* If either SRC is not a pointer type, don't do this
2719 operation in-line. */
2720 if (src_align == 0)
2721 return 0;
2723 dest_mem = get_memory_rtx (dest);
2724 set_mem_align (dest_mem, dest_align);
2725 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2726 src_str = c_getstr (src);
2728 /* If SRC is a string constant and block move would be done
2729 by pieces, we can avoid loading the string from memory
2730 and only stored the computed constants. */
2731 if (src_str
2732 && GET_CODE (len_rtx) == CONST_INT
2733 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2734 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2735 (void *) src_str, dest_align))
2737 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2738 builtin_memcpy_read_str,
2739 (void *) src_str, dest_align, 0);
2740 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2741 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2742 return dest_mem;
2745 src_mem = get_memory_rtx (src);
2746 set_mem_align (src_mem, src_align);
2748 /* Copy word part most expediently. */
2749 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2750 BLOCK_OP_NORMAL);
2752 if (dest_addr == 0)
2754 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2755 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2757 return dest_addr;
2761 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2762 Return 0 if we failed the caller should emit a normal call,
2763 otherwise try to get the result in TARGET, if convenient (and in
2764 mode MODE if that's convenient). If ENDP is 0 return the
2765 destination pointer, if ENDP is 1 return the end pointer ala
2766 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2767 stpcpy. */
2769 static rtx
2770 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2771 int endp)
2773 if (!validate_arglist (arglist,
2774 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2775 return 0;
2776 /* If return value is ignored, transform mempcpy into memcpy. */
2777 else if (target == const0_rtx)
2779 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2781 if (!fn)
2782 return 0;
2784 return expand_expr (build_function_call_expr (fn, arglist),
2785 target, mode, EXPAND_NORMAL);
2787 else
2789 tree dest = TREE_VALUE (arglist);
2790 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2791 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2792 const char *src_str;
2793 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2794 unsigned int dest_align
2795 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2796 rtx dest_mem, src_mem, len_rtx;
2798 /* If DEST is not a pointer type, call the normal function. */
2799 if (dest_align == 0)
2800 return 0;
2802 /* If SRC and DEST are the same (and not volatile), do nothing. */
2803 if (operand_equal_p (src, dest, 0))
2805 tree expr;
2807 if (endp == 0)
2809 /* Evaluate and ignore LEN in case it has side-effects. */
2810 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2811 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2814 if (endp == 2)
2815 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2816 integer_one_node));
2817 len = fold_convert (TREE_TYPE (dest), len);
2818 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2819 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2822 /* If LEN is not constant, call the normal function. */
2823 if (! host_integerp (len, 1))
2824 return 0;
2826 /* If the LEN parameter is zero, return DEST. */
2827 if (tree_low_cst (len, 1) == 0)
2829 /* Evaluate and ignore SRC in case it has side-effects. */
2830 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2831 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2834 /* If either SRC is not a pointer type, don't do this
2835 operation in-line. */
2836 if (src_align == 0)
2837 return 0;
2839 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2840 src_str = c_getstr (src);
2842 /* If SRC is a string constant and block move would be done
2843 by pieces, we can avoid loading the string from memory
2844 and only stored the computed constants. */
2845 if (src_str
2846 && GET_CODE (len_rtx) == CONST_INT
2847 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2848 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2849 (void *) src_str, dest_align))
2851 dest_mem = get_memory_rtx (dest);
2852 set_mem_align (dest_mem, dest_align);
2853 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2854 builtin_memcpy_read_str,
2855 (void *) src_str, dest_align, endp);
2856 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2857 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2858 return dest_mem;
2861 if (GET_CODE (len_rtx) == CONST_INT
2862 && can_move_by_pieces (INTVAL (len_rtx),
2863 MIN (dest_align, src_align)))
2865 dest_mem = get_memory_rtx (dest);
2866 set_mem_align (dest_mem, dest_align);
2867 src_mem = get_memory_rtx (src);
2868 set_mem_align (src_mem, src_align);
2869 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2870 MIN (dest_align, src_align), endp);
2871 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2872 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2873 return dest_mem;
2876 return 0;
2880 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2881 if we failed the caller should emit a normal call. */
2883 static rtx
2884 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2886 if (!validate_arglist (arglist,
2887 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2888 return 0;
2889 else
2891 tree dest = TREE_VALUE (arglist);
2892 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2893 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2895 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2896 unsigned int dest_align
2897 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2899 /* If DEST is not a pointer type, call the normal function. */
2900 if (dest_align == 0)
2901 return 0;
2903 /* If the LEN parameter is zero, return DEST. */
2904 if (integer_zerop (len))
2906 /* Evaluate and ignore SRC in case it has side-effects. */
2907 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2908 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2911 /* If SRC and DEST are the same (and not volatile), return DEST. */
2912 if (operand_equal_p (src, dest, 0))
2914 /* Evaluate and ignore LEN in case it has side-effects. */
2915 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2916 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2919 /* If either SRC is not a pointer type, don't do this
2920 operation in-line. */
2921 if (src_align == 0)
2922 return 0;
2924 /* If src is categorized for a readonly section we can use
2925 normal memcpy. */
2926 if (readonly_data_expr (src))
2928 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2929 if (!fn)
2930 return 0;
2931 return expand_expr (build_function_call_expr (fn, arglist),
2932 target, mode, EXPAND_NORMAL);
2935 /* Otherwise, call the normal function. */
2936 return 0;
2940 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2941 if we failed the caller should emit a normal call. */
2943 static rtx
2944 expand_builtin_bcopy (tree arglist)
2946 tree src, dest, size, newarglist;
2948 if (!validate_arglist (arglist,
2949 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2950 return NULL_RTX;
2952 src = TREE_VALUE (arglist);
2953 dest = TREE_VALUE (TREE_CHAIN (arglist));
2954 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2956 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2957 memmove(ptr y, ptr x, size_t z). This is done this way
2958 so that if it isn't expanded inline, we fallback to
2959 calling bcopy instead of memmove. */
2961 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2962 newarglist = tree_cons (NULL_TREE, src, newarglist);
2963 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2965 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2968 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2969 if we failed the caller should emit a normal call, otherwise try to get
2970 the result in TARGET, if convenient (and in mode MODE if that's
2971 convenient). */
2973 static rtx
2974 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2976 tree fn, len, src, dst;
2978 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2979 return 0;
2981 src = TREE_VALUE (TREE_CHAIN (arglist));
2982 dst = TREE_VALUE (arglist);
2984 /* If SRC and DST are equal (and not volatile), return DST. */
2985 if (operand_equal_p (src, dst, 0))
2986 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2988 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2989 if (!fn)
2990 return 0;
2992 len = c_strlen (src, 1);
2993 if (len == 0 || TREE_SIDE_EFFECTS (len))
2994 return 0;
2996 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2997 arglist = build_tree_list (NULL_TREE, len);
2998 arglist = tree_cons (NULL_TREE, src, arglist);
2999 arglist = tree_cons (NULL_TREE, dst, arglist);
3000 return expand_expr (build_function_call_expr (fn, arglist),
3001 target, mode, EXPAND_NORMAL);
3004 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3005 Return 0 if we failed the caller should emit a normal call,
3006 otherwise try to get the result in TARGET, if convenient (and in
3007 mode MODE if that's convenient). */
3009 static rtx
3010 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3012 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3013 return 0;
3014 else
3016 tree dst, src, len;
3018 /* If return value is ignored, transform stpcpy into strcpy. */
3019 if (target == const0_rtx)
3021 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3022 if (!fn)
3023 return 0;
3025 return expand_expr (build_function_call_expr (fn, arglist),
3026 target, mode, EXPAND_NORMAL);
3029 /* Ensure we get an actual string whose length can be evaluated at
3030 compile-time, not an expression containing a string. This is
3031 because the latter will potentially produce pessimized code
3032 when used to produce the return value. */
3033 src = TREE_VALUE (TREE_CHAIN (arglist));
3034 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3035 return 0;
3037 dst = TREE_VALUE (arglist);
3038 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
3039 arglist = build_tree_list (NULL_TREE, len);
3040 arglist = tree_cons (NULL_TREE, src, arglist);
3041 arglist = tree_cons (NULL_TREE, dst, arglist);
3042 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
3046 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3047 bytes from constant string DATA + OFFSET and return it as target
3048 constant. */
3050 static rtx
3051 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3052 enum machine_mode mode)
3054 const char *str = (const char *) data;
3056 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3057 return const0_rtx;
3059 return c_readstr (str + offset, mode);
3062 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3063 if we failed the caller should emit a normal call. */
3065 static rtx
3066 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3068 if (!validate_arglist (arglist,
3069 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3070 return 0;
3071 else
3073 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3074 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3075 tree fn;
3077 /* We must be passed a constant len parameter. */
3078 if (TREE_CODE (len) != INTEGER_CST)
3079 return 0;
3081 /* If the len parameter is zero, return the dst parameter. */
3082 if (integer_zerop (len))
3084 /* Evaluate and ignore the src argument in case it has
3085 side-effects. */
3086 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3087 VOIDmode, EXPAND_NORMAL);
3088 /* Return the dst parameter. */
3089 return expand_expr (TREE_VALUE (arglist), target, mode,
3090 EXPAND_NORMAL);
3093 /* Now, we must be passed a constant src ptr parameter. */
3094 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3095 return 0;
3097 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3099 /* We're required to pad with trailing zeros if the requested
3100 len is greater than strlen(s2)+1. In that case try to
3101 use store_by_pieces, if it fails, punt. */
3102 if (tree_int_cst_lt (slen, len))
3104 tree dest = TREE_VALUE (arglist);
3105 unsigned int dest_align
3106 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3107 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3108 rtx dest_mem;
3110 if (!p || dest_align == 0 || !host_integerp (len, 1)
3111 || !can_store_by_pieces (tree_low_cst (len, 1),
3112 builtin_strncpy_read_str,
3113 (void *) p, dest_align))
3114 return 0;
3116 dest_mem = get_memory_rtx (dest);
3117 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3118 builtin_strncpy_read_str,
3119 (void *) p, dest_align, 0);
3120 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3121 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3122 return dest_mem;
3125 /* OK transform into builtin memcpy. */
3126 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3127 if (!fn)
3128 return 0;
3129 return expand_expr (build_function_call_expr (fn, arglist),
3130 target, mode, EXPAND_NORMAL);
3134 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3135 bytes from constant string DATA + OFFSET and return it as target
3136 constant. */
3138 static rtx
3139 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3140 enum machine_mode mode)
3142 const char *c = (const char *) data;
3143 char *p = alloca (GET_MODE_SIZE (mode));
3145 memset (p, *c, GET_MODE_SIZE (mode));
3147 return c_readstr (p, mode);
3150 /* Callback routine for store_by_pieces. Return the RTL of a register
3151 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3152 char value given in the RTL register data. For example, if mode is
3153 4 bytes wide, return the RTL for 0x01010101*data. */
3155 static rtx
3156 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3157 enum machine_mode mode)
3159 rtx target, coeff;
3160 size_t size;
3161 char *p;
3163 size = GET_MODE_SIZE (mode);
3164 if (size == 1)
3165 return (rtx) data;
3167 p = alloca (size);
3168 memset (p, 1, size);
3169 coeff = c_readstr (p, mode);
3171 target = convert_to_mode (mode, (rtx) data, 1);
3172 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3173 return force_reg (mode, target);
3176 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3177 if we failed the caller should emit a normal call, otherwise try to get
3178 the result in TARGET, if convenient (and in mode MODE if that's
3179 convenient). */
3181 static rtx
3182 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3184 if (!validate_arglist (arglist,
3185 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3186 return 0;
3187 else
3189 tree dest = TREE_VALUE (arglist);
3190 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3191 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3192 char c;
3194 unsigned int dest_align
3195 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3196 rtx dest_mem, dest_addr, len_rtx;
3198 /* If DEST is not a pointer type, don't do this
3199 operation in-line. */
3200 if (dest_align == 0)
3201 return 0;
3203 /* If the LEN parameter is zero, return DEST. */
3204 if (integer_zerop (len))
3206 /* Evaluate and ignore VAL in case it has side-effects. */
3207 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3208 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3211 if (TREE_CODE (val) != INTEGER_CST)
3213 rtx val_rtx;
3215 if (!host_integerp (len, 1))
3216 return 0;
3218 if (optimize_size && tree_low_cst (len, 1) > 1)
3219 return 0;
3221 /* Assume that we can memset by pieces if we can store the
3222 * the coefficients by pieces (in the required modes).
3223 * We can't pass builtin_memset_gen_str as that emits RTL. */
3224 c = 1;
3225 if (!can_store_by_pieces (tree_low_cst (len, 1),
3226 builtin_memset_read_str,
3227 &c, dest_align))
3228 return 0;
3230 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3231 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3232 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3233 val_rtx);
3234 dest_mem = get_memory_rtx (dest);
3235 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3236 builtin_memset_gen_str,
3237 val_rtx, dest_align, 0);
3238 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3239 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3240 return dest_mem;
3243 if (target_char_cast (val, &c))
3244 return 0;
3246 if (c)
3248 if (!host_integerp (len, 1))
3249 return 0;
3250 if (!can_store_by_pieces (tree_low_cst (len, 1),
3251 builtin_memset_read_str, &c,
3252 dest_align))
3253 return 0;
3255 dest_mem = get_memory_rtx (dest);
3256 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3257 builtin_memset_read_str,
3258 &c, dest_align, 0);
3259 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3260 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3261 return dest_mem;
3264 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3266 dest_mem = get_memory_rtx (dest);
3267 set_mem_align (dest_mem, dest_align);
3268 dest_addr = clear_storage (dest_mem, len_rtx);
3270 if (dest_addr == 0)
3272 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3273 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3276 return dest_addr;
3280 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3281 if we failed the caller should emit a normal call. */
3283 static rtx
3284 expand_builtin_bzero (tree arglist)
3286 tree dest, size, newarglist;
3288 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3289 return NULL_RTX;
3291 dest = TREE_VALUE (arglist);
3292 size = TREE_VALUE (TREE_CHAIN (arglist));
3294 /* New argument list transforming bzero(ptr x, int y) to
3295 memset(ptr x, int 0, size_t y). This is done this way
3296 so that if it isn't expanded inline, we fallback to
3297 calling bzero instead of memset. */
3299 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3300 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3301 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3303 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3306 /* Expand expression EXP, which is a call to the memcmp built-in function.
3307 ARGLIST is the argument list for this call. Return 0 if we failed and the
3308 caller should emit a normal call, otherwise try to get the result in
3309 TARGET, if convenient (and in mode MODE, if that's convenient). */
3311 static rtx
3312 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3313 enum machine_mode mode)
3315 tree arg1, arg2, len;
3316 const char *p1, *p2;
3318 if (!validate_arglist (arglist,
3319 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3320 return 0;
3322 arg1 = TREE_VALUE (arglist);
3323 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3324 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3326 /* If the len parameter is zero, return zero. */
3327 if (integer_zerop (len))
3329 /* Evaluate and ignore arg1 and arg2 in case they have
3330 side-effects. */
3331 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3332 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3333 return const0_rtx;
3336 /* If both arguments are equal (and not volatile), return zero. */
3337 if (operand_equal_p (arg1, arg2, 0))
3339 /* Evaluate and ignore len in case it has side-effects. */
3340 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3341 return const0_rtx;
3344 p1 = c_getstr (arg1);
3345 p2 = c_getstr (arg2);
3347 /* If all arguments are constant, and the value of len is not greater
3348 than the lengths of arg1 and arg2, evaluate at compile-time. */
3349 if (host_integerp (len, 1) && p1 && p2
3350 && compare_tree_int (len, strlen (p1) + 1) <= 0
3351 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3353 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3355 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3358 /* If len parameter is one, return an expression corresponding to
3359 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3360 if (integer_onep (len))
3362 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3363 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3364 tree ind1 =
3365 fold (build1 (CONVERT_EXPR, integer_type_node,
3366 build1 (INDIRECT_REF, cst_uchar_node,
3367 fold_convert (cst_uchar_ptr_node, arg1))));
3368 tree ind2 =
3369 fold (build1 (CONVERT_EXPR, integer_type_node,
3370 build1 (INDIRECT_REF, cst_uchar_node,
3371 fold_convert (cst_uchar_ptr_node, arg2))));
3372 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3373 return expand_expr (result, target, mode, EXPAND_NORMAL);
3376 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3378 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3379 rtx result;
3380 rtx insn;
3382 int arg1_align
3383 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3384 int arg2_align
3385 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3386 enum machine_mode insn_mode;
3388 #ifdef HAVE_cmpmemsi
3389 if (HAVE_cmpmemsi)
3390 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3391 else
3392 #endif
3393 #ifdef HAVE_cmpstrsi
3394 if (HAVE_cmpstrsi)
3395 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3396 else
3397 #endif
3398 return 0;
3400 /* If we don't have POINTER_TYPE, call the function. */
3401 if (arg1_align == 0 || arg2_align == 0)
3402 return 0;
3404 /* Make a place to write the result of the instruction. */
3405 result = target;
3406 if (! (result != 0
3407 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3408 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3409 result = gen_reg_rtx (insn_mode);
3411 arg1_rtx = get_memory_rtx (arg1);
3412 arg2_rtx = get_memory_rtx (arg2);
3413 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3414 #ifdef HAVE_cmpmemsi
3415 if (HAVE_cmpmemsi)
3416 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3417 GEN_INT (MIN (arg1_align, arg2_align)));
3418 else
3419 #endif
3420 #ifdef HAVE_cmpstrsi
3421 if (HAVE_cmpstrsi)
3422 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3423 GEN_INT (MIN (arg1_align, arg2_align)));
3424 else
3425 #endif
3426 abort ();
3428 if (insn)
3429 emit_insn (insn);
3430 else
3431 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3432 TYPE_MODE (integer_type_node), 3,
3433 XEXP (arg1_rtx, 0), Pmode,
3434 XEXP (arg2_rtx, 0), Pmode,
3435 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3436 TYPE_UNSIGNED (sizetype)),
3437 TYPE_MODE (sizetype));
3439 /* Return the value in the proper mode for this function. */
3440 mode = TYPE_MODE (TREE_TYPE (exp));
3441 if (GET_MODE (result) == mode)
3442 return result;
3443 else if (target != 0)
3445 convert_move (target, result, 0);
3446 return target;
3448 else
3449 return convert_to_mode (mode, result, 0);
3451 #endif
3453 return 0;
3456 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3457 if we failed the caller should emit a normal call, otherwise try to get
3458 the result in TARGET, if convenient. */
3460 static rtx
3461 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3463 tree arglist = TREE_OPERAND (exp, 1);
3464 tree arg1, arg2;
3465 const char *p1, *p2;
3467 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3468 return 0;
3470 arg1 = TREE_VALUE (arglist);
3471 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3473 /* If both arguments are equal (and not volatile), return zero. */
3474 if (operand_equal_p (arg1, arg2, 0))
3475 return const0_rtx;
3477 p1 = c_getstr (arg1);
3478 p2 = c_getstr (arg2);
3480 if (p1 && p2)
3482 const int i = strcmp (p1, p2);
3483 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3486 /* If either arg is "", return an expression corresponding to
3487 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3488 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3490 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3491 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3492 tree ind1 =
3493 fold (build1 (CONVERT_EXPR, integer_type_node,
3494 build1 (INDIRECT_REF, cst_uchar_node,
3495 fold_convert (cst_uchar_ptr_node, arg1))));
3496 tree ind2 =
3497 fold (build1 (CONVERT_EXPR, integer_type_node,
3498 build1 (INDIRECT_REF, cst_uchar_node,
3499 fold_convert (cst_uchar_ptr_node, arg2))));
3500 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3501 return expand_expr (result, target, mode, EXPAND_NORMAL);
3504 #ifdef HAVE_cmpstrsi
3505 if (HAVE_cmpstrsi)
3507 tree len, len1, len2;
3508 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3509 rtx result, insn;
3510 tree fndecl;
3512 int arg1_align
3513 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3514 int arg2_align
3515 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3516 enum machine_mode insn_mode
3517 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3519 len1 = c_strlen (arg1, 1);
3520 len2 = c_strlen (arg2, 1);
3522 if (len1)
3523 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3524 if (len2)
3525 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3527 /* If we don't have a constant length for the first, use the length
3528 of the second, if we know it. We don't require a constant for
3529 this case; some cost analysis could be done if both are available
3530 but neither is constant. For now, assume they're equally cheap,
3531 unless one has side effects. If both strings have constant lengths,
3532 use the smaller. */
3534 if (!len1)
3535 len = len2;
3536 else if (!len2)
3537 len = len1;
3538 else if (TREE_SIDE_EFFECTS (len1))
3539 len = len2;
3540 else if (TREE_SIDE_EFFECTS (len2))
3541 len = len1;
3542 else if (TREE_CODE (len1) != INTEGER_CST)
3543 len = len2;
3544 else if (TREE_CODE (len2) != INTEGER_CST)
3545 len = len1;
3546 else if (tree_int_cst_lt (len1, len2))
3547 len = len1;
3548 else
3549 len = len2;
3551 /* If both arguments have side effects, we cannot optimize. */
3552 if (!len || TREE_SIDE_EFFECTS (len))
3553 return 0;
3555 /* If we don't have POINTER_TYPE, call the function. */
3556 if (arg1_align == 0 || arg2_align == 0)
3557 return 0;
3559 /* Make a place to write the result of the instruction. */
3560 result = target;
3561 if (! (result != 0
3562 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3563 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3564 result = gen_reg_rtx (insn_mode);
3566 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3567 arg1 = builtin_save_expr (arg1);
3568 arg2 = builtin_save_expr (arg2);
3570 arg1_rtx = get_memory_rtx (arg1);
3571 arg2_rtx = get_memory_rtx (arg2);
3572 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3573 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3574 GEN_INT (MIN (arg1_align, arg2_align)));
3575 if (insn)
3577 emit_insn (insn);
3579 /* Return the value in the proper mode for this function. */
3580 mode = TYPE_MODE (TREE_TYPE (exp));
3581 if (GET_MODE (result) == mode)
3582 return result;
3583 if (target == 0)
3584 return convert_to_mode (mode, result, 0);
3585 convert_move (target, result, 0);
3586 return target;
3589 /* Expand the library call ourselves using a stabilized argument
3590 list to avoid re-evaluating the function's arguments twice. */
3591 arglist = build_tree_list (NULL_TREE, arg2);
3592 arglist = tree_cons (NULL_TREE, arg1, arglist);
3593 fndecl = get_callee_fndecl (exp);
3594 exp = build_function_call_expr (fndecl, arglist);
3595 return expand_call (exp, target, target == const0_rtx);
3597 #endif
3598 return 0;
3601 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3602 if we failed the caller should emit a normal call, otherwise try to get
3603 the result in TARGET, if convenient. */
3605 static rtx
3606 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3608 tree arglist = TREE_OPERAND (exp, 1);
3609 tree arg1, arg2, arg3;
3610 const char *p1, *p2;
3612 if (!validate_arglist (arglist,
3613 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3614 return 0;
3616 arg1 = TREE_VALUE (arglist);
3617 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3618 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3620 /* If the len parameter is zero, return zero. */
3621 if (integer_zerop (arg3))
3623 /* Evaluate and ignore arg1 and arg2 in case they have
3624 side-effects. */
3625 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3626 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3627 return const0_rtx;
3630 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3631 if (operand_equal_p (arg1, arg2, 0))
3633 /* Evaluate and ignore arg3 in case it has side-effects. */
3634 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3635 return const0_rtx;
3638 p1 = c_getstr (arg1);
3639 p2 = c_getstr (arg2);
3641 /* If all arguments are constant, evaluate at compile-time. */
3642 if (host_integerp (arg3, 1) && p1 && p2)
3644 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3645 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3648 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3649 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3650 if (host_integerp (arg3, 1)
3651 && (tree_low_cst (arg3, 1) == 1
3652 || (tree_low_cst (arg3, 1) > 1
3653 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3655 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3656 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3657 tree ind1 =
3658 fold (build1 (CONVERT_EXPR, integer_type_node,
3659 build1 (INDIRECT_REF, cst_uchar_node,
3660 fold_convert (cst_uchar_ptr_node, arg1))));
3661 tree ind2 =
3662 fold (build1 (CONVERT_EXPR, integer_type_node,
3663 build1 (INDIRECT_REF, cst_uchar_node,
3664 fold_convert (cst_uchar_ptr_node, arg2))));
3665 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3666 return expand_expr (result, target, mode, EXPAND_NORMAL);
3669 /* If c_strlen can determine an expression for one of the string
3670 lengths, and it doesn't have side effects, then emit cmpstrsi
3671 using length MIN(strlen(string)+1, arg3). */
3672 #ifdef HAVE_cmpstrsi
3673 if (HAVE_cmpstrsi)
3675 tree len, len1, len2;
3676 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3677 rtx result, insn;
3678 tree fndecl;
3680 int arg1_align
3681 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3682 int arg2_align
3683 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3684 enum machine_mode insn_mode
3685 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3687 len1 = c_strlen (arg1, 1);
3688 len2 = c_strlen (arg2, 1);
3690 if (len1)
3691 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3692 if (len2)
3693 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3695 /* If we don't have a constant length for the first, use the length
3696 of the second, if we know it. We don't require a constant for
3697 this case; some cost analysis could be done if both are available
3698 but neither is constant. For now, assume they're equally cheap,
3699 unless one has side effects. If both strings have constant lengths,
3700 use the smaller. */
3702 if (!len1)
3703 len = len2;
3704 else if (!len2)
3705 len = len1;
3706 else if (TREE_SIDE_EFFECTS (len1))
3707 len = len2;
3708 else if (TREE_SIDE_EFFECTS (len2))
3709 len = len1;
3710 else if (TREE_CODE (len1) != INTEGER_CST)
3711 len = len2;
3712 else if (TREE_CODE (len2) != INTEGER_CST)
3713 len = len1;
3714 else if (tree_int_cst_lt (len1, len2))
3715 len = len1;
3716 else
3717 len = len2;
3719 /* If both arguments have side effects, we cannot optimize. */
3720 if (!len || TREE_SIDE_EFFECTS (len))
3721 return 0;
3723 /* The actual new length parameter is MIN(len,arg3). */
3724 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3726 /* If we don't have POINTER_TYPE, call the function. */
3727 if (arg1_align == 0 || arg2_align == 0)
3728 return 0;
3730 /* Make a place to write the result of the instruction. */
3731 result = target;
3732 if (! (result != 0
3733 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3734 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3735 result = gen_reg_rtx (insn_mode);
3737 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3738 arg1 = builtin_save_expr (arg1);
3739 arg2 = builtin_save_expr (arg2);
3740 len = builtin_save_expr (len);
3742 arg1_rtx = get_memory_rtx (arg1);
3743 arg2_rtx = get_memory_rtx (arg2);
3744 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3745 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3746 GEN_INT (MIN (arg1_align, arg2_align)));
3747 if (insn)
3749 emit_insn (insn);
3751 /* Return the value in the proper mode for this function. */
3752 mode = TYPE_MODE (TREE_TYPE (exp));
3753 if (GET_MODE (result) == mode)
3754 return result;
3755 if (target == 0)
3756 return convert_to_mode (mode, result, 0);
3757 convert_move (target, result, 0);
3758 return target;
3761 /* Expand the library call ourselves using a stabilized argument
3762 list to avoid re-evaluating the function's arguments twice. */
3763 arglist = build_tree_list (NULL_TREE, len);
3764 arglist = tree_cons (NULL_TREE, arg2, arglist);
3765 arglist = tree_cons (NULL_TREE, arg1, arglist);
3766 fndecl = get_callee_fndecl (exp);
3767 exp = build_function_call_expr (fndecl, arglist);
3768 return expand_call (exp, target, target == const0_rtx);
3770 #endif
3771 return 0;
3774 /* Expand expression EXP, which is a call to the strcat builtin.
3775 Return 0 if we failed the caller should emit a normal call,
3776 otherwise try to get the result in TARGET, if convenient. */
3778 static rtx
3779 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3781 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3782 return 0;
3783 else
3785 tree dst = TREE_VALUE (arglist),
3786 src = TREE_VALUE (TREE_CHAIN (arglist));
3787 const char *p = c_getstr (src);
3789 if (p)
3791 /* If the string length is zero, return the dst parameter. */
3792 if (*p == '\0')
3793 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3794 else if (!optimize_size)
3796 /* Otherwise if !optimize_size, see if we can store by
3797 pieces into (dst + strlen(dst)). */
3798 tree newdst, arglist,
3799 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3801 /* This is the length argument. */
3802 arglist = build_tree_list (NULL_TREE,
3803 fold (size_binop (PLUS_EXPR,
3804 c_strlen (src, 0),
3805 ssize_int (1))));
3806 /* Prepend src argument. */
3807 arglist = tree_cons (NULL_TREE, src, arglist);
3809 /* We're going to use dst more than once. */
3810 dst = builtin_save_expr (dst);
3812 /* Create strlen (dst). */
3813 newdst =
3814 fold (build_function_call_expr (strlen_fn,
3815 build_tree_list (NULL_TREE,
3816 dst)));
3817 /* Create (dst + strlen (dst)). */
3818 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3820 /* Prepend the new dst argument. */
3821 arglist = tree_cons (NULL_TREE, newdst, arglist);
3823 /* We don't want to get turned into a memcpy if the
3824 target is const0_rtx, i.e. when the return value
3825 isn't used. That would produce pessimized code so
3826 pass in a target of zero, it should never actually be
3827 used. If this was successful return the original
3828 dst, not the result of mempcpy. */
3829 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3830 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3831 else
3832 return 0;
3836 return 0;
3840 /* Expand expression EXP, which is a call to the strncat builtin.
3841 Return 0 if we failed the caller should emit a normal call,
3842 otherwise try to get the result in TARGET, if convenient. */
3844 static rtx
3845 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3847 if (!validate_arglist (arglist,
3848 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3849 return 0;
3850 else
3852 tree dst = TREE_VALUE (arglist),
3853 src = TREE_VALUE (TREE_CHAIN (arglist)),
3854 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3855 const char *p = c_getstr (src);
3857 /* If the requested length is zero, or the src parameter string
3858 length is zero, return the dst parameter. */
3859 if (integer_zerop (len) || (p && *p == '\0'))
3861 /* Evaluate and ignore the src and len parameters in case
3862 they have side-effects. */
3863 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3864 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3865 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3868 /* If the requested len is greater than or equal to the string
3869 length, call strcat. */
3870 if (TREE_CODE (len) == INTEGER_CST && p
3871 && compare_tree_int (len, strlen (p)) >= 0)
3873 tree newarglist
3874 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3875 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3877 /* If the replacement _DECL isn't initialized, don't do the
3878 transformation. */
3879 if (!fn)
3880 return 0;
3882 return expand_expr (build_function_call_expr (fn, newarglist),
3883 target, mode, EXPAND_NORMAL);
3885 return 0;
3889 /* Expand expression EXP, which is a call to the strspn builtin.
3890 Return 0 if we failed the caller should emit a normal call,
3891 otherwise try to get the result in TARGET, if convenient. */
3893 static rtx
3894 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3896 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3897 return 0;
3898 else
3900 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3901 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3903 /* If both arguments are constants, evaluate at compile-time. */
3904 if (p1 && p2)
3906 const size_t r = strspn (p1, p2);
3907 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3910 /* If either argument is "", return 0. */
3911 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3913 /* Evaluate and ignore both arguments in case either one has
3914 side-effects. */
3915 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3916 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3917 return const0_rtx;
3919 return 0;
3923 /* Expand expression EXP, which is a call to the strcspn builtin.
3924 Return 0 if we failed the caller should emit a normal call,
3925 otherwise try to get the result in TARGET, if convenient. */
3927 static rtx
3928 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3930 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3931 return 0;
3932 else
3934 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3935 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3937 /* If both arguments are constants, evaluate at compile-time. */
3938 if (p1 && p2)
3940 const size_t r = strcspn (p1, p2);
3941 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3944 /* If the first argument is "", return 0. */
3945 if (p1 && *p1 == '\0')
3947 /* Evaluate and ignore argument s2 in case it has
3948 side-effects. */
3949 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3950 return const0_rtx;
3953 /* If the second argument is "", return __builtin_strlen(s1). */
3954 if (p2 && *p2 == '\0')
3956 tree newarglist = build_tree_list (NULL_TREE, s1),
3957 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3959 /* If the replacement _DECL isn't initialized, don't do the
3960 transformation. */
3961 if (!fn)
3962 return 0;
3964 return expand_expr (build_function_call_expr (fn, newarglist),
3965 target, mode, EXPAND_NORMAL);
3967 return 0;
3971 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3972 if that's convenient. */
3975 expand_builtin_saveregs (void)
3977 rtx val, seq;
3979 /* Don't do __builtin_saveregs more than once in a function.
3980 Save the result of the first call and reuse it. */
3981 if (saveregs_value != 0)
3982 return saveregs_value;
3984 /* When this function is called, it means that registers must be
3985 saved on entry to this function. So we migrate the call to the
3986 first insn of this function. */
3988 start_sequence ();
3990 /* Do whatever the machine needs done in this case. */
3991 val = targetm.calls.expand_builtin_saveregs ();
3993 seq = get_insns ();
3994 end_sequence ();
3996 saveregs_value = val;
3998 /* Put the insns after the NOTE that starts the function. If this
3999 is inside a start_sequence, make the outer-level insn chain current, so
4000 the code is placed at the start of the function. */
4001 push_topmost_sequence ();
4002 emit_insn_after (seq, get_insns ());
4003 pop_topmost_sequence ();
4005 return val;
4008 /* __builtin_args_info (N) returns word N of the arg space info
4009 for the current function. The number and meanings of words
4010 is controlled by the definition of CUMULATIVE_ARGS. */
4012 static rtx
4013 expand_builtin_args_info (tree arglist)
4015 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4016 int *word_ptr = (int *) &current_function_args_info;
4018 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4019 abort ();
4021 if (arglist != 0)
4023 if (!host_integerp (TREE_VALUE (arglist), 0))
4024 error ("argument of `__builtin_args_info' must be constant");
4025 else
4027 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4029 if (wordnum < 0 || wordnum >= nwords)
4030 error ("argument of `__builtin_args_info' out of range");
4031 else
4032 return GEN_INT (word_ptr[wordnum]);
4035 else
4036 error ("missing argument in `__builtin_args_info'");
4038 return const0_rtx;
4041 /* Expand ARGLIST, from a call to __builtin_next_arg. */
4043 static rtx
4044 expand_builtin_next_arg (tree arglist)
4046 tree fntype = TREE_TYPE (current_function_decl);
4048 if (TYPE_ARG_TYPES (fntype) == 0
4049 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4050 == void_type_node))
4052 error ("`va_start' used in function with fixed args");
4053 return const0_rtx;
4056 if (arglist)
4058 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4059 tree arg = TREE_VALUE (arglist);
4061 /* Strip off all nops for the sake of the comparison. This
4062 is not quite the same as STRIP_NOPS. It does more.
4063 We must also strip off INDIRECT_EXPR for C++ reference
4064 parameters. */
4065 while (TREE_CODE (arg) == NOP_EXPR
4066 || TREE_CODE (arg) == CONVERT_EXPR
4067 || TREE_CODE (arg) == NON_LVALUE_EXPR
4068 || TREE_CODE (arg) == INDIRECT_REF)
4069 arg = TREE_OPERAND (arg, 0);
4070 if (arg != last_parm)
4071 warning ("second parameter of `va_start' not last named argument");
4073 else
4074 /* Evidently an out of date version of <stdarg.h>; can't validate
4075 va_start's second argument, but can still work as intended. */
4076 warning ("`__builtin_next_arg' called without an argument");
4078 return expand_binop (Pmode, add_optab,
4079 current_function_internal_arg_pointer,
4080 current_function_arg_offset_rtx,
4081 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4084 /* Make it easier for the backends by protecting the valist argument
4085 from multiple evaluations. */
4087 static tree
4088 stabilize_va_list (tree valist, int needs_lvalue)
4090 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4092 if (TREE_SIDE_EFFECTS (valist))
4093 valist = save_expr (valist);
4095 /* For this case, the backends will be expecting a pointer to
4096 TREE_TYPE (va_list_type_node), but it's possible we've
4097 actually been given an array (an actual va_list_type_node).
4098 So fix it. */
4099 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4101 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4102 tree p2 = build_pointer_type (va_list_type_node);
4104 valist = build1 (ADDR_EXPR, p2, valist);
4105 valist = fold_convert (p1, valist);
4108 else
4110 tree pt;
4112 if (! needs_lvalue)
4114 if (! TREE_SIDE_EFFECTS (valist))
4115 return valist;
4117 pt = build_pointer_type (va_list_type_node);
4118 valist = fold (build1 (ADDR_EXPR, pt, valist));
4119 TREE_SIDE_EFFECTS (valist) = 1;
4122 if (TREE_SIDE_EFFECTS (valist))
4123 valist = save_expr (valist);
4124 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
4125 valist));
4128 return valist;
4131 /* The "standard" definition of va_list is void*. */
4133 tree
4134 std_build_builtin_va_list (void)
4136 return ptr_type_node;
4139 /* The "standard" implementation of va_start: just assign `nextarg' to
4140 the variable. */
4142 void
4143 std_expand_builtin_va_start (tree valist, rtx nextarg)
4145 tree t;
4147 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4148 make_tree (ptr_type_node, nextarg));
4149 TREE_SIDE_EFFECTS (t) = 1;
4151 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4154 /* Expand ARGLIST, from a call to __builtin_va_start. */
4156 static rtx
4157 expand_builtin_va_start (tree arglist)
4159 rtx nextarg;
4160 tree chain, valist;
4162 chain = TREE_CHAIN (arglist);
4164 if (TREE_CHAIN (chain))
4165 error ("too many arguments to function `va_start'");
4167 nextarg = expand_builtin_next_arg (chain);
4168 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4170 #ifdef EXPAND_BUILTIN_VA_START
4171 EXPAND_BUILTIN_VA_START (valist, nextarg);
4172 #else
4173 std_expand_builtin_va_start (valist, nextarg);
4174 #endif
4176 return const0_rtx;
4179 /* The "standard" implementation of va_arg: read the value from the
4180 current (padded) address and increment by the (padded) size. */
4183 std_expand_builtin_va_arg (tree valist, tree type)
4185 tree addr_tree, t, type_size = NULL;
4186 tree align, alignm1;
4187 tree rounded_size;
4188 rtx addr;
4189 HOST_WIDE_INT boundary;
4191 /* Compute the rounded size of the type. */
4192 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4193 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4194 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4196 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4197 requires greater alignment, we must perform dynamic alignment. */
4199 if (boundary > PARM_BOUNDARY)
4201 if (!PAD_VARARGS_DOWN)
4203 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4204 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4205 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4206 TREE_SIDE_EFFECTS (t) = 1;
4207 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4209 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4210 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4211 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4212 TREE_SIDE_EFFECTS (t) = 1;
4213 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4215 if (type == error_mark_node
4216 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4217 || TREE_OVERFLOW (type_size))
4218 rounded_size = size_zero_node;
4219 else
4220 rounded_size = fold (build (MULT_EXPR, sizetype,
4221 fold (build (TRUNC_DIV_EXPR, sizetype,
4222 fold (build (PLUS_EXPR, sizetype,
4223 type_size, alignm1)),
4224 align)),
4225 align));
4227 /* Get AP. */
4228 addr_tree = valist;
4229 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4231 /* Small args are padded downward. */
4232 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4233 fold (build (COND_EXPR, sizetype,
4234 fold (build (GT_EXPR, sizetype,
4235 rounded_size,
4236 align)),
4237 size_zero_node,
4238 fold (build (MINUS_EXPR, sizetype,
4239 rounded_size,
4240 type_size))))));
4243 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4244 addr = copy_to_reg (addr);
4246 /* Compute new value for AP. */
4247 if (! integer_zerop (rounded_size))
4249 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4250 build (PLUS_EXPR, TREE_TYPE (valist), valist,
4251 rounded_size));
4252 TREE_SIDE_EFFECTS (t) = 1;
4253 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4256 return addr;
4259 /* Expand __builtin_va_arg, which is not really a builtin function, but
4260 a very special sort of operator. */
4263 expand_builtin_va_arg (tree valist, tree type)
4265 rtx addr, result;
4266 tree promoted_type, want_va_type, have_va_type;
4268 /* Verify that valist is of the proper type. */
4270 want_va_type = va_list_type_node;
4271 have_va_type = TREE_TYPE (valist);
4272 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4274 /* If va_list is an array type, the argument may have decayed
4275 to a pointer type, e.g. by being passed to another function.
4276 In that case, unwrap both types so that we can compare the
4277 underlying records. */
4278 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4279 || TREE_CODE (have_va_type) == POINTER_TYPE)
4281 want_va_type = TREE_TYPE (want_va_type);
4282 have_va_type = TREE_TYPE (have_va_type);
4285 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4287 error ("first argument to `va_arg' not of type `va_list'");
4288 addr = const0_rtx;
4291 /* Generate a diagnostic for requesting data of a type that cannot
4292 be passed through `...' due to type promotion at the call site. */
4293 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4294 != type)
4296 const char *name = "<anonymous type>", *pname = 0;
4297 static bool gave_help;
4299 if (TYPE_NAME (type))
4301 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4302 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4303 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4304 && DECL_NAME (TYPE_NAME (type)))
4305 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4307 if (TYPE_NAME (promoted_type))
4309 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4310 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4311 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4312 && DECL_NAME (TYPE_NAME (promoted_type)))
4313 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4316 /* Unfortunately, this is merely undefined, rather than a constraint
4317 violation, so we cannot make this an error. If this call is never
4318 executed, the program is still strictly conforming. */
4319 warning ("`%s' is promoted to `%s' when passed through `...'",
4320 name, pname);
4321 if (! gave_help)
4323 gave_help = true;
4324 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4325 pname, name);
4328 /* We can, however, treat "undefined" any way we please.
4329 Call abort to encourage the user to fix the program. */
4330 inform ("if this code is reached, the program will abort");
4331 expand_builtin_trap ();
4333 /* This is dead code, but go ahead and finish so that the
4334 mode of the result comes out right. */
4335 addr = const0_rtx;
4337 else
4339 /* Make it easier for the backends by protecting the valist argument
4340 from multiple evaluations. */
4341 valist = stabilize_va_list (valist, 0);
4343 #ifdef EXPAND_BUILTIN_VA_ARG
4344 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4345 #else
4346 addr = std_expand_builtin_va_arg (valist, type);
4347 #endif
4350 addr = convert_memory_address (Pmode, addr);
4352 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4353 set_mem_alias_set (result, get_varargs_alias_set ());
4355 return result;
4358 /* Expand ARGLIST, from a call to __builtin_va_end. */
4360 static rtx
4361 expand_builtin_va_end (tree arglist)
4363 tree valist = TREE_VALUE (arglist);
4365 /* Evaluate for side effects, if needed. I hate macros that don't
4366 do that. */
4367 if (TREE_SIDE_EFFECTS (valist))
4368 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4370 return const0_rtx;
4373 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4374 builtin rather than just as an assignment in stdarg.h because of the
4375 nastiness of array-type va_list types. */
4377 static rtx
4378 expand_builtin_va_copy (tree arglist)
4380 tree dst, src, t;
4382 dst = TREE_VALUE (arglist);
4383 src = TREE_VALUE (TREE_CHAIN (arglist));
4385 dst = stabilize_va_list (dst, 1);
4386 src = stabilize_va_list (src, 0);
4388 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4390 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4391 TREE_SIDE_EFFECTS (t) = 1;
4392 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4394 else
4396 rtx dstb, srcb, size;
4398 /* Evaluate to pointers. */
4399 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4400 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4401 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4402 VOIDmode, EXPAND_NORMAL);
4404 dstb = convert_memory_address (Pmode, dstb);
4405 srcb = convert_memory_address (Pmode, srcb);
4407 /* "Dereference" to BLKmode memories. */
4408 dstb = gen_rtx_MEM (BLKmode, dstb);
4409 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4410 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4411 srcb = gen_rtx_MEM (BLKmode, srcb);
4412 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4413 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4415 /* Copy. */
4416 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4419 return const0_rtx;
4422 /* Expand a call to one of the builtin functions __builtin_frame_address or
4423 __builtin_return_address. */
4425 static rtx
4426 expand_builtin_frame_address (tree fndecl, tree arglist)
4428 /* The argument must be a nonnegative integer constant.
4429 It counts the number of frames to scan up the stack.
4430 The value is the return address saved in that frame. */
4431 if (arglist == 0)
4432 /* Warning about missing arg was already issued. */
4433 return const0_rtx;
4434 else if (! host_integerp (TREE_VALUE (arglist), 1))
4436 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4437 error ("invalid arg to `__builtin_frame_address'");
4438 else
4439 error ("invalid arg to `__builtin_return_address'");
4440 return const0_rtx;
4442 else
4444 rtx tem
4445 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4446 tree_low_cst (TREE_VALUE (arglist), 1),
4447 hard_frame_pointer_rtx);
4449 /* Some ports cannot access arbitrary stack frames. */
4450 if (tem == NULL)
4452 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4453 warning ("unsupported arg to `__builtin_frame_address'");
4454 else
4455 warning ("unsupported arg to `__builtin_return_address'");
4456 return const0_rtx;
4459 /* For __builtin_frame_address, return what we've got. */
4460 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4461 return tem;
4463 if (GET_CODE (tem) != REG
4464 && ! CONSTANT_P (tem))
4465 tem = copy_to_mode_reg (Pmode, tem);
4466 return tem;
4470 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4471 we failed and the caller should emit a normal call, otherwise try to get
4472 the result in TARGET, if convenient. */
4474 static rtx
4475 expand_builtin_alloca (tree arglist, rtx target)
4477 rtx op0;
4478 rtx result;
4480 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4481 should always expand to function calls. These can be intercepted
4482 in libmudflap. */
4483 if (flag_mudflap)
4484 return 0;
4486 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4487 return 0;
4489 /* Compute the argument. */
4490 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4492 /* Allocate the desired space. */
4493 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4494 result = convert_memory_address (ptr_mode, result);
4496 return result;
4499 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4500 Return 0 if a normal call should be emitted rather than expanding the
4501 function in-line. If convenient, the result should be placed in TARGET.
4502 SUBTARGET may be used as the target for computing one of EXP's operands. */
4504 static rtx
4505 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4506 rtx subtarget, optab op_optab)
4508 rtx op0;
4509 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4510 return 0;
4512 /* Compute the argument. */
4513 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4514 /* Compute op, into TARGET if possible.
4515 Set TARGET to wherever the result comes back. */
4516 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4517 op_optab, op0, target, 1);
4518 if (target == 0)
4519 abort ();
4521 return convert_to_mode (target_mode, target, 0);
4524 /* If the string passed to fputs is a constant and is one character
4525 long, we attempt to transform this call into __builtin_fputc(). */
4527 static rtx
4528 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4530 tree len, fn;
4531 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4532 : implicit_built_in_decls[BUILT_IN_FPUTC];
4533 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4534 : implicit_built_in_decls[BUILT_IN_FWRITE];
4536 /* If the return value is used, or the replacement _DECL isn't
4537 initialized, don't do the transformation. */
4538 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4539 return 0;
4541 /* Verify the arguments in the original call. */
4542 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4543 return 0;
4545 /* Get the length of the string passed to fputs. If the length
4546 can't be determined, punt. */
4547 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4548 || TREE_CODE (len) != INTEGER_CST)
4549 return 0;
4551 switch (compare_tree_int (len, 1))
4553 case -1: /* length is 0, delete the call entirely . */
4555 /* Evaluate and ignore the argument in case it has
4556 side-effects. */
4557 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4558 VOIDmode, EXPAND_NORMAL);
4559 return const0_rtx;
4561 case 0: /* length is 1, call fputc. */
4563 const char *p = c_getstr (TREE_VALUE (arglist));
4565 if (p != NULL)
4567 /* New argument list transforming fputs(string, stream) to
4568 fputc(string[0], stream). */
4569 arglist =
4570 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4571 arglist =
4572 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4573 fn = fn_fputc;
4574 break;
4577 /* Fall through. */
4578 case 1: /* length is greater than 1, call fwrite. */
4580 tree string_arg;
4582 /* If optimizing for size keep fputs. */
4583 if (optimize_size)
4584 return 0;
4585 string_arg = TREE_VALUE (arglist);
4586 /* New argument list transforming fputs(string, stream) to
4587 fwrite(string, 1, len, stream). */
4588 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4589 arglist = tree_cons (NULL_TREE, len, arglist);
4590 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4591 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4592 fn = fn_fwrite;
4593 break;
4595 default:
4596 abort ();
4599 return expand_expr (build_function_call_expr (fn, arglist),
4600 const0_rtx, VOIDmode, EXPAND_NORMAL);
4603 /* Expand a call to __builtin_expect. We return our argument and emit a
4604 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4605 a non-jump context. */
4607 static rtx
4608 expand_builtin_expect (tree arglist, rtx target)
4610 tree exp, c;
4611 rtx note, rtx_c;
4613 if (arglist == NULL_TREE
4614 || TREE_CHAIN (arglist) == NULL_TREE)
4615 return const0_rtx;
4616 exp = TREE_VALUE (arglist);
4617 c = TREE_VALUE (TREE_CHAIN (arglist));
4619 if (TREE_CODE (c) != INTEGER_CST)
4621 error ("second arg to `__builtin_expect' must be a constant");
4622 c = integer_zero_node;
4625 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4627 /* Don't bother with expected value notes for integral constants. */
4628 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4630 /* We do need to force this into a register so that we can be
4631 moderately sure to be able to correctly interpret the branch
4632 condition later. */
4633 target = force_reg (GET_MODE (target), target);
4635 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4637 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4638 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4641 return target;
4644 /* Like expand_builtin_expect, except do this in a jump context. This is
4645 called from do_jump if the conditional is a __builtin_expect. Return either
4646 a list of insns to emit the jump or NULL if we cannot optimize
4647 __builtin_expect. We need to optimize this at jump time so that machines
4648 like the PowerPC don't turn the test into a SCC operation, and then jump
4649 based on the test being 0/1. */
4652 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4654 tree arglist = TREE_OPERAND (exp, 1);
4655 tree arg0 = TREE_VALUE (arglist);
4656 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4657 rtx ret = NULL_RTX;
4659 /* Only handle __builtin_expect (test, 0) and
4660 __builtin_expect (test, 1). */
4661 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4662 && (integer_zerop (arg1) || integer_onep (arg1)))
4664 rtx insn, drop_through_label, temp;
4666 /* Expand the jump insns. */
4667 start_sequence ();
4668 do_jump (arg0, if_false_label, if_true_label);
4669 ret = get_insns ();
4671 drop_through_label = get_last_insn ();
4672 if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4673 drop_through_label = prev_nonnote_insn (drop_through_label);
4674 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4675 drop_through_label = NULL_RTX;
4676 end_sequence ();
4678 if (! if_true_label)
4679 if_true_label = drop_through_label;
4680 if (! if_false_label)
4681 if_false_label = drop_through_label;
4683 /* Go through and add the expect's to each of the conditional jumps. */
4684 insn = ret;
4685 while (insn != NULL_RTX)
4687 rtx next = NEXT_INSN (insn);
4689 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4691 rtx ifelse = SET_SRC (pc_set (insn));
4692 rtx then_dest = XEXP (ifelse, 1);
4693 rtx else_dest = XEXP (ifelse, 2);
4694 int taken = -1;
4696 /* First check if we recognize any of the labels. */
4697 if (GET_CODE (then_dest) == LABEL_REF
4698 && XEXP (then_dest, 0) == if_true_label)
4699 taken = 1;
4700 else if (GET_CODE (then_dest) == LABEL_REF
4701 && XEXP (then_dest, 0) == if_false_label)
4702 taken = 0;
4703 else if (GET_CODE (else_dest) == LABEL_REF
4704 && XEXP (else_dest, 0) == if_false_label)
4705 taken = 1;
4706 else if (GET_CODE (else_dest) == LABEL_REF
4707 && XEXP (else_dest, 0) == if_true_label)
4708 taken = 0;
4709 /* Otherwise check where we drop through. */
4710 else if (else_dest == pc_rtx)
4712 if (next && GET_CODE (next) == NOTE)
4713 next = next_nonnote_insn (next);
4715 if (next && GET_CODE (next) == JUMP_INSN
4716 && any_uncondjump_p (next))
4717 temp = XEXP (SET_SRC (pc_set (next)), 0);
4718 else
4719 temp = next;
4721 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4722 else that can't possibly match either target label. */
4723 if (temp == if_false_label)
4724 taken = 1;
4725 else if (temp == if_true_label)
4726 taken = 0;
4728 else if (then_dest == pc_rtx)
4730 if (next && GET_CODE (next) == NOTE)
4731 next = next_nonnote_insn (next);
4733 if (next && GET_CODE (next) == JUMP_INSN
4734 && any_uncondjump_p (next))
4735 temp = XEXP (SET_SRC (pc_set (next)), 0);
4736 else
4737 temp = next;
4739 if (temp == if_false_label)
4740 taken = 0;
4741 else if (temp == if_true_label)
4742 taken = 1;
4745 if (taken != -1)
4747 /* If the test is expected to fail, reverse the
4748 probabilities. */
4749 if (integer_zerop (arg1))
4750 taken = 1 - taken;
4751 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4755 insn = next;
4759 return ret;
4762 void
4763 expand_builtin_trap (void)
4765 #ifdef HAVE_trap
4766 if (HAVE_trap)
4767 emit_insn (gen_trap ());
4768 else
4769 #endif
4770 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4771 emit_barrier ();
4774 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4775 Return 0 if a normal call should be emitted rather than expanding
4776 the function inline. If convenient, the result should be placed
4777 in TARGET. SUBTARGET may be used as the target for computing
4778 the operand. */
4780 static rtx
4781 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4783 enum machine_mode mode;
4784 tree arg;
4785 rtx op0;
4787 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4788 return 0;
4790 arg = TREE_VALUE (arglist);
4791 mode = TYPE_MODE (TREE_TYPE (arg));
4792 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4793 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4796 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4797 Return 0 if a normal call should be emitted rather than expanding
4798 the function inline. If convenient, the result should be placed
4799 in target. */
4801 static rtx
4802 expand_builtin_cabs (tree arglist, rtx target)
4804 enum machine_mode mode;
4805 tree arg;
4806 rtx op0;
4808 if (arglist == 0 || TREE_CHAIN (arglist))
4809 return 0;
4810 arg = TREE_VALUE (arglist);
4811 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4812 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4813 return 0;
4815 mode = TYPE_MODE (TREE_TYPE (arg));
4816 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4817 return expand_complex_abs (mode, op0, target, 0);
4820 /* Create a new constant string literal and return a char* pointer to it.
4821 The STRING_CST value is the LEN characters at STR. */
4822 static tree
4823 build_string_literal (int len, const char *str)
4825 tree t, elem, index, type;
4827 t = build_string (len, str);
4828 elem = build_type_variant (char_type_node, 1, 0);
4829 index = build_index_type (build_int_2 (len - 1, 0));
4830 type = build_array_type (elem, index);
4831 TREE_TYPE (t) = type;
4832 TREE_CONSTANT (t) = 1;
4833 TREE_INVARIANT (t) = 1;
4834 TREE_READONLY (t) = 1;
4835 TREE_STATIC (t) = 1;
4837 type = build_pointer_type (type);
4838 t = build1 (ADDR_EXPR, type, t);
4840 type = build_pointer_type (elem);
4841 t = build1 (NOP_EXPR, type, t);
4842 return t;
4845 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4846 Return 0 if a normal call should be emitted rather than transforming
4847 the function inline. If convenient, the result should be placed in
4848 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4849 call. */
4850 static rtx
4851 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4852 bool unlocked)
4854 tree fn_putchar = unlocked
4855 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4856 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4857 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4858 : implicit_built_in_decls[BUILT_IN_PUTS];
4859 const char *fmt_str;
4860 tree fn, fmt, arg;
4862 /* If the return value is used, don't do the transformation. */
4863 if (target != const0_rtx)
4864 return 0;
4866 /* Verify the required arguments in the original call. */
4867 if (! arglist)
4868 return 0;
4869 fmt = TREE_VALUE (arglist);
4870 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4871 return 0;
4872 arglist = TREE_CHAIN (arglist);
4874 /* Check whether the format is a literal string constant. */
4875 fmt_str = c_getstr (fmt);
4876 if (fmt_str == NULL)
4877 return 0;
4879 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4880 if (strcmp (fmt_str, "%s\n") == 0)
4882 if (! arglist
4883 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4884 || TREE_CHAIN (arglist))
4885 return 0;
4886 fn = fn_puts;
4888 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4889 else if (strcmp (fmt_str, "%c") == 0)
4891 if (! arglist
4892 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4893 || TREE_CHAIN (arglist))
4894 return 0;
4895 fn = fn_putchar;
4897 else
4899 /* We can't handle anything else with % args or %% ... yet. */
4900 if (strchr (fmt_str, '%'))
4901 return 0;
4903 if (arglist)
4904 return 0;
4906 /* If the format specifier was "", printf does nothing. */
4907 if (fmt_str[0] == '\0')
4908 return const0_rtx;
4909 /* If the format specifier has length of 1, call putchar. */
4910 if (fmt_str[1] == '\0')
4912 /* Given printf("c"), (where c is any one character,)
4913 convert "c"[0] to an int and pass that to the replacement
4914 function. */
4915 arg = build_int_2 (fmt_str[0], 0);
4916 arglist = build_tree_list (NULL_TREE, arg);
4917 fn = fn_putchar;
4919 else
4921 /* If the format specifier was "string\n", call puts("string"). */
4922 size_t len = strlen (fmt_str);
4923 if (fmt_str[len - 1] == '\n')
4925 /* Create a NUL-terminated string that's one char shorter
4926 than the original, stripping off the trailing '\n'. */
4927 char *newstr = alloca (len);
4928 memcpy (newstr, fmt_str, len - 1);
4929 newstr[len - 1] = 0;
4931 arg = build_string_literal (len, newstr);
4932 arglist = build_tree_list (NULL_TREE, arg);
4933 fn = fn_puts;
4935 else
4936 /* We'd like to arrange to call fputs(string,stdout) here,
4937 but we need stdout and don't have a way to get it yet. */
4938 return 0;
4942 if (!fn)
4943 return 0;
4944 return expand_expr (build_function_call_expr (fn, arglist),
4945 target, mode, EXPAND_NORMAL);
4948 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4949 Return 0 if a normal call should be emitted rather than transforming
4950 the function inline. If convenient, the result should be placed in
4951 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4952 call. */
4953 static rtx
4954 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4955 bool unlocked)
4957 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4958 : implicit_built_in_decls[BUILT_IN_FPUTC];
4959 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4960 : implicit_built_in_decls[BUILT_IN_FPUTS];
4961 const char *fmt_str;
4962 tree fn, fmt, fp, arg;
4964 /* If the return value is used, don't do the transformation. */
4965 if (target != const0_rtx)
4966 return 0;
4968 /* Verify the required arguments in the original call. */
4969 if (! arglist)
4970 return 0;
4971 fp = TREE_VALUE (arglist);
4972 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4973 return 0;
4974 arglist = TREE_CHAIN (arglist);
4975 if (! arglist)
4976 return 0;
4977 fmt = TREE_VALUE (arglist);
4978 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4979 return 0;
4980 arglist = TREE_CHAIN (arglist);
4982 /* Check whether the format is a literal string constant. */
4983 fmt_str = c_getstr (fmt);
4984 if (fmt_str == NULL)
4985 return 0;
4987 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4988 if (strcmp (fmt_str, "%s") == 0)
4990 if (! arglist
4991 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4992 || TREE_CHAIN (arglist))
4993 return 0;
4994 arg = TREE_VALUE (arglist);
4995 arglist = build_tree_list (NULL_TREE, fp);
4996 arglist = tree_cons (NULL_TREE, arg, arglist);
4997 fn = fn_fputs;
4999 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5000 else if (strcmp (fmt_str, "%c") == 0)
5002 if (! arglist
5003 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5004 || TREE_CHAIN (arglist))
5005 return 0;
5006 arg = TREE_VALUE (arglist);
5007 arglist = build_tree_list (NULL_TREE, fp);
5008 arglist = tree_cons (NULL_TREE, arg, arglist);
5009 fn = fn_fputc;
5011 else
5013 /* We can't handle anything else with % args or %% ... yet. */
5014 if (strchr (fmt_str, '%'))
5015 return 0;
5017 if (arglist)
5018 return 0;
5020 /* If the format specifier was "", fprintf does nothing. */
5021 if (fmt_str[0] == '\0')
5023 /* Evaluate and ignore FILE* argument for side-effects. */
5024 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5025 return const0_rtx;
5028 /* When "string" doesn't contain %, replace all cases of
5029 fprintf(stream,string) with fputs(string,stream). The fputs
5030 builtin will take care of special cases like length == 1. */
5031 arglist = build_tree_list (NULL_TREE, fp);
5032 arglist = tree_cons (NULL_TREE, fmt, arglist);
5033 fn = fn_fputs;
5036 if (!fn)
5037 return 0;
5038 return expand_expr (build_function_call_expr (fn, arglist),
5039 target, mode, EXPAND_NORMAL);
5042 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5043 a normal call should be emitted rather than expanding the function
5044 inline. If convenient, the result should be placed in TARGET with
5045 mode MODE. */
5047 static rtx
5048 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5050 tree orig_arglist, dest, fmt;
5051 const char *fmt_str;
5053 orig_arglist = arglist;
5055 /* Verify the required arguments in the original call. */
5056 if (! arglist)
5057 return 0;
5058 dest = TREE_VALUE (arglist);
5059 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5060 return 0;
5061 arglist = TREE_CHAIN (arglist);
5062 if (! arglist)
5063 return 0;
5064 fmt = TREE_VALUE (arglist);
5065 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5066 return 0;
5067 arglist = TREE_CHAIN (arglist);
5069 /* Check whether the format is a literal string constant. */
5070 fmt_str = c_getstr (fmt);
5071 if (fmt_str == NULL)
5072 return 0;
5074 /* If the format doesn't contain % args or %%, use strcpy. */
5075 if (strchr (fmt_str, '%') == 0)
5077 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5078 tree exp;
5080 if (arglist || ! fn)
5081 return 0;
5082 expand_expr (build_function_call_expr (fn, orig_arglist),
5083 const0_rtx, VOIDmode, EXPAND_NORMAL);
5084 if (target == const0_rtx)
5085 return const0_rtx;
5086 exp = build_int_2 (strlen (fmt_str), 0);
5087 exp = fold_convert (integer_type_node, exp);
5088 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5090 /* If the format is "%s", use strcpy if the result isn't used. */
5091 else if (strcmp (fmt_str, "%s") == 0)
5093 tree fn, arg, len;
5094 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5096 if (! fn)
5097 return 0;
5099 if (! arglist || TREE_CHAIN (arglist))
5100 return 0;
5101 arg = TREE_VALUE (arglist);
5102 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5103 return 0;
5105 if (target != const0_rtx)
5107 len = c_strlen (arg, 1);
5108 if (! len || TREE_CODE (len) != INTEGER_CST)
5109 return 0;
5111 else
5112 len = NULL_TREE;
5114 arglist = build_tree_list (NULL_TREE, arg);
5115 arglist = tree_cons (NULL_TREE, dest, arglist);
5116 expand_expr (build_function_call_expr (fn, arglist),
5117 const0_rtx, VOIDmode, EXPAND_NORMAL);
5119 if (target == const0_rtx)
5120 return const0_rtx;
5121 return expand_expr (len, target, mode, EXPAND_NORMAL);
5124 return 0;
5127 /* Expand a call to either the entry or exit function profiler. */
5129 static rtx
5130 expand_builtin_profile_func (bool exitp)
5132 rtx this, which;
5134 this = DECL_RTL (current_function_decl);
5135 if (GET_CODE (this) == MEM)
5136 this = XEXP (this, 0);
5137 else
5138 abort ();
5140 if (exitp)
5141 which = profile_function_exit_libfunc;
5142 else
5143 which = profile_function_entry_libfunc;
5145 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5146 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5147 0, hard_frame_pointer_rtx),
5148 Pmode);
5150 return const0_rtx;
5153 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5155 static rtx
5156 round_trampoline_addr (rtx tramp)
5158 rtx temp, addend, mask;
5160 /* If we don't need too much alignment, we'll have been guaranteed
5161 proper alignment by get_trampoline_type. */
5162 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5163 return tramp;
5165 /* Round address up to desired boundary. */
5166 temp = gen_reg_rtx (Pmode);
5167 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5168 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5170 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5171 temp, 0, OPTAB_LIB_WIDEN);
5172 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5173 temp, 0, OPTAB_LIB_WIDEN);
5175 return tramp;
5178 static rtx
5179 expand_builtin_init_trampoline (tree arglist)
5181 tree t_tramp, t_func, t_chain;
5182 rtx r_tramp, r_func, r_chain;
5183 #ifdef TRAMPOLINE_TEMPLATE
5184 rtx blktramp;
5185 #endif
5187 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5188 POINTER_TYPE, VOID_TYPE))
5189 return NULL_RTX;
5191 t_tramp = TREE_VALUE (arglist);
5192 arglist = TREE_CHAIN (arglist);
5193 t_func = TREE_VALUE (arglist);
5194 arglist = TREE_CHAIN (arglist);
5195 t_chain = TREE_VALUE (arglist);
5197 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5198 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5199 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5201 /* Generate insns to initialize the trampoline. */
5202 r_tramp = round_trampoline_addr (r_tramp);
5203 #ifdef TRAMPOLINE_TEMPLATE
5204 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5205 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5206 emit_block_move (blktramp, assemble_trampoline_template (),
5207 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5208 #endif
5209 trampolines_created = 1;
5210 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5212 return const0_rtx;
5215 static rtx
5216 expand_builtin_adjust_trampoline (tree arglist)
5218 rtx tramp;
5220 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5221 return NULL_RTX;
5223 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5224 tramp = round_trampoline_addr (tramp);
5225 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5226 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5227 #endif
5229 return tramp;
5232 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5233 Return NULL_RTX if a normal call should be emitted rather than expanding
5234 the function in-line. EXP is the expression that is a call to the builtin
5235 function; if convenient, the result should be placed in TARGET. */
5237 static rtx
5238 expand_builtin_signbit (tree exp, rtx target)
5240 const struct real_format *fmt;
5241 enum machine_mode fmode, imode, rmode;
5242 HOST_WIDE_INT hi, lo;
5243 tree arg, arglist;
5244 int bitpos;
5245 rtx temp;
5247 arglist = TREE_OPERAND (exp, 1);
5248 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5249 return 0;
5251 arg = TREE_VALUE (arglist);
5252 fmode = TYPE_MODE (TREE_TYPE (arg));
5253 rmode = TYPE_MODE (TREE_TYPE (exp));
5254 fmt = REAL_MODE_FORMAT (fmode);
5256 /* For floating point formats without a sign bit, implement signbit
5257 as "ARG < 0.0". */
5258 if (fmt->signbit < 0)
5260 /* But we can't do this if the format supports signed zero. */
5261 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5262 return 0;
5264 arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
5265 build_real (TREE_TYPE (arg), dconst0)));
5266 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5269 imode = int_mode_for_mode (fmode);
5270 if (imode == BLKmode)
5271 return 0;
5273 bitpos = fmt->signbit;
5274 /* Handle targets with different FP word orders. */
5275 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5277 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5278 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5279 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5282 /* If the sign bit is not in the lowpart and the floating point format
5283 is wider than an integer, check that is twice the size of an integer
5284 so that we can use gen_highpart below. */
5285 if (bitpos >= GET_MODE_BITSIZE (rmode)
5286 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5287 return 0;
5289 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5290 temp = gen_lowpart (imode, temp);
5292 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5294 if (BYTES_BIG_ENDIAN)
5295 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5296 temp = copy_to_mode_reg (imode, temp);
5297 temp = extract_bit_field (temp, 1, bitpos, 1,
5298 NULL_RTX, rmode, rmode,
5299 GET_MODE_SIZE (imode));
5301 else
5303 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5304 temp = gen_lowpart (rmode, temp);
5305 if (bitpos < HOST_BITS_PER_WIDE_INT)
5307 hi = 0;
5308 lo = (HOST_WIDE_INT) 1 << bitpos;
5310 else
5312 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5313 lo = 0;
5316 temp = force_reg (rmode, temp);
5317 temp = expand_binop (rmode, and_optab, temp,
5318 immed_double_const (lo, hi, rmode),
5319 target, 1, OPTAB_LIB_WIDEN);
5321 return temp;
5324 /* Expand fork or exec calls. TARGET is the desired target of the
5325 call. ARGLIST is the list of arguments of the call. FN is the
5326 identificator of the actual function. IGNORE is nonzero if the
5327 value is to be ignored. */
5329 static rtx
5330 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5332 tree id, decl;
5333 tree call;
5335 /* If we are not profiling, just call the function. */
5336 if (!profile_arc_flag)
5337 return NULL_RTX;
5339 /* Otherwise call the wrapper. This should be equivalent for the rest of
5340 compiler, so the code does not diverge, and the wrapper may run the
5341 code necessary for keeping the profiling sane. */
5343 switch (DECL_FUNCTION_CODE (fn))
5345 case BUILT_IN_FORK:
5346 id = get_identifier ("__gcov_fork");
5347 break;
5349 case BUILT_IN_EXECL:
5350 id = get_identifier ("__gcov_execl");
5351 break;
5353 case BUILT_IN_EXECV:
5354 id = get_identifier ("__gcov_execv");
5355 break;
5357 case BUILT_IN_EXECLP:
5358 id = get_identifier ("__gcov_execlp");
5359 break;
5361 case BUILT_IN_EXECLE:
5362 id = get_identifier ("__gcov_execle");
5363 break;
5365 case BUILT_IN_EXECVP:
5366 id = get_identifier ("__gcov_execvp");
5367 break;
5369 case BUILT_IN_EXECVE:
5370 id = get_identifier ("__gcov_execve");
5371 break;
5373 default:
5374 abort ();
5377 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5378 DECL_EXTERNAL (decl) = 1;
5379 TREE_PUBLIC (decl) = 1;
5380 DECL_ARTIFICIAL (decl) = 1;
5381 TREE_NOTHROW (decl) = 1;
5382 call = build_function_call_expr (decl, arglist);
5384 return expand_call (call, target, ignore);
5387 /* Expand an expression EXP that calls a built-in function,
5388 with result going to TARGET if that's convenient
5389 (and in mode MODE if that's convenient).
5390 SUBTARGET may be used as the target for computing one of EXP's operands.
5391 IGNORE is nonzero if the value is to be ignored. */
5394 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5395 int ignore)
5397 tree fndecl = get_callee_fndecl (exp);
5398 tree arglist = TREE_OPERAND (exp, 1);
5399 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5400 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5402 /* Perform postincrements before expanding builtin functions. */
5403 emit_queue ();
5405 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5406 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5408 /* When not optimizing, generate calls to library functions for a certain
5409 set of builtins. */
5410 if (!optimize
5411 && !CALLED_AS_BUILT_IN (fndecl)
5412 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5413 && fcode != BUILT_IN_ALLOCA)
5414 return expand_call (exp, target, ignore);
5416 /* The built-in function expanders test for target == const0_rtx
5417 to determine whether the function's result will be ignored. */
5418 if (ignore)
5419 target = const0_rtx;
5421 /* If the result of a pure or const built-in function is ignored, and
5422 none of its arguments are volatile, we can avoid expanding the
5423 built-in call and just evaluate the arguments for side-effects. */
5424 if (target == const0_rtx
5425 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5427 bool volatilep = false;
5428 tree arg;
5430 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5431 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5433 volatilep = true;
5434 break;
5437 if (! volatilep)
5439 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5440 expand_expr (TREE_VALUE (arg), const0_rtx,
5441 VOIDmode, EXPAND_NORMAL);
5442 return const0_rtx;
5446 switch (fcode)
5448 case BUILT_IN_ABS:
5449 case BUILT_IN_LABS:
5450 case BUILT_IN_LLABS:
5451 case BUILT_IN_IMAXABS:
5452 /* build_function_call changes these into ABS_EXPR. */
5453 abort ();
5455 case BUILT_IN_FABS:
5456 case BUILT_IN_FABSF:
5457 case BUILT_IN_FABSL:
5458 target = expand_builtin_fabs (arglist, target, subtarget);
5459 if (target)
5460 return target;
5461 break;
5463 case BUILT_IN_CABS:
5464 case BUILT_IN_CABSF:
5465 case BUILT_IN_CABSL:
5466 if (flag_unsafe_math_optimizations)
5468 target = expand_builtin_cabs (arglist, target);
5469 if (target)
5470 return target;
5472 break;
5474 case BUILT_IN_CONJ:
5475 case BUILT_IN_CONJF:
5476 case BUILT_IN_CONJL:
5477 case BUILT_IN_CREAL:
5478 case BUILT_IN_CREALF:
5479 case BUILT_IN_CREALL:
5480 case BUILT_IN_CIMAG:
5481 case BUILT_IN_CIMAGF:
5482 case BUILT_IN_CIMAGL:
5483 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5484 and IMAGPART_EXPR. */
5485 abort ();
5487 case BUILT_IN_EXP:
5488 case BUILT_IN_EXPF:
5489 case BUILT_IN_EXPL:
5490 case BUILT_IN_EXP10:
5491 case BUILT_IN_EXP10F:
5492 case BUILT_IN_EXP10L:
5493 case BUILT_IN_POW10:
5494 case BUILT_IN_POW10F:
5495 case BUILT_IN_POW10L:
5496 case BUILT_IN_EXP2:
5497 case BUILT_IN_EXP2F:
5498 case BUILT_IN_EXP2L:
5499 case BUILT_IN_EXPM1:
5500 case BUILT_IN_EXPM1F:
5501 case BUILT_IN_EXPM1L:
5502 case BUILT_IN_LOGB:
5503 case BUILT_IN_LOGBF:
5504 case BUILT_IN_LOGBL:
5505 case BUILT_IN_ILOGB:
5506 case BUILT_IN_ILOGBF:
5507 case BUILT_IN_ILOGBL:
5508 case BUILT_IN_LOG:
5509 case BUILT_IN_LOGF:
5510 case BUILT_IN_LOGL:
5511 case BUILT_IN_LOG10:
5512 case BUILT_IN_LOG10F:
5513 case BUILT_IN_LOG10L:
5514 case BUILT_IN_LOG2:
5515 case BUILT_IN_LOG2F:
5516 case BUILT_IN_LOG2L:
5517 case BUILT_IN_LOG1P:
5518 case BUILT_IN_LOG1PF:
5519 case BUILT_IN_LOG1PL:
5520 case BUILT_IN_TAN:
5521 case BUILT_IN_TANF:
5522 case BUILT_IN_TANL:
5523 case BUILT_IN_ASIN:
5524 case BUILT_IN_ASINF:
5525 case BUILT_IN_ASINL:
5526 case BUILT_IN_ACOS:
5527 case BUILT_IN_ACOSF:
5528 case BUILT_IN_ACOSL:
5529 case BUILT_IN_ATAN:
5530 case BUILT_IN_ATANF:
5531 case BUILT_IN_ATANL:
5532 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5533 because of possible accuracy problems. */
5534 if (! flag_unsafe_math_optimizations)
5535 break;
5536 case BUILT_IN_SQRT:
5537 case BUILT_IN_SQRTF:
5538 case BUILT_IN_SQRTL:
5539 case BUILT_IN_FLOOR:
5540 case BUILT_IN_FLOORF:
5541 case BUILT_IN_FLOORL:
5542 case BUILT_IN_CEIL:
5543 case BUILT_IN_CEILF:
5544 case BUILT_IN_CEILL:
5545 case BUILT_IN_TRUNC:
5546 case BUILT_IN_TRUNCF:
5547 case BUILT_IN_TRUNCL:
5548 case BUILT_IN_ROUND:
5549 case BUILT_IN_ROUNDF:
5550 case BUILT_IN_ROUNDL:
5551 case BUILT_IN_NEARBYINT:
5552 case BUILT_IN_NEARBYINTF:
5553 case BUILT_IN_NEARBYINTL:
5554 target = expand_builtin_mathfn (exp, target, subtarget);
5555 if (target)
5556 return target;
5557 break;
5559 case BUILT_IN_POW:
5560 case BUILT_IN_POWF:
5561 case BUILT_IN_POWL:
5562 target = expand_builtin_pow (exp, target, subtarget);
5563 if (target)
5564 return target;
5565 break;
5567 case BUILT_IN_ATAN2:
5568 case BUILT_IN_ATAN2F:
5569 case BUILT_IN_ATAN2L:
5570 case BUILT_IN_FMOD:
5571 case BUILT_IN_FMODF:
5572 case BUILT_IN_FMODL:
5573 case BUILT_IN_DREM:
5574 case BUILT_IN_DREMF:
5575 case BUILT_IN_DREML:
5576 if (! flag_unsafe_math_optimizations)
5577 break;
5578 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5579 if (target)
5580 return target;
5581 break;
5583 case BUILT_IN_SIN:
5584 case BUILT_IN_SINF:
5585 case BUILT_IN_SINL:
5586 case BUILT_IN_COS:
5587 case BUILT_IN_COSF:
5588 case BUILT_IN_COSL:
5589 if (! flag_unsafe_math_optimizations)
5590 break;
5591 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5592 if (target)
5593 return target;
5594 break;
5596 case BUILT_IN_APPLY_ARGS:
5597 return expand_builtin_apply_args ();
5599 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5600 FUNCTION with a copy of the parameters described by
5601 ARGUMENTS, and ARGSIZE. It returns a block of memory
5602 allocated on the stack into which is stored all the registers
5603 that might possibly be used for returning the result of a
5604 function. ARGUMENTS is the value returned by
5605 __builtin_apply_args. ARGSIZE is the number of bytes of
5606 arguments that must be copied. ??? How should this value be
5607 computed? We'll also need a safe worst case value for varargs
5608 functions. */
5609 case BUILT_IN_APPLY:
5610 if (!validate_arglist (arglist, POINTER_TYPE,
5611 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5612 && !validate_arglist (arglist, REFERENCE_TYPE,
5613 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5614 return const0_rtx;
5615 else
5617 int i;
5618 tree t;
5619 rtx ops[3];
5621 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5622 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5624 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5627 /* __builtin_return (RESULT) causes the function to return the
5628 value described by RESULT. RESULT is address of the block of
5629 memory returned by __builtin_apply. */
5630 case BUILT_IN_RETURN:
5631 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5632 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5633 NULL_RTX, VOIDmode, 0));
5634 return const0_rtx;
5636 case BUILT_IN_SAVEREGS:
5637 return expand_builtin_saveregs ();
5639 case BUILT_IN_ARGS_INFO:
5640 return expand_builtin_args_info (arglist);
5642 /* Return the address of the first anonymous stack arg. */
5643 case BUILT_IN_NEXT_ARG:
5644 simplify_builtin_next_arg (arglist);
5645 return expand_builtin_next_arg (arglist);
5647 case BUILT_IN_CLASSIFY_TYPE:
5648 return expand_builtin_classify_type (arglist);
5650 case BUILT_IN_CONSTANT_P:
5651 return const0_rtx;
5653 case BUILT_IN_FRAME_ADDRESS:
5654 case BUILT_IN_RETURN_ADDRESS:
5655 return expand_builtin_frame_address (fndecl, arglist);
5657 /* Returns the address of the area where the structure is returned.
5658 0 otherwise. */
5659 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5660 if (arglist != 0
5661 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5662 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5663 return const0_rtx;
5664 else
5665 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5667 case BUILT_IN_ALLOCA:
5668 target = expand_builtin_alloca (arglist, target);
5669 if (target)
5670 return target;
5671 break;
5673 case BUILT_IN_STACK_ALLOC:
5674 expand_stack_alloc (TREE_VALUE (arglist),
5675 TREE_VALUE (TREE_CHAIN (arglist)));
5676 return const0_rtx;
5678 case BUILT_IN_STACK_SAVE:
5679 return expand_stack_save ();
5681 case BUILT_IN_STACK_RESTORE:
5682 expand_stack_restore (TREE_VALUE (arglist));
5683 return const0_rtx;
5685 case BUILT_IN_FFS:
5686 case BUILT_IN_FFSL:
5687 case BUILT_IN_FFSLL:
5688 target = expand_builtin_unop (target_mode, arglist, target,
5689 subtarget, ffs_optab);
5690 if (target)
5691 return target;
5692 break;
5694 case BUILT_IN_CLZ:
5695 case BUILT_IN_CLZL:
5696 case BUILT_IN_CLZLL:
5697 target = expand_builtin_unop (target_mode, arglist, target,
5698 subtarget, clz_optab);
5699 if (target)
5700 return target;
5701 break;
5703 case BUILT_IN_CTZ:
5704 case BUILT_IN_CTZL:
5705 case BUILT_IN_CTZLL:
5706 target = expand_builtin_unop (target_mode, arglist, target,
5707 subtarget, ctz_optab);
5708 if (target)
5709 return target;
5710 break;
5712 case BUILT_IN_POPCOUNT:
5713 case BUILT_IN_POPCOUNTL:
5714 case BUILT_IN_POPCOUNTLL:
5715 target = expand_builtin_unop (target_mode, arglist, target,
5716 subtarget, popcount_optab);
5717 if (target)
5718 return target;
5719 break;
5721 case BUILT_IN_PARITY:
5722 case BUILT_IN_PARITYL:
5723 case BUILT_IN_PARITYLL:
5724 target = expand_builtin_unop (target_mode, arglist, target,
5725 subtarget, parity_optab);
5726 if (target)
5727 return target;
5728 break;
5730 case BUILT_IN_STRLEN:
5731 target = expand_builtin_strlen (arglist, target, target_mode);
5732 if (target)
5733 return target;
5734 break;
5736 case BUILT_IN_STRCPY:
5737 target = expand_builtin_strcpy (arglist, target, mode);
5738 if (target)
5739 return target;
5740 break;
5742 case BUILT_IN_STRNCPY:
5743 target = expand_builtin_strncpy (arglist, target, mode);
5744 if (target)
5745 return target;
5746 break;
5748 case BUILT_IN_STPCPY:
5749 target = expand_builtin_stpcpy (arglist, target, mode);
5750 if (target)
5751 return target;
5752 break;
5754 case BUILT_IN_STRCAT:
5755 target = expand_builtin_strcat (arglist, target, mode);
5756 if (target)
5757 return target;
5758 break;
5760 case BUILT_IN_STRNCAT:
5761 target = expand_builtin_strncat (arglist, target, mode);
5762 if (target)
5763 return target;
5764 break;
5766 case BUILT_IN_STRSPN:
5767 target = expand_builtin_strspn (arglist, target, mode);
5768 if (target)
5769 return target;
5770 break;
5772 case BUILT_IN_STRCSPN:
5773 target = expand_builtin_strcspn (arglist, target, mode);
5774 if (target)
5775 return target;
5776 break;
5778 case BUILT_IN_STRSTR:
5779 target = expand_builtin_strstr (arglist, target, mode);
5780 if (target)
5781 return target;
5782 break;
5784 case BUILT_IN_STRPBRK:
5785 target = expand_builtin_strpbrk (arglist, target, mode);
5786 if (target)
5787 return target;
5788 break;
5790 case BUILT_IN_INDEX:
5791 case BUILT_IN_STRCHR:
5792 target = expand_builtin_strchr (arglist, target, mode);
5793 if (target)
5794 return target;
5795 break;
5797 case BUILT_IN_RINDEX:
5798 case BUILT_IN_STRRCHR:
5799 target = expand_builtin_strrchr (arglist, target, mode);
5800 if (target)
5801 return target;
5802 break;
5804 case BUILT_IN_MEMCPY:
5805 target = expand_builtin_memcpy (arglist, target, mode);
5806 if (target)
5807 return target;
5808 break;
5810 case BUILT_IN_MEMPCPY:
5811 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5812 if (target)
5813 return target;
5814 break;
5816 case BUILT_IN_MEMMOVE:
5817 target = expand_builtin_memmove (arglist, target, mode);
5818 if (target)
5819 return target;
5820 break;
5822 case BUILT_IN_BCOPY:
5823 target = expand_builtin_bcopy (arglist);
5824 if (target)
5825 return target;
5826 break;
5828 case BUILT_IN_MEMSET:
5829 target = expand_builtin_memset (arglist, target, mode);
5830 if (target)
5831 return target;
5832 break;
5834 case BUILT_IN_BZERO:
5835 target = expand_builtin_bzero (arglist);
5836 if (target)
5837 return target;
5838 break;
5840 case BUILT_IN_STRCMP:
5841 target = expand_builtin_strcmp (exp, target, mode);
5842 if (target)
5843 return target;
5844 break;
5846 case BUILT_IN_STRNCMP:
5847 target = expand_builtin_strncmp (exp, target, mode);
5848 if (target)
5849 return target;
5850 break;
5852 case BUILT_IN_BCMP:
5853 case BUILT_IN_MEMCMP:
5854 target = expand_builtin_memcmp (exp, arglist, target, mode);
5855 if (target)
5856 return target;
5857 break;
5859 case BUILT_IN_SETJMP:
5860 target = expand_builtin_setjmp (arglist, target);
5861 if (target)
5862 return target;
5863 break;
5865 /* __builtin_longjmp is passed a pointer to an array of five words.
5866 It's similar to the C library longjmp function but works with
5867 __builtin_setjmp above. */
5868 case BUILT_IN_LONGJMP:
5869 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5870 break;
5871 else
5873 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5874 VOIDmode, 0);
5875 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5876 NULL_RTX, VOIDmode, 0);
5878 if (value != const1_rtx)
5880 error ("__builtin_longjmp second argument must be 1");
5881 return const0_rtx;
5884 expand_builtin_longjmp (buf_addr, value);
5885 return const0_rtx;
5888 case BUILT_IN_NONLOCAL_GOTO:
5889 target = expand_builtin_nonlocal_goto (arglist);
5890 if (target)
5891 return target;
5892 break;
5894 /* This updates the setjmp buffer that is its argument with the value
5895 of the current stack pointer. */
5896 case BUILT_IN_UPDATE_SETJMP_BUF:
5897 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5899 rtx buf_addr
5900 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5902 expand_builtin_update_setjmp_buf (buf_addr);
5903 return const0_rtx;
5905 break;
5907 case BUILT_IN_TRAP:
5908 expand_builtin_trap ();
5909 return const0_rtx;
5911 case BUILT_IN_PRINTF:
5912 target = expand_builtin_printf (arglist, target, mode, false);
5913 if (target)
5914 return target;
5915 break;
5917 case BUILT_IN_PRINTF_UNLOCKED:
5918 target = expand_builtin_printf (arglist, target, mode, true);
5919 if (target)
5920 return target;
5921 break;
5923 case BUILT_IN_FPUTS:
5924 target = expand_builtin_fputs (arglist, target, false);
5925 if (target)
5926 return target;
5927 break;
5928 case BUILT_IN_FPUTS_UNLOCKED:
5929 target = expand_builtin_fputs (arglist, target, true);
5930 if (target)
5931 return target;
5932 break;
5934 case BUILT_IN_FPRINTF:
5935 target = expand_builtin_fprintf (arglist, target, mode, false);
5936 if (target)
5937 return target;
5938 break;
5940 case BUILT_IN_FPRINTF_UNLOCKED:
5941 target = expand_builtin_fprintf (arglist, target, mode, true);
5942 if (target)
5943 return target;
5944 break;
5946 case BUILT_IN_SPRINTF:
5947 target = expand_builtin_sprintf (arglist, target, mode);
5948 if (target)
5949 return target;
5950 break;
5952 case BUILT_IN_SIGNBIT:
5953 case BUILT_IN_SIGNBITF:
5954 case BUILT_IN_SIGNBITL:
5955 target = expand_builtin_signbit (exp, target);
5956 if (target)
5957 return target;
5958 break;
5960 /* Various hooks for the DWARF 2 __throw routine. */
5961 case BUILT_IN_UNWIND_INIT:
5962 expand_builtin_unwind_init ();
5963 return const0_rtx;
5964 case BUILT_IN_DWARF_CFA:
5965 return virtual_cfa_rtx;
5966 #ifdef DWARF2_UNWIND_INFO
5967 case BUILT_IN_DWARF_SP_COLUMN:
5968 return expand_builtin_dwarf_sp_column ();
5969 case BUILT_IN_INIT_DWARF_REG_SIZES:
5970 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5971 return const0_rtx;
5972 #endif
5973 case BUILT_IN_FROB_RETURN_ADDR:
5974 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5975 case BUILT_IN_EXTRACT_RETURN_ADDR:
5976 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5977 case BUILT_IN_EH_RETURN:
5978 expand_builtin_eh_return (TREE_VALUE (arglist),
5979 TREE_VALUE (TREE_CHAIN (arglist)));
5980 return const0_rtx;
5981 #ifdef EH_RETURN_DATA_REGNO
5982 case BUILT_IN_EH_RETURN_DATA_REGNO:
5983 return expand_builtin_eh_return_data_regno (arglist);
5984 #endif
5985 case BUILT_IN_EXTEND_POINTER:
5986 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5988 case BUILT_IN_VA_START:
5989 case BUILT_IN_STDARG_START:
5990 return expand_builtin_va_start (arglist);
5991 case BUILT_IN_VA_END:
5992 return expand_builtin_va_end (arglist);
5993 case BUILT_IN_VA_COPY:
5994 return expand_builtin_va_copy (arglist);
5995 case BUILT_IN_EXPECT:
5996 return expand_builtin_expect (arglist, target);
5997 case BUILT_IN_PREFETCH:
5998 expand_builtin_prefetch (arglist);
5999 return const0_rtx;
6001 case BUILT_IN_PROFILE_FUNC_ENTER:
6002 return expand_builtin_profile_func (false);
6003 case BUILT_IN_PROFILE_FUNC_EXIT:
6004 return expand_builtin_profile_func (true);
6006 case BUILT_IN_INIT_TRAMPOLINE:
6007 return expand_builtin_init_trampoline (arglist);
6008 case BUILT_IN_ADJUST_TRAMPOLINE:
6009 return expand_builtin_adjust_trampoline (arglist);
6011 case BUILT_IN_FORK:
6012 case BUILT_IN_EXECL:
6013 case BUILT_IN_EXECV:
6014 case BUILT_IN_EXECLP:
6015 case BUILT_IN_EXECLE:
6016 case BUILT_IN_EXECVP:
6017 case BUILT_IN_EXECVE:
6018 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6019 if (target)
6020 return target;
6021 break;
6023 default: /* just do library call, if unknown builtin */
6024 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
6025 error ("built-in function `%s' not currently supported",
6026 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
6029 /* The switch statement above can drop through to cause the function
6030 to be called normally. */
6031 return expand_call (exp, target, ignore);
6034 /* Determine whether a tree node represents a call to a built-in
6035 function. If the tree T is a call to a built-in function with
6036 the right number of arguments of the appropriate types, return
6037 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6038 Otherwise the return value is END_BUILTINS. */
6040 enum built_in_function
6041 builtin_mathfn_code (tree t)
6043 tree fndecl, arglist, parmlist;
6044 tree argtype, parmtype;
6046 if (TREE_CODE (t) != CALL_EXPR
6047 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6048 return END_BUILTINS;
6050 fndecl = get_callee_fndecl (t);
6051 if (fndecl == NULL_TREE
6052 || TREE_CODE (fndecl) != FUNCTION_DECL
6053 || ! DECL_BUILT_IN (fndecl)
6054 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6055 return END_BUILTINS;
6057 arglist = TREE_OPERAND (t, 1);
6058 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6059 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6061 /* If a function doesn't take a variable number of arguments,
6062 the last element in the list will have type `void'. */
6063 parmtype = TREE_VALUE (parmlist);
6064 if (VOID_TYPE_P (parmtype))
6066 if (arglist)
6067 return END_BUILTINS;
6068 return DECL_FUNCTION_CODE (fndecl);
6071 if (! arglist)
6072 return END_BUILTINS;
6074 argtype = TREE_TYPE (TREE_VALUE (arglist));
6076 if (SCALAR_FLOAT_TYPE_P (parmtype))
6078 if (! SCALAR_FLOAT_TYPE_P (argtype))
6079 return END_BUILTINS;
6081 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6083 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6084 return END_BUILTINS;
6086 else if (POINTER_TYPE_P (parmtype))
6088 if (! POINTER_TYPE_P (argtype))
6089 return END_BUILTINS;
6091 else if (INTEGRAL_TYPE_P (parmtype))
6093 if (! INTEGRAL_TYPE_P (argtype))
6094 return END_BUILTINS;
6096 else
6097 return END_BUILTINS;
6099 arglist = TREE_CHAIN (arglist);
6102 /* Variable-length argument list. */
6103 return DECL_FUNCTION_CODE (fndecl);
6106 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6107 constant. ARGLIST is the argument list of the call. */
6109 static tree
6110 fold_builtin_constant_p (tree arglist)
6112 if (arglist == 0)
6113 return 0;
6115 arglist = TREE_VALUE (arglist);
6117 /* We return 1 for a numeric type that's known to be a constant
6118 value at compile-time or for an aggregate type that's a
6119 literal constant. */
6120 STRIP_NOPS (arglist);
6122 /* If we know this is a constant, emit the constant of one. */
6123 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6124 || (TREE_CODE (arglist) == CONSTRUCTOR
6125 && TREE_CONSTANT (arglist))
6126 || (TREE_CODE (arglist) == ADDR_EXPR
6127 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6128 return integer_one_node;
6130 /* If this expression has side effects, show we don't know it to be a
6131 constant. Likewise if it's a pointer or aggregate type since in
6132 those case we only want literals, since those are only optimized
6133 when generating RTL, not later.
6134 And finally, if we are compiling an initializer, not code, we
6135 need to return a definite result now; there's not going to be any
6136 more optimization done. */
6137 if (TREE_SIDE_EFFECTS (arglist)
6138 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6139 || POINTER_TYPE_P (TREE_TYPE (arglist))
6140 || cfun == 0)
6141 return integer_zero_node;
6143 return 0;
6146 /* Fold a call to __builtin_expect, if we expect that a comparison against
6147 the argument will fold to a constant. In practice, this means a true
6148 constant or the address of a non-weak symbol. ARGLIST is the argument
6149 list of the call. */
6151 static tree
6152 fold_builtin_expect (tree arglist)
6154 tree arg, inner;
6156 if (arglist == 0)
6157 return 0;
6159 arg = TREE_VALUE (arglist);
6161 /* If the argument isn't invariant, then there's nothing we can do. */
6162 if (!TREE_INVARIANT (arg))
6163 return 0;
6165 /* If we're looking at an address of a weak decl, then do not fold. */
6166 inner = arg;
6167 STRIP_NOPS (inner);
6168 if (TREE_CODE (inner) == ADDR_EXPR)
6172 inner = TREE_OPERAND (inner, 0);
6174 while (TREE_CODE (inner) == COMPONENT_REF
6175 || TREE_CODE (inner) == ARRAY_REF);
6176 if (DECL_P (inner) && DECL_WEAK (inner))
6177 return 0;
6180 /* Otherwise, ARG already has the proper type for the return value. */
6181 return arg;
6184 /* Fold a call to __builtin_classify_type. */
6186 static tree
6187 fold_builtin_classify_type (tree arglist)
6189 if (arglist == 0)
6190 return build_int_2 (no_type_class, 0);
6192 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6195 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6197 static tree
6198 fold_builtin_inf (tree type, int warn)
6200 REAL_VALUE_TYPE real;
6202 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6203 warning ("target format does not support infinity");
6205 real_inf (&real);
6206 return build_real (type, real);
6209 /* Fold a call to __builtin_nan or __builtin_nans. */
6211 static tree
6212 fold_builtin_nan (tree arglist, tree type, int quiet)
6214 REAL_VALUE_TYPE real;
6215 const char *str;
6217 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6218 return 0;
6219 str = c_getstr (TREE_VALUE (arglist));
6220 if (!str)
6221 return 0;
6223 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6224 return 0;
6226 return build_real (type, real);
6229 /* Return true if the floating point expression T has an integer value.
6230 We also allow +Inf, -Inf and NaN to be considered integer values. */
6232 static bool
6233 integer_valued_real_p (tree t)
6235 switch (TREE_CODE (t))
6237 case FLOAT_EXPR:
6238 return true;
6240 case ABS_EXPR:
6241 case SAVE_EXPR:
6242 case NON_LVALUE_EXPR:
6243 return integer_valued_real_p (TREE_OPERAND (t, 0));
6245 case COMPOUND_EXPR:
6246 case MODIFY_EXPR:
6247 case BIND_EXPR:
6248 return integer_valued_real_p (TREE_OPERAND (t, 1));
6250 case PLUS_EXPR:
6251 case MINUS_EXPR:
6252 case MULT_EXPR:
6253 case MIN_EXPR:
6254 case MAX_EXPR:
6255 return integer_valued_real_p (TREE_OPERAND (t, 0))
6256 && integer_valued_real_p (TREE_OPERAND (t, 1));
6258 case COND_EXPR:
6259 return integer_valued_real_p (TREE_OPERAND (t, 1))
6260 && integer_valued_real_p (TREE_OPERAND (t, 2));
6262 case REAL_CST:
6263 if (! TREE_CONSTANT_OVERFLOW (t))
6265 REAL_VALUE_TYPE c, cint;
6267 c = TREE_REAL_CST (t);
6268 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6269 return real_identical (&c, &cint);
6272 case NOP_EXPR:
6274 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6275 if (TREE_CODE (type) == INTEGER_TYPE)
6276 return true;
6277 if (TREE_CODE (type) == REAL_TYPE)
6278 return integer_valued_real_p (TREE_OPERAND (t, 0));
6279 break;
6282 case CALL_EXPR:
6283 switch (builtin_mathfn_code (t))
6285 case BUILT_IN_CEIL:
6286 case BUILT_IN_CEILF:
6287 case BUILT_IN_CEILL:
6288 case BUILT_IN_FLOOR:
6289 case BUILT_IN_FLOORF:
6290 case BUILT_IN_FLOORL:
6291 case BUILT_IN_NEARBYINT:
6292 case BUILT_IN_NEARBYINTF:
6293 case BUILT_IN_NEARBYINTL:
6294 case BUILT_IN_RINT:
6295 case BUILT_IN_RINTF:
6296 case BUILT_IN_RINTL:
6297 case BUILT_IN_ROUND:
6298 case BUILT_IN_ROUNDF:
6299 case BUILT_IN_ROUNDL:
6300 case BUILT_IN_TRUNC:
6301 case BUILT_IN_TRUNCF:
6302 case BUILT_IN_TRUNCL:
6303 return true;
6305 default:
6306 break;
6308 break;
6310 default:
6311 break;
6313 return false;
6316 /* EXP is assumed to be builtin call where truncation can be propagated
6317 across (for instance floor((double)f) == (double)floorf (f).
6318 Do the transformation. */
6320 static tree
6321 fold_trunc_transparent_mathfn (tree exp)
6323 tree fndecl = get_callee_fndecl (exp);
6324 tree arglist = TREE_OPERAND (exp, 1);
6325 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6326 tree arg;
6328 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6329 return 0;
6331 arg = TREE_VALUE (arglist);
6332 /* Integer rounding functions are idempotent. */
6333 if (fcode == builtin_mathfn_code (arg))
6334 return arg;
6336 /* If argument is already integer valued, and we don't need to worry
6337 about setting errno, there's no need to perform rounding. */
6338 if (! flag_errno_math && integer_valued_real_p (arg))
6339 return arg;
6341 if (optimize)
6343 tree arg0 = strip_float_extensions (arg);
6344 tree ftype = TREE_TYPE (exp);
6345 tree newtype = TREE_TYPE (arg0);
6346 tree decl;
6348 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6349 && (decl = mathfn_built_in (newtype, fcode)))
6351 arglist =
6352 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6353 return fold_convert (ftype,
6354 build_function_call_expr (decl, arglist));
6357 return 0;
6360 /* EXP is assumed to be builtin call which can narrow the FP type of
6361 the argument, for instance lround((double)f) -> lroundf (f). */
6363 static tree
6364 fold_fixed_mathfn (tree exp)
6366 tree fndecl = get_callee_fndecl (exp);
6367 tree arglist = TREE_OPERAND (exp, 1);
6368 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6369 tree arg;
6371 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6372 return 0;
6374 arg = TREE_VALUE (arglist);
6376 /* If argument is already integer valued, and we don't need to worry
6377 about setting errno, there's no need to perform rounding. */
6378 if (! flag_errno_math && integer_valued_real_p (arg))
6379 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6381 if (optimize)
6383 tree ftype = TREE_TYPE (arg);
6384 tree arg0 = strip_float_extensions (arg);
6385 tree newtype = TREE_TYPE (arg0);
6386 tree decl;
6388 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6389 && (decl = mathfn_built_in (newtype, fcode)))
6391 arglist =
6392 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6393 return build_function_call_expr (decl, arglist);
6396 return 0;
6399 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6400 is the argument list and TYPE is the return type. Return
6401 NULL_TREE if no if no simplification can be made. */
6403 static tree
6404 fold_builtin_cabs (tree arglist, tree type)
6406 tree arg;
6408 if (!arglist || TREE_CHAIN (arglist))
6409 return NULL_TREE;
6411 arg = TREE_VALUE (arglist);
6412 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6413 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6414 return NULL_TREE;
6416 /* Evaluate cabs of a constant at compile-time. */
6417 if (flag_unsafe_math_optimizations
6418 && TREE_CODE (arg) == COMPLEX_CST
6419 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6420 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6421 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6422 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6424 REAL_VALUE_TYPE r, i;
6426 r = TREE_REAL_CST (TREE_REALPART (arg));
6427 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6429 real_arithmetic (&r, MULT_EXPR, &r, &r);
6430 real_arithmetic (&i, MULT_EXPR, &i, &i);
6431 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6432 if (real_sqrt (&r, TYPE_MODE (type), &r)
6433 || ! flag_trapping_math)
6434 return build_real (type, r);
6437 /* If either part is zero, cabs is fabs of the other. */
6438 if (TREE_CODE (arg) == COMPLEX_EXPR
6439 && real_zerop (TREE_OPERAND (arg, 0)))
6440 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6441 if (TREE_CODE (arg) == COMPLEX_EXPR
6442 && real_zerop (TREE_OPERAND (arg, 1)))
6443 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6445 if (flag_unsafe_math_optimizations)
6447 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6449 if (sqrtfn != NULL_TREE)
6451 tree rpart, ipart, result, arglist;
6453 arg = builtin_save_expr (arg);
6455 rpart = fold (build1 (REALPART_EXPR, type, arg));
6456 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6458 rpart = builtin_save_expr (rpart);
6459 ipart = builtin_save_expr (ipart);
6461 result = fold (build (PLUS_EXPR, type,
6462 fold (build (MULT_EXPR, type,
6463 rpart, rpart)),
6464 fold (build (MULT_EXPR, type,
6465 ipart, ipart))));
6467 arglist = build_tree_list (NULL_TREE, result);
6468 return build_function_call_expr (sqrtfn, arglist);
6472 return NULL_TREE;
6475 /* Fold function call to builtin trunc, truncf or truncl. Return
6476 NULL_TREE if no simplification can be made. */
6478 static tree
6479 fold_builtin_trunc (tree exp)
6481 tree arglist = TREE_OPERAND (exp, 1);
6482 tree arg;
6484 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6485 return 0;
6487 /* Optimize trunc of constant value. */
6488 arg = TREE_VALUE (arglist);
6489 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6491 REAL_VALUE_TYPE r, x;
6492 tree type = TREE_TYPE (exp);
6494 x = TREE_REAL_CST (arg);
6495 real_trunc (&r, TYPE_MODE (type), &x);
6496 return build_real (type, r);
6499 return fold_trunc_transparent_mathfn (exp);
6502 /* Fold function call to builtin floor, floorf or floorl. Return
6503 NULL_TREE if no simplification can be made. */
6505 static tree
6506 fold_builtin_floor (tree exp)
6508 tree arglist = TREE_OPERAND (exp, 1);
6509 tree arg;
6511 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6512 return 0;
6514 /* Optimize floor of constant value. */
6515 arg = TREE_VALUE (arglist);
6516 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6518 REAL_VALUE_TYPE x;
6520 x = TREE_REAL_CST (arg);
6521 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6523 tree type = TREE_TYPE (exp);
6524 REAL_VALUE_TYPE r;
6526 real_floor (&r, TYPE_MODE (type), &x);
6527 return build_real (type, r);
6531 return fold_trunc_transparent_mathfn (exp);
6534 /* Fold function call to builtin ceil, ceilf or ceill. Return
6535 NULL_TREE if no simplification can be made. */
6537 static tree
6538 fold_builtin_ceil (tree exp)
6540 tree arglist = TREE_OPERAND (exp, 1);
6541 tree arg;
6543 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6544 return 0;
6546 /* Optimize ceil of constant value. */
6547 arg = TREE_VALUE (arglist);
6548 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6550 REAL_VALUE_TYPE x;
6552 x = TREE_REAL_CST (arg);
6553 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6555 tree type = TREE_TYPE (exp);
6556 REAL_VALUE_TYPE r;
6558 real_ceil (&r, TYPE_MODE (type), &x);
6559 return build_real (type, r);
6563 return fold_trunc_transparent_mathfn (exp);
6566 /* Fold function call to builtin round, roundf or roundl. Return
6567 NULL_TREE if no simplification can be made. */
6569 static tree
6570 fold_builtin_round (tree exp)
6572 tree arglist = TREE_OPERAND (exp, 1);
6573 tree arg;
6575 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6576 return 0;
6578 /* Optimize round of constant value. */
6579 arg = TREE_VALUE (arglist);
6580 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6582 REAL_VALUE_TYPE x;
6584 x = TREE_REAL_CST (arg);
6585 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6587 tree type = TREE_TYPE (exp);
6588 REAL_VALUE_TYPE r;
6590 real_round (&r, TYPE_MODE (type), &x);
6591 return build_real (type, r);
6595 return fold_trunc_transparent_mathfn (exp);
6598 /* Fold function call to builtin lround, lroundf or lroundl (or the
6599 corresponding long long versions). Return NULL_TREE if no
6600 simplification can be made. */
6602 static tree
6603 fold_builtin_lround (tree exp)
6605 tree arglist = TREE_OPERAND (exp, 1);
6606 tree arg;
6608 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6609 return 0;
6611 /* Optimize lround of constant value. */
6612 arg = TREE_VALUE (arglist);
6613 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6615 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6617 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6619 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6620 HOST_WIDE_INT hi, lo;
6621 REAL_VALUE_TYPE r;
6623 real_round (&r, TYPE_MODE (ftype), &x);
6624 REAL_VALUE_TO_INT (&lo, &hi, r);
6625 result = build_int_2 (lo, hi);
6626 if (int_fits_type_p (result, itype))
6627 return fold_convert (itype, result);
6631 return fold_fixed_mathfn (exp);
6634 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6635 and their long and long long variants (i.e. ffsl and ffsll).
6636 Return NULL_TREE if no simplification can be made. */
6638 static tree
6639 fold_builtin_bitop (tree exp)
6641 tree fndecl = get_callee_fndecl (exp);
6642 tree arglist = TREE_OPERAND (exp, 1);
6643 tree arg;
6645 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6646 return NULL_TREE;
6648 /* Optimize for constant argument. */
6649 arg = TREE_VALUE (arglist);
6650 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6652 HOST_WIDE_INT hi, width, result;
6653 unsigned HOST_WIDE_INT lo;
6654 tree type, t;
6656 type = TREE_TYPE (arg);
6657 width = TYPE_PRECISION (type);
6658 lo = TREE_INT_CST_LOW (arg);
6660 /* Clear all the bits that are beyond the type's precision. */
6661 if (width > HOST_BITS_PER_WIDE_INT)
6663 hi = TREE_INT_CST_HIGH (arg);
6664 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6665 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6667 else
6669 hi = 0;
6670 if (width < HOST_BITS_PER_WIDE_INT)
6671 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6674 switch (DECL_FUNCTION_CODE (fndecl))
6676 case BUILT_IN_FFS:
6677 case BUILT_IN_FFSL:
6678 case BUILT_IN_FFSLL:
6679 if (lo != 0)
6680 result = exact_log2 (lo & -lo) + 1;
6681 else if (hi != 0)
6682 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6683 else
6684 result = 0;
6685 break;
6687 case BUILT_IN_CLZ:
6688 case BUILT_IN_CLZL:
6689 case BUILT_IN_CLZLL:
6690 if (hi != 0)
6691 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6692 else if (lo != 0)
6693 result = width - floor_log2 (lo) - 1;
6694 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6695 result = width;
6696 break;
6698 case BUILT_IN_CTZ:
6699 case BUILT_IN_CTZL:
6700 case BUILT_IN_CTZLL:
6701 if (lo != 0)
6702 result = exact_log2 (lo & -lo);
6703 else if (hi != 0)
6704 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6705 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6706 result = width;
6707 break;
6709 case BUILT_IN_POPCOUNT:
6710 case BUILT_IN_POPCOUNTL:
6711 case BUILT_IN_POPCOUNTLL:
6712 result = 0;
6713 while (lo)
6714 result++, lo &= lo - 1;
6715 while (hi)
6716 result++, hi &= hi - 1;
6717 break;
6719 case BUILT_IN_PARITY:
6720 case BUILT_IN_PARITYL:
6721 case BUILT_IN_PARITYLL:
6722 result = 0;
6723 while (lo)
6724 result++, lo &= lo - 1;
6725 while (hi)
6726 result++, hi &= hi - 1;
6727 result &= 1;
6728 break;
6730 default:
6731 abort();
6734 t = build_int_2 (result, 0);
6735 TREE_TYPE (t) = TREE_TYPE (exp);
6736 return t;
6739 return NULL_TREE;
6742 /* Return true if EXPR is the real constant contained in VALUE. */
6744 static bool
6745 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6747 STRIP_NOPS (expr);
6749 return ((TREE_CODE (expr) == REAL_CST
6750 && ! TREE_CONSTANT_OVERFLOW (expr)
6751 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6752 || (TREE_CODE (expr) == COMPLEX_CST
6753 && real_dconstp (TREE_REALPART (expr), value)
6754 && real_zerop (TREE_IMAGPART (expr))));
6757 /* A subroutine of fold_builtin to fold the various logarithmic
6758 functions. EXP is the CALL_EXPR of a call to a builtin logN
6759 function. VALUE is the base of the logN function. */
6761 static tree
6762 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6764 tree arglist = TREE_OPERAND (exp, 1);
6766 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6768 tree fndecl = get_callee_fndecl (exp);
6769 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6770 tree arg = TREE_VALUE (arglist);
6771 const enum built_in_function fcode = builtin_mathfn_code (arg);
6773 /* Optimize logN(1.0) = 0.0. */
6774 if (real_onep (arg))
6775 return build_real (type, dconst0);
6777 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6778 exactly, then only do this if flag_unsafe_math_optimizations. */
6779 if (exact_real_truncate (TYPE_MODE (type), value)
6780 || flag_unsafe_math_optimizations)
6782 const REAL_VALUE_TYPE value_truncate =
6783 real_value_truncate (TYPE_MODE (type), *value);
6784 if (real_dconstp (arg, &value_truncate))
6785 return build_real (type, dconst1);
6788 /* Special case, optimize logN(expN(x)) = x. */
6789 if (flag_unsafe_math_optimizations
6790 && ((value == &dconste
6791 && (fcode == BUILT_IN_EXP
6792 || fcode == BUILT_IN_EXPF
6793 || fcode == BUILT_IN_EXPL))
6794 || (value == &dconst2
6795 && (fcode == BUILT_IN_EXP2
6796 || fcode == BUILT_IN_EXP2F
6797 || fcode == BUILT_IN_EXP2L))
6798 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6799 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6801 /* Optimize logN(func()) for various exponential functions. We
6802 want to determine the value "x" and the power "exponent" in
6803 order to transform logN(x**exponent) into exponent*logN(x). */
6804 if (flag_unsafe_math_optimizations)
6806 tree exponent = 0, x = 0;
6808 switch (fcode)
6810 case BUILT_IN_EXP:
6811 case BUILT_IN_EXPF:
6812 case BUILT_IN_EXPL:
6813 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6814 x = build_real (type,
6815 real_value_truncate (TYPE_MODE (type), dconste));
6816 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6817 break;
6818 case BUILT_IN_EXP2:
6819 case BUILT_IN_EXP2F:
6820 case BUILT_IN_EXP2L:
6821 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6822 x = build_real (type, dconst2);
6823 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6824 break;
6825 case BUILT_IN_EXP10:
6826 case BUILT_IN_EXP10F:
6827 case BUILT_IN_EXP10L:
6828 case BUILT_IN_POW10:
6829 case BUILT_IN_POW10F:
6830 case BUILT_IN_POW10L:
6831 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6832 x = build_real (type, dconst10);
6833 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6834 break;
6835 case BUILT_IN_SQRT:
6836 case BUILT_IN_SQRTF:
6837 case BUILT_IN_SQRTL:
6838 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6839 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6840 exponent = build_real (type, dconsthalf);
6841 break;
6842 case BUILT_IN_CBRT:
6843 case BUILT_IN_CBRTF:
6844 case BUILT_IN_CBRTL:
6845 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6846 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6847 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6848 dconstthird));
6849 break;
6850 case BUILT_IN_POW:
6851 case BUILT_IN_POWF:
6852 case BUILT_IN_POWL:
6853 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6854 x = TREE_VALUE (TREE_OPERAND (arg, 1));
6855 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6856 break;
6857 default:
6858 break;
6861 /* Now perform the optimization. */
6862 if (x && exponent)
6864 tree logfn;
6865 arglist = build_tree_list (NULL_TREE, x);
6866 logfn = build_function_call_expr (fndecl, arglist);
6867 return fold (build (MULT_EXPR, type, exponent, logfn));
6872 return 0;
6875 /* A subroutine of fold_builtin to fold the various exponent
6876 functions. EXP is the CALL_EXPR of a call to a builtin function.
6877 VALUE is the value which will be raised to a power. */
6879 static tree
6880 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6882 tree arglist = TREE_OPERAND (exp, 1);
6884 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6886 tree fndecl = get_callee_fndecl (exp);
6887 tree type = TREE_TYPE (TREE_TYPE (fndecl));
6888 tree arg = TREE_VALUE (arglist);
6890 /* Optimize exp*(0.0) = 1.0. */
6891 if (real_zerop (arg))
6892 return build_real (type, dconst1);
6894 /* Optimize expN(1.0) = N. */
6895 if (real_onep (arg))
6897 REAL_VALUE_TYPE cst;
6899 real_convert (&cst, TYPE_MODE (type), value);
6900 return build_real (type, cst);
6903 /* Attempt to evaluate expN(integer) at compile-time. */
6904 if (flag_unsafe_math_optimizations
6905 && TREE_CODE (arg) == REAL_CST
6906 && ! TREE_CONSTANT_OVERFLOW (arg))
6908 REAL_VALUE_TYPE cint;
6909 REAL_VALUE_TYPE c;
6910 HOST_WIDE_INT n;
6912 c = TREE_REAL_CST (arg);
6913 n = real_to_integer (&c);
6914 real_from_integer (&cint, VOIDmode, n,
6915 n < 0 ? -1 : 0, 0);
6916 if (real_identical (&c, &cint))
6918 REAL_VALUE_TYPE x;
6920 real_powi (&x, TYPE_MODE (type), value, n);
6921 return build_real (type, x);
6925 /* Optimize expN(logN(x)) = x. */
6926 if (flag_unsafe_math_optimizations)
6928 const enum built_in_function fcode = builtin_mathfn_code (arg);
6930 if ((value == &dconste
6931 && (fcode == BUILT_IN_LOG
6932 || fcode == BUILT_IN_LOGF
6933 || fcode == BUILT_IN_LOGL))
6934 || (value == &dconst2
6935 && (fcode == BUILT_IN_LOG2
6936 || fcode == BUILT_IN_LOG2F
6937 || fcode == BUILT_IN_LOG2L))
6938 || (value == &dconst10
6939 && (fcode == BUILT_IN_LOG10
6940 || fcode == BUILT_IN_LOG10F
6941 || fcode == BUILT_IN_LOG10L)))
6942 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6946 return 0;
6949 /* Fold function call to builtin memcpy. Return
6950 NULL_TREE if no simplification can be made. */
6952 static tree
6953 fold_builtin_memcpy (tree exp)
6955 tree arglist = TREE_OPERAND (exp, 1);
6956 tree dest, src, len;
6958 if (!validate_arglist (arglist,
6959 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6960 return 0;
6962 dest = TREE_VALUE (arglist);
6963 src = TREE_VALUE (TREE_CHAIN (arglist));
6964 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6966 /* If the LEN parameter is zero, return DEST. */
6967 if (integer_zerop (len))
6968 return omit_one_operand (TREE_TYPE (exp), dest, src);
6970 /* If SRC and DEST are the same (and not volatile), return DEST. */
6971 if (operand_equal_p (src, dest, 0))
6972 return omit_one_operand (TREE_TYPE (exp), dest, len);
6974 return 0;
6977 /* Fold function call to builtin mempcpy. Return
6978 NULL_TREE if no simplification can be made. */
6980 static tree
6981 fold_builtin_mempcpy (tree exp)
6983 tree arglist = TREE_OPERAND (exp, 1);
6984 tree dest, src, len;
6986 if (!validate_arglist (arglist,
6987 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6988 return 0;
6990 dest = TREE_VALUE (arglist);
6991 src = TREE_VALUE (TREE_CHAIN (arglist));
6992 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6994 /* If the LEN parameter is zero, return DEST. */
6995 if (integer_zerop (len))
6996 return omit_one_operand (TREE_TYPE (exp), dest, src);
6998 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6999 if (operand_equal_p (src, dest, 0))
7001 tree temp = fold_convert (TREE_TYPE (dest), len);
7002 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7003 return fold_convert (TREE_TYPE (exp), temp);
7006 return 0;
7009 /* Fold function call to builtin memmove. Return
7010 NULL_TREE if no simplification can be made. */
7012 static tree
7013 fold_builtin_memmove (tree exp)
7015 tree arglist = TREE_OPERAND (exp, 1);
7016 tree dest, src, len;
7018 if (!validate_arglist (arglist,
7019 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7020 return 0;
7022 dest = TREE_VALUE (arglist);
7023 src = TREE_VALUE (TREE_CHAIN (arglist));
7024 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7026 /* If the LEN parameter is zero, return DEST. */
7027 if (integer_zerop (len))
7028 return omit_one_operand (TREE_TYPE (exp), dest, src);
7030 /* If SRC and DEST are the same (and not volatile), return DEST. */
7031 if (operand_equal_p (src, dest, 0))
7032 return omit_one_operand (TREE_TYPE (exp), dest, len);
7034 return 0;
7037 /* Fold function call to builtin strcpy. Return
7038 NULL_TREE if no simplification can be made. */
7040 static tree
7041 fold_builtin_strcpy (tree exp)
7043 tree arglist = TREE_OPERAND (exp, 1);
7044 tree dest, src;
7046 if (!validate_arglist (arglist,
7047 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7048 return 0;
7050 dest = TREE_VALUE (arglist);
7051 src = TREE_VALUE (TREE_CHAIN (arglist));
7053 /* If SRC and DEST are the same (and not volatile), return DEST. */
7054 if (operand_equal_p (src, dest, 0))
7055 return fold_convert (TREE_TYPE (exp), dest);
7057 return 0;
7060 /* Fold function call to builtin strncpy. Return
7061 NULL_TREE if no simplification can be made. */
7063 static tree
7064 fold_builtin_strncpy (tree exp)
7066 tree arglist = TREE_OPERAND (exp, 1);
7067 tree dest, src, len;
7069 if (!validate_arglist (arglist,
7070 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7071 return 0;
7073 dest = TREE_VALUE (arglist);
7074 src = TREE_VALUE (TREE_CHAIN (arglist));
7075 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7077 /* If the LEN parameter is zero, return DEST. */
7078 if (integer_zerop (len))
7079 return omit_one_operand (TREE_TYPE (exp), dest, src);
7081 return 0;
7084 /* Fold function call to builtin memcmp. Return
7085 NULL_TREE if no simplification can be made. */
7087 static tree
7088 fold_builtin_memcmp (tree exp)
7090 tree arglist = TREE_OPERAND (exp, 1);
7091 tree arg1, arg2, len;
7093 if (!validate_arglist (arglist,
7094 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7095 return 0;
7097 arg1 = TREE_VALUE (arglist);
7098 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7099 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7101 /* If the LEN parameter is zero, return zero. */
7102 if (integer_zerop (len))
7104 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7105 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7108 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7109 if (operand_equal_p (arg1, arg2, 0))
7110 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7112 return 0;
7115 /* Fold function call to builtin strcmp. Return
7116 NULL_TREE if no simplification can be made. */
7118 static tree
7119 fold_builtin_strcmp (tree exp)
7121 tree arglist = TREE_OPERAND (exp, 1);
7122 tree arg1, arg2;
7123 const char *p1, *p2;
7125 if (!validate_arglist (arglist,
7126 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7127 return 0;
7129 arg1 = TREE_VALUE (arglist);
7130 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7132 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7133 if (operand_equal_p (arg1, arg2, 0))
7134 return fold_convert (TREE_TYPE (exp), integer_zero_node);
7136 p1 = c_getstr (arg1);
7137 p2 = c_getstr (arg2);
7139 if (p1 && p2)
7141 tree temp;
7142 const int i = strcmp (p1, p2);
7143 if (i < 0)
7144 temp = integer_minus_one_node;
7145 else if (i > 0)
7146 temp = integer_one_node;
7147 else
7148 temp = integer_zero_node;
7149 return fold_convert (TREE_TYPE (exp), temp);
7152 return 0;
7155 /* Fold function call to builtin strncmp. Return
7156 NULL_TREE if no simplification can be made. */
7158 static tree
7159 fold_builtin_strncmp (tree exp)
7161 tree arglist = TREE_OPERAND (exp, 1);
7162 tree arg1, arg2, len;
7163 const char *p1, *p2;
7165 if (!validate_arglist (arglist,
7166 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7167 return 0;
7169 arg1 = TREE_VALUE (arglist);
7170 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7171 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7173 /* If the LEN parameter is zero, return zero. */
7174 if (integer_zerop (len))
7176 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7177 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7180 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7181 if (operand_equal_p (arg1, arg2, 0))
7182 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7184 p1 = c_getstr (arg1);
7185 p2 = c_getstr (arg2);
7187 if (host_integerp (len, 1) && p1 && p2)
7189 tree temp;
7190 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7191 if (i < 0)
7192 temp = integer_minus_one_node;
7193 else if (i > 0)
7194 temp = integer_one_node;
7195 else
7196 temp = integer_zero_node;
7197 return fold_convert (TREE_TYPE (exp), temp);
7200 return 0;
7203 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7204 NULL_TREE if no simplification can be made. */
7206 static tree
7207 fold_builtin_signbit (tree exp)
7209 tree arglist = TREE_OPERAND (exp, 1);
7210 tree arg, temp;
7212 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7213 return NULL_TREE;
7215 arg = TREE_VALUE (arglist);
7217 /* If ARG is a compile-time constant, determine the result. */
7218 if (TREE_CODE (arg) == REAL_CST
7219 && !TREE_CONSTANT_OVERFLOW (arg))
7221 REAL_VALUE_TYPE c;
7223 c = TREE_REAL_CST (arg);
7224 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7225 return fold_convert (TREE_TYPE (exp), temp);
7228 /* If ARG is non-negative, the result is always zero. */
7229 if (tree_expr_nonnegative_p (arg))
7230 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7232 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7233 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7234 return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
7235 build_real (TREE_TYPE (arg), dconst0)));
7237 return NULL_TREE;
7240 /* Fold a call to builtin isascii. */
7242 static tree
7243 fold_builtin_isascii (tree arglist)
7245 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7246 return 0;
7247 else
7249 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7250 tree arg = TREE_VALUE (arglist);
7252 arg = fold (build (EQ_EXPR, integer_type_node,
7253 build (BIT_AND_EXPR, integer_type_node, arg,
7254 build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7255 ~ (HOST_WIDE_INT) 0)),
7256 integer_zero_node));
7258 if (in_gimple_form && !TREE_CONSTANT (arg))
7259 return NULL_TREE;
7260 else
7261 return arg;
7265 /* Fold a call to builtin toascii. */
7267 static tree
7268 fold_builtin_toascii (tree arglist)
7270 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7271 return 0;
7272 else
7274 /* Transform toascii(c) -> (c & 0x7f). */
7275 tree arg = TREE_VALUE (arglist);
7277 return fold (build (BIT_AND_EXPR, integer_type_node, arg,
7278 build_int_2 (0x7f, 0)));
7282 /* Fold a call to builtin isdigit. */
7284 static tree
7285 fold_builtin_isdigit (tree arglist)
7287 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7288 return 0;
7289 else
7291 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7292 /* According to the C standard, isdigit is unaffected by locale. */
7293 tree arg = TREE_VALUE (arglist);
7294 arg = fold_convert (unsigned_type_node, arg);
7295 arg = build (MINUS_EXPR, unsigned_type_node, arg,
7296 fold_convert (unsigned_type_node,
7297 build_int_2 (TARGET_DIGIT0, 0)));
7298 arg = build (LE_EXPR, integer_type_node, arg,
7299 fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7300 arg = fold (arg);
7301 if (in_gimple_form && !TREE_CONSTANT (arg))
7302 return NULL_TREE;
7303 else
7304 return arg;
7308 /* Used by constant folding to eliminate some builtin calls early. EXP is
7309 the CALL_EXPR of a call to a builtin function. */
7311 static tree
7312 fold_builtin_1 (tree exp)
7314 tree fndecl = get_callee_fndecl (exp);
7315 tree arglist = TREE_OPERAND (exp, 1);
7316 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7318 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7319 return 0;
7321 switch (DECL_FUNCTION_CODE (fndecl))
7323 case BUILT_IN_CONSTANT_P:
7324 return fold_builtin_constant_p (arglist);
7326 case BUILT_IN_EXPECT:
7327 return fold_builtin_expect (arglist);
7329 case BUILT_IN_CLASSIFY_TYPE:
7330 return fold_builtin_classify_type (arglist);
7332 case BUILT_IN_STRLEN:
7333 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7335 tree len = c_strlen (TREE_VALUE (arglist), 0);
7336 if (len)
7338 /* Convert from the internal "sizetype" type to "size_t". */
7339 if (size_type_node)
7340 len = fold_convert (size_type_node, len);
7341 return len;
7344 break;
7346 case BUILT_IN_FABS:
7347 case BUILT_IN_FABSF:
7348 case BUILT_IN_FABSL:
7349 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7350 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
7351 break;
7353 case BUILT_IN_CABS:
7354 case BUILT_IN_CABSF:
7355 case BUILT_IN_CABSL:
7356 return fold_builtin_cabs (arglist, type);
7358 case BUILT_IN_SQRT:
7359 case BUILT_IN_SQRTF:
7360 case BUILT_IN_SQRTL:
7361 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7363 enum built_in_function fcode;
7364 tree arg = TREE_VALUE (arglist);
7366 /* Optimize sqrt of constant value. */
7367 if (TREE_CODE (arg) == REAL_CST
7368 && ! TREE_CONSTANT_OVERFLOW (arg))
7370 REAL_VALUE_TYPE r, x;
7372 x = TREE_REAL_CST (arg);
7373 if (real_sqrt (&r, TYPE_MODE (type), &x)
7374 || (!flag_trapping_math && !flag_errno_math))
7375 return build_real (type, r);
7378 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7379 fcode = builtin_mathfn_code (arg);
7380 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7382 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7383 arg = fold (build (MULT_EXPR, type,
7384 TREE_VALUE (TREE_OPERAND (arg, 1)),
7385 build_real (type, dconsthalf)));
7386 arglist = build_tree_list (NULL_TREE, arg);
7387 return build_function_call_expr (expfn, arglist);
7390 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7391 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7393 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7395 if (powfn)
7397 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7398 tree tree_root;
7399 /* The inner root was either sqrt or cbrt. */
7400 REAL_VALUE_TYPE dconstroot =
7401 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7403 /* Adjust for the outer root. */
7404 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7405 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7406 tree_root = build_real (type, dconstroot);
7407 arglist = tree_cons (NULL_TREE, arg0,
7408 build_tree_list (NULL_TREE, tree_root));
7409 return build_function_call_expr (powfn, arglist);
7413 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
7414 if (flag_unsafe_math_optimizations
7415 && (fcode == BUILT_IN_POW
7416 || fcode == BUILT_IN_POWF
7417 || fcode == BUILT_IN_POWL))
7419 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7420 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7421 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7422 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7423 build_real (type, dconsthalf)));
7424 arglist = tree_cons (NULL_TREE, arg0,
7425 build_tree_list (NULL_TREE, narg1));
7426 return build_function_call_expr (powfn, arglist);
7429 break;
7431 case BUILT_IN_CBRT:
7432 case BUILT_IN_CBRTF:
7433 case BUILT_IN_CBRTL:
7434 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7436 tree arg = TREE_VALUE (arglist);
7437 const enum built_in_function fcode = builtin_mathfn_code (arg);
7439 /* Optimize cbrt of constant value. */
7440 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7441 return arg;
7443 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7444 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7446 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7447 const REAL_VALUE_TYPE third_trunc =
7448 real_value_truncate (TYPE_MODE (type), dconstthird);
7449 arg = fold (build (MULT_EXPR, type,
7450 TREE_VALUE (TREE_OPERAND (arg, 1)),
7451 build_real (type, third_trunc)));
7452 arglist = build_tree_list (NULL_TREE, arg);
7453 return build_function_call_expr (expfn, arglist);
7456 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7457 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
7458 x is negative pow will error but cbrt won't. */
7459 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7461 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7463 if (powfn)
7465 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7466 tree tree_root;
7467 REAL_VALUE_TYPE dconstroot = dconstthird;
7469 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7470 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7471 tree_root = build_real (type, dconstroot);
7472 arglist = tree_cons (NULL_TREE, arg0,
7473 build_tree_list (NULL_TREE, tree_root));
7474 return build_function_call_expr (powfn, arglist);
7479 break;
7481 case BUILT_IN_SIN:
7482 case BUILT_IN_SINF:
7483 case BUILT_IN_SINL:
7484 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7486 tree arg = TREE_VALUE (arglist);
7488 /* Optimize sin(0.0) = 0.0. */
7489 if (real_zerop (arg))
7490 return arg;
7492 break;
7494 case BUILT_IN_COS:
7495 case BUILT_IN_COSF:
7496 case BUILT_IN_COSL:
7497 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7499 tree arg = TREE_VALUE (arglist);
7501 /* Optimize cos(0.0) = 1.0. */
7502 if (real_zerop (arg))
7503 return build_real (type, dconst1);
7505 /* Optimize cos(-x) into cos(x). */
7506 if (TREE_CODE (arg) == NEGATE_EXPR)
7508 tree arglist = build_tree_list (NULL_TREE,
7509 TREE_OPERAND (arg, 0));
7510 return build_function_call_expr (fndecl, arglist);
7513 break;
7515 case BUILT_IN_EXP:
7516 case BUILT_IN_EXPF:
7517 case BUILT_IN_EXPL:
7518 return fold_builtin_exponent (exp, &dconste);
7519 case BUILT_IN_EXP2:
7520 case BUILT_IN_EXP2F:
7521 case BUILT_IN_EXP2L:
7522 return fold_builtin_exponent (exp, &dconst2);
7523 case BUILT_IN_EXP10:
7524 case BUILT_IN_EXP10F:
7525 case BUILT_IN_EXP10L:
7526 case BUILT_IN_POW10:
7527 case BUILT_IN_POW10F:
7528 case BUILT_IN_POW10L:
7529 return fold_builtin_exponent (exp, &dconst10);
7530 case BUILT_IN_LOG:
7531 case BUILT_IN_LOGF:
7532 case BUILT_IN_LOGL:
7533 return fold_builtin_logarithm (exp, &dconste);
7534 break;
7535 case BUILT_IN_LOG2:
7536 case BUILT_IN_LOG2F:
7537 case BUILT_IN_LOG2L:
7538 return fold_builtin_logarithm (exp, &dconst2);
7539 break;
7540 case BUILT_IN_LOG10:
7541 case BUILT_IN_LOG10F:
7542 case BUILT_IN_LOG10L:
7543 return fold_builtin_logarithm (exp, &dconst10);
7544 break;
7546 case BUILT_IN_TAN:
7547 case BUILT_IN_TANF:
7548 case BUILT_IN_TANL:
7549 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7551 enum built_in_function fcode;
7552 tree arg = TREE_VALUE (arglist);
7554 /* Optimize tan(0.0) = 0.0. */
7555 if (real_zerop (arg))
7556 return arg;
7558 /* Optimize tan(atan(x)) = x. */
7559 fcode = builtin_mathfn_code (arg);
7560 if (flag_unsafe_math_optimizations
7561 && (fcode == BUILT_IN_ATAN
7562 || fcode == BUILT_IN_ATANF
7563 || fcode == BUILT_IN_ATANL))
7564 return TREE_VALUE (TREE_OPERAND (arg, 1));
7566 break;
7568 case BUILT_IN_ATAN:
7569 case BUILT_IN_ATANF:
7570 case BUILT_IN_ATANL:
7571 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7573 tree arg = TREE_VALUE (arglist);
7575 /* Optimize atan(0.0) = 0.0. */
7576 if (real_zerop (arg))
7577 return arg;
7579 /* Optimize atan(1.0) = pi/4. */
7580 if (real_onep (arg))
7582 REAL_VALUE_TYPE cst;
7584 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7585 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7586 return build_real (type, cst);
7589 break;
7591 case BUILT_IN_POW:
7592 case BUILT_IN_POWF:
7593 case BUILT_IN_POWL:
7594 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7596 enum built_in_function fcode;
7597 tree arg0 = TREE_VALUE (arglist);
7598 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7600 /* Optimize pow(1.0,y) = 1.0. */
7601 if (real_onep (arg0))
7602 return omit_one_operand (type, build_real (type, dconst1), arg1);
7604 if (TREE_CODE (arg1) == REAL_CST
7605 && ! TREE_CONSTANT_OVERFLOW (arg1))
7607 REAL_VALUE_TYPE c;
7608 c = TREE_REAL_CST (arg1);
7610 /* Optimize pow(x,0.0) = 1.0. */
7611 if (REAL_VALUES_EQUAL (c, dconst0))
7612 return omit_one_operand (type, build_real (type, dconst1),
7613 arg0);
7615 /* Optimize pow(x,1.0) = x. */
7616 if (REAL_VALUES_EQUAL (c, dconst1))
7617 return arg0;
7619 /* Optimize pow(x,-1.0) = 1.0/x. */
7620 if (REAL_VALUES_EQUAL (c, dconstm1))
7621 return fold (build (RDIV_EXPR, type,
7622 build_real (type, dconst1),
7623 arg0));
7625 /* Optimize pow(x,0.5) = sqrt(x). */
7626 if (flag_unsafe_math_optimizations
7627 && REAL_VALUES_EQUAL (c, dconsthalf))
7629 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7631 if (sqrtfn != NULL_TREE)
7633 tree arglist = build_tree_list (NULL_TREE, arg0);
7634 return build_function_call_expr (sqrtfn, arglist);
7638 /* Attempt to evaluate pow at compile-time. */
7639 if (TREE_CODE (arg0) == REAL_CST
7640 && ! TREE_CONSTANT_OVERFLOW (arg0))
7642 REAL_VALUE_TYPE cint;
7643 HOST_WIDE_INT n;
7645 n = real_to_integer (&c);
7646 real_from_integer (&cint, VOIDmode, n,
7647 n < 0 ? -1 : 0, 0);
7648 if (real_identical (&c, &cint))
7650 REAL_VALUE_TYPE x;
7651 bool inexact;
7653 x = TREE_REAL_CST (arg0);
7654 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7655 if (flag_unsafe_math_optimizations || !inexact)
7656 return build_real (type, x);
7661 /* Optimize pow(expN(x),y) = expN(x*y). */
7662 fcode = builtin_mathfn_code (arg0);
7663 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7665 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7666 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7667 arg = fold (build (MULT_EXPR, type, arg, arg1));
7668 arglist = build_tree_list (NULL_TREE, arg);
7669 return build_function_call_expr (expfn, arglist);
7672 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7673 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7675 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7676 tree narg1 = fold (build (MULT_EXPR, type, arg1,
7677 build_real (type, dconsthalf)));
7679 arglist = tree_cons (NULL_TREE, narg0,
7680 build_tree_list (NULL_TREE, narg1));
7681 return build_function_call_expr (fndecl, arglist);
7684 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7685 if (flag_unsafe_math_optimizations
7686 && (fcode == BUILT_IN_POW
7687 || fcode == BUILT_IN_POWF
7688 || fcode == BUILT_IN_POWL))
7690 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7691 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7692 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7693 arglist = tree_cons (NULL_TREE, arg00,
7694 build_tree_list (NULL_TREE, narg1));
7695 return build_function_call_expr (fndecl, arglist);
7698 break;
7700 case BUILT_IN_INF:
7701 case BUILT_IN_INFF:
7702 case BUILT_IN_INFL:
7703 return fold_builtin_inf (type, true);
7705 case BUILT_IN_HUGE_VAL:
7706 case BUILT_IN_HUGE_VALF:
7707 case BUILT_IN_HUGE_VALL:
7708 return fold_builtin_inf (type, false);
7710 case BUILT_IN_NAN:
7711 case BUILT_IN_NANF:
7712 case BUILT_IN_NANL:
7713 return fold_builtin_nan (arglist, type, true);
7715 case BUILT_IN_NANS:
7716 case BUILT_IN_NANSF:
7717 case BUILT_IN_NANSL:
7718 return fold_builtin_nan (arglist, type, false);
7720 case BUILT_IN_FLOOR:
7721 case BUILT_IN_FLOORF:
7722 case BUILT_IN_FLOORL:
7723 return fold_builtin_floor (exp);
7725 case BUILT_IN_CEIL:
7726 case BUILT_IN_CEILF:
7727 case BUILT_IN_CEILL:
7728 return fold_builtin_ceil (exp);
7730 case BUILT_IN_TRUNC:
7731 case BUILT_IN_TRUNCF:
7732 case BUILT_IN_TRUNCL:
7733 return fold_builtin_trunc (exp);
7735 case BUILT_IN_ROUND:
7736 case BUILT_IN_ROUNDF:
7737 case BUILT_IN_ROUNDL:
7738 return fold_builtin_round (exp);
7740 case BUILT_IN_NEARBYINT:
7741 case BUILT_IN_NEARBYINTF:
7742 case BUILT_IN_NEARBYINTL:
7743 case BUILT_IN_RINT:
7744 case BUILT_IN_RINTF:
7745 case BUILT_IN_RINTL:
7746 return fold_trunc_transparent_mathfn (exp);
7748 case BUILT_IN_LROUND:
7749 case BUILT_IN_LROUNDF:
7750 case BUILT_IN_LROUNDL:
7751 case BUILT_IN_LLROUND:
7752 case BUILT_IN_LLROUNDF:
7753 case BUILT_IN_LLROUNDL:
7754 return fold_builtin_lround (exp);
7756 case BUILT_IN_LRINT:
7757 case BUILT_IN_LRINTF:
7758 case BUILT_IN_LRINTL:
7759 case BUILT_IN_LLRINT:
7760 case BUILT_IN_LLRINTF:
7761 case BUILT_IN_LLRINTL:
7762 return fold_fixed_mathfn (exp);
7764 case BUILT_IN_FFS:
7765 case BUILT_IN_FFSL:
7766 case BUILT_IN_FFSLL:
7767 case BUILT_IN_CLZ:
7768 case BUILT_IN_CLZL:
7769 case BUILT_IN_CLZLL:
7770 case BUILT_IN_CTZ:
7771 case BUILT_IN_CTZL:
7772 case BUILT_IN_CTZLL:
7773 case BUILT_IN_POPCOUNT:
7774 case BUILT_IN_POPCOUNTL:
7775 case BUILT_IN_POPCOUNTLL:
7776 case BUILT_IN_PARITY:
7777 case BUILT_IN_PARITYL:
7778 case BUILT_IN_PARITYLL:
7779 return fold_builtin_bitop (exp);
7781 case BUILT_IN_MEMCPY:
7782 return fold_builtin_memcpy (exp);
7784 case BUILT_IN_MEMPCPY:
7785 return fold_builtin_mempcpy (exp);
7787 case BUILT_IN_MEMMOVE:
7788 return fold_builtin_memmove (exp);
7790 case BUILT_IN_STRCPY:
7791 return fold_builtin_strcpy (exp);
7793 case BUILT_IN_STRNCPY:
7794 return fold_builtin_strncpy (exp);
7796 case BUILT_IN_MEMCMP:
7797 return fold_builtin_memcmp (exp);
7799 case BUILT_IN_STRCMP:
7800 return fold_builtin_strcmp (exp);
7802 case BUILT_IN_STRNCMP:
7803 return fold_builtin_strncmp (exp);
7805 case BUILT_IN_SIGNBIT:
7806 case BUILT_IN_SIGNBITF:
7807 case BUILT_IN_SIGNBITL:
7808 return fold_builtin_signbit (exp);
7810 case BUILT_IN_ISASCII:
7811 return fold_builtin_isascii (arglist);
7813 case BUILT_IN_TOASCII:
7814 return fold_builtin_toascii (arglist);
7816 case BUILT_IN_ISDIGIT:
7817 return fold_builtin_isdigit (arglist);
7819 default:
7820 break;
7823 return 0;
7826 /* A wrapper function for builtin folding that prevents warnings for
7827 "statement without effect" and the like, caused by removing the
7828 call node earlier than the warning is generated. */
7830 tree
7831 fold_builtin (tree exp)
7833 exp = fold_builtin_1 (exp);
7834 if (exp)
7836 /* ??? Don't clobber shared nodes such as integer_zero_node. */
7837 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
7838 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
7839 TREE_NO_WARNING (exp) = 1;
7841 return exp;
7844 /* Conveniently construct a function call expression. */
7846 tree
7847 build_function_call_expr (tree fn, tree arglist)
7849 tree call_expr;
7851 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7852 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7853 call_expr, arglist, NULL_TREE);
7854 return fold (call_expr);
7857 /* This function validates the types of a function call argument list
7858 represented as a tree chain of parameters against a specified list
7859 of tree_codes. If the last specifier is a 0, that represents an
7860 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7862 static int
7863 validate_arglist (tree arglist, ...)
7865 enum tree_code code;
7866 int res = 0;
7867 va_list ap;
7869 va_start (ap, arglist);
7873 code = va_arg (ap, enum tree_code);
7874 switch (code)
7876 case 0:
7877 /* This signifies an ellipses, any further arguments are all ok. */
7878 res = 1;
7879 goto end;
7880 case VOID_TYPE:
7881 /* This signifies an endlink, if no arguments remain, return
7882 true, otherwise return false. */
7883 res = arglist == 0;
7884 goto end;
7885 default:
7886 /* If no parameters remain or the parameter's code does not
7887 match the specified code, return false. Otherwise continue
7888 checking any remaining arguments. */
7889 if (arglist == 0
7890 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7891 goto end;
7892 break;
7894 arglist = TREE_CHAIN (arglist);
7896 while (1);
7898 /* We need gotos here since we can only have one VA_CLOSE in a
7899 function. */
7900 end: ;
7901 va_end (ap);
7903 return res;
7906 /* Default target-specific builtin expander that does nothing. */
7909 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7910 rtx target ATTRIBUTE_UNUSED,
7911 rtx subtarget ATTRIBUTE_UNUSED,
7912 enum machine_mode mode ATTRIBUTE_UNUSED,
7913 int ignore ATTRIBUTE_UNUSED)
7915 return NULL_RTX;
7918 /* Returns true is EXP represents data that would potentially reside
7919 in a readonly section. */
7921 static bool
7922 readonly_data_expr (tree exp)
7924 STRIP_NOPS (exp);
7926 if (TREE_CODE (exp) == ADDR_EXPR)
7927 return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7928 else
7929 return false;
7932 /* Front-end to the simplify_builtin_XXX routines.
7934 EXP is a call to a builtin function. If possible try to simplify
7935 that into a constant, expression or call to a more efficient
7936 builtin function.
7938 If IGNORE is nonzero, then the result of this builtin function
7939 call is ignored.
7941 If simplification is possible, return the simplified tree, otherwise
7942 return NULL_TREE. */
7944 tree
7945 simplify_builtin (tree exp, int ignore)
7947 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7948 tree arglist = TREE_OPERAND (exp, 1);
7949 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7950 tree val;
7952 switch (fcode)
7954 case BUILT_IN_FPUTS:
7955 val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
7956 break;
7957 case BUILT_IN_FPUTS_UNLOCKED:
7958 val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
7959 break;
7960 case BUILT_IN_STRSTR:
7961 val = simplify_builtin_strstr (arglist);
7962 break;
7963 case BUILT_IN_STRCAT:
7964 val = simplify_builtin_strcat (arglist);
7965 break;
7966 case BUILT_IN_STRNCAT:
7967 val = simplify_builtin_strncat (arglist);
7968 break;
7969 case BUILT_IN_STRSPN:
7970 val = simplify_builtin_strspn (arglist);
7971 break;
7972 case BUILT_IN_STRCSPN:
7973 val = simplify_builtin_strcspn (arglist);
7974 break;
7975 case BUILT_IN_STRCHR:
7976 case BUILT_IN_INDEX:
7977 val = simplify_builtin_strchr (arglist);
7978 break;
7979 case BUILT_IN_STRRCHR:
7980 case BUILT_IN_RINDEX:
7981 val = simplify_builtin_strrchr (arglist);
7982 break;
7983 case BUILT_IN_STRCPY:
7984 val = simplify_builtin_strcpy (arglist, NULL_TREE);
7985 break;
7986 case BUILT_IN_STRNCPY:
7987 val = simplify_builtin_strncpy (arglist, NULL_TREE);
7988 break;
7989 case BUILT_IN_STRCMP:
7990 val = simplify_builtin_strcmp (arglist);
7991 break;
7992 case BUILT_IN_STRNCMP:
7993 val = simplify_builtin_strncmp (arglist);
7994 break;
7995 case BUILT_IN_STRPBRK:
7996 val = simplify_builtin_strpbrk (arglist);
7997 break;
7998 case BUILT_IN_BCMP:
7999 case BUILT_IN_MEMCMP:
8000 val = simplify_builtin_memcmp (arglist);
8001 break;
8002 case BUILT_IN_VA_START:
8003 simplify_builtin_va_start (arglist);
8004 val = NULL_TREE;
8005 break;
8006 case BUILT_IN_SPRINTF:
8007 val = simplify_builtin_sprintf (arglist, ignore);
8008 break;
8009 case BUILT_IN_CONSTANT_P:
8010 val = fold_builtin_constant_p (arglist);
8011 /* Gimplification will pull the CALL_EXPR for the builtin out of
8012 an if condition. When not optimizing, we'll not CSE it back.
8013 To avoid link error types of regressions, return false now. */
8014 if (!val && !optimize)
8015 val = integer_zero_node;
8016 break;
8017 default:
8018 val = NULL_TREE;
8019 break;
8022 if (val)
8023 val = convert (TREE_TYPE (exp), val);
8024 return val;
8027 /* Simplify a call to the strstr builtin.
8029 Return 0 if no simplification was possible, otherwise return the
8030 simplified form of the call as a tree.
8032 The simplified form may be a constant or other expression which
8033 computes the same value, but in a more efficient manner (including
8034 calls to other builtin functions).
8036 The call may contain arguments which need to be evaluated, but
8037 which are not useful to determine the result of the call. In
8038 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8039 COMPOUND_EXPR will be an argument which must be evaluated.
8040 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8041 COMPOUND_EXPR in the chain will contain the tree for the simplified
8042 form of the builtin function call. */
8044 static tree
8045 simplify_builtin_strstr (tree arglist)
8047 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8048 return 0;
8049 else
8051 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8052 tree fn;
8053 const char *p1, *p2;
8055 p2 = c_getstr (s2);
8056 if (p2 == NULL)
8057 return 0;
8059 p1 = c_getstr (s1);
8060 if (p1 != NULL)
8062 const char *r = strstr (p1, p2);
8064 /* Return an offset into the constant string argument. */
8065 if (r == NULL)
8066 return integer_zero_node;
8067 else
8068 return fold (build (PLUS_EXPR, TREE_TYPE (s1),
8069 s1, convert (TREE_TYPE (s1),
8070 ssize_int (r - p1))));
8073 if (p2[0] == '\0')
8074 return s1;
8076 if (p2[1] != '\0')
8077 return 0;
8079 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8080 if (!fn)
8081 return 0;
8083 /* New argument list transforming strstr(s1, s2) to
8084 strchr(s1, s2[0]). */
8085 arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8086 arglist = tree_cons (NULL_TREE, s1, arglist);
8087 return build_function_call_expr (fn, arglist);
8091 /* Simplify a call to the strstr builtin.
8093 Return 0 if no simplification was possible, otherwise return the
8094 simplified form of the call as a tree.
8096 The simplified form may be a constant or other expression which
8097 computes the same value, but in a more efficient manner (including
8098 calls to other builtin functions).
8100 The call may contain arguments which need to be evaluated, but
8101 which are not useful to determine the result of the call. In
8102 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8103 COMPOUND_EXPR will be an argument which must be evaluated.
8104 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8105 COMPOUND_EXPR in the chain will contain the tree for the simplified
8106 form of the builtin function call. */
8108 static tree
8109 simplify_builtin_strchr (tree arglist)
8111 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8112 return 0;
8113 else
8115 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8116 const char *p1;
8118 if (TREE_CODE (s2) != INTEGER_CST)
8119 return 0;
8121 p1 = c_getstr (s1);
8122 if (p1 != NULL)
8124 char c;
8125 const char *r;
8127 if (target_char_cast (s2, &c))
8128 return 0;
8130 r = strchr (p1, c);
8132 if (r == NULL)
8133 return integer_zero_node;
8135 /* Return an offset into the constant string argument. */
8136 return fold (build (PLUS_EXPR, TREE_TYPE (s1),
8137 s1, convert (TREE_TYPE (s1),
8138 ssize_int (r - p1))));
8141 /* FIXME: Should use here strchrM optab so that ports can optimize
8142 this. */
8143 return 0;
8147 /* Simplify a call to the strrchr builtin.
8149 Return 0 if no simplification was possible, otherwise return the
8150 simplified form of the call as a tree.
8152 The simplified form may be a constant or other expression which
8153 computes the same value, but in a more efficient manner (including
8154 calls to other builtin functions).
8156 The call may contain arguments which need to be evaluated, but
8157 which are not useful to determine the result of the call. In
8158 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8159 COMPOUND_EXPR will be an argument which must be evaluated.
8160 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8161 COMPOUND_EXPR in the chain will contain the tree for the simplified
8162 form of the builtin function call. */
8164 static tree
8165 simplify_builtin_strrchr (tree arglist)
8167 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8168 return 0;
8169 else
8171 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8172 tree fn;
8173 const char *p1;
8175 if (TREE_CODE (s2) != INTEGER_CST)
8176 return 0;
8178 p1 = c_getstr (s1);
8179 if (p1 != NULL)
8181 char c;
8182 const char *r;
8184 if (target_char_cast (s2, &c))
8185 return 0;
8187 r = strrchr (p1, c);
8189 if (r == NULL)
8190 return integer_zero_node;
8192 /* Return an offset into the constant string argument. */
8193 return fold (build (PLUS_EXPR, TREE_TYPE (s1),
8194 s1, convert (TREE_TYPE (s1),
8195 ssize_int (r - p1))));
8198 if (! integer_zerop (s2))
8199 return 0;
8201 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8202 if (!fn)
8203 return 0;
8205 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8206 return build_function_call_expr (fn, arglist);
8210 /* Simplify a call to the strpbrk builtin.
8212 Return 0 if no simplification was possible, otherwise return the
8213 simplified form of the call as a tree.
8215 The simplified form may be a constant or other expression which
8216 computes the same value, but in a more efficient manner (including
8217 calls to other builtin functions).
8219 The call may contain arguments which need to be evaluated, but
8220 which are not useful to determine the result of the call. In
8221 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8222 COMPOUND_EXPR will be an argument which must be evaluated.
8223 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8224 COMPOUND_EXPR in the chain will contain the tree for the simplified
8225 form of the builtin function call. */
8227 static tree
8228 simplify_builtin_strpbrk (tree arglist)
8230 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8231 return 0;
8232 else
8234 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8235 tree fn;
8236 const char *p1, *p2;
8238 p2 = c_getstr (s2);
8239 if (p2 == NULL)
8240 return 0;
8242 p1 = c_getstr (s1);
8243 if (p1 != NULL)
8245 const char *r = strpbrk (p1, p2);
8247 if (r == NULL)
8248 return integer_zero_node;
8250 /* Return an offset into the constant string argument. */
8251 return fold (build (PLUS_EXPR, TREE_TYPE (s1),
8252 s1, convert (TREE_TYPE (s1),
8253 ssize_int (r - p1))));
8256 if (p2[0] == '\0')
8258 /* strpbrk(x, "") == NULL.
8259 Evaluate and ignore the arguments in case they had
8260 side-effects. */
8261 return build (COMPOUND_EXPR, integer_type_node, s1,
8262 integer_zero_node);
8265 if (p2[1] != '\0')
8266 return 0; /* Really call strpbrk. */
8268 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8269 if (!fn)
8270 return 0;
8272 /* New argument list transforming strpbrk(s1, s2) to
8273 strchr(s1, s2[0]). */
8274 arglist =
8275 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8276 arglist = tree_cons (NULL_TREE, s1, arglist);
8277 return build_function_call_expr (fn, arglist);
8281 /* Simplify a call to the strcpy builtin.
8283 Return 0 if no simplification was possible, otherwise return the
8284 simplified form of the call as a tree.
8286 The simplified form may be a constant or other expression which
8287 computes the same value, but in a more efficient manner (including
8288 calls to other builtin functions).
8290 The call may contain arguments which need to be evaluated, but
8291 which are not useful to determine the result of the call. In
8292 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8293 COMPOUND_EXPR will be an argument which must be evaluated.
8294 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8295 COMPOUND_EXPR in the chain will contain the tree for the simplified
8296 form of the builtin function call. */
8298 tree
8299 simplify_builtin_strcpy (tree arglist, tree len)
8301 tree fn;
8303 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8304 return 0;
8306 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8307 if (!fn)
8308 return 0;
8310 if (!len)
8312 len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
8313 if (!len)
8314 return 0;
8315 if (TREE_SIDE_EFFECTS (len))
8316 return 0;
8319 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8320 chainon (arglist, build_tree_list (NULL_TREE, len));
8321 return build_function_call_expr (fn, arglist);
8324 /* Simplify a call to the strncpy builtin.
8326 Return 0 if no simplification was possible, otherwise return the
8327 simplified form of the call as a tree.
8329 The simplified form may be a constant or other expression which
8330 computes the same value, but in a more efficient manner (including
8331 calls to other builtin functions).
8333 The call may contain arguments which need to be evaluated, but
8334 which are not useful to determine the result of the call. In
8335 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8336 COMPOUND_EXPR will be an argument which must be evaluated.
8337 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8338 COMPOUND_EXPR in the chain will contain the tree for the simplified
8339 form of the builtin function call. */
8341 tree
8342 simplify_builtin_strncpy (tree arglist, tree slen)
8344 if (!validate_arglist (arglist,
8345 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8346 return 0;
8347 else
8349 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8350 tree fn;
8352 /* We must be passed a constant len parameter. */
8353 if (TREE_CODE (len) != INTEGER_CST)
8354 return 0;
8356 /* If the len parameter is zero, return the dst parameter. */
8357 if (integer_zerop (len))
8359 /* Evaluate and ignore the src argument in case it has
8360 side-effects and return the dst parameter. */
8361 return build (COMPOUND_EXPR, TREE_TYPE (TREE_VALUE (arglist)),
8362 TREE_VALUE (TREE_CHAIN (arglist)),
8363 TREE_VALUE (arglist));
8366 if (!slen)
8367 slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 0);
8369 /* Now, we must be passed a constant src ptr parameter. */
8370 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8371 return 0;
8373 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8375 /* We do not support simplification of this case, though we do
8376 support it when expanding trees into RTL. */
8377 /* FIXME: generate a call to __builtin_memset. */
8378 if (tree_int_cst_lt (slen, len))
8379 return 0;
8381 /* OK transform into builtin memcpy. */
8382 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8383 if (!fn)
8384 return 0;
8385 return build_function_call_expr (fn, arglist);
8389 /* Simplify a call to the memcmp builtin.
8391 Return 0 if no simplification was possible, otherwise return the
8392 simplified form of the call as a tree.
8394 The simplified form may be a constant or other expression which
8395 computes the same value, but in a more efficient manner (including
8396 calls to other builtin functions).
8398 The call may contain arguments which need to be evaluated, but
8399 which are not useful to determine the result of the call. In
8400 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8401 COMPOUND_EXPR will be an argument which must be evaluated.
8402 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8403 COMPOUND_EXPR in the chain will contain the tree for the simplified
8404 form of the builtin function call. */
8406 static tree
8407 simplify_builtin_memcmp (tree arglist)
8409 tree arg1, arg2, len;
8410 const char *p1, *p2;
8412 if (!validate_arglist (arglist,
8413 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8414 return 0;
8416 arg1 = TREE_VALUE (arglist);
8417 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8418 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8420 /* If the len parameter is zero, return zero. */
8421 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
8423 /* Evaluate and ignore arg1 and arg2 in case they have
8424 side-effects. */
8425 return build (COMPOUND_EXPR, integer_type_node, arg1,
8426 build (COMPOUND_EXPR, integer_type_node,
8427 arg2, integer_zero_node));
8430 p1 = c_getstr (arg1);
8431 p2 = c_getstr (arg2);
8433 /* If all arguments are constant, and the value of len is not greater
8434 than the lengths of arg1 and arg2, evaluate at compile-time. */
8435 if (host_integerp (len, 1) && p1 && p2
8436 && compare_tree_int (len, strlen (p1) + 1) <= 0
8437 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8439 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8441 return (r < 0
8442 ? integer_minus_one_node
8443 : (r > 0 ? integer_one_node : integer_zero_node));
8446 /* If len parameter is one, return an expression corresponding to
8447 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8448 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8450 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8451 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8452 tree ind1 =
8453 fold (build1 (CONVERT_EXPR, integer_type_node,
8454 build1 (INDIRECT_REF, cst_uchar_node,
8455 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
8456 tree ind2 =
8457 fold (build1 (CONVERT_EXPR, integer_type_node,
8458 build1 (INDIRECT_REF, cst_uchar_node,
8459 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
8460 return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
8463 return 0;
8466 /* Simplify a call to the strcmp builtin.
8468 Return 0 if no simplification was possible, otherwise return the
8469 simplified form of the call as a tree.
8471 The simplified form may be a constant or other expression which
8472 computes the same value, but in a more efficient manner (including
8473 calls to other builtin functions).
8475 The call may contain arguments which need to be evaluated, but
8476 which are not useful to determine the result of the call. In
8477 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8478 COMPOUND_EXPR will be an argument which must be evaluated.
8479 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8480 COMPOUND_EXPR in the chain will contain the tree for the simplified
8481 form of the builtin function call. */
8483 static tree
8484 simplify_builtin_strcmp (tree arglist)
8486 tree arg1, arg2;
8487 const char *p1, *p2;
8489 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8490 return 0;
8492 arg1 = TREE_VALUE (arglist);
8493 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8495 /* If both arguments are equal (and not volatile), return zero. */
8496 if (operand_equal_p (arg1, arg2, 0))
8497 return integer_zero_node;
8499 p1 = c_getstr (arg1);
8500 p2 = c_getstr (arg2);
8502 if (p1 && p2)
8504 const int i = strcmp (p1, p2);
8505 return (i < 0
8506 ? integer_minus_one_node
8507 : (i > 0 ? integer_one_node : integer_zero_node));
8510 /* If either arg is "", return an expression corresponding to
8511 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8512 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8514 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8515 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8516 tree ind1 =
8517 fold (build1 (CONVERT_EXPR, integer_type_node,
8518 build1 (INDIRECT_REF, cst_uchar_node,
8519 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
8520 tree ind2 =
8521 fold (build1 (CONVERT_EXPR, integer_type_node,
8522 build1 (INDIRECT_REF, cst_uchar_node,
8523 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
8524 return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
8527 return 0;
8530 /* Simplify a call to the strncmp builtin.
8532 Return 0 if no simplification was possible, otherwise return the
8533 simplified form of the call as a tree.
8535 The simplified form may be a constant or other expression which
8536 computes the same value, but in a more efficient manner (including
8537 calls to other builtin functions).
8539 The call may contain arguments which need to be evaluated, but
8540 which are not useful to determine the result of the call. In
8541 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8542 COMPOUND_EXPR will be an argument which must be evaluated.
8543 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8544 COMPOUND_EXPR in the chain will contain the tree for the simplified
8545 form of the builtin function call. */
8547 static tree
8548 simplify_builtin_strncmp (tree arglist)
8550 tree arg1, arg2, arg3;
8551 const char *p1, *p2;
8553 if (!validate_arglist (arglist,
8554 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8555 return 0;
8557 arg1 = TREE_VALUE (arglist);
8558 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8559 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8561 /* If the len parameter is zero, return zero. */
8562 if (integer_zerop (arg3))
8564 /* Evaluate and ignore arg1 and arg2 in case they have
8565 side-effects. */
8566 return build (COMPOUND_EXPR, integer_type_node, arg1,
8567 build (COMPOUND_EXPR, integer_type_node,
8568 arg2, integer_zero_node));
8571 /* If arg1 and arg2 are equal (and not volatile), return zero. */
8572 if (operand_equal_p (arg1, arg2, 0))
8574 /* Evaluate and ignore arg3 in case it has side-effects. */
8575 return build (COMPOUND_EXPR, integer_type_node, arg3, integer_zero_node);
8578 p1 = c_getstr (arg1);
8579 p2 = c_getstr (arg2);
8581 /* If all arguments are constant, evaluate at compile-time. */
8582 if (host_integerp (arg3, 1) && p1 && p2)
8584 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
8585 return (r < 0
8586 ? integer_minus_one_node
8587 : (r > 0 ? integer_one_node : integer_zero_node));
8590 /* If len == 1 or (either string parameter is "" and (len >= 1)),
8591 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
8592 if (host_integerp (arg3, 1)
8593 && (tree_low_cst (arg3, 1) == 1
8594 || (tree_low_cst (arg3, 1) > 1
8595 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
8597 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8598 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8599 tree ind1 =
8600 fold (build1 (CONVERT_EXPR, integer_type_node,
8601 build1 (INDIRECT_REF, cst_uchar_node,
8602 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
8603 tree ind2 =
8604 fold (build1 (CONVERT_EXPR, integer_type_node,
8605 build1 (INDIRECT_REF, cst_uchar_node,
8606 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
8607 return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
8610 return 0;
8613 /* Simplify a call to the strcat builtin.
8615 Return 0 if no simplification was possible, otherwise return the
8616 simplified form of the call as a tree.
8618 The simplified form may be a constant or other expression which
8619 computes the same value, but in a more efficient manner (including
8620 calls to other builtin functions).
8622 The call may contain arguments which need to be evaluated, but
8623 which are not useful to determine the result of the call. In
8624 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8625 COMPOUND_EXPR will be an argument which must be evaluated.
8626 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8627 COMPOUND_EXPR in the chain will contain the tree for the simplified
8628 form of the builtin function call. */
8630 static tree
8631 simplify_builtin_strcat (tree arglist)
8633 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8634 return 0;
8635 else
8637 tree dst = TREE_VALUE (arglist),
8638 src = TREE_VALUE (TREE_CHAIN (arglist));
8639 const char *p = c_getstr (src);
8641 /* If the string length is zero, return the dst parameter. */
8642 if (p && *p == '\0')
8643 return dst;
8645 return 0;
8649 /* Simplify a call to the strncat builtin.
8651 Return 0 if no simplification was possible, otherwise return the
8652 simplified form of the call as a tree.
8654 The simplified form may be a constant or other expression which
8655 computes the same value, but in a more efficient manner (including
8656 calls to other builtin functions).
8658 The call may contain arguments which need to be evaluated, but
8659 which are not useful to determine the result of the call. In
8660 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8661 COMPOUND_EXPR will be an argument which must be evaluated.
8662 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8663 COMPOUND_EXPR in the chain will contain the tree for the simplified
8664 form of the builtin function call. */
8666 static tree
8667 simplify_builtin_strncat (tree arglist)
8669 if (!validate_arglist (arglist,
8670 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8671 return 0;
8672 else
8674 tree dst = TREE_VALUE (arglist);
8675 tree src = TREE_VALUE (TREE_CHAIN (arglist));
8676 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8677 const char *p = c_getstr (src);
8679 /* If the requested length is zero, or the src parameter string
8680 length is zero, return the dst parameter. */
8681 if (integer_zerop (len) || (p && *p == '\0'))
8682 return build (COMPOUND_EXPR, TREE_TYPE (dst), src,
8683 build (COMPOUND_EXPR, integer_type_node, len, dst));
8685 /* If the requested len is greater than or equal to the string
8686 length, call strcat. */
8687 if (TREE_CODE (len) == INTEGER_CST && p
8688 && compare_tree_int (len, strlen (p)) >= 0)
8690 tree newarglist
8691 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8692 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8694 /* If the replacement _DECL isn't initialized, don't do the
8695 transformation. */
8696 if (!fn)
8697 return 0;
8699 return build_function_call_expr (fn, newarglist);
8701 return 0;
8705 /* Simplify a call to the strspn builtin.
8707 Return 0 if no simplification was possible, otherwise return the
8708 simplified form of the call as a tree.
8710 The simplified form may be a constant or other expression which
8711 computes the same value, but in a more efficient manner (including
8712 calls to other builtin functions).
8714 The call may contain arguments which need to be evaluated, but
8715 which are not useful to determine the result of the call. In
8716 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8717 COMPOUND_EXPR will be an argument which must be evaluated.
8718 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8719 COMPOUND_EXPR in the chain will contain the tree for the simplified
8720 form of the builtin function call. */
8722 static tree
8723 simplify_builtin_strspn (tree arglist)
8725 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8726 return 0;
8727 else
8729 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8730 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8732 /* If both arguments are constants, evaluate at compile-time. */
8733 if (p1 && p2)
8735 const size_t r = strspn (p1, p2);
8736 return size_int (r);
8739 /* If either argument is "", return 0. */
8740 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8742 /* Evaluate and ignore both arguments in case either one has
8743 side-effects. */
8744 return build (COMPOUND_EXPR, integer_type_node, s1,
8745 build (COMPOUND_EXPR, integer_type_node,
8746 s2, integer_zero_node));
8748 return 0;
8752 /* Simplify a call to the strcspn builtin.
8754 Return 0 if no simplification was possible, otherwise return the
8755 simplified form of the call as a tree.
8757 The simplified form may be a constant or other expression which
8758 computes the same value, but in a more efficient manner (including
8759 calls to other builtin functions).
8761 The call may contain arguments which need to be evaluated, but
8762 which are not useful to determine the result of the call. In
8763 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8764 COMPOUND_EXPR will be an argument which must be evaluated.
8765 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8766 COMPOUND_EXPR in the chain will contain the tree for the simplified
8767 form of the builtin function call. */
8769 static tree
8770 simplify_builtin_strcspn (tree arglist)
8772 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8773 return 0;
8774 else
8776 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8777 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8779 /* If both arguments are constants, evaluate at compile-time. */
8780 if (p1 && p2)
8782 const size_t r = strcspn (p1, p2);
8783 return size_int (r);
8786 /* If the first argument is "", return 0. */
8787 if (p1 && *p1 == '\0')
8789 /* Evaluate and ignore argument s2 in case it has
8790 side-effects. */
8791 return build (COMPOUND_EXPR, integer_type_node,
8792 s2, integer_zero_node);
8795 /* If the second argument is "", return __builtin_strlen(s1). */
8796 if (p2 && *p2 == '\0')
8798 tree newarglist = build_tree_list (NULL_TREE, s1),
8799 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8801 /* If the replacement _DECL isn't initialized, don't do the
8802 transformation. */
8803 if (!fn)
8804 return 0;
8806 return build_function_call_expr (fn, newarglist);
8808 return 0;
8812 /* Simplify a call to the fputs builtin.
8814 Return 0 if no simplification was possible, otherwise return the
8815 simplified form of the call as a tree.
8817 The simplified form may be a constant or other expression which
8818 computes the same value, but in a more efficient manner (including
8819 calls to other builtin functions).
8821 The call may contain arguments which need to be evaluated, but
8822 which are not useful to determine the result of the call. In
8823 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8824 COMPOUND_EXPR will be an argument which must be evaluated.
8825 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8826 COMPOUND_EXPR in the chain will contain the tree for the simplified
8827 form of the builtin function call.
8829 If KNOWN_LEN is non-NULL, it represents the known length of the string.
8830 This is determined by SSA-CCP in cases where the string itself is not
8831 known to be constant but its length is always the same constant. */
8833 tree
8834 simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
8836 tree len, fn;
8837 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8838 : implicit_built_in_decls[BUILT_IN_FPUTC];
8839 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8840 : implicit_built_in_decls[BUILT_IN_FWRITE];
8842 /* If the return value is used, or the replacement _DECL isn't
8843 initialized, don't do the transformation. */
8844 if (!ignore || !fn_fputc || !fn_fwrite)
8845 return 0;
8847 /* Verify the arguments in the original call. */
8848 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8849 return 0;
8851 len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 0);
8853 /* Get the length of the string passed to fputs. If the length
8854 can't be determined, punt. */
8855 if (!len
8856 || TREE_CODE (len) != INTEGER_CST)
8857 return 0;
8859 switch (compare_tree_int (len, 1))
8861 case -1: /* length is 0, delete the call entirely . */
8863 return build (COMPOUND_EXPR, integer_type_node,
8864 TREE_VALUE (TREE_CHAIN (arglist)), integer_zero_node);
8866 case 0: /* length is 1, call fputc. */
8868 const char *p = c_getstr (TREE_VALUE (arglist));
8870 if (p != NULL)
8872 /* New argument list transforming fputs(string, stream) to
8873 fputc(string[0], stream). */
8874 arglist =
8875 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
8876 arglist =
8877 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
8878 fn = fn_fputc;
8879 break;
8882 /* FALLTHROUGH */
8883 case 1: /* length is greater than 1, call fwrite. */
8885 tree string_arg;
8887 /* If optimizing for size keep fputs. */
8888 if (optimize_size)
8889 return 0;
8890 string_arg = TREE_VALUE (arglist);
8891 /* New argument list transforming fputs(string, stream) to
8892 fwrite(string, 1, len, stream). */
8893 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
8894 arglist = tree_cons (NULL_TREE, len, arglist);
8895 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8896 arglist = tree_cons (NULL_TREE, string_arg, arglist);
8897 fn = fn_fwrite;
8898 break;
8900 default:
8901 abort ();
8904 return build_function_call_expr (fn, arglist);
8907 static void
8908 simplify_builtin_va_start (tree arglist)
8910 tree chain = TREE_CHAIN (arglist);
8912 if (TREE_CHAIN (chain))
8913 error ("too many arguments to function `va_start'");
8915 simplify_builtin_next_arg (chain);
8918 static void
8919 simplify_builtin_next_arg (tree arglist)
8921 tree fntype = TREE_TYPE (current_function_decl);
8923 if (TYPE_ARG_TYPES (fntype) == 0
8924 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8925 == void_type_node))
8926 error ("`va_start' used in function with fixed args");
8927 else if (arglist)
8929 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8930 tree arg = TREE_VALUE (arglist);
8932 /* Strip off all nops for the sake of the comparison. This
8933 is not quite the same as STRIP_NOPS. It does more.
8934 We must also strip off INDIRECT_EXPR for C++ reference
8935 parameters. */
8936 while (TREE_CODE (arg) == NOP_EXPR
8937 || TREE_CODE (arg) == CONVERT_EXPR
8938 || TREE_CODE (arg) == NON_LVALUE_EXPR
8939 || TREE_CODE (arg) == INDIRECT_REF)
8940 arg = TREE_OPERAND (arg, 0);
8941 if (arg != last_parm)
8942 warning ("second parameter of `va_start' not last named argument");
8943 TREE_VALUE (arglist) = arg;
8945 else
8946 /* Evidently an out of date version of <stdarg.h>; can't validate
8947 va_start's second argument, but can still work as intended. */
8948 warning ("`__builtin_next_arg' called without an argument");
8952 /* Simplify a call to the sprintf builtin.
8954 Return 0 if no simplification was possible, otherwise return the
8955 simplified form of the call as a tree. If IGNORED is true, it means that
8956 the caller does not use the returned value of the function. */
8958 static tree
8959 simplify_builtin_sprintf (tree arglist, int ignored)
8961 tree call, retval, dest, fmt;
8962 const char *fmt_str = NULL;
8964 /* Verify the required arguments in the original call. We deal with two
8965 types of sprintf() calls: 'sprintf (str, fmt)' and
8966 'sprintf (dest, "%s", orig)'. */
8967 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8968 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8969 VOID_TYPE))
8970 return NULL_TREE;
8972 /* Get the destination string and the format specifier. */
8973 dest = TREE_VALUE (arglist);
8974 fmt = TREE_VALUE (TREE_CHAIN (arglist));
8976 /* Check whether the format is a literal string constant. */
8977 fmt_str = c_getstr (fmt);
8978 if (fmt_str == NULL)
8979 return NULL_TREE;
8981 call = NULL_TREE;
8982 retval = NULL_TREE;
8984 /* If the format doesn't contain % args or %%, use strcpy. */
8985 if (strchr (fmt_str, '%') == NULL)
8987 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8989 if (!fn)
8990 return NULL_TREE;
8992 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8993 'format' is known to contain no % formats. */
8994 arglist = build_tree_list (NULL_TREE, fmt);
8995 arglist = tree_cons (NULL_TREE, dest, arglist);
8996 call = build_function_call_expr (fn, arglist);
8997 if (!ignored)
8998 retval = build_int_2 (strlen (fmt_str), 0);
9001 /* If the format is "%s", use strcpy if the result isn't used. */
9002 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9004 tree fn, orig;
9005 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9007 if (!fn)
9008 return NULL_TREE;
9010 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9011 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9012 arglist = build_tree_list (NULL_TREE, orig);
9013 arglist = tree_cons (NULL_TREE, dest, arglist);
9014 if (!ignored)
9016 retval = c_strlen (orig, 1);
9017 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9018 return NULL_TREE;
9020 call = build_function_call_expr (fn, arglist);
9023 if (call && retval)
9025 retval = convert
9026 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9027 retval);
9028 return build (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9030 else
9031 return call;