* config.gcc: Add sh-*-symbianelf target.
[official-gcc.git] / gcc / builtins.c
blob5b2a63ff9428b571bff2e72c3932a32be423023a
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
50 #define CALLED_AS_BUILT_IN(NODE) \
51 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
53 #ifndef PAD_VARARGS_DOWN
54 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 #endif
57 /* Define the names of the builtin function types and codes. */
58 const char *const built_in_class_names[4]
59 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
61 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
62 const char *const built_in_names[(int) END_BUILTINS] =
64 #include "builtins.def"
66 #undef DEF_BUILTIN
68 /* Setup an array of _DECL trees, make sure each element is
69 initialized to NULL_TREE. */
70 tree built_in_decls[(int) END_BUILTINS];
71 /* Declarations used when constructing the builtin implicitly in the compiler.
72 It may be NULL_TREE when this is invalid (for instance runtime is not
73 required to implement the function call in all cases). */
74 tree implicit_built_in_decls[(int) END_BUILTINS];
76 static int get_pointer_alignment (tree, unsigned int);
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree);
81 static tree build_string_literal (int, const char *);
82 static int apply_args_size (void);
83 static int apply_result_size (void);
84 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
85 static rtx result_vector (int, rtx);
86 #endif
87 static rtx expand_builtin_setjmp (tree, rtx);
88 static void expand_builtin_update_setjmp_buf (rtx);
89 static void expand_builtin_prefetch (tree);
90 static rtx expand_builtin_apply_args (void);
91 static rtx expand_builtin_apply_args_1 (void);
92 static rtx expand_builtin_apply (rtx, rtx, rtx);
93 static void expand_builtin_return (rtx);
94 static enum type_class type_to_class (tree);
95 static rtx expand_builtin_classify_type (tree);
96 static void expand_errno_check (tree, rtx);
97 static rtx expand_builtin_mathfn (tree, rtx, rtx);
98 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (tree);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_bzero (tree);
125 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_alloca (tree, rtx);
131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
132 static rtx expand_builtin_frame_address (tree, tree);
133 static rtx expand_builtin_fputs (tree, rtx, bool);
134 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
137 static tree stabilize_va_list (tree, int);
138 static rtx expand_builtin_expect (tree, rtx);
139 static tree fold_builtin_constant_p (tree);
140 static tree fold_builtin_classify_type (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_cabs (tree, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_cabs (tree, tree);
151 static tree fold_builtin_trunc (tree);
152 static tree fold_builtin_floor (tree);
153 static tree fold_builtin_ceil (tree);
154 static tree fold_builtin_round (tree);
155 static tree fold_builtin_bitop (tree);
156 static tree fold_builtin_memcpy (tree);
157 static tree fold_builtin_mempcpy (tree);
158 static tree fold_builtin_memmove (tree);
159 static tree fold_builtin_strchr (tree, bool);
160 static tree fold_builtin_memcmp (tree);
161 static tree fold_builtin_strcmp (tree);
162 static tree fold_builtin_strncmp (tree);
163 static tree fold_builtin_signbit (tree);
164 static tree fold_builtin_copysign (tree, tree);
165 static tree fold_builtin_isascii (tree);
166 static tree fold_builtin_toascii (tree);
167 static tree fold_builtin_isdigit (tree);
168 static tree fold_builtin_fabs (tree, tree);
169 static tree fold_builtin_abs (tree, tree);
170 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
171 static tree fold_builtin_1 (tree, bool);
173 static tree simplify_builtin_memcmp (tree);
174 static tree simplify_builtin_strcmp (tree);
175 static tree simplify_builtin_strncmp (tree);
176 static tree simplify_builtin_strpbrk (tree);
177 static tree simplify_builtin_strstr (tree);
178 static tree simplify_builtin_strchr (tree);
179 static tree simplify_builtin_strrchr (tree);
180 static tree simplify_builtin_strcat (tree);
181 static tree simplify_builtin_strncat (tree);
182 static tree simplify_builtin_strspn (tree);
183 static tree simplify_builtin_strcspn (tree);
184 static void simplify_builtin_next_arg (tree);
185 static void simplify_builtin_va_start (tree);
186 static tree simplify_builtin_sprintf (tree, int);
189 /* Return the alignment in bits of EXP, a pointer valued expression.
190 But don't return more than MAX_ALIGN no matter what.
191 The alignment returned is, by default, the alignment of the thing that
192 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
194 Otherwise, look at the expression to see if we can do better, i.e., if the
195 expression is actually pointing at an object whose alignment is tighter. */
197 static int
198 get_pointer_alignment (tree exp, unsigned int max_align)
200 unsigned int align, inner;
202 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
203 return 0;
205 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
206 align = MIN (align, max_align);
208 while (1)
210 switch (TREE_CODE (exp))
212 case NOP_EXPR:
213 case CONVERT_EXPR:
214 case NON_LVALUE_EXPR:
215 exp = TREE_OPERAND (exp, 0);
216 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
217 return align;
219 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
220 align = MIN (inner, max_align);
221 break;
223 case PLUS_EXPR:
224 /* If sum of pointer + int, restrict our maximum alignment to that
225 imposed by the integer. If not, we can't do any better than
226 ALIGN. */
227 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
228 return align;
230 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
231 & (max_align / BITS_PER_UNIT - 1))
232 != 0)
233 max_align >>= 1;
235 exp = TREE_OPERAND (exp, 0);
236 break;
238 case ADDR_EXPR:
239 /* See what we are pointing at and look at its alignment. */
240 exp = TREE_OPERAND (exp, 0);
241 if (TREE_CODE (exp) == FUNCTION_DECL)
242 align = FUNCTION_BOUNDARY;
243 else if (DECL_P (exp))
244 align = DECL_ALIGN (exp);
245 #ifdef CONSTANT_ALIGNMENT
246 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
247 align = CONSTANT_ALIGNMENT (exp, align);
248 #endif
249 return MIN (align, max_align);
251 default:
252 return align;
257 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
258 way, because it could contain a zero byte in the middle.
259 TREE_STRING_LENGTH is the size of the character array, not the string.
261 ONLY_VALUE should be nonzero if the result is not going to be emitted
262 into the instruction stream and zero if it is going to be expanded.
263 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
264 is returned, otherwise NULL, since
265 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
266 evaluate the side-effects.
268 The value returned is of type `ssizetype'.
270 Unfortunately, string_constant can't access the values of const char
271 arrays with initializers, so neither can we do so here. */
273 tree
274 c_strlen (tree src, int only_value)
276 tree offset_node;
277 HOST_WIDE_INT offset;
278 int max;
279 const char *ptr;
281 STRIP_NOPS (src);
282 if (TREE_CODE (src) == COND_EXPR
283 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
285 tree len1, len2;
287 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
288 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
289 if (tree_int_cst_equal (len1, len2))
290 return len1;
293 if (TREE_CODE (src) == COMPOUND_EXPR
294 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
295 return c_strlen (TREE_OPERAND (src, 1), only_value);
297 src = string_constant (src, &offset_node);
298 if (src == 0)
299 return 0;
301 max = TREE_STRING_LENGTH (src) - 1;
302 ptr = TREE_STRING_POINTER (src);
304 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
306 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
307 compute the offset to the following null if we don't know where to
308 start searching for it. */
309 int i;
311 for (i = 0; i < max; i++)
312 if (ptr[i] == 0)
313 return 0;
315 /* We don't know the starting offset, but we do know that the string
316 has no internal zero bytes. We can assume that the offset falls
317 within the bounds of the string; otherwise, the programmer deserves
318 what he gets. Subtract the offset from the length of the string,
319 and return that. This would perhaps not be valid if we were dealing
320 with named arrays in addition to literal string constants. */
322 return size_diffop (size_int (max), offset_node);
325 /* We have a known offset into the string. Start searching there for
326 a null character if we can represent it as a single HOST_WIDE_INT. */
327 if (offset_node == 0)
328 offset = 0;
329 else if (! host_integerp (offset_node, 0))
330 offset = -1;
331 else
332 offset = tree_low_cst (offset_node, 0);
334 /* If the offset is known to be out of bounds, warn, and call strlen at
335 runtime. */
336 if (offset < 0 || offset > max)
338 warning ("offset outside bounds of constant string");
339 return 0;
342 /* Use strlen to search for the first zero byte. Since any strings
343 constructed with build_string will have nulls appended, we win even
344 if we get handed something like (char[4])"abcd".
346 Since OFFSET is our starting index into the string, no further
347 calculation is needed. */
348 return ssize_int (strlen (ptr + offset));
351 /* Return a char pointer for a C string if it is a string constant
352 or sum of string constant and integer constant. */
354 static const char *
355 c_getstr (tree src)
357 tree offset_node;
359 src = string_constant (src, &offset_node);
360 if (src == 0)
361 return 0;
363 if (offset_node == 0)
364 return TREE_STRING_POINTER (src);
365 else if (!host_integerp (offset_node, 1)
366 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
367 return 0;
369 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
372 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
373 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
375 static rtx
376 c_readstr (const char *str, enum machine_mode mode)
378 HOST_WIDE_INT c[2];
379 HOST_WIDE_INT ch;
380 unsigned int i, j;
382 if (GET_MODE_CLASS (mode) != MODE_INT)
383 abort ();
384 c[0] = 0;
385 c[1] = 0;
386 ch = 1;
387 for (i = 0; i < GET_MODE_SIZE (mode); i++)
389 j = i;
390 if (WORDS_BIG_ENDIAN)
391 j = GET_MODE_SIZE (mode) - i - 1;
392 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
393 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
394 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
395 j *= BITS_PER_UNIT;
396 if (j > 2 * HOST_BITS_PER_WIDE_INT)
397 abort ();
398 if (ch)
399 ch = (unsigned char) str[i];
400 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
402 return immed_double_const (c[0], c[1], mode);
405 /* Cast a target constant CST to target CHAR and if that value fits into
406 host char type, return zero and put that value into variable pointed by
407 P. */
409 static int
410 target_char_cast (tree cst, char *p)
412 unsigned HOST_WIDE_INT val, hostval;
414 if (!host_integerp (cst, 1)
415 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
416 return 1;
418 val = tree_low_cst (cst, 1);
419 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
420 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
422 hostval = val;
423 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
424 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
426 if (val != hostval)
427 return 1;
429 *p = hostval;
430 return 0;
433 /* Similar to save_expr, but assumes that arbitrary code is not executed
434 in between the multiple evaluations. In particular, we assume that a
435 non-addressable local variable will not be modified. */
437 static tree
438 builtin_save_expr (tree exp)
440 if (TREE_ADDRESSABLE (exp) == 0
441 && (TREE_CODE (exp) == PARM_DECL
442 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
443 return exp;
445 return save_expr (exp);
448 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
449 times to get the address of either a higher stack frame, or a return
450 address located within it (depending on FNDECL_CODE). */
453 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
454 rtx tem)
456 int i;
458 /* Some machines need special handling before we can access
459 arbitrary frames. For example, on the sparc, we must first flush
460 all register windows to the stack. */
461 #ifdef SETUP_FRAME_ADDRESSES
462 if (count > 0)
463 SETUP_FRAME_ADDRESSES ();
464 #endif
466 /* On the sparc, the return address is not in the frame, it is in a
467 register. There is no way to access it off of the current frame
468 pointer, but it can be accessed off the previous frame pointer by
469 reading the value from the register window save area. */
470 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
471 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
472 count--;
473 #endif
475 /* Scan back COUNT frames to the specified frame. */
476 for (i = 0; i < count; i++)
478 /* Assume the dynamic chain pointer is in the word that the
479 frame address points to, unless otherwise specified. */
480 #ifdef DYNAMIC_CHAIN_ADDRESS
481 tem = DYNAMIC_CHAIN_ADDRESS (tem);
482 #endif
483 tem = memory_address (Pmode, tem);
484 tem = gen_rtx_MEM (Pmode, tem);
485 set_mem_alias_set (tem, get_frame_alias_set ());
486 tem = copy_to_reg (tem);
489 /* For __builtin_frame_address, return what we've got. */
490 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
491 return tem;
493 /* For __builtin_return_address, Get the return address from that
494 frame. */
495 #ifdef RETURN_ADDR_RTX
496 tem = RETURN_ADDR_RTX (count, tem);
497 #else
498 tem = memory_address (Pmode,
499 plus_constant (tem, GET_MODE_SIZE (Pmode)));
500 tem = gen_rtx_MEM (Pmode, tem);
501 set_mem_alias_set (tem, get_frame_alias_set ());
502 #endif
503 return tem;
506 /* Alias set used for setjmp buffer. */
507 static HOST_WIDE_INT setjmp_alias_set = -1;
509 /* Construct the leading half of a __builtin_setjmp call. Control will
510 return to RECEIVER_LABEL. This is used directly by sjlj exception
511 handling code. */
513 void
514 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
516 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
517 rtx stack_save;
518 rtx mem;
520 if (setjmp_alias_set == -1)
521 setjmp_alias_set = new_alias_set ();
523 buf_addr = convert_memory_address (Pmode, buf_addr);
525 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
527 emit_queue ();
529 /* We store the frame pointer and the address of receiver_label in
530 the buffer and use the rest of it for the stack save area, which
531 is machine-dependent. */
533 mem = gen_rtx_MEM (Pmode, buf_addr);
534 set_mem_alias_set (mem, setjmp_alias_set);
535 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
537 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
538 set_mem_alias_set (mem, setjmp_alias_set);
540 emit_move_insn (validize_mem (mem),
541 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
543 stack_save = gen_rtx_MEM (sa_mode,
544 plus_constant (buf_addr,
545 2 * GET_MODE_SIZE (Pmode)));
546 set_mem_alias_set (stack_save, setjmp_alias_set);
547 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
549 /* If there is further processing to do, do it. */
550 #ifdef HAVE_builtin_setjmp_setup
551 if (HAVE_builtin_setjmp_setup)
552 emit_insn (gen_builtin_setjmp_setup (buf_addr));
553 #endif
555 /* Tell optimize_save_area_alloca that extra work is going to
556 need to go on during alloca. */
557 current_function_calls_setjmp = 1;
559 /* Set this so all the registers get saved in our frame; we need to be
560 able to copy the saved values for any registers from frames we unwind. */
561 current_function_has_nonlocal_label = 1;
564 /* Construct the trailing part of a __builtin_setjmp call.
565 This is used directly by sjlj exception handling code. */
567 void
568 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
570 /* Clobber the FP when we get here, so we have to make sure it's
571 marked as used by this function. */
572 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
574 /* Mark the static chain as clobbered here so life information
575 doesn't get messed up for it. */
576 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
578 /* Now put in the code to restore the frame pointer, and argument
579 pointer, if needed. The code below is from expand_end_bindings
580 in stmt.c; see detailed documentation there. */
581 #ifdef HAVE_nonlocal_goto
582 if (! HAVE_nonlocal_goto)
583 #endif
584 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
586 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
587 if (fixed_regs[ARG_POINTER_REGNUM])
589 #ifdef ELIMINABLE_REGS
590 size_t i;
591 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
593 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
594 if (elim_regs[i].from == ARG_POINTER_REGNUM
595 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
596 break;
598 if (i == ARRAY_SIZE (elim_regs))
599 #endif
601 /* Now restore our arg pointer from the address at which it
602 was saved in our stack frame. */
603 emit_move_insn (virtual_incoming_args_rtx,
604 copy_to_reg (get_arg_pointer_save_area (cfun)));
607 #endif
609 #ifdef HAVE_builtin_setjmp_receiver
610 if (HAVE_builtin_setjmp_receiver)
611 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
612 else
613 #endif
614 #ifdef HAVE_nonlocal_goto_receiver
615 if (HAVE_nonlocal_goto_receiver)
616 emit_insn (gen_nonlocal_goto_receiver ());
617 else
618 #endif
619 { /* Nothing */ }
621 /* @@@ This is a kludge. Not all machine descriptions define a blockage
622 insn, but we must not allow the code we just generated to be reordered
623 by scheduling. Specifically, the update of the frame pointer must
624 happen immediately, not later. So emit an ASM_INPUT to act as blockage
625 insn. */
626 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
629 /* __builtin_setjmp is passed a pointer to an array of five words (not
630 all will be used on all machines). It operates similarly to the C
631 library function of the same name, but is more efficient. Much of
632 the code below (and for longjmp) is copied from the handling of
633 non-local gotos.
635 NOTE: This is intended for use by GNAT and the exception handling
636 scheme in the compiler and will only work in the method used by
637 them. */
639 static rtx
640 expand_builtin_setjmp (tree arglist, rtx target)
642 rtx buf_addr, next_lab, cont_lab;
644 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
645 return NULL_RTX;
647 if (target == 0 || !REG_P (target)
648 || REGNO (target) < FIRST_PSEUDO_REGISTER)
649 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
651 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
653 next_lab = gen_label_rtx ();
654 cont_lab = gen_label_rtx ();
656 expand_builtin_setjmp_setup (buf_addr, next_lab);
658 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
659 ensure that pending stack adjustments are flushed. */
660 emit_move_insn (target, const0_rtx);
661 emit_jump (cont_lab);
663 emit_label (next_lab);
665 expand_builtin_setjmp_receiver (next_lab);
667 /* Set TARGET to one. */
668 emit_move_insn (target, const1_rtx);
669 emit_label (cont_lab);
671 /* Tell flow about the strange goings on. Putting `next_lab' on
672 `nonlocal_goto_handler_labels' to indicates that function
673 calls may traverse the arc back to this label. */
675 current_function_has_nonlocal_label = 1;
676 nonlocal_goto_handler_labels
677 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
679 return target;
682 /* __builtin_longjmp is passed a pointer to an array of five words (not
683 all will be used on all machines). It operates similarly to the C
684 library function of the same name, but is more efficient. Much of
685 the code below is copied from the handling of non-local gotos.
687 NOTE: This is intended for use by GNAT and the exception handling
688 scheme in the compiler and will only work in the method used by
689 them. */
691 void
692 expand_builtin_longjmp (rtx buf_addr, rtx value)
694 rtx fp, lab, stack, insn, last;
695 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
697 if (setjmp_alias_set == -1)
698 setjmp_alias_set = new_alias_set ();
700 buf_addr = convert_memory_address (Pmode, buf_addr);
702 buf_addr = force_reg (Pmode, buf_addr);
704 /* We used to store value in static_chain_rtx, but that fails if pointers
705 are smaller than integers. We instead require that the user must pass
706 a second argument of 1, because that is what builtin_setjmp will
707 return. This also makes EH slightly more efficient, since we are no
708 longer copying around a value that we don't care about. */
709 if (value != const1_rtx)
710 abort ();
712 current_function_calls_longjmp = 1;
714 last = get_last_insn ();
715 #ifdef HAVE_builtin_longjmp
716 if (HAVE_builtin_longjmp)
717 emit_insn (gen_builtin_longjmp (buf_addr));
718 else
719 #endif
721 fp = gen_rtx_MEM (Pmode, buf_addr);
722 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
723 GET_MODE_SIZE (Pmode)));
725 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
726 2 * GET_MODE_SIZE (Pmode)));
727 set_mem_alias_set (fp, setjmp_alias_set);
728 set_mem_alias_set (lab, setjmp_alias_set);
729 set_mem_alias_set (stack, setjmp_alias_set);
731 /* Pick up FP, label, and SP from the block and jump. This code is
732 from expand_goto in stmt.c; see there for detailed comments. */
733 #if HAVE_nonlocal_goto
734 if (HAVE_nonlocal_goto)
735 /* We have to pass a value to the nonlocal_goto pattern that will
736 get copied into the static_chain pointer, but it does not matter
737 what that value is, because builtin_setjmp does not use it. */
738 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
739 else
740 #endif
742 lab = copy_to_reg (lab);
744 emit_insn (gen_rtx_CLOBBER (VOIDmode,
745 gen_rtx_MEM (BLKmode,
746 gen_rtx_SCRATCH (VOIDmode))));
747 emit_insn (gen_rtx_CLOBBER (VOIDmode,
748 gen_rtx_MEM (BLKmode,
749 hard_frame_pointer_rtx)));
751 emit_move_insn (hard_frame_pointer_rtx, fp);
752 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
754 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
755 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
756 emit_indirect_jump (lab);
760 /* Search backwards and mark the jump insn as a non-local goto.
761 Note that this precludes the use of __builtin_longjmp to a
762 __builtin_setjmp target in the same function. However, we've
763 already cautioned the user that these functions are for
764 internal exception handling use only. */
765 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
767 if (insn == last)
768 abort ();
769 if (JUMP_P (insn))
771 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
772 REG_NOTES (insn));
773 break;
775 else if (CALL_P (insn))
776 break;
780 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
781 and the address of the save area. */
783 static rtx
784 expand_builtin_nonlocal_goto (tree arglist)
786 tree t_label, t_save_area;
787 rtx r_label, r_save_area, r_fp, r_sp, insn;
789 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
790 return NULL_RTX;
792 t_label = TREE_VALUE (arglist);
793 arglist = TREE_CHAIN (arglist);
794 t_save_area = TREE_VALUE (arglist);
796 r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
797 r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
798 r_fp = gen_rtx_MEM (Pmode, r_save_area);
799 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
800 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
802 current_function_has_nonlocal_goto = 1;
804 #if HAVE_nonlocal_goto
805 /* ??? We no longer need to pass the static chain value, afaik. */
806 if (HAVE_nonlocal_goto)
807 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
808 else
809 #endif
811 r_label = copy_to_reg (r_label);
813 emit_insn (gen_rtx_CLOBBER (VOIDmode,
814 gen_rtx_MEM (BLKmode,
815 gen_rtx_SCRATCH (VOIDmode))));
817 emit_insn (gen_rtx_CLOBBER (VOIDmode,
818 gen_rtx_MEM (BLKmode,
819 hard_frame_pointer_rtx)));
821 /* Restore frame pointer for containing function.
822 This sets the actual hard register used for the frame pointer
823 to the location of the function's incoming static chain info.
824 The non-local goto handler will then adjust it to contain the
825 proper value and reload the argument pointer, if needed. */
826 emit_move_insn (hard_frame_pointer_rtx, r_fp);
827 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
829 /* USE of hard_frame_pointer_rtx added for consistency;
830 not clear if really needed. */
831 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
832 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
833 emit_indirect_jump (r_label);
836 /* Search backwards to the jump insn and mark it as a
837 non-local goto. */
838 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
840 if (JUMP_P (insn))
842 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
843 const0_rtx, REG_NOTES (insn));
844 break;
846 else if (CALL_P (insn))
847 break;
850 return const0_rtx;
853 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
854 (not all will be used on all machines) that was passed to __builtin_setjmp.
855 It updates the stack pointer in that block to correspond to the current
856 stack pointer. */
858 static void
859 expand_builtin_update_setjmp_buf (rtx buf_addr)
861 enum machine_mode sa_mode = Pmode;
862 rtx stack_save;
865 #ifdef HAVE_save_stack_nonlocal
866 if (HAVE_save_stack_nonlocal)
867 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
868 #endif
869 #ifdef STACK_SAVEAREA_MODE
870 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
871 #endif
873 stack_save
874 = gen_rtx_MEM (sa_mode,
875 memory_address
876 (sa_mode,
877 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
879 #ifdef HAVE_setjmp
880 if (HAVE_setjmp)
881 emit_insn (gen_setjmp ());
882 #endif
884 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
887 /* Expand a call to __builtin_prefetch. For a target that does not support
888 data prefetch, evaluate the memory address argument in case it has side
889 effects. */
891 static void
892 expand_builtin_prefetch (tree arglist)
894 tree arg0, arg1, arg2;
895 rtx op0, op1, op2;
897 if (!validate_arglist (arglist, POINTER_TYPE, 0))
898 return;
900 arg0 = TREE_VALUE (arglist);
901 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
902 zero (read) and argument 2 (locality) defaults to 3 (high degree of
903 locality). */
904 if (TREE_CHAIN (arglist))
906 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
907 if (TREE_CHAIN (TREE_CHAIN (arglist)))
908 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
909 else
910 arg2 = build_int_2 (3, 0);
912 else
914 arg1 = integer_zero_node;
915 arg2 = build_int_2 (3, 0);
918 /* Argument 0 is an address. */
919 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
921 /* Argument 1 (read/write flag) must be a compile-time constant int. */
922 if (TREE_CODE (arg1) != INTEGER_CST)
924 error ("second arg to `__builtin_prefetch' must be a constant");
925 arg1 = integer_zero_node;
927 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
928 /* Argument 1 must be either zero or one. */
929 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
931 warning ("invalid second arg to __builtin_prefetch; using zero");
932 op1 = const0_rtx;
935 /* Argument 2 (locality) must be a compile-time constant int. */
936 if (TREE_CODE (arg2) != INTEGER_CST)
938 error ("third arg to `__builtin_prefetch' must be a constant");
939 arg2 = integer_zero_node;
941 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
942 /* Argument 2 must be 0, 1, 2, or 3. */
943 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
945 warning ("invalid third arg to __builtin_prefetch; using zero");
946 op2 = const0_rtx;
949 #ifdef HAVE_prefetch
950 if (HAVE_prefetch)
952 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
953 (op0,
954 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
955 || (GET_MODE (op0) != Pmode))
957 op0 = convert_memory_address (Pmode, op0);
958 op0 = force_reg (Pmode, op0);
960 emit_insn (gen_prefetch (op0, op1, op2));
962 else
963 #endif
964 op0 = protect_from_queue (op0, 0);
965 /* Don't do anything with direct references to volatile memory, but
966 generate code to handle other side effects. */
967 if (!MEM_P (op0) && side_effects_p (op0))
968 emit_insn (op0);
971 /* Get a MEM rtx for expression EXP which is the address of an operand
972 to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */
974 static rtx
975 get_memory_rtx (tree exp)
977 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
978 rtx mem;
980 addr = convert_memory_address (Pmode, addr);
982 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
984 /* Get an expression we can use to find the attributes to assign to MEM.
985 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
986 we can. First remove any nops. */
987 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
988 || TREE_CODE (exp) == NON_LVALUE_EXPR)
989 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
990 exp = TREE_OPERAND (exp, 0);
992 if (TREE_CODE (exp) == ADDR_EXPR)
994 exp = TREE_OPERAND (exp, 0);
995 set_mem_attributes (mem, exp, 0);
997 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
999 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1000 /* memcpy, memset and other builtin stringops can alias with anything. */
1001 set_mem_alias_set (mem, 0);
1004 return mem;
1007 /* Built-in functions to perform an untyped call and return. */
1009 /* For each register that may be used for calling a function, this
1010 gives a mode used to copy the register's value. VOIDmode indicates
1011 the register is not used for calling a function. If the machine
1012 has register windows, this gives only the outbound registers.
1013 INCOMING_REGNO gives the corresponding inbound register. */
1014 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1016 /* For each register that may be used for returning values, this gives
1017 a mode used to copy the register's value. VOIDmode indicates the
1018 register is not used for returning values. If the machine has
1019 register windows, this gives only the outbound registers.
1020 INCOMING_REGNO gives the corresponding inbound register. */
1021 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1023 /* For each register that may be used for calling a function, this
1024 gives the offset of that register into the block returned by
1025 __builtin_apply_args. 0 indicates that the register is not
1026 used for calling a function. */
1027 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1029 /* Return the size required for the block returned by __builtin_apply_args,
1030 and initialize apply_args_mode. */
1032 static int
1033 apply_args_size (void)
1035 static int size = -1;
1036 int align;
1037 unsigned int regno;
1038 enum machine_mode mode;
1040 /* The values computed by this function never change. */
1041 if (size < 0)
1043 /* The first value is the incoming arg-pointer. */
1044 size = GET_MODE_SIZE (Pmode);
1046 /* The second value is the structure value address unless this is
1047 passed as an "invisible" first argument. */
1048 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1049 size += GET_MODE_SIZE (Pmode);
1051 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1052 if (FUNCTION_ARG_REGNO_P (regno))
1054 mode = reg_raw_mode[regno];
1056 if (mode == VOIDmode)
1057 abort ();
1059 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1060 if (size % align != 0)
1061 size = CEIL (size, align) * align;
1062 apply_args_reg_offset[regno] = size;
1063 size += GET_MODE_SIZE (mode);
1064 apply_args_mode[regno] = mode;
1066 else
1068 apply_args_mode[regno] = VOIDmode;
1069 apply_args_reg_offset[regno] = 0;
1072 return size;
1075 /* Return the size required for the block returned by __builtin_apply,
1076 and initialize apply_result_mode. */
1078 static int
1079 apply_result_size (void)
1081 static int size = -1;
1082 int align, regno;
1083 enum machine_mode mode;
1085 /* The values computed by this function never change. */
1086 if (size < 0)
1088 size = 0;
1090 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1091 if (FUNCTION_VALUE_REGNO_P (regno))
1093 mode = reg_raw_mode[regno];
1095 if (mode == VOIDmode)
1096 abort ();
1098 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1099 if (size % align != 0)
1100 size = CEIL (size, align) * align;
1101 size += GET_MODE_SIZE (mode);
1102 apply_result_mode[regno] = mode;
1104 else
1105 apply_result_mode[regno] = VOIDmode;
1107 /* Allow targets that use untyped_call and untyped_return to override
1108 the size so that machine-specific information can be stored here. */
1109 #ifdef APPLY_RESULT_SIZE
1110 size = APPLY_RESULT_SIZE;
1111 #endif
1113 return size;
1116 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1117 /* Create a vector describing the result block RESULT. If SAVEP is true,
1118 the result block is used to save the values; otherwise it is used to
1119 restore the values. */
1121 static rtx
1122 result_vector (int savep, rtx result)
1124 int regno, size, align, nelts;
1125 enum machine_mode mode;
1126 rtx reg, mem;
1127 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1129 size = nelts = 0;
1130 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1131 if ((mode = apply_result_mode[regno]) != VOIDmode)
1133 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1134 if (size % align != 0)
1135 size = CEIL (size, align) * align;
1136 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1137 mem = adjust_address (result, mode, size);
1138 savevec[nelts++] = (savep
1139 ? gen_rtx_SET (VOIDmode, mem, reg)
1140 : gen_rtx_SET (VOIDmode, reg, mem));
1141 size += GET_MODE_SIZE (mode);
1143 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1145 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1147 /* Save the state required to perform an untyped call with the same
1148 arguments as were passed to the current function. */
1150 static rtx
1151 expand_builtin_apply_args_1 (void)
1153 rtx registers, tem;
1154 int size, align, regno;
1155 enum machine_mode mode;
1156 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1158 /* Create a block where the arg-pointer, structure value address,
1159 and argument registers can be saved. */
1160 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1162 /* Walk past the arg-pointer and structure value address. */
1163 size = GET_MODE_SIZE (Pmode);
1164 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1165 size += GET_MODE_SIZE (Pmode);
1167 /* Save each register used in calling a function to the block. */
1168 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1169 if ((mode = apply_args_mode[regno]) != VOIDmode)
1171 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1172 if (size % align != 0)
1173 size = CEIL (size, align) * align;
1175 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1177 emit_move_insn (adjust_address (registers, mode, size), tem);
1178 size += GET_MODE_SIZE (mode);
1181 /* Save the arg pointer to the block. */
1182 tem = copy_to_reg (virtual_incoming_args_rtx);
1183 #ifdef STACK_GROWS_DOWNWARD
1184 /* We need the pointer as the caller actually passed them to us, not
1185 as we might have pretended they were passed. Make sure it's a valid
1186 operand, as emit_move_insn isn't expected to handle a PLUS. */
1188 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1189 NULL_RTX);
1190 #endif
1191 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1193 size = GET_MODE_SIZE (Pmode);
1195 /* Save the structure value address unless this is passed as an
1196 "invisible" first argument. */
1197 if (struct_incoming_value)
1199 emit_move_insn (adjust_address (registers, Pmode, size),
1200 copy_to_reg (struct_incoming_value));
1201 size += GET_MODE_SIZE (Pmode);
1204 /* Return the address of the block. */
1205 return copy_addr_to_reg (XEXP (registers, 0));
1208 /* __builtin_apply_args returns block of memory allocated on
1209 the stack into which is stored the arg pointer, structure
1210 value address, static chain, and all the registers that might
1211 possibly be used in performing a function call. The code is
1212 moved to the start of the function so the incoming values are
1213 saved. */
1215 static rtx
1216 expand_builtin_apply_args (void)
1218 /* Don't do __builtin_apply_args more than once in a function.
1219 Save the result of the first call and reuse it. */
1220 if (apply_args_value != 0)
1221 return apply_args_value;
1223 /* When this function is called, it means that registers must be
1224 saved on entry to this function. So we migrate the
1225 call to the first insn of this function. */
1226 rtx temp;
1227 rtx seq;
1229 start_sequence ();
1230 temp = expand_builtin_apply_args_1 ();
1231 seq = get_insns ();
1232 end_sequence ();
1234 apply_args_value = temp;
1236 /* Put the insns after the NOTE that starts the function.
1237 If this is inside a start_sequence, make the outer-level insn
1238 chain current, so the code is placed at the start of the
1239 function. */
1240 push_topmost_sequence ();
1241 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1242 pop_topmost_sequence ();
1243 return temp;
1247 /* Perform an untyped call and save the state required to perform an
1248 untyped return of whatever value was returned by the given function. */
1250 static rtx
1251 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1253 int size, align, regno;
1254 enum machine_mode mode;
1255 rtx incoming_args, result, reg, dest, src, call_insn;
1256 rtx old_stack_level = 0;
1257 rtx call_fusage = 0;
1258 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1260 arguments = convert_memory_address (Pmode, arguments);
1262 /* Create a block where the return registers can be saved. */
1263 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1265 /* Fetch the arg pointer from the ARGUMENTS block. */
1266 incoming_args = gen_reg_rtx (Pmode);
1267 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1268 #ifndef STACK_GROWS_DOWNWARD
1269 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1270 incoming_args, 0, OPTAB_LIB_WIDEN);
1271 #endif
1273 /* Perform postincrements before actually calling the function. */
1274 emit_queue ();
1276 /* Push a new argument block and copy the arguments. Do not allow
1277 the (potential) memcpy call below to interfere with our stack
1278 manipulations. */
1279 do_pending_stack_adjust ();
1280 NO_DEFER_POP;
1282 /* Save the stack with nonlocal if available. */
1283 #ifdef HAVE_save_stack_nonlocal
1284 if (HAVE_save_stack_nonlocal)
1285 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1286 else
1287 #endif
1288 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1290 /* Allocate a block of memory onto the stack and copy the memory
1291 arguments to the outgoing arguments address. */
1292 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1293 dest = virtual_outgoing_args_rtx;
1294 #ifndef STACK_GROWS_DOWNWARD
1295 if (GET_CODE (argsize) == CONST_INT)
1296 dest = plus_constant (dest, -INTVAL (argsize));
1297 else
1298 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1299 #endif
1300 dest = gen_rtx_MEM (BLKmode, dest);
1301 set_mem_align (dest, PARM_BOUNDARY);
1302 src = gen_rtx_MEM (BLKmode, incoming_args);
1303 set_mem_align (src, PARM_BOUNDARY);
1304 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1306 /* Refer to the argument block. */
1307 apply_args_size ();
1308 arguments = gen_rtx_MEM (BLKmode, arguments);
1309 set_mem_align (arguments, PARM_BOUNDARY);
1311 /* Walk past the arg-pointer and structure value address. */
1312 size = GET_MODE_SIZE (Pmode);
1313 if (struct_value)
1314 size += GET_MODE_SIZE (Pmode);
1316 /* Restore each of the registers previously saved. Make USE insns
1317 for each of these registers for use in making the call. */
1318 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1319 if ((mode = apply_args_mode[regno]) != VOIDmode)
1321 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1322 if (size % align != 0)
1323 size = CEIL (size, align) * align;
1324 reg = gen_rtx_REG (mode, regno);
1325 emit_move_insn (reg, adjust_address (arguments, mode, size));
1326 use_reg (&call_fusage, reg);
1327 size += GET_MODE_SIZE (mode);
1330 /* Restore the structure value address unless this is passed as an
1331 "invisible" first argument. */
1332 size = GET_MODE_SIZE (Pmode);
1333 if (struct_value)
1335 rtx value = gen_reg_rtx (Pmode);
1336 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1337 emit_move_insn (struct_value, value);
1338 if (REG_P (struct_value))
1339 use_reg (&call_fusage, struct_value);
1340 size += GET_MODE_SIZE (Pmode);
1343 /* All arguments and registers used for the call are set up by now! */
1344 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1346 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1347 and we don't want to load it into a register as an optimization,
1348 because prepare_call_address already did it if it should be done. */
1349 if (GET_CODE (function) != SYMBOL_REF)
1350 function = memory_address (FUNCTION_MODE, function);
1352 /* Generate the actual call instruction and save the return value. */
1353 #ifdef HAVE_untyped_call
1354 if (HAVE_untyped_call)
1355 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1356 result, result_vector (1, result)));
1357 else
1358 #endif
1359 #ifdef HAVE_call_value
1360 if (HAVE_call_value)
1362 rtx valreg = 0;
1364 /* Locate the unique return register. It is not possible to
1365 express a call that sets more than one return register using
1366 call_value; use untyped_call for that. In fact, untyped_call
1367 only needs to save the return registers in the given block. */
1368 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1369 if ((mode = apply_result_mode[regno]) != VOIDmode)
1371 if (valreg)
1372 abort (); /* HAVE_untyped_call required. */
1373 valreg = gen_rtx_REG (mode, regno);
1376 emit_call_insn (GEN_CALL_VALUE (valreg,
1377 gen_rtx_MEM (FUNCTION_MODE, function),
1378 const0_rtx, NULL_RTX, const0_rtx));
1380 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1382 else
1383 #endif
1384 abort ();
1386 /* Find the CALL insn we just emitted, and attach the register usage
1387 information. */
1388 call_insn = last_call_insn ();
1389 add_function_usage_to (call_insn, call_fusage);
1391 /* Restore the stack. */
1392 #ifdef HAVE_save_stack_nonlocal
1393 if (HAVE_save_stack_nonlocal)
1394 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1395 else
1396 #endif
1397 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1399 OK_DEFER_POP;
1401 /* Return the address of the result block. */
1402 result = copy_addr_to_reg (XEXP (result, 0));
1403 return convert_memory_address (ptr_mode, result);
1406 /* Perform an untyped return. */
1408 static void
1409 expand_builtin_return (rtx result)
1411 int size, align, regno;
1412 enum machine_mode mode;
1413 rtx reg;
1414 rtx call_fusage = 0;
1416 result = convert_memory_address (Pmode, result);
1418 apply_result_size ();
1419 result = gen_rtx_MEM (BLKmode, result);
1421 #ifdef HAVE_untyped_return
1422 if (HAVE_untyped_return)
1424 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1425 emit_barrier ();
1426 return;
1428 #endif
1430 /* Restore the return value and note that each value is used. */
1431 size = 0;
1432 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1433 if ((mode = apply_result_mode[regno]) != VOIDmode)
1435 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1436 if (size % align != 0)
1437 size = CEIL (size, align) * align;
1438 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1439 emit_move_insn (reg, adjust_address (result, mode, size));
1441 push_to_sequence (call_fusage);
1442 emit_insn (gen_rtx_USE (VOIDmode, reg));
1443 call_fusage = get_insns ();
1444 end_sequence ();
1445 size += GET_MODE_SIZE (mode);
1448 /* Put the USE insns before the return. */
1449 emit_insn (call_fusage);
1451 /* Return whatever values was restored by jumping directly to the end
1452 of the function. */
1453 expand_naked_return ();
1456 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1458 static enum type_class
1459 type_to_class (tree type)
1461 switch (TREE_CODE (type))
1463 case VOID_TYPE: return void_type_class;
1464 case INTEGER_TYPE: return integer_type_class;
1465 case CHAR_TYPE: return char_type_class;
1466 case ENUMERAL_TYPE: return enumeral_type_class;
1467 case BOOLEAN_TYPE: return boolean_type_class;
1468 case POINTER_TYPE: return pointer_type_class;
1469 case REFERENCE_TYPE: return reference_type_class;
1470 case OFFSET_TYPE: return offset_type_class;
1471 case REAL_TYPE: return real_type_class;
1472 case COMPLEX_TYPE: return complex_type_class;
1473 case FUNCTION_TYPE: return function_type_class;
1474 case METHOD_TYPE: return method_type_class;
1475 case RECORD_TYPE: return record_type_class;
1476 case UNION_TYPE:
1477 case QUAL_UNION_TYPE: return union_type_class;
1478 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1479 ? string_type_class : array_type_class);
1480 case SET_TYPE: return set_type_class;
1481 case FILE_TYPE: return file_type_class;
1482 case LANG_TYPE: return lang_type_class;
1483 default: return no_type_class;
1487 /* Expand a call to __builtin_classify_type with arguments found in
1488 ARGLIST. */
1490 static rtx
1491 expand_builtin_classify_type (tree arglist)
1493 if (arglist != 0)
1494 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1495 return GEN_INT (no_type_class);
1498 /* This helper macro, meant to be used in mathfn_built_in below,
1499 determines which among a set of three builtin math functions is
1500 appropriate for a given type mode. The `F' and `L' cases are
1501 automatically generated from the `double' case. */
1502 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1503 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1504 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1505 fcodel = BUILT_IN_MATHFN##L ; break;
1507 /* Return mathematic function equivalent to FN but operating directly
1508 on TYPE, if available. If we can't do the conversion, return zero. */
1509 tree
1510 mathfn_built_in (tree type, enum built_in_function fn)
1512 enum built_in_function fcode, fcodef, fcodel;
1514 switch (fn)
1516 CASE_MATHFN (BUILT_IN_ACOS)
1517 CASE_MATHFN (BUILT_IN_ACOSH)
1518 CASE_MATHFN (BUILT_IN_ASIN)
1519 CASE_MATHFN (BUILT_IN_ASINH)
1520 CASE_MATHFN (BUILT_IN_ATAN)
1521 CASE_MATHFN (BUILT_IN_ATAN2)
1522 CASE_MATHFN (BUILT_IN_ATANH)
1523 CASE_MATHFN (BUILT_IN_CBRT)
1524 CASE_MATHFN (BUILT_IN_CEIL)
1525 CASE_MATHFN (BUILT_IN_COPYSIGN)
1526 CASE_MATHFN (BUILT_IN_COS)
1527 CASE_MATHFN (BUILT_IN_COSH)
1528 CASE_MATHFN (BUILT_IN_DREM)
1529 CASE_MATHFN (BUILT_IN_ERF)
1530 CASE_MATHFN (BUILT_IN_ERFC)
1531 CASE_MATHFN (BUILT_IN_EXP)
1532 CASE_MATHFN (BUILT_IN_EXP10)
1533 CASE_MATHFN (BUILT_IN_EXP2)
1534 CASE_MATHFN (BUILT_IN_EXPM1)
1535 CASE_MATHFN (BUILT_IN_FABS)
1536 CASE_MATHFN (BUILT_IN_FDIM)
1537 CASE_MATHFN (BUILT_IN_FLOOR)
1538 CASE_MATHFN (BUILT_IN_FMA)
1539 CASE_MATHFN (BUILT_IN_FMAX)
1540 CASE_MATHFN (BUILT_IN_FMIN)
1541 CASE_MATHFN (BUILT_IN_FMOD)
1542 CASE_MATHFN (BUILT_IN_FREXP)
1543 CASE_MATHFN (BUILT_IN_GAMMA)
1544 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1545 CASE_MATHFN (BUILT_IN_HYPOT)
1546 CASE_MATHFN (BUILT_IN_ILOGB)
1547 CASE_MATHFN (BUILT_IN_INF)
1548 CASE_MATHFN (BUILT_IN_J0)
1549 CASE_MATHFN (BUILT_IN_J1)
1550 CASE_MATHFN (BUILT_IN_JN)
1551 CASE_MATHFN (BUILT_IN_LDEXP)
1552 CASE_MATHFN (BUILT_IN_LGAMMA)
1553 CASE_MATHFN (BUILT_IN_LLRINT)
1554 CASE_MATHFN (BUILT_IN_LLROUND)
1555 CASE_MATHFN (BUILT_IN_LOG)
1556 CASE_MATHFN (BUILT_IN_LOG10)
1557 CASE_MATHFN (BUILT_IN_LOG1P)
1558 CASE_MATHFN (BUILT_IN_LOG2)
1559 CASE_MATHFN (BUILT_IN_LOGB)
1560 CASE_MATHFN (BUILT_IN_LRINT)
1561 CASE_MATHFN (BUILT_IN_LROUND)
1562 CASE_MATHFN (BUILT_IN_MODF)
1563 CASE_MATHFN (BUILT_IN_NAN)
1564 CASE_MATHFN (BUILT_IN_NANS)
1565 CASE_MATHFN (BUILT_IN_NEARBYINT)
1566 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1567 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1568 CASE_MATHFN (BUILT_IN_POW)
1569 CASE_MATHFN (BUILT_IN_POW10)
1570 CASE_MATHFN (BUILT_IN_REMAINDER)
1571 CASE_MATHFN (BUILT_IN_REMQUO)
1572 CASE_MATHFN (BUILT_IN_RINT)
1573 CASE_MATHFN (BUILT_IN_ROUND)
1574 CASE_MATHFN (BUILT_IN_SCALB)
1575 CASE_MATHFN (BUILT_IN_SCALBLN)
1576 CASE_MATHFN (BUILT_IN_SCALBN)
1577 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1578 CASE_MATHFN (BUILT_IN_SIN)
1579 CASE_MATHFN (BUILT_IN_SINCOS)
1580 CASE_MATHFN (BUILT_IN_SINH)
1581 CASE_MATHFN (BUILT_IN_SQRT)
1582 CASE_MATHFN (BUILT_IN_TAN)
1583 CASE_MATHFN (BUILT_IN_TANH)
1584 CASE_MATHFN (BUILT_IN_TGAMMA)
1585 CASE_MATHFN (BUILT_IN_TRUNC)
1586 CASE_MATHFN (BUILT_IN_Y0)
1587 CASE_MATHFN (BUILT_IN_Y1)
1588 CASE_MATHFN (BUILT_IN_YN)
1590 default:
1591 return 0;
1594 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1595 return implicit_built_in_decls[fcode];
1596 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1597 return implicit_built_in_decls[fcodef];
1598 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1599 return implicit_built_in_decls[fcodel];
1600 else
1601 return 0;
1604 /* If errno must be maintained, expand the RTL to check if the result,
1605 TARGET, of a built-in function call, EXP, is NaN, and if so set
1606 errno to EDOM. */
1608 static void
1609 expand_errno_check (tree exp, rtx target)
1611 rtx lab = gen_label_rtx ();
1613 /* Test the result; if it is NaN, set errno=EDOM because
1614 the argument was not in the domain. */
1615 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1616 0, lab);
1618 #ifdef TARGET_EDOM
1619 /* If this built-in doesn't throw an exception, set errno directly. */
1620 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1622 #ifdef GEN_ERRNO_RTX
1623 rtx errno_rtx = GEN_ERRNO_RTX;
1624 #else
1625 rtx errno_rtx
1626 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1627 #endif
1628 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1629 emit_label (lab);
1630 return;
1632 #endif
1634 /* We can't set errno=EDOM directly; let the library call do it.
1635 Pop the arguments right away in case the call gets deleted. */
1636 NO_DEFER_POP;
1637 expand_call (exp, target, 0);
1638 OK_DEFER_POP;
1639 emit_label (lab);
1643 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1644 Return 0 if a normal call should be emitted rather than expanding the
1645 function in-line. EXP is the expression that is a call to the builtin
1646 function; if convenient, the result should be placed in TARGET.
1647 SUBTARGET may be used as the target for computing one of EXP's operands. */
1649 static rtx
1650 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1652 optab builtin_optab;
1653 rtx op0, insns, before_call;
1654 tree fndecl = get_callee_fndecl (exp);
1655 tree arglist = TREE_OPERAND (exp, 1);
1656 enum machine_mode mode;
1657 bool errno_set = false;
1658 tree arg, narg;
1660 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1661 return 0;
1663 arg = TREE_VALUE (arglist);
1665 switch (DECL_FUNCTION_CODE (fndecl))
1667 case BUILT_IN_SQRT:
1668 case BUILT_IN_SQRTF:
1669 case BUILT_IN_SQRTL:
1670 errno_set = ! tree_expr_nonnegative_p (arg);
1671 builtin_optab = sqrt_optab;
1672 break;
1673 case BUILT_IN_EXP:
1674 case BUILT_IN_EXPF:
1675 case BUILT_IN_EXPL:
1676 errno_set = true; builtin_optab = exp_optab; break;
1677 case BUILT_IN_EXP10:
1678 case BUILT_IN_EXP10F:
1679 case BUILT_IN_EXP10L:
1680 case BUILT_IN_POW10:
1681 case BUILT_IN_POW10F:
1682 case BUILT_IN_POW10L:
1683 errno_set = true; builtin_optab = exp10_optab; break;
1684 case BUILT_IN_EXP2:
1685 case BUILT_IN_EXP2F:
1686 case BUILT_IN_EXP2L:
1687 errno_set = true; builtin_optab = exp2_optab; break;
1688 case BUILT_IN_EXPM1:
1689 case BUILT_IN_EXPM1F:
1690 case BUILT_IN_EXPM1L:
1691 errno_set = true; builtin_optab = expm1_optab; break;
1692 case BUILT_IN_LOGB:
1693 case BUILT_IN_LOGBF:
1694 case BUILT_IN_LOGBL:
1695 errno_set = true; builtin_optab = logb_optab; break;
1696 case BUILT_IN_ILOGB:
1697 case BUILT_IN_ILOGBF:
1698 case BUILT_IN_ILOGBL:
1699 errno_set = true; builtin_optab = ilogb_optab; break;
1700 case BUILT_IN_LOG:
1701 case BUILT_IN_LOGF:
1702 case BUILT_IN_LOGL:
1703 errno_set = true; builtin_optab = log_optab; break;
1704 case BUILT_IN_LOG10:
1705 case BUILT_IN_LOG10F:
1706 case BUILT_IN_LOG10L:
1707 errno_set = true; builtin_optab = log10_optab; break;
1708 case BUILT_IN_LOG2:
1709 case BUILT_IN_LOG2F:
1710 case BUILT_IN_LOG2L:
1711 errno_set = true; builtin_optab = log2_optab; break;
1712 case BUILT_IN_LOG1P:
1713 case BUILT_IN_LOG1PF:
1714 case BUILT_IN_LOG1PL:
1715 errno_set = true; builtin_optab = log1p_optab; break;
1716 case BUILT_IN_ASIN:
1717 case BUILT_IN_ASINF:
1718 case BUILT_IN_ASINL:
1719 builtin_optab = asin_optab; break;
1720 case BUILT_IN_ACOS:
1721 case BUILT_IN_ACOSF:
1722 case BUILT_IN_ACOSL:
1723 builtin_optab = acos_optab; break;
1724 case BUILT_IN_TAN:
1725 case BUILT_IN_TANF:
1726 case BUILT_IN_TANL:
1727 builtin_optab = tan_optab; break;
1728 case BUILT_IN_ATAN:
1729 case BUILT_IN_ATANF:
1730 case BUILT_IN_ATANL:
1731 builtin_optab = atan_optab; break;
1732 case BUILT_IN_FLOOR:
1733 case BUILT_IN_FLOORF:
1734 case BUILT_IN_FLOORL:
1735 builtin_optab = floor_optab; break;
1736 case BUILT_IN_CEIL:
1737 case BUILT_IN_CEILF:
1738 case BUILT_IN_CEILL:
1739 builtin_optab = ceil_optab; break;
1740 case BUILT_IN_TRUNC:
1741 case BUILT_IN_TRUNCF:
1742 case BUILT_IN_TRUNCL:
1743 builtin_optab = btrunc_optab; break;
1744 case BUILT_IN_ROUND:
1745 case BUILT_IN_ROUNDF:
1746 case BUILT_IN_ROUNDL:
1747 builtin_optab = round_optab; break;
1748 case BUILT_IN_NEARBYINT:
1749 case BUILT_IN_NEARBYINTF:
1750 case BUILT_IN_NEARBYINTL:
1751 builtin_optab = nearbyint_optab; break;
1752 default:
1753 abort ();
1756 /* Make a suitable register to place result in. */
1757 mode = TYPE_MODE (TREE_TYPE (exp));
1759 if (! flag_errno_math || ! HONOR_NANS (mode))
1760 errno_set = false;
1762 /* Before working hard, check whether the instruction is available. */
1763 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1765 target = gen_reg_rtx (mode);
1767 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1768 need to expand the argument again. This way, we will not perform
1769 side-effects more the once. */
1770 narg = builtin_save_expr (arg);
1771 if (narg != arg)
1773 arglist = build_tree_list (NULL_TREE, arg);
1774 exp = build_function_call_expr (fndecl, arglist);
1777 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1779 emit_queue ();
1780 start_sequence ();
1782 /* Compute into TARGET.
1783 Set TARGET to wherever the result comes back. */
1784 target = expand_unop (mode, builtin_optab, op0, target, 0);
1786 if (target != 0)
1788 if (errno_set)
1789 expand_errno_check (exp, target);
1791 /* Output the entire sequence. */
1792 insns = get_insns ();
1793 end_sequence ();
1794 emit_insn (insns);
1795 return target;
1798 /* If we were unable to expand via the builtin, stop the sequence
1799 (without outputting the insns) and call to the library function
1800 with the stabilized argument list. */
1801 end_sequence ();
1804 before_call = get_last_insn ();
1806 target = expand_call (exp, target, target == const0_rtx);
1808 /* If this is a sqrt operation and we don't care about errno, try to
1809 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1810 This allows the semantics of the libcall to be visible to the RTL
1811 optimizers. */
1812 if (builtin_optab == sqrt_optab && !errno_set)
1814 /* Search backwards through the insns emitted by expand_call looking
1815 for the instruction with the REG_RETVAL note. */
1816 rtx last = get_last_insn ();
1817 while (last != before_call)
1819 if (find_reg_note (last, REG_RETVAL, NULL))
1821 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1822 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1823 two elements, i.e. symbol_ref(sqrt) and the operand. */
1824 if (note
1825 && GET_CODE (note) == EXPR_LIST
1826 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1827 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1828 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1830 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1831 /* Check operand is a register with expected mode. */
1832 if (operand
1833 && REG_P (operand)
1834 && GET_MODE (operand) == mode)
1836 /* Replace the REG_EQUAL note with a SQRT rtx. */
1837 rtx equiv = gen_rtx_SQRT (mode, operand);
1838 set_unique_reg_note (last, REG_EQUAL, equiv);
1841 break;
1843 last = PREV_INSN (last);
1847 return target;
1850 /* Expand a call to the builtin binary math functions (pow and atan2).
1851 Return 0 if a normal call should be emitted rather than expanding the
1852 function in-line. EXP is the expression that is a call to the builtin
1853 function; if convenient, the result should be placed in TARGET.
1854 SUBTARGET may be used as the target for computing one of EXP's
1855 operands. */
1857 static rtx
1858 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1860 optab builtin_optab;
1861 rtx op0, op1, insns;
1862 tree fndecl = get_callee_fndecl (exp);
1863 tree arglist = TREE_OPERAND (exp, 1);
1864 tree arg0, arg1, temp, narg;
1865 enum machine_mode mode;
1866 bool errno_set = true;
1867 bool stable = true;
1869 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1870 return 0;
1872 arg0 = TREE_VALUE (arglist);
1873 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1875 switch (DECL_FUNCTION_CODE (fndecl))
1877 case BUILT_IN_POW:
1878 case BUILT_IN_POWF:
1879 case BUILT_IN_POWL:
1880 builtin_optab = pow_optab; break;
1881 case BUILT_IN_ATAN2:
1882 case BUILT_IN_ATAN2F:
1883 case BUILT_IN_ATAN2L:
1884 builtin_optab = atan2_optab; break;
1885 case BUILT_IN_FMOD:
1886 case BUILT_IN_FMODF:
1887 case BUILT_IN_FMODL:
1888 builtin_optab = fmod_optab; break;
1889 case BUILT_IN_DREM:
1890 case BUILT_IN_DREMF:
1891 case BUILT_IN_DREML:
1892 builtin_optab = drem_optab; break;
1893 default:
1894 abort ();
1897 /* Make a suitable register to place result in. */
1898 mode = TYPE_MODE (TREE_TYPE (exp));
1900 /* Before working hard, check whether the instruction is available. */
1901 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1902 return 0;
1904 target = gen_reg_rtx (mode);
1906 if (! flag_errno_math || ! HONOR_NANS (mode))
1907 errno_set = false;
1909 /* Always stabilize the argument list. */
1910 narg = builtin_save_expr (arg1);
1911 if (narg != arg1)
1913 temp = build_tree_list (NULL_TREE, narg);
1914 stable = false;
1916 else
1917 temp = TREE_CHAIN (arglist);
1919 narg = builtin_save_expr (arg0);
1920 if (narg != arg0)
1922 arglist = tree_cons (NULL_TREE, narg, temp);
1923 stable = false;
1925 else if (! stable)
1926 arglist = tree_cons (NULL_TREE, arg0, temp);
1928 if (! stable)
1929 exp = build_function_call_expr (fndecl, arglist);
1931 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1932 op1 = expand_expr (arg1, 0, VOIDmode, 0);
1934 emit_queue ();
1935 start_sequence ();
1937 /* Compute into TARGET.
1938 Set TARGET to wherever the result comes back. */
1939 target = expand_binop (mode, builtin_optab, op0, op1,
1940 target, 0, OPTAB_DIRECT);
1942 /* If we were unable to expand via the builtin, stop the sequence
1943 (without outputting the insns) and call to the library function
1944 with the stabilized argument list. */
1945 if (target == 0)
1947 end_sequence ();
1948 return expand_call (exp, target, target == const0_rtx);
1951 if (errno_set)
1952 expand_errno_check (exp, target);
1954 /* Output the entire sequence. */
1955 insns = get_insns ();
1956 end_sequence ();
1957 emit_insn (insns);
1959 return target;
1962 /* Expand a call to the builtin sin and cos math functions.
1963 Return 0 if a normal call should be emitted rather than expanding the
1964 function in-line. EXP is the expression that is a call to the builtin
1965 function; if convenient, the result should be placed in TARGET.
1966 SUBTARGET may be used as the target for computing one of EXP's
1967 operands. */
1969 static rtx
1970 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1972 optab builtin_optab;
1973 rtx op0, insns, before_call;
1974 tree fndecl = get_callee_fndecl (exp);
1975 tree arglist = TREE_OPERAND (exp, 1);
1976 enum machine_mode mode;
1977 bool errno_set = false;
1978 tree arg, narg;
1980 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1981 return 0;
1983 arg = TREE_VALUE (arglist);
1985 switch (DECL_FUNCTION_CODE (fndecl))
1987 case BUILT_IN_SIN:
1988 case BUILT_IN_SINF:
1989 case BUILT_IN_SINL:
1990 case BUILT_IN_COS:
1991 case BUILT_IN_COSF:
1992 case BUILT_IN_COSL:
1993 builtin_optab = sincos_optab; break;
1994 default:
1995 abort ();
1998 /* Make a suitable register to place result in. */
1999 mode = TYPE_MODE (TREE_TYPE (exp));
2001 if (! flag_errno_math || ! HONOR_NANS (mode))
2002 errno_set = false;
2004 /* Check if sincos insn is available, otherwise fallback
2005 to sin or cos insn. */
2006 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2007 switch (DECL_FUNCTION_CODE (fndecl))
2009 case BUILT_IN_SIN:
2010 case BUILT_IN_SINF:
2011 case BUILT_IN_SINL:
2012 builtin_optab = sin_optab; break;
2013 case BUILT_IN_COS:
2014 case BUILT_IN_COSF:
2015 case BUILT_IN_COSL:
2016 builtin_optab = cos_optab; break;
2017 default:
2018 abort();
2022 /* Before working hard, check whether the instruction is available. */
2023 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2025 target = gen_reg_rtx (mode);
2027 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2028 need to expand the argument again. This way, we will not perform
2029 side-effects more the once. */
2030 narg = save_expr (arg);
2031 if (narg != arg)
2033 arglist = build_tree_list (NULL_TREE, arg);
2034 exp = build_function_call_expr (fndecl, arglist);
2037 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2039 emit_queue ();
2040 start_sequence ();
2042 /* Compute into TARGET.
2043 Set TARGET to wherever the result comes back. */
2044 if (builtin_optab == sincos_optab)
2046 switch (DECL_FUNCTION_CODE (fndecl))
2048 case BUILT_IN_SIN:
2049 case BUILT_IN_SINF:
2050 case BUILT_IN_SINL:
2051 if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
2052 abort();
2053 break;
2054 case BUILT_IN_COS:
2055 case BUILT_IN_COSF:
2056 case BUILT_IN_COSL:
2057 if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2058 abort();
2059 break;
2060 default:
2061 abort();
2064 else
2066 target = expand_unop (mode, builtin_optab, op0, target, 0);
2069 if (target != 0)
2071 if (errno_set)
2072 expand_errno_check (exp, target);
2074 /* Output the entire sequence. */
2075 insns = get_insns ();
2076 end_sequence ();
2077 emit_insn (insns);
2078 return target;
2081 /* If we were unable to expand via the builtin, stop the sequence
2082 (without outputting the insns) and call to the library function
2083 with the stabilized argument list. */
2084 end_sequence ();
2087 before_call = get_last_insn ();
2089 target = expand_call (exp, target, target == const0_rtx);
2091 return target;
2094 /* To evaluate powi(x,n), the floating point value x raised to the
2095 constant integer exponent n, we use a hybrid algorithm that
2096 combines the "window method" with look-up tables. For an
2097 introduction to exponentiation algorithms and "addition chains",
2098 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2099 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2100 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2101 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2103 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2104 multiplications to inline before calling the system library's pow
2105 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2106 so this default never requires calling pow, powf or powl. */
2108 #ifndef POWI_MAX_MULTS
2109 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2110 #endif
2112 /* The size of the "optimal power tree" lookup table. All
2113 exponents less than this value are simply looked up in the
2114 powi_table below. This threshold is also used to size the
2115 cache of pseudo registers that hold intermediate results. */
2116 #define POWI_TABLE_SIZE 256
2118 /* The size, in bits of the window, used in the "window method"
2119 exponentiation algorithm. This is equivalent to a radix of
2120 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2121 #define POWI_WINDOW_SIZE 3
2123 /* The following table is an efficient representation of an
2124 "optimal power tree". For each value, i, the corresponding
2125 value, j, in the table states than an optimal evaluation
2126 sequence for calculating pow(x,i) can be found by evaluating
2127 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2128 100 integers is given in Knuth's "Seminumerical algorithms". */
2130 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2132 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2133 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2134 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2135 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2136 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2137 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2138 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2139 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2140 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2141 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2142 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2143 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2144 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2145 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2146 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2147 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2148 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2149 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2150 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2151 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2152 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2153 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2154 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2155 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2156 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2157 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2158 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2159 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2160 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2161 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2162 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2163 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2167 /* Return the number of multiplications required to calculate
2168 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2169 subroutine of powi_cost. CACHE is an array indicating
2170 which exponents have already been calculated. */
2172 static int
2173 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2175 /* If we've already calculated this exponent, then this evaluation
2176 doesn't require any additional multiplications. */
2177 if (cache[n])
2178 return 0;
2180 cache[n] = true;
2181 return powi_lookup_cost (n - powi_table[n], cache)
2182 + powi_lookup_cost (powi_table[n], cache) + 1;
2185 /* Return the number of multiplications required to calculate
2186 powi(x,n) for an arbitrary x, given the exponent N. This
2187 function needs to be kept in sync with expand_powi below. */
2189 static int
2190 powi_cost (HOST_WIDE_INT n)
2192 bool cache[POWI_TABLE_SIZE];
2193 unsigned HOST_WIDE_INT digit;
2194 unsigned HOST_WIDE_INT val;
2195 int result;
2197 if (n == 0)
2198 return 0;
2200 /* Ignore the reciprocal when calculating the cost. */
2201 val = (n < 0) ? -n : n;
2203 /* Initialize the exponent cache. */
2204 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2205 cache[1] = true;
2207 result = 0;
2209 while (val >= POWI_TABLE_SIZE)
2211 if (val & 1)
2213 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2214 result += powi_lookup_cost (digit, cache)
2215 + POWI_WINDOW_SIZE + 1;
2216 val >>= POWI_WINDOW_SIZE;
2218 else
2220 val >>= 1;
2221 result++;
2225 return result + powi_lookup_cost (val, cache);
2228 /* Recursive subroutine of expand_powi. This function takes the array,
2229 CACHE, of already calculated exponents and an exponent N and returns
2230 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2232 static rtx
2233 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2235 unsigned HOST_WIDE_INT digit;
2236 rtx target, result;
2237 rtx op0, op1;
2239 if (n < POWI_TABLE_SIZE)
2241 if (cache[n])
2242 return cache[n];
2244 target = gen_reg_rtx (mode);
2245 cache[n] = target;
2247 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2248 op1 = expand_powi_1 (mode, powi_table[n], cache);
2250 else if (n & 1)
2252 target = gen_reg_rtx (mode);
2253 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2254 op0 = expand_powi_1 (mode, n - digit, cache);
2255 op1 = expand_powi_1 (mode, digit, cache);
2257 else
2259 target = gen_reg_rtx (mode);
2260 op0 = expand_powi_1 (mode, n >> 1, cache);
2261 op1 = op0;
2264 result = expand_mult (mode, op0, op1, target, 0);
2265 if (result != target)
2266 emit_move_insn (target, result);
2267 return target;
2270 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2271 floating point operand in mode MODE, and N is the exponent. This
2272 function needs to be kept in sync with powi_cost above. */
2274 static rtx
2275 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2277 unsigned HOST_WIDE_INT val;
2278 rtx cache[POWI_TABLE_SIZE];
2279 rtx result;
2281 if (n == 0)
2282 return CONST1_RTX (mode);
2284 val = (n < 0) ? -n : n;
2286 memset (cache, 0, sizeof (cache));
2287 cache[1] = x;
2289 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2291 /* If the original exponent was negative, reciprocate the result. */
2292 if (n < 0)
2293 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2294 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2296 return result;
2299 /* Expand a call to the pow built-in mathematical function. Return 0 if
2300 a normal call should be emitted rather than expanding the function
2301 in-line. EXP is the expression that is a call to the builtin
2302 function; if convenient, the result should be placed in TARGET. */
2304 static rtx
2305 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2307 tree arglist = TREE_OPERAND (exp, 1);
2308 tree arg0, arg1;
2310 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2311 return 0;
2313 arg0 = TREE_VALUE (arglist);
2314 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2316 if (TREE_CODE (arg1) == REAL_CST
2317 && ! TREE_CONSTANT_OVERFLOW (arg1))
2319 REAL_VALUE_TYPE cint;
2320 REAL_VALUE_TYPE c;
2321 HOST_WIDE_INT n;
2323 c = TREE_REAL_CST (arg1);
2324 n = real_to_integer (&c);
2325 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2326 if (real_identical (&c, &cint))
2328 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2329 Otherwise, check the number of multiplications required.
2330 Note that pow never sets errno for an integer exponent. */
2331 if ((n >= -1 && n <= 2)
2332 || (flag_unsafe_math_optimizations
2333 && ! optimize_size
2334 && powi_cost (n) <= POWI_MAX_MULTS))
2336 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2337 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2338 op = force_reg (mode, op);
2339 return expand_powi (op, mode, n);
2344 if (! flag_unsafe_math_optimizations)
2345 return NULL_RTX;
2346 return expand_builtin_mathfn_2 (exp, target, subtarget);
2349 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2350 if we failed the caller should emit a normal call, otherwise
2351 try to get the result in TARGET, if convenient. */
2353 static rtx
2354 expand_builtin_strlen (tree arglist, rtx target,
2355 enum machine_mode target_mode)
2357 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2358 return 0;
2359 else
2361 rtx pat;
2362 tree len, src = TREE_VALUE (arglist);
2363 rtx result, src_reg, char_rtx, before_strlen;
2364 enum machine_mode insn_mode = target_mode, char_mode;
2365 enum insn_code icode = CODE_FOR_nothing;
2366 int align;
2368 /* If the length can be computed at compile-time, return it. */
2369 len = c_strlen (src, 0);
2370 if (len)
2371 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2373 /* If the length can be computed at compile-time and is constant
2374 integer, but there are side-effects in src, evaluate
2375 src for side-effects, then return len.
2376 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2377 can be optimized into: i++; x = 3; */
2378 len = c_strlen (src, 1);
2379 if (len && TREE_CODE (len) == INTEGER_CST)
2381 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2382 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2385 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2387 /* If SRC is not a pointer type, don't do this operation inline. */
2388 if (align == 0)
2389 return 0;
2391 /* Bail out if we can't compute strlen in the right mode. */
2392 while (insn_mode != VOIDmode)
2394 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2395 if (icode != CODE_FOR_nothing)
2396 break;
2398 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2400 if (insn_mode == VOIDmode)
2401 return 0;
2403 /* Make a place to write the result of the instruction. */
2404 result = target;
2405 if (! (result != 0
2406 && REG_P (result)
2407 && GET_MODE (result) == insn_mode
2408 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2409 result = gen_reg_rtx (insn_mode);
2411 /* Make a place to hold the source address. We will not expand
2412 the actual source until we are sure that the expansion will
2413 not fail -- there are trees that cannot be expanded twice. */
2414 src_reg = gen_reg_rtx (Pmode);
2416 /* Mark the beginning of the strlen sequence so we can emit the
2417 source operand later. */
2418 before_strlen = get_last_insn ();
2420 char_rtx = const0_rtx;
2421 char_mode = insn_data[(int) icode].operand[2].mode;
2422 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2423 char_mode))
2424 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2426 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2427 char_rtx, GEN_INT (align));
2428 if (! pat)
2429 return 0;
2430 emit_insn (pat);
2432 /* Now that we are assured of success, expand the source. */
2433 start_sequence ();
2434 pat = memory_address (BLKmode,
2435 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2436 if (pat != src_reg)
2437 emit_move_insn (src_reg, pat);
2438 pat = get_insns ();
2439 end_sequence ();
2441 if (before_strlen)
2442 emit_insn_after (pat, before_strlen);
2443 else
2444 emit_insn_before (pat, get_insns ());
2446 /* Return the value in the proper mode for this function. */
2447 if (GET_MODE (result) == target_mode)
2448 target = result;
2449 else if (target != 0)
2450 convert_move (target, result, 0);
2451 else
2452 target = convert_to_mode (target_mode, result, 0);
2454 return target;
2458 /* Expand a call to the strstr builtin. Return 0 if we failed the
2459 caller should emit a normal call, otherwise try to get the result
2460 in TARGET, if convenient (and in mode MODE if that's convenient). */
2462 static rtx
2463 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2465 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2466 return 0;
2467 else
2469 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2470 tree fn, tmp;
2471 const char *p1, *p2;
2473 p2 = c_getstr (s2);
2474 if (p2 == NULL)
2475 return 0;
2477 p1 = c_getstr (s1);
2478 if (p1 != NULL)
2480 const char *r = strstr (p1, p2);
2482 if (r == NULL)
2483 return const0_rtx;
2485 /* Return an offset into the constant string argument. */
2486 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2487 fold_convert (TREE_TYPE (s1),
2488 ssize_int (r - p1))));
2489 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2492 if (p2[0] == '\0')
2493 return expand_expr (s1, target, mode, EXPAND_NORMAL);
2495 if (p2[1] != '\0')
2496 return 0;
2498 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2499 if (!fn)
2500 return 0;
2502 /* New argument list transforming strstr(s1, s2) to
2503 strchr(s1, s2[0]). */
2504 arglist =
2505 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2506 arglist = tree_cons (NULL_TREE, s1, arglist);
2507 return expand_expr (build_function_call_expr (fn, arglist),
2508 target, mode, EXPAND_NORMAL);
2512 /* Expand a call to the strchr builtin. Return 0 if we failed the
2513 caller should emit a normal call, otherwise try to get the result
2514 in TARGET, if convenient (and in mode MODE if that's convenient). */
2516 static rtx
2517 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2519 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2520 return 0;
2521 else
2523 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2524 const char *p1;
2526 if (TREE_CODE (s2) != INTEGER_CST)
2527 return 0;
2529 p1 = c_getstr (s1);
2530 if (p1 != NULL)
2532 char c;
2533 const char *r;
2534 tree tmp;
2536 if (target_char_cast (s2, &c))
2537 return 0;
2539 r = strchr (p1, c);
2541 if (r == NULL)
2542 return const0_rtx;
2544 /* Return an offset into the constant string argument. */
2545 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2546 fold_convert (TREE_TYPE (s1),
2547 ssize_int (r - p1))));
2548 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2551 /* FIXME: Should use here strchrM optab so that ports can optimize
2552 this. */
2553 return 0;
2557 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2558 caller should emit a normal call, otherwise try to get the result
2559 in TARGET, if convenient (and in mode MODE if that's convenient). */
2561 static rtx
2562 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2564 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2565 return 0;
2566 else
2568 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2569 tree fn, tmp;
2570 const char *p1;
2572 if (TREE_CODE (s2) != INTEGER_CST)
2573 return 0;
2575 p1 = c_getstr (s1);
2576 if (p1 != NULL)
2578 char c;
2579 const char *r;
2581 if (target_char_cast (s2, &c))
2582 return 0;
2584 r = strrchr (p1, c);
2586 if (r == NULL)
2587 return const0_rtx;
2589 /* Return an offset into the constant string argument. */
2590 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2591 fold_convert (TREE_TYPE (s1),
2592 ssize_int (r - p1))));
2593 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2596 if (! integer_zerop (s2))
2597 return 0;
2599 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2600 if (!fn)
2601 return 0;
2603 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2604 return expand_expr (build_function_call_expr (fn, arglist),
2605 target, mode, EXPAND_NORMAL);
2609 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2610 caller should emit a normal call, otherwise try to get the result
2611 in TARGET, if convenient (and in mode MODE if that's convenient). */
2613 static rtx
2614 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2616 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2617 return 0;
2618 else
2620 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2621 tree fn, tmp;
2622 const char *p1, *p2;
2624 p2 = c_getstr (s2);
2625 if (p2 == NULL)
2626 return 0;
2628 p1 = c_getstr (s1);
2629 if (p1 != NULL)
2631 const char *r = strpbrk (p1, p2);
2633 if (r == NULL)
2634 return const0_rtx;
2636 /* Return an offset into the constant string argument. */
2637 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2638 fold_convert (TREE_TYPE (s1),
2639 ssize_int (r - p1))));
2640 return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2643 if (p2[0] == '\0')
2645 /* strpbrk(x, "") == NULL.
2646 Evaluate and ignore the arguments in case they had
2647 side-effects. */
2648 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2649 return const0_rtx;
2652 if (p2[1] != '\0')
2653 return 0; /* Really call strpbrk. */
2655 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2656 if (!fn)
2657 return 0;
2659 /* New argument list transforming strpbrk(s1, s2) to
2660 strchr(s1, s2[0]). */
2661 arglist =
2662 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2663 arglist = tree_cons (NULL_TREE, s1, arglist);
2664 return expand_expr (build_function_call_expr (fn, arglist),
2665 target, mode, EXPAND_NORMAL);
2669 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2670 bytes from constant string DATA + OFFSET and return it as target
2671 constant. */
2673 static rtx
2674 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2675 enum machine_mode mode)
2677 const char *str = (const char *) data;
2679 if (offset < 0
2680 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2681 > strlen (str) + 1))
2682 abort (); /* Attempt to read past the end of constant string. */
2684 return c_readstr (str + offset, mode);
2687 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2688 Return 0 if we failed, the caller should emit a normal call,
2689 otherwise try to get the result in TARGET, if convenient (and in
2690 mode MODE if that's convenient). */
2691 static rtx
2692 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2694 if (!validate_arglist (arglist,
2695 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2696 return 0;
2697 else
2699 tree dest = TREE_VALUE (arglist);
2700 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2701 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2702 const char *src_str;
2703 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2704 unsigned int dest_align
2705 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2706 rtx dest_mem, src_mem, dest_addr, len_rtx;
2708 /* If DEST is not a pointer type, call the normal function. */
2709 if (dest_align == 0)
2710 return 0;
2712 /* If the LEN parameter is zero, return DEST. */
2713 if (integer_zerop (len))
2715 /* Evaluate and ignore SRC in case it has side-effects. */
2716 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2717 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2720 /* If SRC and DEST are the same (and not volatile), return DEST. */
2721 if (operand_equal_p (src, dest, 0))
2723 /* Evaluate and ignore LEN in case it has side-effects. */
2724 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2725 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2728 /* If either SRC is not a pointer type, don't do this
2729 operation in-line. */
2730 if (src_align == 0)
2731 return 0;
2733 dest_mem = get_memory_rtx (dest);
2734 set_mem_align (dest_mem, dest_align);
2735 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2736 src_str = c_getstr (src);
2738 /* If SRC is a string constant and block move would be done
2739 by pieces, we can avoid loading the string from memory
2740 and only stored the computed constants. */
2741 if (src_str
2742 && GET_CODE (len_rtx) == CONST_INT
2743 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2744 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2745 (void *) src_str, dest_align))
2747 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2748 builtin_memcpy_read_str,
2749 (void *) src_str, dest_align, 0);
2750 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2751 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2752 return dest_mem;
2755 src_mem = get_memory_rtx (src);
2756 set_mem_align (src_mem, src_align);
2758 /* Copy word part most expediently. */
2759 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2760 BLOCK_OP_NORMAL);
2762 if (dest_addr == 0)
2764 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2765 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2767 return dest_addr;
2771 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2772 Return 0 if we failed the caller should emit a normal call,
2773 otherwise try to get the result in TARGET, if convenient (and in
2774 mode MODE if that's convenient). If ENDP is 0 return the
2775 destination pointer, if ENDP is 1 return the end pointer ala
2776 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2777 stpcpy. */
2779 static rtx
2780 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2781 int endp)
2783 if (!validate_arglist (arglist,
2784 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2785 return 0;
2786 /* If return value is ignored, transform mempcpy into memcpy. */
2787 else if (target == const0_rtx)
2789 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2791 if (!fn)
2792 return 0;
2794 return expand_expr (build_function_call_expr (fn, arglist),
2795 target, mode, EXPAND_NORMAL);
2797 else
2799 tree dest = TREE_VALUE (arglist);
2800 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2801 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2802 const char *src_str;
2803 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2804 unsigned int dest_align
2805 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2806 rtx dest_mem, src_mem, len_rtx;
2808 /* If DEST is not a pointer type, call the normal function. */
2809 if (dest_align == 0)
2810 return 0;
2812 /* If SRC and DEST are the same (and not volatile), do nothing. */
2813 if (operand_equal_p (src, dest, 0))
2815 tree expr;
2817 if (endp == 0)
2819 /* Evaluate and ignore LEN in case it has side-effects. */
2820 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2821 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2824 if (endp == 2)
2825 len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2826 integer_one_node));
2827 len = fold_convert (TREE_TYPE (dest), len);
2828 expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2829 return expand_expr (expr, target, mode, EXPAND_NORMAL);
2832 /* If LEN is not constant, call the normal function. */
2833 if (! host_integerp (len, 1))
2834 return 0;
2836 /* If the LEN parameter is zero, return DEST. */
2837 if (tree_low_cst (len, 1) == 0)
2839 /* Evaluate and ignore SRC in case it has side-effects. */
2840 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2841 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2844 /* If either SRC is not a pointer type, don't do this
2845 operation in-line. */
2846 if (src_align == 0)
2847 return 0;
2849 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2850 src_str = c_getstr (src);
2852 /* If SRC is a string constant and block move would be done
2853 by pieces, we can avoid loading the string from memory
2854 and only stored the computed constants. */
2855 if (src_str
2856 && GET_CODE (len_rtx) == CONST_INT
2857 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2858 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2859 (void *) src_str, dest_align))
2861 dest_mem = get_memory_rtx (dest);
2862 set_mem_align (dest_mem, dest_align);
2863 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2864 builtin_memcpy_read_str,
2865 (void *) src_str, dest_align, endp);
2866 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2867 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2868 return dest_mem;
2871 if (GET_CODE (len_rtx) == CONST_INT
2872 && can_move_by_pieces (INTVAL (len_rtx),
2873 MIN (dest_align, src_align)))
2875 dest_mem = get_memory_rtx (dest);
2876 set_mem_align (dest_mem, dest_align);
2877 src_mem = get_memory_rtx (src);
2878 set_mem_align (src_mem, src_align);
2879 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2880 MIN (dest_align, src_align), endp);
2881 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2882 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2883 return dest_mem;
2886 return 0;
2890 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2891 if we failed the caller should emit a normal call. */
2893 static rtx
2894 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2896 if (!validate_arglist (arglist,
2897 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2898 return 0;
2899 else
2901 tree dest = TREE_VALUE (arglist);
2902 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2903 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2905 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2906 unsigned int dest_align
2907 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2909 /* If DEST is not a pointer type, call the normal function. */
2910 if (dest_align == 0)
2911 return 0;
2913 /* If the LEN parameter is zero, return DEST. */
2914 if (integer_zerop (len))
2916 /* Evaluate and ignore SRC in case it has side-effects. */
2917 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2918 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2921 /* If SRC and DEST are the same (and not volatile), return DEST. */
2922 if (operand_equal_p (src, dest, 0))
2924 /* Evaluate and ignore LEN in case it has side-effects. */
2925 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2926 return expand_expr (dest, target, mode, EXPAND_NORMAL);
2929 /* If either SRC is not a pointer type, don't do this
2930 operation in-line. */
2931 if (src_align == 0)
2932 return 0;
2934 /* If src is categorized for a readonly section we can use
2935 normal memcpy. */
2936 if (readonly_data_expr (src))
2938 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2939 if (!fn)
2940 return 0;
2941 return expand_expr (build_function_call_expr (fn, arglist),
2942 target, mode, EXPAND_NORMAL);
2945 /* Otherwise, call the normal function. */
2946 return 0;
2950 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2951 if we failed the caller should emit a normal call. */
2953 static rtx
2954 expand_builtin_bcopy (tree arglist)
2956 tree src, dest, size, newarglist;
2958 if (!validate_arglist (arglist,
2959 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2960 return NULL_RTX;
2962 src = TREE_VALUE (arglist);
2963 dest = TREE_VALUE (TREE_CHAIN (arglist));
2964 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2966 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2967 memmove(ptr y, ptr x, size_t z). This is done this way
2968 so that if it isn't expanded inline, we fallback to
2969 calling bcopy instead of memmove. */
2971 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2972 newarglist = tree_cons (NULL_TREE, src, newarglist);
2973 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2975 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2978 #ifndef HAVE_movstr
2979 # define HAVE_movstr 0
2980 # define CODE_FOR_movstr CODE_FOR_nothing
2981 #endif
2983 /* Expand into a movstr instruction, if one is available. Return 0 if
2984 we failed, the caller should emit a normal call, otherwise try to
2985 get the result in TARGET, if convenient. If ENDP is 0 return the
2986 destination pointer, if ENDP is 1 return the end pointer ala
2987 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2988 stpcpy. */
2990 static rtx
2991 expand_movstr (tree dest, tree src, rtx target, int endp)
2993 rtx end;
2994 rtx dest_mem;
2995 rtx src_mem;
2996 rtx insn;
2997 const struct insn_data * data;
2999 if (!HAVE_movstr)
3000 return 0;
3002 dest_mem = get_memory_rtx (dest);
3003 src_mem = get_memory_rtx (src);
3004 if (!endp)
3006 target = force_reg (Pmode, XEXP (dest_mem, 0));
3007 dest_mem = replace_equiv_address (dest_mem, target);
3008 end = gen_reg_rtx (Pmode);
3010 else
3012 if (target == 0 || target == const0_rtx)
3014 end = gen_reg_rtx (Pmode);
3015 if (target == 0)
3016 target = end;
3018 else
3019 end = target;
3022 data = insn_data + CODE_FOR_movstr;
3024 if (data->operand[0].mode != VOIDmode)
3025 end = gen_lowpart (data->operand[0].mode, end);
3027 insn = data->genfun (end, dest_mem, src_mem);
3029 if (insn == 0)
3030 abort ();
3032 emit_insn (insn);
3034 /* movstr is supposed to set end to the address of the NUL
3035 terminator. If the caller requested a mempcpy-like return value,
3036 adjust it. */
3037 if (endp == 1 && target != const0_rtx)
3038 emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3039 end), 1));
3041 return target;
3044 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3045 if we failed the caller should emit a normal call, otherwise try to get
3046 the result in TARGET, if convenient (and in mode MODE if that's
3047 convenient). */
3049 static rtx
3050 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3052 tree fn, len, src, dst;
3054 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3055 return 0;
3057 src = TREE_VALUE (TREE_CHAIN (arglist));
3058 dst = TREE_VALUE (arglist);
3060 /* If SRC and DST are equal (and not volatile), return DST. */
3061 if (operand_equal_p (src, dst, 0))
3062 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3064 len = c_strlen (src, 1);
3065 if (len == 0 || TREE_SIDE_EFFECTS (len))
3066 return expand_movstr (TREE_VALUE (arglist),
3067 TREE_VALUE (TREE_CHAIN (arglist)),
3068 target, /*endp=*/0);
3070 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3071 if (!fn)
3072 return 0;
3074 len = size_binop (PLUS_EXPR, len, ssize_int (1));
3075 arglist = build_tree_list (NULL_TREE, len);
3076 arglist = tree_cons (NULL_TREE, src, arglist);
3077 arglist = tree_cons (NULL_TREE, dst, arglist);
3078 return expand_expr (build_function_call_expr (fn, arglist),
3079 target, mode, EXPAND_NORMAL);
3082 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3083 Return 0 if we failed the caller should emit a normal call,
3084 otherwise try to get the result in TARGET, if convenient (and in
3085 mode MODE if that's convenient). */
3087 static rtx
3088 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3090 /* If return value is ignored, transform stpcpy into strcpy. */
3091 if (target == const0_rtx)
3093 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3094 if (!fn)
3095 return 0;
3097 return expand_expr (build_function_call_expr (fn, arglist),
3098 target, mode, EXPAND_NORMAL);
3101 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3102 return 0;
3103 else
3105 tree dst, src, len, lenp1;
3106 tree narglist;
3107 rtx ret;
3109 /* Ensure we get an actual string whose length can be evaluated at
3110 compile-time, not an expression containing a string. This is
3111 because the latter will potentially produce pessimized code
3112 when used to produce the return value. */
3113 src = TREE_VALUE (TREE_CHAIN (arglist));
3114 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3115 return expand_movstr (TREE_VALUE (arglist),
3116 TREE_VALUE (TREE_CHAIN (arglist)),
3117 target, /*endp=*/2);
3119 dst = TREE_VALUE (arglist);
3120 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3121 narglist = build_tree_list (NULL_TREE, lenp1);
3122 narglist = tree_cons (NULL_TREE, src, narglist);
3123 narglist = tree_cons (NULL_TREE, dst, narglist);
3124 ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3126 if (ret)
3127 return ret;
3129 if (TREE_CODE (len) == INTEGER_CST)
3131 rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3133 if (GET_CODE (len_rtx) == CONST_INT)
3135 ret = expand_builtin_strcpy (arglist, target, mode);
3137 if (ret)
3139 if (! target)
3140 target = gen_reg_rtx (mode);
3141 if (GET_MODE (target) != GET_MODE (ret))
3142 ret = gen_lowpart (GET_MODE (target), ret);
3144 ret = emit_move_insn (target,
3145 plus_constant (ret,
3146 INTVAL (len_rtx)));
3147 if (! ret)
3148 abort ();
3150 return target;
3155 return expand_movstr (TREE_VALUE (arglist),
3156 TREE_VALUE (TREE_CHAIN (arglist)),
3157 target, /*endp=*/2);
3161 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3162 bytes from constant string DATA + OFFSET and return it as target
3163 constant. */
3165 static rtx
3166 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3167 enum machine_mode mode)
3169 const char *str = (const char *) data;
3171 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3172 return const0_rtx;
3174 return c_readstr (str + offset, mode);
3177 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3178 if we failed the caller should emit a normal call. */
3180 static rtx
3181 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3183 if (!validate_arglist (arglist,
3184 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3185 return 0;
3186 else
3188 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3189 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3190 tree fn;
3192 /* We must be passed a constant len parameter. */
3193 if (TREE_CODE (len) != INTEGER_CST)
3194 return 0;
3196 /* If the len parameter is zero, return the dst parameter. */
3197 if (integer_zerop (len))
3199 /* Evaluate and ignore the src argument in case it has
3200 side-effects. */
3201 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3202 VOIDmode, EXPAND_NORMAL);
3203 /* Return the dst parameter. */
3204 return expand_expr (TREE_VALUE (arglist), target, mode,
3205 EXPAND_NORMAL);
3208 /* Now, we must be passed a constant src ptr parameter. */
3209 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3210 return 0;
3212 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3214 /* We're required to pad with trailing zeros if the requested
3215 len is greater than strlen(s2)+1. In that case try to
3216 use store_by_pieces, if it fails, punt. */
3217 if (tree_int_cst_lt (slen, len))
3219 tree dest = TREE_VALUE (arglist);
3220 unsigned int dest_align
3221 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3222 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3223 rtx dest_mem;
3225 if (!p || dest_align == 0 || !host_integerp (len, 1)
3226 || !can_store_by_pieces (tree_low_cst (len, 1),
3227 builtin_strncpy_read_str,
3228 (void *) p, dest_align))
3229 return 0;
3231 dest_mem = get_memory_rtx (dest);
3232 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3233 builtin_strncpy_read_str,
3234 (void *) p, dest_align, 0);
3235 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3236 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3237 return dest_mem;
3240 /* OK transform into builtin memcpy. */
3241 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3242 if (!fn)
3243 return 0;
3244 return expand_expr (build_function_call_expr (fn, arglist),
3245 target, mode, EXPAND_NORMAL);
3249 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3250 bytes from constant string DATA + OFFSET and return it as target
3251 constant. */
3253 static rtx
3254 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3255 enum machine_mode mode)
3257 const char *c = (const char *) data;
3258 char *p = alloca (GET_MODE_SIZE (mode));
3260 memset (p, *c, GET_MODE_SIZE (mode));
3262 return c_readstr (p, mode);
3265 /* Callback routine for store_by_pieces. Return the RTL of a register
3266 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3267 char value given in the RTL register data. For example, if mode is
3268 4 bytes wide, return the RTL for 0x01010101*data. */
3270 static rtx
3271 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3272 enum machine_mode mode)
3274 rtx target, coeff;
3275 size_t size;
3276 char *p;
3278 size = GET_MODE_SIZE (mode);
3279 if (size == 1)
3280 return (rtx) data;
3282 p = alloca (size);
3283 memset (p, 1, size);
3284 coeff = c_readstr (p, mode);
3286 target = convert_to_mode (mode, (rtx) data, 1);
3287 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3288 return force_reg (mode, target);
3291 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3292 if we failed the caller should emit a normal call, otherwise try to get
3293 the result in TARGET, if convenient (and in mode MODE if that's
3294 convenient). */
3296 static rtx
3297 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3299 if (!validate_arglist (arglist,
3300 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3301 return 0;
3302 else
3304 tree dest = TREE_VALUE (arglist);
3305 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3306 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3307 char c;
3309 unsigned int dest_align
3310 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3311 rtx dest_mem, dest_addr, len_rtx;
3313 /* If DEST is not a pointer type, don't do this
3314 operation in-line. */
3315 if (dest_align == 0)
3316 return 0;
3318 /* If the LEN parameter is zero, return DEST. */
3319 if (integer_zerop (len))
3321 /* Evaluate and ignore VAL in case it has side-effects. */
3322 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3323 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3326 if (TREE_CODE (val) != INTEGER_CST)
3328 rtx val_rtx;
3330 if (!host_integerp (len, 1))
3331 return 0;
3333 if (optimize_size && tree_low_cst (len, 1) > 1)
3334 return 0;
3336 /* Assume that we can memset by pieces if we can store the
3337 * the coefficients by pieces (in the required modes).
3338 * We can't pass builtin_memset_gen_str as that emits RTL. */
3339 c = 1;
3340 if (!can_store_by_pieces (tree_low_cst (len, 1),
3341 builtin_memset_read_str,
3342 &c, dest_align))
3343 return 0;
3345 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3346 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3347 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3348 val_rtx);
3349 dest_mem = get_memory_rtx (dest);
3350 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3351 builtin_memset_gen_str,
3352 val_rtx, dest_align, 0);
3353 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3354 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3355 return dest_mem;
3358 if (target_char_cast (val, &c))
3359 return 0;
3361 if (c)
3363 if (!host_integerp (len, 1))
3364 return 0;
3365 if (!can_store_by_pieces (tree_low_cst (len, 1),
3366 builtin_memset_read_str, &c,
3367 dest_align))
3368 return 0;
3370 dest_mem = get_memory_rtx (dest);
3371 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3372 builtin_memset_read_str,
3373 &c, dest_align, 0);
3374 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3375 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3376 return dest_mem;
3379 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3381 dest_mem = get_memory_rtx (dest);
3382 set_mem_align (dest_mem, dest_align);
3383 dest_addr = clear_storage (dest_mem, len_rtx);
3385 if (dest_addr == 0)
3387 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3388 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3391 return dest_addr;
3395 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3396 if we failed the caller should emit a normal call. */
3398 static rtx
3399 expand_builtin_bzero (tree arglist)
3401 tree dest, size, newarglist;
3403 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3404 return NULL_RTX;
3406 dest = TREE_VALUE (arglist);
3407 size = TREE_VALUE (TREE_CHAIN (arglist));
3409 /* New argument list transforming bzero(ptr x, int y) to
3410 memset(ptr x, int 0, size_t y). This is done this way
3411 so that if it isn't expanded inline, we fallback to
3412 calling bzero instead of memset. */
3414 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3415 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3416 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3418 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3421 /* Expand expression EXP, which is a call to the memcmp built-in function.
3422 ARGLIST is the argument list for this call. Return 0 if we failed and the
3423 caller should emit a normal call, otherwise try to get the result in
3424 TARGET, if convenient (and in mode MODE, if that's convenient). */
3426 static rtx
3427 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3428 enum machine_mode mode)
3430 tree arg1, arg2, len;
3431 const char *p1, *p2;
3433 if (!validate_arglist (arglist,
3434 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3435 return 0;
3437 arg1 = TREE_VALUE (arglist);
3438 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3439 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3441 /* If the len parameter is zero, return zero. */
3442 if (integer_zerop (len))
3444 /* Evaluate and ignore arg1 and arg2 in case they have
3445 side-effects. */
3446 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3447 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3448 return const0_rtx;
3451 /* If both arguments are equal (and not volatile), return zero. */
3452 if (operand_equal_p (arg1, arg2, 0))
3454 /* Evaluate and ignore len in case it has side-effects. */
3455 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3456 return const0_rtx;
3459 p1 = c_getstr (arg1);
3460 p2 = c_getstr (arg2);
3462 /* If all arguments are constant, and the value of len is not greater
3463 than the lengths of arg1 and arg2, evaluate at compile-time. */
3464 if (host_integerp (len, 1) && p1 && p2
3465 && compare_tree_int (len, strlen (p1) + 1) <= 0
3466 && compare_tree_int (len, strlen (p2) + 1) <= 0)
3468 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3470 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3473 /* If len parameter is one, return an expression corresponding to
3474 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3475 if (integer_onep (len))
3477 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3478 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3479 tree ind1 =
3480 fold (build1 (CONVERT_EXPR, integer_type_node,
3481 build1 (INDIRECT_REF, cst_uchar_node,
3482 fold_convert (cst_uchar_ptr_node, arg1))));
3483 tree ind2 =
3484 fold (build1 (CONVERT_EXPR, integer_type_node,
3485 build1 (INDIRECT_REF, cst_uchar_node,
3486 fold_convert (cst_uchar_ptr_node, arg2))));
3487 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3488 return expand_expr (result, target, mode, EXPAND_NORMAL);
3491 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3493 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3494 rtx result;
3495 rtx insn;
3497 int arg1_align
3498 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3499 int arg2_align
3500 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3501 enum machine_mode insn_mode;
3503 #ifdef HAVE_cmpmemsi
3504 if (HAVE_cmpmemsi)
3505 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3506 else
3507 #endif
3508 #ifdef HAVE_cmpstrsi
3509 if (HAVE_cmpstrsi)
3510 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3511 else
3512 #endif
3513 return 0;
3515 /* If we don't have POINTER_TYPE, call the function. */
3516 if (arg1_align == 0 || arg2_align == 0)
3517 return 0;
3519 /* Make a place to write the result of the instruction. */
3520 result = target;
3521 if (! (result != 0
3522 && REG_P (result) && GET_MODE (result) == insn_mode
3523 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3524 result = gen_reg_rtx (insn_mode);
3526 arg1_rtx = get_memory_rtx (arg1);
3527 arg2_rtx = get_memory_rtx (arg2);
3528 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3529 #ifdef HAVE_cmpmemsi
3530 if (HAVE_cmpmemsi)
3531 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3532 GEN_INT (MIN (arg1_align, arg2_align)));
3533 else
3534 #endif
3535 #ifdef HAVE_cmpstrsi
3536 if (HAVE_cmpstrsi)
3537 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3538 GEN_INT (MIN (arg1_align, arg2_align)));
3539 else
3540 #endif
3541 abort ();
3543 if (insn)
3544 emit_insn (insn);
3545 else
3546 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3547 TYPE_MODE (integer_type_node), 3,
3548 XEXP (arg1_rtx, 0), Pmode,
3549 XEXP (arg2_rtx, 0), Pmode,
3550 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3551 TYPE_UNSIGNED (sizetype)),
3552 TYPE_MODE (sizetype));
3554 /* Return the value in the proper mode for this function. */
3555 mode = TYPE_MODE (TREE_TYPE (exp));
3556 if (GET_MODE (result) == mode)
3557 return result;
3558 else if (target != 0)
3560 convert_move (target, result, 0);
3561 return target;
3563 else
3564 return convert_to_mode (mode, result, 0);
3566 #endif
3568 return 0;
3571 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3572 if we failed the caller should emit a normal call, otherwise try to get
3573 the result in TARGET, if convenient. */
3575 static rtx
3576 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3578 tree arglist = TREE_OPERAND (exp, 1);
3579 tree arg1, arg2;
3580 const char *p1, *p2;
3582 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3583 return 0;
3585 arg1 = TREE_VALUE (arglist);
3586 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3588 /* If both arguments are equal (and not volatile), return zero. */
3589 if (operand_equal_p (arg1, arg2, 0))
3590 return const0_rtx;
3592 p1 = c_getstr (arg1);
3593 p2 = c_getstr (arg2);
3595 if (p1 && p2)
3597 const int i = strcmp (p1, p2);
3598 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3601 /* If either arg is "", return an expression corresponding to
3602 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3603 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3605 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3606 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3607 tree ind1 =
3608 fold (build1 (CONVERT_EXPR, integer_type_node,
3609 build1 (INDIRECT_REF, cst_uchar_node,
3610 fold_convert (cst_uchar_ptr_node, arg1))));
3611 tree ind2 =
3612 fold (build1 (CONVERT_EXPR, integer_type_node,
3613 build1 (INDIRECT_REF, cst_uchar_node,
3614 fold_convert (cst_uchar_ptr_node, arg2))));
3615 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3616 return expand_expr (result, target, mode, EXPAND_NORMAL);
3619 #ifdef HAVE_cmpstrsi
3620 if (HAVE_cmpstrsi)
3622 tree len, len1, len2;
3623 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3624 rtx result, insn;
3625 tree fndecl;
3627 int arg1_align
3628 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3629 int arg2_align
3630 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3631 enum machine_mode insn_mode
3632 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3634 len1 = c_strlen (arg1, 1);
3635 len2 = c_strlen (arg2, 1);
3637 if (len1)
3638 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3639 if (len2)
3640 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3642 /* If we don't have a constant length for the first, use the length
3643 of the second, if we know it. We don't require a constant for
3644 this case; some cost analysis could be done if both are available
3645 but neither is constant. For now, assume they're equally cheap,
3646 unless one has side effects. If both strings have constant lengths,
3647 use the smaller. */
3649 if (!len1)
3650 len = len2;
3651 else if (!len2)
3652 len = len1;
3653 else if (TREE_SIDE_EFFECTS (len1))
3654 len = len2;
3655 else if (TREE_SIDE_EFFECTS (len2))
3656 len = len1;
3657 else if (TREE_CODE (len1) != INTEGER_CST)
3658 len = len2;
3659 else if (TREE_CODE (len2) != INTEGER_CST)
3660 len = len1;
3661 else if (tree_int_cst_lt (len1, len2))
3662 len = len1;
3663 else
3664 len = len2;
3666 /* If both arguments have side effects, we cannot optimize. */
3667 if (!len || TREE_SIDE_EFFECTS (len))
3668 return 0;
3670 /* If we don't have POINTER_TYPE, call the function. */
3671 if (arg1_align == 0 || arg2_align == 0)
3672 return 0;
3674 /* Make a place to write the result of the instruction. */
3675 result = target;
3676 if (! (result != 0
3677 && REG_P (result) && GET_MODE (result) == insn_mode
3678 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3679 result = gen_reg_rtx (insn_mode);
3681 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3682 arg1 = builtin_save_expr (arg1);
3683 arg2 = builtin_save_expr (arg2);
3685 arg1_rtx = get_memory_rtx (arg1);
3686 arg2_rtx = get_memory_rtx (arg2);
3687 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3688 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3689 GEN_INT (MIN (arg1_align, arg2_align)));
3690 if (insn)
3692 emit_insn (insn);
3694 /* Return the value in the proper mode for this function. */
3695 mode = TYPE_MODE (TREE_TYPE (exp));
3696 if (GET_MODE (result) == mode)
3697 return result;
3698 if (target == 0)
3699 return convert_to_mode (mode, result, 0);
3700 convert_move (target, result, 0);
3701 return target;
3704 /* Expand the library call ourselves using a stabilized argument
3705 list to avoid re-evaluating the function's arguments twice. */
3706 arglist = build_tree_list (NULL_TREE, arg2);
3707 arglist = tree_cons (NULL_TREE, arg1, arglist);
3708 fndecl = get_callee_fndecl (exp);
3709 exp = build_function_call_expr (fndecl, arglist);
3710 return expand_call (exp, target, target == const0_rtx);
3712 #endif
3713 return 0;
3716 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3717 if we failed the caller should emit a normal call, otherwise try to get
3718 the result in TARGET, if convenient. */
3720 static rtx
3721 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3723 tree arglist = TREE_OPERAND (exp, 1);
3724 tree arg1, arg2, arg3;
3725 const char *p1, *p2;
3727 if (!validate_arglist (arglist,
3728 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3729 return 0;
3731 arg1 = TREE_VALUE (arglist);
3732 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3733 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3735 /* If the len parameter is zero, return zero. */
3736 if (integer_zerop (arg3))
3738 /* Evaluate and ignore arg1 and arg2 in case they have
3739 side-effects. */
3740 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3741 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3742 return const0_rtx;
3745 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3746 if (operand_equal_p (arg1, arg2, 0))
3748 /* Evaluate and ignore arg3 in case it has side-effects. */
3749 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3750 return const0_rtx;
3753 p1 = c_getstr (arg1);
3754 p2 = c_getstr (arg2);
3756 /* If all arguments are constant, evaluate at compile-time. */
3757 if (host_integerp (arg3, 1) && p1 && p2)
3759 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3760 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3763 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3764 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3765 if (host_integerp (arg3, 1)
3766 && (tree_low_cst (arg3, 1) == 1
3767 || (tree_low_cst (arg3, 1) > 1
3768 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3770 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3771 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3772 tree ind1 =
3773 fold (build1 (CONVERT_EXPR, integer_type_node,
3774 build1 (INDIRECT_REF, cst_uchar_node,
3775 fold_convert (cst_uchar_ptr_node, arg1))));
3776 tree ind2 =
3777 fold (build1 (CONVERT_EXPR, integer_type_node,
3778 build1 (INDIRECT_REF, cst_uchar_node,
3779 fold_convert (cst_uchar_ptr_node, arg2))));
3780 tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3781 return expand_expr (result, target, mode, EXPAND_NORMAL);
3784 /* If c_strlen can determine an expression for one of the string
3785 lengths, and it doesn't have side effects, then emit cmpstrsi
3786 using length MIN(strlen(string)+1, arg3). */
3787 #ifdef HAVE_cmpstrsi
3788 if (HAVE_cmpstrsi)
3790 tree len, len1, len2;
3791 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3792 rtx result, insn;
3793 tree fndecl;
3795 int arg1_align
3796 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3797 int arg2_align
3798 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3799 enum machine_mode insn_mode
3800 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3802 len1 = c_strlen (arg1, 1);
3803 len2 = c_strlen (arg2, 1);
3805 if (len1)
3806 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3807 if (len2)
3808 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3810 /* If we don't have a constant length for the first, use the length
3811 of the second, if we know it. We don't require a constant for
3812 this case; some cost analysis could be done if both are available
3813 but neither is constant. For now, assume they're equally cheap,
3814 unless one has side effects. If both strings have constant lengths,
3815 use the smaller. */
3817 if (!len1)
3818 len = len2;
3819 else if (!len2)
3820 len = len1;
3821 else if (TREE_SIDE_EFFECTS (len1))
3822 len = len2;
3823 else if (TREE_SIDE_EFFECTS (len2))
3824 len = len1;
3825 else if (TREE_CODE (len1) != INTEGER_CST)
3826 len = len2;
3827 else if (TREE_CODE (len2) != INTEGER_CST)
3828 len = len1;
3829 else if (tree_int_cst_lt (len1, len2))
3830 len = len1;
3831 else
3832 len = len2;
3834 /* If both arguments have side effects, we cannot optimize. */
3835 if (!len || TREE_SIDE_EFFECTS (len))
3836 return 0;
3838 /* The actual new length parameter is MIN(len,arg3). */
3839 len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len, arg3));
3841 /* If we don't have POINTER_TYPE, call the function. */
3842 if (arg1_align == 0 || arg2_align == 0)
3843 return 0;
3845 /* Make a place to write the result of the instruction. */
3846 result = target;
3847 if (! (result != 0
3848 && REG_P (result) && GET_MODE (result) == insn_mode
3849 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3850 result = gen_reg_rtx (insn_mode);
3852 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3853 arg1 = builtin_save_expr (arg1);
3854 arg2 = builtin_save_expr (arg2);
3855 len = builtin_save_expr (len);
3857 arg1_rtx = get_memory_rtx (arg1);
3858 arg2_rtx = get_memory_rtx (arg2);
3859 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3860 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3861 GEN_INT (MIN (arg1_align, arg2_align)));
3862 if (insn)
3864 emit_insn (insn);
3866 /* Return the value in the proper mode for this function. */
3867 mode = TYPE_MODE (TREE_TYPE (exp));
3868 if (GET_MODE (result) == mode)
3869 return result;
3870 if (target == 0)
3871 return convert_to_mode (mode, result, 0);
3872 convert_move (target, result, 0);
3873 return target;
3876 /* Expand the library call ourselves using a stabilized argument
3877 list to avoid re-evaluating the function's arguments twice. */
3878 arglist = build_tree_list (NULL_TREE, len);
3879 arglist = tree_cons (NULL_TREE, arg2, arglist);
3880 arglist = tree_cons (NULL_TREE, arg1, arglist);
3881 fndecl = get_callee_fndecl (exp);
3882 exp = build_function_call_expr (fndecl, arglist);
3883 return expand_call (exp, target, target == const0_rtx);
3885 #endif
3886 return 0;
3889 /* Expand expression EXP, which is a call to the strcat 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_strcat (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 dst = TREE_VALUE (arglist),
3901 src = TREE_VALUE (TREE_CHAIN (arglist));
3902 const char *p = c_getstr (src);
3904 if (p)
3906 /* If the string length is zero, return the dst parameter. */
3907 if (*p == '\0')
3908 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3909 else if (!optimize_size)
3911 /* Otherwise if !optimize_size, see if we can store by
3912 pieces into (dst + strlen(dst)). */
3913 tree newdst, arglist,
3914 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3916 /* This is the length argument. */
3917 arglist = build_tree_list (NULL_TREE,
3918 fold (size_binop (PLUS_EXPR,
3919 c_strlen (src, 0),
3920 ssize_int (1))));
3921 /* Prepend src argument. */
3922 arglist = tree_cons (NULL_TREE, src, arglist);
3924 /* We're going to use dst more than once. */
3925 dst = builtin_save_expr (dst);
3927 /* Create strlen (dst). */
3928 newdst =
3929 fold (build_function_call_expr (strlen_fn,
3930 build_tree_list (NULL_TREE,
3931 dst)));
3932 /* Create (dst + strlen (dst)). */
3933 newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3935 /* Prepend the new dst argument. */
3936 arglist = tree_cons (NULL_TREE, newdst, arglist);
3938 /* We don't want to get turned into a memcpy if the
3939 target is const0_rtx, i.e. when the return value
3940 isn't used. That would produce pessimized code so
3941 pass in a target of zero, it should never actually be
3942 used. If this was successful return the original
3943 dst, not the result of mempcpy. */
3944 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3945 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3946 else
3947 return 0;
3951 return 0;
3955 /* Expand expression EXP, which is a call to the strncat builtin.
3956 Return 0 if we failed the caller should emit a normal call,
3957 otherwise try to get the result in TARGET, if convenient. */
3959 static rtx
3960 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3962 if (!validate_arglist (arglist,
3963 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3964 return 0;
3965 else
3967 tree dst = TREE_VALUE (arglist),
3968 src = TREE_VALUE (TREE_CHAIN (arglist)),
3969 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3970 const char *p = c_getstr (src);
3972 /* If the requested length is zero, or the src parameter string
3973 length is zero, return the dst parameter. */
3974 if (integer_zerop (len) || (p && *p == '\0'))
3976 /* Evaluate and ignore the src and len parameters in case
3977 they have side-effects. */
3978 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3979 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3980 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3983 /* If the requested len is greater than or equal to the string
3984 length, call strcat. */
3985 if (TREE_CODE (len) == INTEGER_CST && p
3986 && compare_tree_int (len, strlen (p)) >= 0)
3988 tree newarglist
3989 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3990 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3992 /* If the replacement _DECL isn't initialized, don't do the
3993 transformation. */
3994 if (!fn)
3995 return 0;
3997 return expand_expr (build_function_call_expr (fn, newarglist),
3998 target, mode, EXPAND_NORMAL);
4000 return 0;
4004 /* Expand expression EXP, which is a call to the strspn builtin.
4005 Return 0 if we failed the caller should emit a normal call,
4006 otherwise try to get the result in TARGET, if convenient. */
4008 static rtx
4009 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4011 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4012 return 0;
4013 else
4015 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4016 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4018 /* If both arguments are constants, evaluate at compile-time. */
4019 if (p1 && p2)
4021 const size_t r = strspn (p1, p2);
4022 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4025 /* If either argument is "", return 0. */
4026 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4028 /* Evaluate and ignore both arguments in case either one has
4029 side-effects. */
4030 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4031 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4032 return const0_rtx;
4034 return 0;
4038 /* Expand expression EXP, which is a call to the strcspn builtin.
4039 Return 0 if we failed the caller should emit a normal call,
4040 otherwise try to get the result in TARGET, if convenient. */
4042 static rtx
4043 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4045 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4046 return 0;
4047 else
4049 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4050 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4052 /* If both arguments are constants, evaluate at compile-time. */
4053 if (p1 && p2)
4055 const size_t r = strcspn (p1, p2);
4056 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4059 /* If the first argument is "", return 0. */
4060 if (p1 && *p1 == '\0')
4062 /* Evaluate and ignore argument s2 in case it has
4063 side-effects. */
4064 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4065 return const0_rtx;
4068 /* If the second argument is "", return __builtin_strlen(s1). */
4069 if (p2 && *p2 == '\0')
4071 tree newarglist = build_tree_list (NULL_TREE, s1),
4072 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4074 /* If the replacement _DECL isn't initialized, don't do the
4075 transformation. */
4076 if (!fn)
4077 return 0;
4079 return expand_expr (build_function_call_expr (fn, newarglist),
4080 target, mode, EXPAND_NORMAL);
4082 return 0;
4086 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4087 if that's convenient. */
4090 expand_builtin_saveregs (void)
4092 rtx val, seq;
4094 /* Don't do __builtin_saveregs more than once in a function.
4095 Save the result of the first call and reuse it. */
4096 if (saveregs_value != 0)
4097 return saveregs_value;
4099 /* When this function is called, it means that registers must be
4100 saved on entry to this function. So we migrate the call to the
4101 first insn of this function. */
4103 start_sequence ();
4105 /* Do whatever the machine needs done in this case. */
4106 val = targetm.calls.expand_builtin_saveregs ();
4108 seq = get_insns ();
4109 end_sequence ();
4111 saveregs_value = val;
4113 /* Put the insns after the NOTE that starts the function. If this
4114 is inside a start_sequence, make the outer-level insn chain current, so
4115 the code is placed at the start of the function. */
4116 push_topmost_sequence ();
4117 emit_insn_after (seq, entry_of_function ());
4118 pop_topmost_sequence ();
4120 return val;
4123 /* __builtin_args_info (N) returns word N of the arg space info
4124 for the current function. The number and meanings of words
4125 is controlled by the definition of CUMULATIVE_ARGS. */
4127 static rtx
4128 expand_builtin_args_info (tree arglist)
4130 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4131 int *word_ptr = (int *) &current_function_args_info;
4133 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4134 abort ();
4136 if (arglist != 0)
4138 if (!host_integerp (TREE_VALUE (arglist), 0))
4139 error ("argument of `__builtin_args_info' must be constant");
4140 else
4142 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4144 if (wordnum < 0 || wordnum >= nwords)
4145 error ("argument of `__builtin_args_info' out of range");
4146 else
4147 return GEN_INT (word_ptr[wordnum]);
4150 else
4151 error ("missing argument in `__builtin_args_info'");
4153 return const0_rtx;
4156 /* Expand ARGLIST, from a call to __builtin_next_arg. */
4158 static rtx
4159 expand_builtin_next_arg (tree arglist)
4161 tree fntype = TREE_TYPE (current_function_decl);
4163 if (TYPE_ARG_TYPES (fntype) == 0
4164 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4165 == void_type_node))
4167 error ("`va_start' used in function with fixed args");
4168 return const0_rtx;
4171 if (arglist)
4173 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4174 tree arg = TREE_VALUE (arglist);
4176 /* Strip off all nops for the sake of the comparison. This
4177 is not quite the same as STRIP_NOPS. It does more.
4178 We must also strip off INDIRECT_EXPR for C++ reference
4179 parameters. */
4180 while (TREE_CODE (arg) == NOP_EXPR
4181 || TREE_CODE (arg) == CONVERT_EXPR
4182 || TREE_CODE (arg) == NON_LVALUE_EXPR
4183 || TREE_CODE (arg) == INDIRECT_REF)
4184 arg = TREE_OPERAND (arg, 0);
4185 if (arg != last_parm)
4186 warning ("second parameter of `va_start' not last named argument");
4188 else
4189 /* Evidently an out of date version of <stdarg.h>; can't validate
4190 va_start's second argument, but can still work as intended. */
4191 warning ("`__builtin_next_arg' called without an argument");
4193 return expand_binop (Pmode, add_optab,
4194 current_function_internal_arg_pointer,
4195 current_function_arg_offset_rtx,
4196 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4199 /* Make it easier for the backends by protecting the valist argument
4200 from multiple evaluations. */
4202 static tree
4203 stabilize_va_list (tree valist, int needs_lvalue)
4205 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4207 if (TREE_SIDE_EFFECTS (valist))
4208 valist = save_expr (valist);
4210 /* For this case, the backends will be expecting a pointer to
4211 TREE_TYPE (va_list_type_node), but it's possible we've
4212 actually been given an array (an actual va_list_type_node).
4213 So fix it. */
4214 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4216 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4217 valist = build_fold_addr_expr_with_type (valist, p1);
4220 else
4222 tree pt;
4224 if (! needs_lvalue)
4226 if (! TREE_SIDE_EFFECTS (valist))
4227 return valist;
4229 pt = build_pointer_type (va_list_type_node);
4230 valist = fold (build1 (ADDR_EXPR, pt, valist));
4231 TREE_SIDE_EFFECTS (valist) = 1;
4234 if (TREE_SIDE_EFFECTS (valist))
4235 valist = save_expr (valist);
4236 valist = build_fold_indirect_ref (valist);
4239 return valist;
4242 /* The "standard" definition of va_list is void*. */
4244 tree
4245 std_build_builtin_va_list (void)
4247 return ptr_type_node;
4250 /* The "standard" implementation of va_start: just assign `nextarg' to
4251 the variable. */
4253 void
4254 std_expand_builtin_va_start (tree valist, rtx nextarg)
4256 tree t;
4258 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4259 make_tree (ptr_type_node, nextarg));
4260 TREE_SIDE_EFFECTS (t) = 1;
4262 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4265 /* Expand ARGLIST, from a call to __builtin_va_start. */
4267 static rtx
4268 expand_builtin_va_start (tree arglist)
4270 rtx nextarg;
4271 tree chain, valist;
4273 chain = TREE_CHAIN (arglist);
4275 if (TREE_CHAIN (chain))
4276 error ("too many arguments to function `va_start'");
4278 nextarg = expand_builtin_next_arg (chain);
4279 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4281 #ifdef EXPAND_BUILTIN_VA_START
4282 EXPAND_BUILTIN_VA_START (valist, nextarg);
4283 #else
4284 std_expand_builtin_va_start (valist, nextarg);
4285 #endif
4287 return const0_rtx;
4290 /* The "standard" implementation of va_arg: read the value from the
4291 current (padded) address and increment by the (padded) size. */
4294 std_expand_builtin_va_arg (tree valist, tree type)
4296 tree addr_tree, t, type_size = NULL;
4297 tree align, alignm1;
4298 tree rounded_size;
4299 rtx addr;
4300 HOST_WIDE_INT boundary;
4302 /* Compute the rounded size of the type. */
4303 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4304 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4305 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4307 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4308 requires greater alignment, we must perform dynamic alignment. */
4310 if (boundary > PARM_BOUNDARY)
4312 if (!PAD_VARARGS_DOWN)
4314 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4315 build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4316 build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4317 TREE_SIDE_EFFECTS (t) = 1;
4318 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4320 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4321 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4322 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4323 TREE_SIDE_EFFECTS (t) = 1;
4324 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4326 if (type == error_mark_node
4327 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4328 || TREE_OVERFLOW (type_size))
4329 rounded_size = size_zero_node;
4330 else
4332 rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
4333 rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype,
4334 rounded_size, align));
4335 rounded_size = fold (build2 (MULT_EXPR, sizetype,
4336 rounded_size, align));
4339 /* Get AP. */
4340 addr_tree = valist;
4341 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4343 /* Small args are padded downward. */
4344 addr_tree = fold (build2 (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4345 fold (build3 (COND_EXPR, sizetype,
4346 fold (build2 (GT_EXPR, sizetype,
4347 rounded_size,
4348 align)),
4349 size_zero_node,
4350 fold (build2 (MINUS_EXPR,
4351 sizetype,
4352 rounded_size,
4353 type_size))))));
4356 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4357 addr = copy_to_reg (addr);
4359 /* Compute new value for AP. */
4360 if (! integer_zerop (rounded_size))
4362 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4363 build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4364 rounded_size));
4365 TREE_SIDE_EFFECTS (t) = 1;
4366 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4369 return addr;
4372 /* Expand __builtin_va_arg, which is not really a builtin function, but
4373 a very special sort of operator. */
4376 expand_builtin_va_arg (tree valist, tree type)
4378 rtx addr, result;
4379 tree promoted_type, want_va_type, have_va_type;
4381 /* Verify that valist is of the proper type. */
4383 want_va_type = va_list_type_node;
4384 have_va_type = TREE_TYPE (valist);
4385 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4387 /* If va_list is an array type, the argument may have decayed
4388 to a pointer type, e.g. by being passed to another function.
4389 In that case, unwrap both types so that we can compare the
4390 underlying records. */
4391 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4392 || TREE_CODE (have_va_type) == POINTER_TYPE)
4394 want_va_type = TREE_TYPE (want_va_type);
4395 have_va_type = TREE_TYPE (have_va_type);
4398 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4400 error ("first argument to `va_arg' not of type `va_list'");
4401 addr = const0_rtx;
4404 /* Generate a diagnostic for requesting data of a type that cannot
4405 be passed through `...' due to type promotion at the call site. */
4406 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4407 != type)
4409 const char *name = "<anonymous type>", *pname = 0;
4410 static bool gave_help;
4412 if (TYPE_NAME (type))
4414 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4415 name = IDENTIFIER_POINTER (TYPE_NAME (type));
4416 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4417 && DECL_NAME (TYPE_NAME (type)))
4418 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4420 if (TYPE_NAME (promoted_type))
4422 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4423 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4424 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4425 && DECL_NAME (TYPE_NAME (promoted_type)))
4426 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4429 /* Unfortunately, this is merely undefined, rather than a constraint
4430 violation, so we cannot make this an error. If this call is never
4431 executed, the program is still strictly conforming. */
4432 warning ("`%s' is promoted to `%s' when passed through `...'",
4433 name, pname);
4434 if (! gave_help)
4436 gave_help = true;
4437 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4438 pname, name);
4441 /* We can, however, treat "undefined" any way we please.
4442 Call abort to encourage the user to fix the program. */
4443 inform ("if this code is reached, the program will abort");
4444 expand_builtin_trap ();
4446 /* This is dead code, but go ahead and finish so that the
4447 mode of the result comes out right. */
4448 addr = const0_rtx;
4450 else
4452 /* Make it easier for the backends by protecting the valist argument
4453 from multiple evaluations. */
4454 valist = stabilize_va_list (valist, 0);
4456 #ifdef EXPAND_BUILTIN_VA_ARG
4457 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4458 #else
4459 addr = std_expand_builtin_va_arg (valist, type);
4460 #endif
4463 addr = convert_memory_address (Pmode, addr);
4465 result = gen_rtx_MEM (TYPE_MODE (type), addr);
4466 set_mem_alias_set (result, get_varargs_alias_set ());
4468 return result;
4471 /* Like std_expand_builtin_va_arg, but gimplify instead of expanding. */
4473 tree
4474 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4476 tree addr, t, type_size, rounded_size, valist_tmp;
4477 unsigned HOST_WIDE_INT align, boundary;
4479 #ifdef ARGS_GROW_DOWNWARD
4480 /* All of the alignment and movement below is for args-grow-up machines.
4481 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4482 implement their own specialized gimplify_va_arg_expr routines. */
4483 abort ();
4484 #endif
4486 align = PARM_BOUNDARY / BITS_PER_UNIT;
4487 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4489 /* Hoist the valist value into a temporary for the moment. */
4490 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4492 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4493 requires greater alignment, we must perform dynamic alignment. */
4494 if (boundary > align)
4496 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4497 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4498 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4499 gimplify_and_add (t, pre_p);
4501 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4502 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4503 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4504 gimplify_and_add (t, pre_p);
4507 /* Compute the rounded size of the type. */
4508 type_size = size_in_bytes (type);
4509 rounded_size = round_up (type_size, align);
4511 /* Reduce rounded_size so it's sharable with the postqueue. */
4512 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4514 /* Get AP. */
4515 addr = valist_tmp;
4516 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4518 /* Small args are padded downward. */
4519 t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4520 t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4521 size_binop (MINUS_EXPR, rounded_size, type_size)));
4522 t = fold_convert (TREE_TYPE (addr), t);
4523 addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4526 /* Compute new value for AP. */
4527 t = fold_convert (TREE_TYPE (valist), rounded_size);
4528 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4529 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4530 gimplify_and_add (t, pre_p);
4532 addr = fold_convert (build_pointer_type (type), addr);
4533 return build_fold_indirect_ref (addr);
4536 /* Like std_gimplify_va_arg_expr, but uses pass-by-reference. */
4538 tree
4539 ind_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4541 tree t;
4542 t = build_pointer_type (type);
4543 t = std_gimplify_va_arg_expr (valist, t, pre_p, post_p);
4544 return build_fold_indirect_ref (t);
4547 /* Return a dummy expression of type TYPE in order to keep going after an
4548 error. */
4550 static tree
4551 dummy_object (tree type)
4553 tree t = convert (build_pointer_type (type), null_pointer_node);
4554 return build1 (INDIRECT_REF, type, t);
4557 /* Like expand_builtin_va_arg, but gimplify instead of expanding. */
4559 enum gimplify_status
4560 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4562 tree promoted_type, want_va_type, have_va_type;
4563 tree valist = TREE_OPERAND (*expr_p, 0);
4564 tree type = TREE_TYPE (*expr_p);
4565 tree t;
4567 /* Verify that valist is of the proper type. */
4568 want_va_type = va_list_type_node;
4569 have_va_type = TREE_TYPE (valist);
4571 if (have_va_type == error_mark_node)
4572 return GS_ERROR;
4574 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4576 /* If va_list is an array type, the argument may have decayed
4577 to a pointer type, e.g. by being passed to another function.
4578 In that case, unwrap both types so that we can compare the
4579 underlying records. */
4580 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4581 || TREE_CODE (have_va_type) == POINTER_TYPE)
4583 want_va_type = TREE_TYPE (want_va_type);
4584 have_va_type = TREE_TYPE (have_va_type);
4588 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4590 error ("first argument to `va_arg' not of type `va_list'");
4591 return GS_ERROR;
4594 /* Generate a diagnostic for requesting data of a type that cannot
4595 be passed through `...' due to type promotion at the call site. */
4596 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4597 != type)
4599 static bool gave_help;
4601 /* Unfortunately, this is merely undefined, rather than a constraint
4602 violation, so we cannot make this an error. If this call is never
4603 executed, the program is still strictly conforming. */
4604 warning ("`%T' is promoted to `%T' when passed through `...'",
4605 type, promoted_type);
4606 if (! gave_help)
4608 gave_help = true;
4609 warning ("(so you should pass `%T' not `%T' to `va_arg')",
4610 promoted_type, type);
4613 /* We can, however, treat "undefined" any way we please.
4614 Call abort to encourage the user to fix the program. */
4615 inform ("if this code is reached, the program will abort");
4616 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4617 NULL);
4618 append_to_statement_list (t, pre_p);
4620 /* This is dead code, but go ahead and finish so that the
4621 mode of the result comes out right. */
4622 *expr_p = dummy_object (type);
4623 return GS_ALL_DONE;
4625 else
4627 /* Make it easier for the backends by protecting the valist argument
4628 from multiple evaluations. */
4629 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4631 /* For this case, the backends will be expecting a pointer to
4632 TREE_TYPE (va_list_type_node), but it's possible we've
4633 actually been given an array (an actual va_list_type_node).
4634 So fix it. */
4635 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4637 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4638 valist = build_fold_addr_expr_with_type (valist, p1);
4640 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4642 else
4643 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4645 if (!targetm.calls.gimplify_va_arg_expr)
4646 /* Once most targets are converted this should abort. */
4647 return GS_ALL_DONE;
4649 *expr_p = targetm.calls.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4650 return GS_OK;
4654 /* Expand ARGLIST, from a call to __builtin_va_end. */
4656 static rtx
4657 expand_builtin_va_end (tree arglist)
4659 tree valist = TREE_VALUE (arglist);
4661 /* Evaluate for side effects, if needed. I hate macros that don't
4662 do that. */
4663 if (TREE_SIDE_EFFECTS (valist))
4664 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4666 return const0_rtx;
4669 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4670 builtin rather than just as an assignment in stdarg.h because of the
4671 nastiness of array-type va_list types. */
4673 static rtx
4674 expand_builtin_va_copy (tree arglist)
4676 tree dst, src, t;
4678 dst = TREE_VALUE (arglist);
4679 src = TREE_VALUE (TREE_CHAIN (arglist));
4681 dst = stabilize_va_list (dst, 1);
4682 src = stabilize_va_list (src, 0);
4684 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4686 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4687 TREE_SIDE_EFFECTS (t) = 1;
4688 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4690 else
4692 rtx dstb, srcb, size;
4694 /* Evaluate to pointers. */
4695 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4696 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4697 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4698 VOIDmode, EXPAND_NORMAL);
4700 dstb = convert_memory_address (Pmode, dstb);
4701 srcb = convert_memory_address (Pmode, srcb);
4703 /* "Dereference" to BLKmode memories. */
4704 dstb = gen_rtx_MEM (BLKmode, dstb);
4705 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4706 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4707 srcb = gen_rtx_MEM (BLKmode, srcb);
4708 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4709 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4711 /* Copy. */
4712 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4715 return const0_rtx;
4718 /* Expand a call to one of the builtin functions __builtin_frame_address or
4719 __builtin_return_address. */
4721 static rtx
4722 expand_builtin_frame_address (tree fndecl, tree arglist)
4724 /* The argument must be a nonnegative integer constant.
4725 It counts the number of frames to scan up the stack.
4726 The value is the return address saved in that frame. */
4727 if (arglist == 0)
4728 /* Warning about missing arg was already issued. */
4729 return const0_rtx;
4730 else if (! host_integerp (TREE_VALUE (arglist), 1))
4732 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4733 error ("invalid arg to `__builtin_frame_address'");
4734 else
4735 error ("invalid arg to `__builtin_return_address'");
4736 return const0_rtx;
4738 else
4740 rtx tem
4741 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4742 tree_low_cst (TREE_VALUE (arglist), 1),
4743 hard_frame_pointer_rtx);
4745 /* Some ports cannot access arbitrary stack frames. */
4746 if (tem == NULL)
4748 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4749 warning ("unsupported arg to `__builtin_frame_address'");
4750 else
4751 warning ("unsupported arg to `__builtin_return_address'");
4752 return const0_rtx;
4755 /* For __builtin_frame_address, return what we've got. */
4756 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4757 return tem;
4759 if (!REG_P (tem)
4760 && ! CONSTANT_P (tem))
4761 tem = copy_to_mode_reg (Pmode, tem);
4762 return tem;
4766 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4767 we failed and the caller should emit a normal call, otherwise try to get
4768 the result in TARGET, if convenient. */
4770 static rtx
4771 expand_builtin_alloca (tree arglist, rtx target)
4773 rtx op0;
4774 rtx result;
4776 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4777 should always expand to function calls. These can be intercepted
4778 in libmudflap. */
4779 if (flag_mudflap)
4780 return 0;
4782 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4783 return 0;
4785 /* Compute the argument. */
4786 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4788 /* Allocate the desired space. */
4789 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4790 result = convert_memory_address (ptr_mode, result);
4792 return result;
4795 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4796 Return 0 if a normal call should be emitted rather than expanding the
4797 function in-line. If convenient, the result should be placed in TARGET.
4798 SUBTARGET may be used as the target for computing one of EXP's operands. */
4800 static rtx
4801 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4802 rtx subtarget, optab op_optab)
4804 rtx op0;
4805 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4806 return 0;
4808 /* Compute the argument. */
4809 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4810 /* Compute op, into TARGET if possible.
4811 Set TARGET to wherever the result comes back. */
4812 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4813 op_optab, op0, target, 1);
4814 if (target == 0)
4815 abort ();
4817 return convert_to_mode (target_mode, target, 0);
4820 /* If the string passed to fputs is a constant and is one character
4821 long, we attempt to transform this call into __builtin_fputc(). */
4823 static rtx
4824 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4826 tree len, fn;
4827 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4828 : implicit_built_in_decls[BUILT_IN_FPUTC];
4829 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4830 : implicit_built_in_decls[BUILT_IN_FWRITE];
4832 /* If the return value is used, or the replacement _DECL isn't
4833 initialized, don't do the transformation. */
4834 if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4835 return 0;
4837 /* Verify the arguments in the original call. */
4838 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4839 return 0;
4841 /* Get the length of the string passed to fputs. If the length
4842 can't be determined, punt. */
4843 if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4844 || TREE_CODE (len) != INTEGER_CST)
4845 return 0;
4847 switch (compare_tree_int (len, 1))
4849 case -1: /* length is 0, delete the call entirely . */
4851 /* Evaluate and ignore the argument in case it has
4852 side-effects. */
4853 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4854 VOIDmode, EXPAND_NORMAL);
4855 return const0_rtx;
4857 case 0: /* length is 1, call fputc. */
4859 const char *p = c_getstr (TREE_VALUE (arglist));
4861 if (p != NULL)
4863 /* New argument list transforming fputs(string, stream) to
4864 fputc(string[0], stream). */
4865 arglist =
4866 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4867 arglist =
4868 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4869 fn = fn_fputc;
4870 break;
4873 /* Fall through. */
4874 case 1: /* length is greater than 1, call fwrite. */
4876 tree string_arg;
4878 /* If optimizing for size keep fputs. */
4879 if (optimize_size)
4880 return 0;
4881 string_arg = TREE_VALUE (arglist);
4882 /* New argument list transforming fputs(string, stream) to
4883 fwrite(string, 1, len, stream). */
4884 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4885 arglist = tree_cons (NULL_TREE, len, arglist);
4886 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4887 arglist = tree_cons (NULL_TREE, string_arg, arglist);
4888 fn = fn_fwrite;
4889 break;
4891 default:
4892 abort ();
4895 return expand_expr (build_function_call_expr (fn, arglist),
4896 const0_rtx, VOIDmode, EXPAND_NORMAL);
4899 /* Expand a call to __builtin_expect. We return our argument and emit a
4900 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4901 a non-jump context. */
4903 static rtx
4904 expand_builtin_expect (tree arglist, rtx target)
4906 tree exp, c;
4907 rtx note, rtx_c;
4909 if (arglist == NULL_TREE
4910 || TREE_CHAIN (arglist) == NULL_TREE)
4911 return const0_rtx;
4912 exp = TREE_VALUE (arglist);
4913 c = TREE_VALUE (TREE_CHAIN (arglist));
4915 if (TREE_CODE (c) != INTEGER_CST)
4917 error ("second arg to `__builtin_expect' must be a constant");
4918 c = integer_zero_node;
4921 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4923 /* Don't bother with expected value notes for integral constants. */
4924 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4926 /* We do need to force this into a register so that we can be
4927 moderately sure to be able to correctly interpret the branch
4928 condition later. */
4929 target = force_reg (GET_MODE (target), target);
4931 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4933 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4934 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4937 return target;
4940 /* Like expand_builtin_expect, except do this in a jump context. This is
4941 called from do_jump if the conditional is a __builtin_expect. Return either
4942 a list of insns to emit the jump or NULL if we cannot optimize
4943 __builtin_expect. We need to optimize this at jump time so that machines
4944 like the PowerPC don't turn the test into a SCC operation, and then jump
4945 based on the test being 0/1. */
4948 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4950 tree arglist = TREE_OPERAND (exp, 1);
4951 tree arg0 = TREE_VALUE (arglist);
4952 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4953 rtx ret = NULL_RTX;
4955 /* Only handle __builtin_expect (test, 0) and
4956 __builtin_expect (test, 1). */
4957 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4958 && (integer_zerop (arg1) || integer_onep (arg1)))
4960 rtx insn, drop_through_label, temp;
4962 /* Expand the jump insns. */
4963 start_sequence ();
4964 do_jump (arg0, if_false_label, if_true_label);
4965 ret = get_insns ();
4967 drop_through_label = get_last_insn ();
4968 if (drop_through_label && NOTE_P (drop_through_label))
4969 drop_through_label = prev_nonnote_insn (drop_through_label);
4970 if (drop_through_label && !LABEL_P (drop_through_label))
4971 drop_through_label = NULL_RTX;
4972 end_sequence ();
4974 if (! if_true_label)
4975 if_true_label = drop_through_label;
4976 if (! if_false_label)
4977 if_false_label = drop_through_label;
4979 /* Go through and add the expect's to each of the conditional jumps. */
4980 insn = ret;
4981 while (insn != NULL_RTX)
4983 rtx next = NEXT_INSN (insn);
4985 if (JUMP_P (insn) && any_condjump_p (insn))
4987 rtx ifelse = SET_SRC (pc_set (insn));
4988 rtx then_dest = XEXP (ifelse, 1);
4989 rtx else_dest = XEXP (ifelse, 2);
4990 int taken = -1;
4992 /* First check if we recognize any of the labels. */
4993 if (GET_CODE (then_dest) == LABEL_REF
4994 && XEXP (then_dest, 0) == if_true_label)
4995 taken = 1;
4996 else if (GET_CODE (then_dest) == LABEL_REF
4997 && XEXP (then_dest, 0) == if_false_label)
4998 taken = 0;
4999 else if (GET_CODE (else_dest) == LABEL_REF
5000 && XEXP (else_dest, 0) == if_false_label)
5001 taken = 1;
5002 else if (GET_CODE (else_dest) == LABEL_REF
5003 && XEXP (else_dest, 0) == if_true_label)
5004 taken = 0;
5005 /* Otherwise check where we drop through. */
5006 else if (else_dest == pc_rtx)
5008 if (next && NOTE_P (next))
5009 next = next_nonnote_insn (next);
5011 if (next && JUMP_P (next)
5012 && any_uncondjump_p (next))
5013 temp = XEXP (SET_SRC (pc_set (next)), 0);
5014 else
5015 temp = next;
5017 /* TEMP is either a CODE_LABEL, NULL_RTX or something
5018 else that can't possibly match either target label. */
5019 if (temp == if_false_label)
5020 taken = 1;
5021 else if (temp == if_true_label)
5022 taken = 0;
5024 else if (then_dest == pc_rtx)
5026 if (next && NOTE_P (next))
5027 next = next_nonnote_insn (next);
5029 if (next && JUMP_P (next)
5030 && any_uncondjump_p (next))
5031 temp = XEXP (SET_SRC (pc_set (next)), 0);
5032 else
5033 temp = next;
5035 if (temp == if_false_label)
5036 taken = 0;
5037 else if (temp == if_true_label)
5038 taken = 1;
5041 if (taken != -1)
5043 /* If the test is expected to fail, reverse the
5044 probabilities. */
5045 if (integer_zerop (arg1))
5046 taken = 1 - taken;
5047 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
5051 insn = next;
5055 return ret;
5058 void
5059 expand_builtin_trap (void)
5061 #ifdef HAVE_trap
5062 if (HAVE_trap)
5063 emit_insn (gen_trap ());
5064 else
5065 #endif
5066 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5067 emit_barrier ();
5070 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
5071 Return 0 if a normal call should be emitted rather than expanding
5072 the function inline. If convenient, the result should be placed
5073 in TARGET. SUBTARGET may be used as the target for computing
5074 the operand. */
5076 static rtx
5077 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
5079 enum machine_mode mode;
5080 tree arg;
5081 rtx op0;
5083 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5084 return 0;
5086 arg = TREE_VALUE (arglist);
5087 mode = TYPE_MODE (TREE_TYPE (arg));
5088 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
5089 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5092 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
5093 Return 0 if a normal call should be emitted rather than expanding
5094 the function inline. If convenient, the result should be placed
5095 in target. */
5097 static rtx
5098 expand_builtin_cabs (tree arglist, rtx target)
5100 enum machine_mode mode;
5101 tree arg;
5102 rtx op0;
5104 if (arglist == 0 || TREE_CHAIN (arglist))
5105 return 0;
5106 arg = TREE_VALUE (arglist);
5107 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5108 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5109 return 0;
5111 mode = TYPE_MODE (TREE_TYPE (arg));
5112 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5113 return expand_complex_abs (mode, op0, target, 0);
5116 /* Create a new constant string literal and return a char* pointer to it.
5117 The STRING_CST value is the LEN characters at STR. */
5118 static tree
5119 build_string_literal (int len, const char *str)
5121 tree t, elem, index, type;
5123 t = build_string (len, str);
5124 elem = build_type_variant (char_type_node, 1, 0);
5125 index = build_index_type (build_int_2 (len - 1, 0));
5126 type = build_array_type (elem, index);
5127 TREE_TYPE (t) = type;
5128 TREE_CONSTANT (t) = 1;
5129 TREE_INVARIANT (t) = 1;
5130 TREE_READONLY (t) = 1;
5131 TREE_STATIC (t) = 1;
5133 type = build_pointer_type (type);
5134 t = build1 (ADDR_EXPR, type, t);
5136 type = build_pointer_type (elem);
5137 t = build1 (NOP_EXPR, type, t);
5138 return t;
5141 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
5142 Return 0 if a normal call should be emitted rather than transforming
5143 the function inline. If convenient, the result should be placed in
5144 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
5145 call. */
5146 static rtx
5147 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
5148 bool unlocked)
5150 tree fn_putchar = unlocked
5151 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5152 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5153 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5154 : implicit_built_in_decls[BUILT_IN_PUTS];
5155 const char *fmt_str;
5156 tree fn, fmt, arg;
5158 /* If the return value is used, don't do the transformation. */
5159 if (target != const0_rtx)
5160 return 0;
5162 /* Verify the required arguments in the original call. */
5163 if (! arglist)
5164 return 0;
5165 fmt = TREE_VALUE (arglist);
5166 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5167 return 0;
5168 arglist = TREE_CHAIN (arglist);
5170 /* Check whether the format is a literal string constant. */
5171 fmt_str = c_getstr (fmt);
5172 if (fmt_str == NULL)
5173 return 0;
5175 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
5176 if (strcmp (fmt_str, "%s\n") == 0)
5178 if (! arglist
5179 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5180 || TREE_CHAIN (arglist))
5181 return 0;
5182 fn = fn_puts;
5184 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5185 else if (strcmp (fmt_str, "%c") == 0)
5187 if (! arglist
5188 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5189 || TREE_CHAIN (arglist))
5190 return 0;
5191 fn = fn_putchar;
5193 else
5195 /* We can't handle anything else with % args or %% ... yet. */
5196 if (strchr (fmt_str, '%'))
5197 return 0;
5199 if (arglist)
5200 return 0;
5202 /* If the format specifier was "", printf does nothing. */
5203 if (fmt_str[0] == '\0')
5204 return const0_rtx;
5205 /* If the format specifier has length of 1, call putchar. */
5206 if (fmt_str[1] == '\0')
5208 /* Given printf("c"), (where c is any one character,)
5209 convert "c"[0] to an int and pass that to the replacement
5210 function. */
5211 arg = build_int_2 (fmt_str[0], 0);
5212 arglist = build_tree_list (NULL_TREE, arg);
5213 fn = fn_putchar;
5215 else
5217 /* If the format specifier was "string\n", call puts("string"). */
5218 size_t len = strlen (fmt_str);
5219 if (fmt_str[len - 1] == '\n')
5221 /* Create a NUL-terminated string that's one char shorter
5222 than the original, stripping off the trailing '\n'. */
5223 char *newstr = alloca (len);
5224 memcpy (newstr, fmt_str, len - 1);
5225 newstr[len - 1] = 0;
5227 arg = build_string_literal (len, newstr);
5228 arglist = build_tree_list (NULL_TREE, arg);
5229 fn = fn_puts;
5231 else
5232 /* We'd like to arrange to call fputs(string,stdout) here,
5233 but we need stdout and don't have a way to get it yet. */
5234 return 0;
5238 if (!fn)
5239 return 0;
5240 return expand_expr (build_function_call_expr (fn, arglist),
5241 target, mode, EXPAND_NORMAL);
5244 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5245 Return 0 if a normal call should be emitted rather than transforming
5246 the function inline. If convenient, the result should be placed in
5247 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5248 call. */
5249 static rtx
5250 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5251 bool unlocked)
5253 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5254 : implicit_built_in_decls[BUILT_IN_FPUTC];
5255 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5256 : implicit_built_in_decls[BUILT_IN_FPUTS];
5257 const char *fmt_str;
5258 tree fn, fmt, fp, arg;
5260 /* If the return value is used, don't do the transformation. */
5261 if (target != const0_rtx)
5262 return 0;
5264 /* Verify the required arguments in the original call. */
5265 if (! arglist)
5266 return 0;
5267 fp = TREE_VALUE (arglist);
5268 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5269 return 0;
5270 arglist = TREE_CHAIN (arglist);
5271 if (! arglist)
5272 return 0;
5273 fmt = TREE_VALUE (arglist);
5274 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5275 return 0;
5276 arglist = TREE_CHAIN (arglist);
5278 /* Check whether the format is a literal string constant. */
5279 fmt_str = c_getstr (fmt);
5280 if (fmt_str == NULL)
5281 return 0;
5283 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5284 if (strcmp (fmt_str, "%s") == 0)
5286 if (! arglist
5287 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5288 || TREE_CHAIN (arglist))
5289 return 0;
5290 arg = TREE_VALUE (arglist);
5291 arglist = build_tree_list (NULL_TREE, fp);
5292 arglist = tree_cons (NULL_TREE, arg, arglist);
5293 fn = fn_fputs;
5295 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5296 else if (strcmp (fmt_str, "%c") == 0)
5298 if (! arglist
5299 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5300 || TREE_CHAIN (arglist))
5301 return 0;
5302 arg = TREE_VALUE (arglist);
5303 arglist = build_tree_list (NULL_TREE, fp);
5304 arglist = tree_cons (NULL_TREE, arg, arglist);
5305 fn = fn_fputc;
5307 else
5309 /* We can't handle anything else with % args or %% ... yet. */
5310 if (strchr (fmt_str, '%'))
5311 return 0;
5313 if (arglist)
5314 return 0;
5316 /* If the format specifier was "", fprintf does nothing. */
5317 if (fmt_str[0] == '\0')
5319 /* Evaluate and ignore FILE* argument for side-effects. */
5320 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5321 return const0_rtx;
5324 /* When "string" doesn't contain %, replace all cases of
5325 fprintf(stream,string) with fputs(string,stream). The fputs
5326 builtin will take care of special cases like length == 1. */
5327 arglist = build_tree_list (NULL_TREE, fp);
5328 arglist = tree_cons (NULL_TREE, fmt, arglist);
5329 fn = fn_fputs;
5332 if (!fn)
5333 return 0;
5334 return expand_expr (build_function_call_expr (fn, arglist),
5335 target, mode, EXPAND_NORMAL);
5338 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5339 a normal call should be emitted rather than expanding the function
5340 inline. If convenient, the result should be placed in TARGET with
5341 mode MODE. */
5343 static rtx
5344 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5346 tree orig_arglist, dest, fmt;
5347 const char *fmt_str;
5349 orig_arglist = arglist;
5351 /* Verify the required arguments in the original call. */
5352 if (! arglist)
5353 return 0;
5354 dest = TREE_VALUE (arglist);
5355 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5356 return 0;
5357 arglist = TREE_CHAIN (arglist);
5358 if (! arglist)
5359 return 0;
5360 fmt = TREE_VALUE (arglist);
5361 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5362 return 0;
5363 arglist = TREE_CHAIN (arglist);
5365 /* Check whether the format is a literal string constant. */
5366 fmt_str = c_getstr (fmt);
5367 if (fmt_str == NULL)
5368 return 0;
5370 /* If the format doesn't contain % args or %%, use strcpy. */
5371 if (strchr (fmt_str, '%') == 0)
5373 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5374 tree exp;
5376 if (arglist || ! fn)
5377 return 0;
5378 expand_expr (build_function_call_expr (fn, orig_arglist),
5379 const0_rtx, VOIDmode, EXPAND_NORMAL);
5380 if (target == const0_rtx)
5381 return const0_rtx;
5382 exp = build_int_2 (strlen (fmt_str), 0);
5383 exp = fold_convert (integer_type_node, exp);
5384 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5386 /* If the format is "%s", use strcpy if the result isn't used. */
5387 else if (strcmp (fmt_str, "%s") == 0)
5389 tree fn, arg, len;
5390 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5392 if (! fn)
5393 return 0;
5395 if (! arglist || TREE_CHAIN (arglist))
5396 return 0;
5397 arg = TREE_VALUE (arglist);
5398 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5399 return 0;
5401 if (target != const0_rtx)
5403 len = c_strlen (arg, 1);
5404 if (! len || TREE_CODE (len) != INTEGER_CST)
5405 return 0;
5407 else
5408 len = NULL_TREE;
5410 arglist = build_tree_list (NULL_TREE, arg);
5411 arglist = tree_cons (NULL_TREE, dest, arglist);
5412 expand_expr (build_function_call_expr (fn, arglist),
5413 const0_rtx, VOIDmode, EXPAND_NORMAL);
5415 if (target == const0_rtx)
5416 return const0_rtx;
5417 return expand_expr (len, target, mode, EXPAND_NORMAL);
5420 return 0;
5423 /* Expand a call to either the entry or exit function profiler. */
5425 static rtx
5426 expand_builtin_profile_func (bool exitp)
5428 rtx this, which;
5430 this = DECL_RTL (current_function_decl);
5431 if (MEM_P (this))
5432 this = XEXP (this, 0);
5433 else
5434 abort ();
5436 if (exitp)
5437 which = profile_function_exit_libfunc;
5438 else
5439 which = profile_function_entry_libfunc;
5441 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5442 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5443 0, hard_frame_pointer_rtx),
5444 Pmode);
5446 return const0_rtx;
5449 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5451 static rtx
5452 round_trampoline_addr (rtx tramp)
5454 rtx temp, addend, mask;
5456 /* If we don't need too much alignment, we'll have been guaranteed
5457 proper alignment by get_trampoline_type. */
5458 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5459 return tramp;
5461 /* Round address up to desired boundary. */
5462 temp = gen_reg_rtx (Pmode);
5463 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5464 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5466 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5467 temp, 0, OPTAB_LIB_WIDEN);
5468 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5469 temp, 0, OPTAB_LIB_WIDEN);
5471 return tramp;
5474 static rtx
5475 expand_builtin_init_trampoline (tree arglist)
5477 tree t_tramp, t_func, t_chain;
5478 rtx r_tramp, r_func, r_chain;
5479 #ifdef TRAMPOLINE_TEMPLATE
5480 rtx blktramp;
5481 #endif
5483 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5484 POINTER_TYPE, VOID_TYPE))
5485 return NULL_RTX;
5487 t_tramp = TREE_VALUE (arglist);
5488 arglist = TREE_CHAIN (arglist);
5489 t_func = TREE_VALUE (arglist);
5490 arglist = TREE_CHAIN (arglist);
5491 t_chain = TREE_VALUE (arglist);
5493 r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5494 r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5495 r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5497 /* Generate insns to initialize the trampoline. */
5498 r_tramp = round_trampoline_addr (r_tramp);
5499 #ifdef TRAMPOLINE_TEMPLATE
5500 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5501 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5502 emit_block_move (blktramp, assemble_trampoline_template (),
5503 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5504 #endif
5505 trampolines_created = 1;
5506 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5508 return const0_rtx;
5511 static rtx
5512 expand_builtin_adjust_trampoline (tree arglist)
5514 rtx tramp;
5516 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5517 return NULL_RTX;
5519 tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5520 tramp = round_trampoline_addr (tramp);
5521 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5522 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5523 #endif
5525 return tramp;
5528 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5529 Return NULL_RTX if a normal call should be emitted rather than expanding
5530 the function in-line. EXP is the expression that is a call to the builtin
5531 function; if convenient, the result should be placed in TARGET. */
5533 static rtx
5534 expand_builtin_signbit (tree exp, rtx target)
5536 const struct real_format *fmt;
5537 enum machine_mode fmode, imode, rmode;
5538 HOST_WIDE_INT hi, lo;
5539 tree arg, arglist;
5540 int bitpos;
5541 rtx temp;
5543 arglist = TREE_OPERAND (exp, 1);
5544 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5545 return 0;
5547 arg = TREE_VALUE (arglist);
5548 fmode = TYPE_MODE (TREE_TYPE (arg));
5549 rmode = TYPE_MODE (TREE_TYPE (exp));
5550 fmt = REAL_MODE_FORMAT (fmode);
5552 /* For floating point formats without a sign bit, implement signbit
5553 as "ARG < 0.0". */
5554 if (fmt->signbit < 0)
5556 /* But we can't do this if the format supports signed zero. */
5557 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5558 return 0;
5560 arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5561 build_real (TREE_TYPE (arg), dconst0)));
5562 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5565 imode = int_mode_for_mode (fmode);
5566 if (imode == BLKmode)
5567 return 0;
5569 bitpos = fmt->signbit;
5570 /* Handle targets with different FP word orders. */
5571 if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5573 int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5574 int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5575 bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5578 /* If the sign bit is not in the lowpart and the floating point format
5579 is wider than an integer, check that is twice the size of an integer
5580 so that we can use gen_highpart below. */
5581 if (bitpos >= GET_MODE_BITSIZE (rmode)
5582 && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5583 return 0;
5585 temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5586 temp = gen_lowpart (imode, temp);
5588 if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5590 if (BYTES_BIG_ENDIAN)
5591 bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5592 temp = copy_to_mode_reg (imode, temp);
5593 temp = extract_bit_field (temp, 1, bitpos, 1,
5594 NULL_RTX, rmode, rmode);
5596 else
5598 if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5599 temp = gen_lowpart (rmode, temp);
5600 if (bitpos < HOST_BITS_PER_WIDE_INT)
5602 hi = 0;
5603 lo = (HOST_WIDE_INT) 1 << bitpos;
5605 else
5607 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5608 lo = 0;
5611 temp = force_reg (rmode, temp);
5612 temp = expand_binop (rmode, and_optab, temp,
5613 immed_double_const (lo, hi, rmode),
5614 target, 1, OPTAB_LIB_WIDEN);
5616 return temp;
5619 /* Expand fork or exec calls. TARGET is the desired target of the
5620 call. ARGLIST is the list of arguments of the call. FN is the
5621 identificator of the actual function. IGNORE is nonzero if the
5622 value is to be ignored. */
5624 static rtx
5625 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5627 tree id, decl;
5628 tree call;
5630 /* If we are not profiling, just call the function. */
5631 if (!profile_arc_flag)
5632 return NULL_RTX;
5634 /* Otherwise call the wrapper. This should be equivalent for the rest of
5635 compiler, so the code does not diverge, and the wrapper may run the
5636 code necessary for keeping the profiling sane. */
5638 switch (DECL_FUNCTION_CODE (fn))
5640 case BUILT_IN_FORK:
5641 id = get_identifier ("__gcov_fork");
5642 break;
5644 case BUILT_IN_EXECL:
5645 id = get_identifier ("__gcov_execl");
5646 break;
5648 case BUILT_IN_EXECV:
5649 id = get_identifier ("__gcov_execv");
5650 break;
5652 case BUILT_IN_EXECLP:
5653 id = get_identifier ("__gcov_execlp");
5654 break;
5656 case BUILT_IN_EXECLE:
5657 id = get_identifier ("__gcov_execle");
5658 break;
5660 case BUILT_IN_EXECVP:
5661 id = get_identifier ("__gcov_execvp");
5662 break;
5664 case BUILT_IN_EXECVE:
5665 id = get_identifier ("__gcov_execve");
5666 break;
5668 default:
5669 abort ();
5672 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5673 DECL_EXTERNAL (decl) = 1;
5674 TREE_PUBLIC (decl) = 1;
5675 DECL_ARTIFICIAL (decl) = 1;
5676 TREE_NOTHROW (decl) = 1;
5677 call = build_function_call_expr (decl, arglist);
5679 return expand_call (call, target, ignore);
5682 /* Expand an expression EXP that calls a built-in function,
5683 with result going to TARGET if that's convenient
5684 (and in mode MODE if that's convenient).
5685 SUBTARGET may be used as the target for computing one of EXP's operands.
5686 IGNORE is nonzero if the value is to be ignored. */
5689 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5690 int ignore)
5692 tree fndecl = get_callee_fndecl (exp);
5693 tree arglist = TREE_OPERAND (exp, 1);
5694 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5695 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5697 /* Perform postincrements before expanding builtin functions. */
5698 emit_queue ();
5700 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5701 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5703 /* When not optimizing, generate calls to library functions for a certain
5704 set of builtins. */
5705 if (!optimize
5706 && !CALLED_AS_BUILT_IN (fndecl)
5707 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5708 && fcode != BUILT_IN_ALLOCA)
5709 return expand_call (exp, target, ignore);
5711 /* The built-in function expanders test for target == const0_rtx
5712 to determine whether the function's result will be ignored. */
5713 if (ignore)
5714 target = const0_rtx;
5716 /* If the result of a pure or const built-in function is ignored, and
5717 none of its arguments are volatile, we can avoid expanding the
5718 built-in call and just evaluate the arguments for side-effects. */
5719 if (target == const0_rtx
5720 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5722 bool volatilep = false;
5723 tree arg;
5725 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5726 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5728 volatilep = true;
5729 break;
5732 if (! volatilep)
5734 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5735 expand_expr (TREE_VALUE (arg), const0_rtx,
5736 VOIDmode, EXPAND_NORMAL);
5737 return const0_rtx;
5741 switch (fcode)
5743 case BUILT_IN_FABS:
5744 case BUILT_IN_FABSF:
5745 case BUILT_IN_FABSL:
5746 target = expand_builtin_fabs (arglist, target, subtarget);
5747 if (target)
5748 return target;
5749 break;
5751 case BUILT_IN_CABS:
5752 case BUILT_IN_CABSF:
5753 case BUILT_IN_CABSL:
5754 if (flag_unsafe_math_optimizations)
5756 target = expand_builtin_cabs (arglist, target);
5757 if (target)
5758 return target;
5760 break;
5762 case BUILT_IN_EXP:
5763 case BUILT_IN_EXPF:
5764 case BUILT_IN_EXPL:
5765 case BUILT_IN_EXP10:
5766 case BUILT_IN_EXP10F:
5767 case BUILT_IN_EXP10L:
5768 case BUILT_IN_POW10:
5769 case BUILT_IN_POW10F:
5770 case BUILT_IN_POW10L:
5771 case BUILT_IN_EXP2:
5772 case BUILT_IN_EXP2F:
5773 case BUILT_IN_EXP2L:
5774 case BUILT_IN_EXPM1:
5775 case BUILT_IN_EXPM1F:
5776 case BUILT_IN_EXPM1L:
5777 case BUILT_IN_LOGB:
5778 case BUILT_IN_LOGBF:
5779 case BUILT_IN_LOGBL:
5780 case BUILT_IN_ILOGB:
5781 case BUILT_IN_ILOGBF:
5782 case BUILT_IN_ILOGBL:
5783 case BUILT_IN_LOG:
5784 case BUILT_IN_LOGF:
5785 case BUILT_IN_LOGL:
5786 case BUILT_IN_LOG10:
5787 case BUILT_IN_LOG10F:
5788 case BUILT_IN_LOG10L:
5789 case BUILT_IN_LOG2:
5790 case BUILT_IN_LOG2F:
5791 case BUILT_IN_LOG2L:
5792 case BUILT_IN_LOG1P:
5793 case BUILT_IN_LOG1PF:
5794 case BUILT_IN_LOG1PL:
5795 case BUILT_IN_TAN:
5796 case BUILT_IN_TANF:
5797 case BUILT_IN_TANL:
5798 case BUILT_IN_ASIN:
5799 case BUILT_IN_ASINF:
5800 case BUILT_IN_ASINL:
5801 case BUILT_IN_ACOS:
5802 case BUILT_IN_ACOSF:
5803 case BUILT_IN_ACOSL:
5804 case BUILT_IN_ATAN:
5805 case BUILT_IN_ATANF:
5806 case BUILT_IN_ATANL:
5807 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5808 because of possible accuracy problems. */
5809 if (! flag_unsafe_math_optimizations)
5810 break;
5811 case BUILT_IN_SQRT:
5812 case BUILT_IN_SQRTF:
5813 case BUILT_IN_SQRTL:
5814 case BUILT_IN_FLOOR:
5815 case BUILT_IN_FLOORF:
5816 case BUILT_IN_FLOORL:
5817 case BUILT_IN_CEIL:
5818 case BUILT_IN_CEILF:
5819 case BUILT_IN_CEILL:
5820 case BUILT_IN_TRUNC:
5821 case BUILT_IN_TRUNCF:
5822 case BUILT_IN_TRUNCL:
5823 case BUILT_IN_ROUND:
5824 case BUILT_IN_ROUNDF:
5825 case BUILT_IN_ROUNDL:
5826 case BUILT_IN_NEARBYINT:
5827 case BUILT_IN_NEARBYINTF:
5828 case BUILT_IN_NEARBYINTL:
5829 target = expand_builtin_mathfn (exp, target, subtarget);
5830 if (target)
5831 return target;
5832 break;
5834 case BUILT_IN_POW:
5835 case BUILT_IN_POWF:
5836 case BUILT_IN_POWL:
5837 target = expand_builtin_pow (exp, target, subtarget);
5838 if (target)
5839 return target;
5840 break;
5842 case BUILT_IN_ATAN2:
5843 case BUILT_IN_ATAN2F:
5844 case BUILT_IN_ATAN2L:
5845 case BUILT_IN_FMOD:
5846 case BUILT_IN_FMODF:
5847 case BUILT_IN_FMODL:
5848 case BUILT_IN_DREM:
5849 case BUILT_IN_DREMF:
5850 case BUILT_IN_DREML:
5851 if (! flag_unsafe_math_optimizations)
5852 break;
5853 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5854 if (target)
5855 return target;
5856 break;
5858 case BUILT_IN_SIN:
5859 case BUILT_IN_SINF:
5860 case BUILT_IN_SINL:
5861 case BUILT_IN_COS:
5862 case BUILT_IN_COSF:
5863 case BUILT_IN_COSL:
5864 if (! flag_unsafe_math_optimizations)
5865 break;
5866 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5867 if (target)
5868 return target;
5869 break;
5871 case BUILT_IN_APPLY_ARGS:
5872 return expand_builtin_apply_args ();
5874 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5875 FUNCTION with a copy of the parameters described by
5876 ARGUMENTS, and ARGSIZE. It returns a block of memory
5877 allocated on the stack into which is stored all the registers
5878 that might possibly be used for returning the result of a
5879 function. ARGUMENTS is the value returned by
5880 __builtin_apply_args. ARGSIZE is the number of bytes of
5881 arguments that must be copied. ??? How should this value be
5882 computed? We'll also need a safe worst case value for varargs
5883 functions. */
5884 case BUILT_IN_APPLY:
5885 if (!validate_arglist (arglist, POINTER_TYPE,
5886 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5887 && !validate_arglist (arglist, REFERENCE_TYPE,
5888 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5889 return const0_rtx;
5890 else
5892 int i;
5893 tree t;
5894 rtx ops[3];
5896 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5897 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5899 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5902 /* __builtin_return (RESULT) causes the function to return the
5903 value described by RESULT. RESULT is address of the block of
5904 memory returned by __builtin_apply. */
5905 case BUILT_IN_RETURN:
5906 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5907 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5908 NULL_RTX, VOIDmode, 0));
5909 return const0_rtx;
5911 case BUILT_IN_SAVEREGS:
5912 return expand_builtin_saveregs ();
5914 case BUILT_IN_ARGS_INFO:
5915 return expand_builtin_args_info (arglist);
5917 /* Return the address of the first anonymous stack arg. */
5918 case BUILT_IN_NEXT_ARG:
5919 simplify_builtin_next_arg (arglist);
5920 return expand_builtin_next_arg (arglist);
5922 case BUILT_IN_CLASSIFY_TYPE:
5923 return expand_builtin_classify_type (arglist);
5925 case BUILT_IN_CONSTANT_P:
5926 return const0_rtx;
5928 case BUILT_IN_FRAME_ADDRESS:
5929 case BUILT_IN_RETURN_ADDRESS:
5930 return expand_builtin_frame_address (fndecl, arglist);
5932 /* Returns the address of the area where the structure is returned.
5933 0 otherwise. */
5934 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5935 if (arglist != 0
5936 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5937 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5938 return const0_rtx;
5939 else
5940 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5942 case BUILT_IN_ALLOCA:
5943 target = expand_builtin_alloca (arglist, target);
5944 if (target)
5945 return target;
5946 break;
5948 case BUILT_IN_STACK_ALLOC:
5949 expand_stack_alloc (TREE_VALUE (arglist),
5950 TREE_VALUE (TREE_CHAIN (arglist)));
5951 return const0_rtx;
5953 case BUILT_IN_STACK_SAVE:
5954 return expand_stack_save ();
5956 case BUILT_IN_STACK_RESTORE:
5957 expand_stack_restore (TREE_VALUE (arglist));
5958 return const0_rtx;
5960 case BUILT_IN_FFS:
5961 case BUILT_IN_FFSL:
5962 case BUILT_IN_FFSLL:
5963 case BUILT_IN_FFSIMAX:
5964 target = expand_builtin_unop (target_mode, arglist, target,
5965 subtarget, ffs_optab);
5966 if (target)
5967 return target;
5968 break;
5970 case BUILT_IN_CLZ:
5971 case BUILT_IN_CLZL:
5972 case BUILT_IN_CLZLL:
5973 case BUILT_IN_CLZIMAX:
5974 target = expand_builtin_unop (target_mode, arglist, target,
5975 subtarget, clz_optab);
5976 if (target)
5977 return target;
5978 break;
5980 case BUILT_IN_CTZ:
5981 case BUILT_IN_CTZL:
5982 case BUILT_IN_CTZLL:
5983 case BUILT_IN_CTZIMAX:
5984 target = expand_builtin_unop (target_mode, arglist, target,
5985 subtarget, ctz_optab);
5986 if (target)
5987 return target;
5988 break;
5990 case BUILT_IN_POPCOUNT:
5991 case BUILT_IN_POPCOUNTL:
5992 case BUILT_IN_POPCOUNTLL:
5993 case BUILT_IN_POPCOUNTIMAX:
5994 target = expand_builtin_unop (target_mode, arglist, target,
5995 subtarget, popcount_optab);
5996 if (target)
5997 return target;
5998 break;
6000 case BUILT_IN_PARITY:
6001 case BUILT_IN_PARITYL:
6002 case BUILT_IN_PARITYLL:
6003 case BUILT_IN_PARITYIMAX:
6004 target = expand_builtin_unop (target_mode, arglist, target,
6005 subtarget, parity_optab);
6006 if (target)
6007 return target;
6008 break;
6010 case BUILT_IN_STRLEN:
6011 target = expand_builtin_strlen (arglist, target, target_mode);
6012 if (target)
6013 return target;
6014 break;
6016 case BUILT_IN_STRCPY:
6017 target = expand_builtin_strcpy (arglist, target, mode);
6018 if (target)
6019 return target;
6020 break;
6022 case BUILT_IN_STRNCPY:
6023 target = expand_builtin_strncpy (arglist, target, mode);
6024 if (target)
6025 return target;
6026 break;
6028 case BUILT_IN_STPCPY:
6029 target = expand_builtin_stpcpy (arglist, target, mode);
6030 if (target)
6031 return target;
6032 break;
6034 case BUILT_IN_STRCAT:
6035 target = expand_builtin_strcat (arglist, target, mode);
6036 if (target)
6037 return target;
6038 break;
6040 case BUILT_IN_STRNCAT:
6041 target = expand_builtin_strncat (arglist, target, mode);
6042 if (target)
6043 return target;
6044 break;
6046 case BUILT_IN_STRSPN:
6047 target = expand_builtin_strspn (arglist, target, mode);
6048 if (target)
6049 return target;
6050 break;
6052 case BUILT_IN_STRCSPN:
6053 target = expand_builtin_strcspn (arglist, target, mode);
6054 if (target)
6055 return target;
6056 break;
6058 case BUILT_IN_STRSTR:
6059 target = expand_builtin_strstr (arglist, target, mode);
6060 if (target)
6061 return target;
6062 break;
6064 case BUILT_IN_STRPBRK:
6065 target = expand_builtin_strpbrk (arglist, target, mode);
6066 if (target)
6067 return target;
6068 break;
6070 case BUILT_IN_INDEX:
6071 case BUILT_IN_STRCHR:
6072 target = expand_builtin_strchr (arglist, target, mode);
6073 if (target)
6074 return target;
6075 break;
6077 case BUILT_IN_RINDEX:
6078 case BUILT_IN_STRRCHR:
6079 target = expand_builtin_strrchr (arglist, target, mode);
6080 if (target)
6081 return target;
6082 break;
6084 case BUILT_IN_MEMCPY:
6085 target = expand_builtin_memcpy (arglist, target, mode);
6086 if (target)
6087 return target;
6088 break;
6090 case BUILT_IN_MEMPCPY:
6091 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
6092 if (target)
6093 return target;
6094 break;
6096 case BUILT_IN_MEMMOVE:
6097 target = expand_builtin_memmove (arglist, target, mode);
6098 if (target)
6099 return target;
6100 break;
6102 case BUILT_IN_BCOPY:
6103 target = expand_builtin_bcopy (arglist);
6104 if (target)
6105 return target;
6106 break;
6108 case BUILT_IN_MEMSET:
6109 target = expand_builtin_memset (arglist, target, mode);
6110 if (target)
6111 return target;
6112 break;
6114 case BUILT_IN_BZERO:
6115 target = expand_builtin_bzero (arglist);
6116 if (target)
6117 return target;
6118 break;
6120 case BUILT_IN_STRCMP:
6121 target = expand_builtin_strcmp (exp, target, mode);
6122 if (target)
6123 return target;
6124 break;
6126 case BUILT_IN_STRNCMP:
6127 target = expand_builtin_strncmp (exp, target, mode);
6128 if (target)
6129 return target;
6130 break;
6132 case BUILT_IN_BCMP:
6133 case BUILT_IN_MEMCMP:
6134 target = expand_builtin_memcmp (exp, arglist, target, mode);
6135 if (target)
6136 return target;
6137 break;
6139 case BUILT_IN_SETJMP:
6140 target = expand_builtin_setjmp (arglist, target);
6141 if (target)
6142 return target;
6143 break;
6145 /* __builtin_longjmp is passed a pointer to an array of five words.
6146 It's similar to the C library longjmp function but works with
6147 __builtin_setjmp above. */
6148 case BUILT_IN_LONGJMP:
6149 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6150 break;
6151 else
6153 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6154 VOIDmode, 0);
6155 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6156 NULL_RTX, VOIDmode, 0);
6158 if (value != const1_rtx)
6160 error ("__builtin_longjmp second argument must be 1");
6161 return const0_rtx;
6164 expand_builtin_longjmp (buf_addr, value);
6165 return const0_rtx;
6168 case BUILT_IN_NONLOCAL_GOTO:
6169 target = expand_builtin_nonlocal_goto (arglist);
6170 if (target)
6171 return target;
6172 break;
6174 /* This updates the setjmp buffer that is its argument with the value
6175 of the current stack pointer. */
6176 case BUILT_IN_UPDATE_SETJMP_BUF:
6177 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6179 rtx buf_addr
6180 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6182 expand_builtin_update_setjmp_buf (buf_addr);
6183 return const0_rtx;
6185 break;
6187 case BUILT_IN_TRAP:
6188 expand_builtin_trap ();
6189 return const0_rtx;
6191 case BUILT_IN_PRINTF:
6192 target = expand_builtin_printf (arglist, target, mode, false);
6193 if (target)
6194 return target;
6195 break;
6197 case BUILT_IN_PRINTF_UNLOCKED:
6198 target = expand_builtin_printf (arglist, target, mode, true);
6199 if (target)
6200 return target;
6201 break;
6203 case BUILT_IN_FPUTS:
6204 target = expand_builtin_fputs (arglist, target, false);
6205 if (target)
6206 return target;
6207 break;
6208 case BUILT_IN_FPUTS_UNLOCKED:
6209 target = expand_builtin_fputs (arglist, target, true);
6210 if (target)
6211 return target;
6212 break;
6214 case BUILT_IN_FPRINTF:
6215 target = expand_builtin_fprintf (arglist, target, mode, false);
6216 if (target)
6217 return target;
6218 break;
6220 case BUILT_IN_FPRINTF_UNLOCKED:
6221 target = expand_builtin_fprintf (arglist, target, mode, true);
6222 if (target)
6223 return target;
6224 break;
6226 case BUILT_IN_SPRINTF:
6227 target = expand_builtin_sprintf (arglist, target, mode);
6228 if (target)
6229 return target;
6230 break;
6232 case BUILT_IN_SIGNBIT:
6233 case BUILT_IN_SIGNBITF:
6234 case BUILT_IN_SIGNBITL:
6235 target = expand_builtin_signbit (exp, target);
6236 if (target)
6237 return target;
6238 break;
6240 /* Various hooks for the DWARF 2 __throw routine. */
6241 case BUILT_IN_UNWIND_INIT:
6242 expand_builtin_unwind_init ();
6243 return const0_rtx;
6244 case BUILT_IN_DWARF_CFA:
6245 return virtual_cfa_rtx;
6246 #ifdef DWARF2_UNWIND_INFO
6247 case BUILT_IN_DWARF_SP_COLUMN:
6248 return expand_builtin_dwarf_sp_column ();
6249 case BUILT_IN_INIT_DWARF_REG_SIZES:
6250 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6251 return const0_rtx;
6252 #endif
6253 case BUILT_IN_FROB_RETURN_ADDR:
6254 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6255 case BUILT_IN_EXTRACT_RETURN_ADDR:
6256 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6257 case BUILT_IN_EH_RETURN:
6258 expand_builtin_eh_return (TREE_VALUE (arglist),
6259 TREE_VALUE (TREE_CHAIN (arglist)));
6260 return const0_rtx;
6261 #ifdef EH_RETURN_DATA_REGNO
6262 case BUILT_IN_EH_RETURN_DATA_REGNO:
6263 return expand_builtin_eh_return_data_regno (arglist);
6264 #endif
6265 case BUILT_IN_EXTEND_POINTER:
6266 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6268 case BUILT_IN_VA_START:
6269 case BUILT_IN_STDARG_START:
6270 return expand_builtin_va_start (arglist);
6271 case BUILT_IN_VA_END:
6272 return expand_builtin_va_end (arglist);
6273 case BUILT_IN_VA_COPY:
6274 return expand_builtin_va_copy (arglist);
6275 case BUILT_IN_EXPECT:
6276 return expand_builtin_expect (arglist, target);
6277 case BUILT_IN_PREFETCH:
6278 expand_builtin_prefetch (arglist);
6279 return const0_rtx;
6281 case BUILT_IN_PROFILE_FUNC_ENTER:
6282 return expand_builtin_profile_func (false);
6283 case BUILT_IN_PROFILE_FUNC_EXIT:
6284 return expand_builtin_profile_func (true);
6286 case BUILT_IN_INIT_TRAMPOLINE:
6287 return expand_builtin_init_trampoline (arglist);
6288 case BUILT_IN_ADJUST_TRAMPOLINE:
6289 return expand_builtin_adjust_trampoline (arglist);
6291 case BUILT_IN_FORK:
6292 case BUILT_IN_EXECL:
6293 case BUILT_IN_EXECV:
6294 case BUILT_IN_EXECLP:
6295 case BUILT_IN_EXECLE:
6296 case BUILT_IN_EXECVP:
6297 case BUILT_IN_EXECVE:
6298 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6299 if (target)
6300 return target;
6301 break;
6303 default: /* just do library call, if unknown builtin */
6304 break;
6307 /* The switch statement above can drop through to cause the function
6308 to be called normally. */
6309 return expand_call (exp, target, ignore);
6312 /* Determine whether a tree node represents a call to a built-in
6313 function. If the tree T is a call to a built-in function with
6314 the right number of arguments of the appropriate types, return
6315 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6316 Otherwise the return value is END_BUILTINS. */
6318 enum built_in_function
6319 builtin_mathfn_code (tree t)
6321 tree fndecl, arglist, parmlist;
6322 tree argtype, parmtype;
6324 if (TREE_CODE (t) != CALL_EXPR
6325 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6326 return END_BUILTINS;
6328 fndecl = get_callee_fndecl (t);
6329 if (fndecl == NULL_TREE
6330 || TREE_CODE (fndecl) != FUNCTION_DECL
6331 || ! DECL_BUILT_IN (fndecl)
6332 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6333 return END_BUILTINS;
6335 arglist = TREE_OPERAND (t, 1);
6336 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6337 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6339 /* If a function doesn't take a variable number of arguments,
6340 the last element in the list will have type `void'. */
6341 parmtype = TREE_VALUE (parmlist);
6342 if (VOID_TYPE_P (parmtype))
6344 if (arglist)
6345 return END_BUILTINS;
6346 return DECL_FUNCTION_CODE (fndecl);
6349 if (! arglist)
6350 return END_BUILTINS;
6352 argtype = TREE_TYPE (TREE_VALUE (arglist));
6354 if (SCALAR_FLOAT_TYPE_P (parmtype))
6356 if (! SCALAR_FLOAT_TYPE_P (argtype))
6357 return END_BUILTINS;
6359 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6361 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6362 return END_BUILTINS;
6364 else if (POINTER_TYPE_P (parmtype))
6366 if (! POINTER_TYPE_P (argtype))
6367 return END_BUILTINS;
6369 else if (INTEGRAL_TYPE_P (parmtype))
6371 if (! INTEGRAL_TYPE_P (argtype))
6372 return END_BUILTINS;
6374 else
6375 return END_BUILTINS;
6377 arglist = TREE_CHAIN (arglist);
6380 /* Variable-length argument list. */
6381 return DECL_FUNCTION_CODE (fndecl);
6384 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6385 constant. ARGLIST is the argument list of the call. */
6387 static tree
6388 fold_builtin_constant_p (tree arglist)
6390 if (arglist == 0)
6391 return 0;
6393 arglist = TREE_VALUE (arglist);
6395 /* We return 1 for a numeric type that's known to be a constant
6396 value at compile-time or for an aggregate type that's a
6397 literal constant. */
6398 STRIP_NOPS (arglist);
6400 /* If we know this is a constant, emit the constant of one. */
6401 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6402 || (TREE_CODE (arglist) == CONSTRUCTOR
6403 && TREE_CONSTANT (arglist))
6404 || (TREE_CODE (arglist) == ADDR_EXPR
6405 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6406 return integer_one_node;
6408 /* If this expression has side effects, show we don't know it to be a
6409 constant. Likewise if it's a pointer or aggregate type since in
6410 those case we only want literals, since those are only optimized
6411 when generating RTL, not later.
6412 And finally, if we are compiling an initializer, not code, we
6413 need to return a definite result now; there's not going to be any
6414 more optimization done. */
6415 if (TREE_SIDE_EFFECTS (arglist)
6416 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6417 || POINTER_TYPE_P (TREE_TYPE (arglist))
6418 || cfun == 0)
6419 return integer_zero_node;
6421 return 0;
6424 /* Fold a call to __builtin_expect, if we expect that a comparison against
6425 the argument will fold to a constant. In practice, this means a true
6426 constant or the address of a non-weak symbol. ARGLIST is the argument
6427 list of the call. */
6429 static tree
6430 fold_builtin_expect (tree arglist)
6432 tree arg, inner;
6434 if (arglist == 0)
6435 return 0;
6437 arg = TREE_VALUE (arglist);
6439 /* If the argument isn't invariant, then there's nothing we can do. */
6440 if (!TREE_INVARIANT (arg))
6441 return 0;
6443 /* If we're looking at an address of a weak decl, then do not fold. */
6444 inner = arg;
6445 STRIP_NOPS (inner);
6446 if (TREE_CODE (inner) == ADDR_EXPR)
6450 inner = TREE_OPERAND (inner, 0);
6452 while (TREE_CODE (inner) == COMPONENT_REF
6453 || TREE_CODE (inner) == ARRAY_REF);
6454 if (DECL_P (inner) && DECL_WEAK (inner))
6455 return 0;
6458 /* Otherwise, ARG already has the proper type for the return value. */
6459 return arg;
6462 /* Fold a call to __builtin_classify_type. */
6464 static tree
6465 fold_builtin_classify_type (tree arglist)
6467 if (arglist == 0)
6468 return build_int_2 (no_type_class, 0);
6470 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6473 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6475 static tree
6476 fold_builtin_inf (tree type, int warn)
6478 REAL_VALUE_TYPE real;
6480 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6481 warning ("target format does not support infinity");
6483 real_inf (&real);
6484 return build_real (type, real);
6487 /* Fold a call to __builtin_nan or __builtin_nans. */
6489 static tree
6490 fold_builtin_nan (tree arglist, tree type, int quiet)
6492 REAL_VALUE_TYPE real;
6493 const char *str;
6495 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6496 return 0;
6497 str = c_getstr (TREE_VALUE (arglist));
6498 if (!str)
6499 return 0;
6501 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6502 return 0;
6504 return build_real (type, real);
6507 /* Return true if the floating point expression T has an integer value.
6508 We also allow +Inf, -Inf and NaN to be considered integer values. */
6510 static bool
6511 integer_valued_real_p (tree t)
6513 switch (TREE_CODE (t))
6515 case FLOAT_EXPR:
6516 return true;
6518 case ABS_EXPR:
6519 case SAVE_EXPR:
6520 case NON_LVALUE_EXPR:
6521 return integer_valued_real_p (TREE_OPERAND (t, 0));
6523 case COMPOUND_EXPR:
6524 case MODIFY_EXPR:
6525 case BIND_EXPR:
6526 return integer_valued_real_p (TREE_OPERAND (t, 1));
6528 case PLUS_EXPR:
6529 case MINUS_EXPR:
6530 case MULT_EXPR:
6531 case MIN_EXPR:
6532 case MAX_EXPR:
6533 return integer_valued_real_p (TREE_OPERAND (t, 0))
6534 && integer_valued_real_p (TREE_OPERAND (t, 1));
6536 case COND_EXPR:
6537 return integer_valued_real_p (TREE_OPERAND (t, 1))
6538 && integer_valued_real_p (TREE_OPERAND (t, 2));
6540 case REAL_CST:
6541 if (! TREE_CONSTANT_OVERFLOW (t))
6543 REAL_VALUE_TYPE c, cint;
6545 c = TREE_REAL_CST (t);
6546 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6547 return real_identical (&c, &cint);
6550 case NOP_EXPR:
6552 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6553 if (TREE_CODE (type) == INTEGER_TYPE)
6554 return true;
6555 if (TREE_CODE (type) == REAL_TYPE)
6556 return integer_valued_real_p (TREE_OPERAND (t, 0));
6557 break;
6560 case CALL_EXPR:
6561 switch (builtin_mathfn_code (t))
6563 case BUILT_IN_CEIL:
6564 case BUILT_IN_CEILF:
6565 case BUILT_IN_CEILL:
6566 case BUILT_IN_FLOOR:
6567 case BUILT_IN_FLOORF:
6568 case BUILT_IN_FLOORL:
6569 case BUILT_IN_NEARBYINT:
6570 case BUILT_IN_NEARBYINTF:
6571 case BUILT_IN_NEARBYINTL:
6572 case BUILT_IN_RINT:
6573 case BUILT_IN_RINTF:
6574 case BUILT_IN_RINTL:
6575 case BUILT_IN_ROUND:
6576 case BUILT_IN_ROUNDF:
6577 case BUILT_IN_ROUNDL:
6578 case BUILT_IN_TRUNC:
6579 case BUILT_IN_TRUNCF:
6580 case BUILT_IN_TRUNCL:
6581 return true;
6583 default:
6584 break;
6586 break;
6588 default:
6589 break;
6591 return false;
6594 /* EXP is assumed to be builtin call where truncation can be propagated
6595 across (for instance floor((double)f) == (double)floorf (f).
6596 Do the transformation. */
6598 static tree
6599 fold_trunc_transparent_mathfn (tree exp)
6601 tree fndecl = get_callee_fndecl (exp);
6602 tree arglist = TREE_OPERAND (exp, 1);
6603 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6604 tree arg;
6606 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6607 return 0;
6609 arg = TREE_VALUE (arglist);
6610 /* Integer rounding functions are idempotent. */
6611 if (fcode == builtin_mathfn_code (arg))
6612 return arg;
6614 /* If argument is already integer valued, and we don't need to worry
6615 about setting errno, there's no need to perform rounding. */
6616 if (! flag_errno_math && integer_valued_real_p (arg))
6617 return arg;
6619 if (optimize)
6621 tree arg0 = strip_float_extensions (arg);
6622 tree ftype = TREE_TYPE (exp);
6623 tree newtype = TREE_TYPE (arg0);
6624 tree decl;
6626 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6627 && (decl = mathfn_built_in (newtype, fcode)))
6629 arglist =
6630 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6631 return fold_convert (ftype,
6632 build_function_call_expr (decl, arglist));
6635 return 0;
6638 /* EXP is assumed to be builtin call which can narrow the FP type of
6639 the argument, for instance lround((double)f) -> lroundf (f). */
6641 static tree
6642 fold_fixed_mathfn (tree exp)
6644 tree fndecl = get_callee_fndecl (exp);
6645 tree arglist = TREE_OPERAND (exp, 1);
6646 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6647 tree arg;
6649 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6650 return 0;
6652 arg = TREE_VALUE (arglist);
6654 /* If argument is already integer valued, and we don't need to worry
6655 about setting errno, there's no need to perform rounding. */
6656 if (! flag_errno_math && integer_valued_real_p (arg))
6657 return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6659 if (optimize)
6661 tree ftype = TREE_TYPE (arg);
6662 tree arg0 = strip_float_extensions (arg);
6663 tree newtype = TREE_TYPE (arg0);
6664 tree decl;
6666 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6667 && (decl = mathfn_built_in (newtype, fcode)))
6669 arglist =
6670 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6671 return build_function_call_expr (decl, arglist);
6674 return 0;
6677 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6678 is the argument list and TYPE is the return type. Return
6679 NULL_TREE if no if no simplification can be made. */
6681 static tree
6682 fold_builtin_cabs (tree arglist, tree type)
6684 tree arg;
6686 if (!arglist || TREE_CHAIN (arglist))
6687 return NULL_TREE;
6689 arg = TREE_VALUE (arglist);
6690 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6691 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6692 return NULL_TREE;
6694 /* Evaluate cabs of a constant at compile-time. */
6695 if (flag_unsafe_math_optimizations
6696 && TREE_CODE (arg) == COMPLEX_CST
6697 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6698 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6699 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6700 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6702 REAL_VALUE_TYPE r, i;
6704 r = TREE_REAL_CST (TREE_REALPART (arg));
6705 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6707 real_arithmetic (&r, MULT_EXPR, &r, &r);
6708 real_arithmetic (&i, MULT_EXPR, &i, &i);
6709 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6710 if (real_sqrt (&r, TYPE_MODE (type), &r)
6711 || ! flag_trapping_math)
6712 return build_real (type, r);
6715 /* If either part is zero, cabs is fabs of the other. */
6716 if (TREE_CODE (arg) == COMPLEX_EXPR
6717 && real_zerop (TREE_OPERAND (arg, 0)))
6718 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6719 if (TREE_CODE (arg) == COMPLEX_EXPR
6720 && real_zerop (TREE_OPERAND (arg, 1)))
6721 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6723 if (flag_unsafe_math_optimizations)
6725 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6727 if (sqrtfn != NULL_TREE)
6729 tree rpart, ipart, result, arglist;
6731 arg = builtin_save_expr (arg);
6733 rpart = fold (build1 (REALPART_EXPR, type, arg));
6734 ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6736 rpart = builtin_save_expr (rpart);
6737 ipart = builtin_save_expr (ipart);
6739 result = fold (build2 (PLUS_EXPR, type,
6740 fold (build2 (MULT_EXPR, type,
6741 rpart, rpart)),
6742 fold (build2 (MULT_EXPR, type,
6743 ipart, ipart))));
6745 arglist = build_tree_list (NULL_TREE, result);
6746 return build_function_call_expr (sqrtfn, arglist);
6750 return NULL_TREE;
6753 /* Fold function call to builtin trunc, truncf or truncl. Return
6754 NULL_TREE if no simplification can be made. */
6756 static tree
6757 fold_builtin_trunc (tree exp)
6759 tree arglist = TREE_OPERAND (exp, 1);
6760 tree arg;
6762 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6763 return 0;
6765 /* Optimize trunc of constant value. */
6766 arg = TREE_VALUE (arglist);
6767 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6769 REAL_VALUE_TYPE r, x;
6770 tree type = TREE_TYPE (exp);
6772 x = TREE_REAL_CST (arg);
6773 real_trunc (&r, TYPE_MODE (type), &x);
6774 return build_real (type, r);
6777 return fold_trunc_transparent_mathfn (exp);
6780 /* Fold function call to builtin floor, floorf or floorl. Return
6781 NULL_TREE if no simplification can be made. */
6783 static tree
6784 fold_builtin_floor (tree exp)
6786 tree arglist = TREE_OPERAND (exp, 1);
6787 tree arg;
6789 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6790 return 0;
6792 /* Optimize floor of constant value. */
6793 arg = TREE_VALUE (arglist);
6794 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6796 REAL_VALUE_TYPE x;
6798 x = TREE_REAL_CST (arg);
6799 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6801 tree type = TREE_TYPE (exp);
6802 REAL_VALUE_TYPE r;
6804 real_floor (&r, TYPE_MODE (type), &x);
6805 return build_real (type, r);
6809 return fold_trunc_transparent_mathfn (exp);
6812 /* Fold function call to builtin ceil, ceilf or ceill. Return
6813 NULL_TREE if no simplification can be made. */
6815 static tree
6816 fold_builtin_ceil (tree exp)
6818 tree arglist = TREE_OPERAND (exp, 1);
6819 tree arg;
6821 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6822 return 0;
6824 /* Optimize ceil of constant value. */
6825 arg = TREE_VALUE (arglist);
6826 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6828 REAL_VALUE_TYPE x;
6830 x = TREE_REAL_CST (arg);
6831 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6833 tree type = TREE_TYPE (exp);
6834 REAL_VALUE_TYPE r;
6836 real_ceil (&r, TYPE_MODE (type), &x);
6837 return build_real (type, r);
6841 return fold_trunc_transparent_mathfn (exp);
6844 /* Fold function call to builtin round, roundf or roundl. Return
6845 NULL_TREE if no simplification can be made. */
6847 static tree
6848 fold_builtin_round (tree exp)
6850 tree arglist = TREE_OPERAND (exp, 1);
6851 tree arg;
6853 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6854 return 0;
6856 /* Optimize round of constant value. */
6857 arg = TREE_VALUE (arglist);
6858 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6860 REAL_VALUE_TYPE x;
6862 x = TREE_REAL_CST (arg);
6863 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6865 tree type = TREE_TYPE (exp);
6866 REAL_VALUE_TYPE r;
6868 real_round (&r, TYPE_MODE (type), &x);
6869 return build_real (type, r);
6873 return fold_trunc_transparent_mathfn (exp);
6876 /* Fold function call to builtin lround, lroundf or lroundl (or the
6877 corresponding long long versions). Return NULL_TREE if no
6878 simplification can be made. */
6880 static tree
6881 fold_builtin_lround (tree exp)
6883 tree arglist = TREE_OPERAND (exp, 1);
6884 tree arg;
6886 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6887 return 0;
6889 /* Optimize lround of constant value. */
6890 arg = TREE_VALUE (arglist);
6891 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6893 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6895 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6897 tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6898 HOST_WIDE_INT hi, lo;
6899 REAL_VALUE_TYPE r;
6901 real_round (&r, TYPE_MODE (ftype), &x);
6902 REAL_VALUE_TO_INT (&lo, &hi, r);
6903 result = build_int_2 (lo, hi);
6904 if (int_fits_type_p (result, itype))
6905 return fold_convert (itype, result);
6909 return fold_fixed_mathfn (exp);
6912 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6913 and their long and long long variants (i.e. ffsl and ffsll).
6914 Return NULL_TREE if no simplification can be made. */
6916 static tree
6917 fold_builtin_bitop (tree exp)
6919 tree fndecl = get_callee_fndecl (exp);
6920 tree arglist = TREE_OPERAND (exp, 1);
6921 tree arg;
6923 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6924 return NULL_TREE;
6926 /* Optimize for constant argument. */
6927 arg = TREE_VALUE (arglist);
6928 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6930 HOST_WIDE_INT hi, width, result;
6931 unsigned HOST_WIDE_INT lo;
6932 tree type, t;
6934 type = TREE_TYPE (arg);
6935 width = TYPE_PRECISION (type);
6936 lo = TREE_INT_CST_LOW (arg);
6938 /* Clear all the bits that are beyond the type's precision. */
6939 if (width > HOST_BITS_PER_WIDE_INT)
6941 hi = TREE_INT_CST_HIGH (arg);
6942 if (width < 2 * HOST_BITS_PER_WIDE_INT)
6943 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6945 else
6947 hi = 0;
6948 if (width < HOST_BITS_PER_WIDE_INT)
6949 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6952 switch (DECL_FUNCTION_CODE (fndecl))
6954 case BUILT_IN_FFS:
6955 case BUILT_IN_FFSL:
6956 case BUILT_IN_FFSLL:
6957 if (lo != 0)
6958 result = exact_log2 (lo & -lo) + 1;
6959 else if (hi != 0)
6960 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6961 else
6962 result = 0;
6963 break;
6965 case BUILT_IN_CLZ:
6966 case BUILT_IN_CLZL:
6967 case BUILT_IN_CLZLL:
6968 if (hi != 0)
6969 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6970 else if (lo != 0)
6971 result = width - floor_log2 (lo) - 1;
6972 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6973 result = width;
6974 break;
6976 case BUILT_IN_CTZ:
6977 case BUILT_IN_CTZL:
6978 case BUILT_IN_CTZLL:
6979 if (lo != 0)
6980 result = exact_log2 (lo & -lo);
6981 else if (hi != 0)
6982 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6983 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6984 result = width;
6985 break;
6987 case BUILT_IN_POPCOUNT:
6988 case BUILT_IN_POPCOUNTL:
6989 case BUILT_IN_POPCOUNTLL:
6990 result = 0;
6991 while (lo)
6992 result++, lo &= lo - 1;
6993 while (hi)
6994 result++, hi &= hi - 1;
6995 break;
6997 case BUILT_IN_PARITY:
6998 case BUILT_IN_PARITYL:
6999 case BUILT_IN_PARITYLL:
7000 result = 0;
7001 while (lo)
7002 result++, lo &= lo - 1;
7003 while (hi)
7004 result++, hi &= hi - 1;
7005 result &= 1;
7006 break;
7008 default:
7009 abort();
7012 t = build_int_2 (result, 0);
7013 TREE_TYPE (t) = TREE_TYPE (exp);
7014 return t;
7017 return NULL_TREE;
7020 /* Return true if EXPR is the real constant contained in VALUE. */
7022 static bool
7023 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7025 STRIP_NOPS (expr);
7027 return ((TREE_CODE (expr) == REAL_CST
7028 && ! TREE_CONSTANT_OVERFLOW (expr)
7029 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7030 || (TREE_CODE (expr) == COMPLEX_CST
7031 && real_dconstp (TREE_REALPART (expr), value)
7032 && real_zerop (TREE_IMAGPART (expr))));
7035 /* A subroutine of fold_builtin to fold the various logarithmic
7036 functions. EXP is the CALL_EXPR of a call to a builtin logN
7037 function. VALUE is the base of the logN function. */
7039 static tree
7040 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
7042 tree arglist = TREE_OPERAND (exp, 1);
7044 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7046 tree fndecl = get_callee_fndecl (exp);
7047 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7048 tree arg = TREE_VALUE (arglist);
7049 const enum built_in_function fcode = builtin_mathfn_code (arg);
7051 /* Optimize logN(1.0) = 0.0. */
7052 if (real_onep (arg))
7053 return build_real (type, dconst0);
7055 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7056 exactly, then only do this if flag_unsafe_math_optimizations. */
7057 if (exact_real_truncate (TYPE_MODE (type), value)
7058 || flag_unsafe_math_optimizations)
7060 const REAL_VALUE_TYPE value_truncate =
7061 real_value_truncate (TYPE_MODE (type), *value);
7062 if (real_dconstp (arg, &value_truncate))
7063 return build_real (type, dconst1);
7066 /* Special case, optimize logN(expN(x)) = x. */
7067 if (flag_unsafe_math_optimizations
7068 && ((value == &dconste
7069 && (fcode == BUILT_IN_EXP
7070 || fcode == BUILT_IN_EXPF
7071 || fcode == BUILT_IN_EXPL))
7072 || (value == &dconst2
7073 && (fcode == BUILT_IN_EXP2
7074 || fcode == BUILT_IN_EXP2F
7075 || fcode == BUILT_IN_EXP2L))
7076 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7077 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7079 /* Optimize logN(func()) for various exponential functions. We
7080 want to determine the value "x" and the power "exponent" in
7081 order to transform logN(x**exponent) into exponent*logN(x). */
7082 if (flag_unsafe_math_optimizations)
7084 tree exponent = 0, x = 0;
7086 switch (fcode)
7088 case BUILT_IN_EXP:
7089 case BUILT_IN_EXPF:
7090 case BUILT_IN_EXPL:
7091 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7092 x = build_real (type,
7093 real_value_truncate (TYPE_MODE (type), dconste));
7094 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7095 break;
7096 case BUILT_IN_EXP2:
7097 case BUILT_IN_EXP2F:
7098 case BUILT_IN_EXP2L:
7099 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7100 x = build_real (type, dconst2);
7101 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7102 break;
7103 case BUILT_IN_EXP10:
7104 case BUILT_IN_EXP10F:
7105 case BUILT_IN_EXP10L:
7106 case BUILT_IN_POW10:
7107 case BUILT_IN_POW10F:
7108 case BUILT_IN_POW10L:
7109 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7110 x = build_real (type, dconst10);
7111 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7112 break;
7113 case BUILT_IN_SQRT:
7114 case BUILT_IN_SQRTF:
7115 case BUILT_IN_SQRTL:
7116 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7117 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7118 exponent = build_real (type, dconsthalf);
7119 break;
7120 case BUILT_IN_CBRT:
7121 case BUILT_IN_CBRTF:
7122 case BUILT_IN_CBRTL:
7123 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7124 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7125 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7126 dconstthird));
7127 break;
7128 case BUILT_IN_POW:
7129 case BUILT_IN_POWF:
7130 case BUILT_IN_POWL:
7131 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7132 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7133 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7134 break;
7135 default:
7136 break;
7139 /* Now perform the optimization. */
7140 if (x && exponent)
7142 tree logfn;
7143 arglist = build_tree_list (NULL_TREE, x);
7144 logfn = build_function_call_expr (fndecl, arglist);
7145 return fold (build2 (MULT_EXPR, type, exponent, logfn));
7150 return 0;
7153 /* A subroutine of fold_builtin to fold the various exponent
7154 functions. EXP is the CALL_EXPR of a call to a builtin function.
7155 VALUE is the value which will be raised to a power. */
7157 static tree
7158 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
7160 tree arglist = TREE_OPERAND (exp, 1);
7162 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7164 tree fndecl = get_callee_fndecl (exp);
7165 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7166 tree arg = TREE_VALUE (arglist);
7168 /* Optimize exp*(0.0) = 1.0. */
7169 if (real_zerop (arg))
7170 return build_real (type, dconst1);
7172 /* Optimize expN(1.0) = N. */
7173 if (real_onep (arg))
7175 REAL_VALUE_TYPE cst;
7177 real_convert (&cst, TYPE_MODE (type), value);
7178 return build_real (type, cst);
7181 /* Attempt to evaluate expN(integer) at compile-time. */
7182 if (flag_unsafe_math_optimizations
7183 && TREE_CODE (arg) == REAL_CST
7184 && ! TREE_CONSTANT_OVERFLOW (arg))
7186 REAL_VALUE_TYPE cint;
7187 REAL_VALUE_TYPE c;
7188 HOST_WIDE_INT n;
7190 c = TREE_REAL_CST (arg);
7191 n = real_to_integer (&c);
7192 real_from_integer (&cint, VOIDmode, n,
7193 n < 0 ? -1 : 0, 0);
7194 if (real_identical (&c, &cint))
7196 REAL_VALUE_TYPE x;
7198 real_powi (&x, TYPE_MODE (type), value, n);
7199 return build_real (type, x);
7203 /* Optimize expN(logN(x)) = x. */
7204 if (flag_unsafe_math_optimizations)
7206 const enum built_in_function fcode = builtin_mathfn_code (arg);
7208 if ((value == &dconste
7209 && (fcode == BUILT_IN_LOG
7210 || fcode == BUILT_IN_LOGF
7211 || fcode == BUILT_IN_LOGL))
7212 || (value == &dconst2
7213 && (fcode == BUILT_IN_LOG2
7214 || fcode == BUILT_IN_LOG2F
7215 || fcode == BUILT_IN_LOG2L))
7216 || (value == &dconst10
7217 && (fcode == BUILT_IN_LOG10
7218 || fcode == BUILT_IN_LOG10F
7219 || fcode == BUILT_IN_LOG10L)))
7220 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7224 return 0;
7227 /* Fold function call to builtin memcpy. Return
7228 NULL_TREE if no simplification can be made. */
7230 static tree
7231 fold_builtin_memcpy (tree exp)
7233 tree arglist = TREE_OPERAND (exp, 1);
7234 tree dest, src, len;
7236 if (!validate_arglist (arglist,
7237 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7238 return 0;
7240 dest = TREE_VALUE (arglist);
7241 src = TREE_VALUE (TREE_CHAIN (arglist));
7242 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7244 /* If the LEN parameter is zero, return DEST. */
7245 if (integer_zerop (len))
7246 return omit_one_operand (TREE_TYPE (exp), dest, src);
7248 /* If SRC and DEST are the same (and not volatile), return DEST. */
7249 if (operand_equal_p (src, dest, 0))
7250 return omit_one_operand (TREE_TYPE (exp), dest, len);
7252 return 0;
7255 /* Fold function call to builtin mempcpy. Return
7256 NULL_TREE if no simplification can be made. */
7258 static tree
7259 fold_builtin_mempcpy (tree exp)
7261 tree arglist = TREE_OPERAND (exp, 1);
7262 tree dest, src, len;
7264 if (!validate_arglist (arglist,
7265 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7266 return 0;
7268 dest = TREE_VALUE (arglist);
7269 src = TREE_VALUE (TREE_CHAIN (arglist));
7270 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7272 /* If the LEN parameter is zero, return DEST. */
7273 if (integer_zerop (len))
7274 return omit_one_operand (TREE_TYPE (exp), dest, src);
7276 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7277 if (operand_equal_p (src, dest, 0))
7279 tree temp = fold_convert (TREE_TYPE (dest), len);
7280 temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7281 return fold_convert (TREE_TYPE (exp), temp);
7284 return 0;
7287 /* Fold function call to builtin memmove. Return
7288 NULL_TREE if no simplification can be made. */
7290 static tree
7291 fold_builtin_memmove (tree exp)
7293 tree arglist = TREE_OPERAND (exp, 1);
7294 tree dest, src, len;
7296 if (!validate_arglist (arglist,
7297 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7298 return 0;
7300 dest = TREE_VALUE (arglist);
7301 src = TREE_VALUE (TREE_CHAIN (arglist));
7302 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7304 /* If the LEN parameter is zero, return DEST. */
7305 if (integer_zerop (len))
7306 return omit_one_operand (TREE_TYPE (exp), dest, src);
7308 /* If SRC and DEST are the same (and not volatile), return DEST. */
7309 if (operand_equal_p (src, dest, 0))
7310 return omit_one_operand (TREE_TYPE (exp), dest, len);
7312 return 0;
7315 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7316 the length of the string to be copied. Return NULL_TREE if no
7317 simplification can be made. */
7319 tree
7320 fold_builtin_strcpy (tree exp, tree len)
7322 tree arglist = TREE_OPERAND (exp, 1);
7323 tree dest, src, fn;
7325 if (!validate_arglist (arglist,
7326 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7327 return 0;
7329 dest = TREE_VALUE (arglist);
7330 src = TREE_VALUE (TREE_CHAIN (arglist));
7332 /* If SRC and DEST are the same (and not volatile), return DEST. */
7333 if (operand_equal_p (src, dest, 0))
7334 return fold_convert (TREE_TYPE (exp), dest);
7336 if (optimize_size)
7337 return 0;
7339 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7340 if (!fn)
7341 return 0;
7343 if (!len)
7345 len = c_strlen (src, 1);
7346 if (! len || TREE_SIDE_EFFECTS (len))
7347 return 0;
7350 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7351 arglist = build_tree_list (NULL_TREE, len);
7352 arglist = tree_cons (NULL_TREE, src, arglist);
7353 arglist = tree_cons (NULL_TREE, dest, arglist);
7354 return fold_convert (TREE_TYPE (exp),
7355 build_function_call_expr (fn, arglist));
7358 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7359 the length of the source string. Return NULL_TREE if no simplification
7360 can be made. */
7362 tree
7363 fold_builtin_strncpy (tree exp, tree slen)
7365 tree arglist = TREE_OPERAND (exp, 1);
7366 tree dest, src, len, fn;
7368 if (!validate_arglist (arglist,
7369 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7370 return 0;
7372 dest = TREE_VALUE (arglist);
7373 src = TREE_VALUE (TREE_CHAIN (arglist));
7374 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7376 /* If the LEN parameter is zero, return DEST. */
7377 if (integer_zerop (len))
7378 return omit_one_operand (TREE_TYPE (exp), dest, src);
7380 /* We can't compare slen with len as constants below if len is not a
7381 constant. */
7382 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7383 return 0;
7385 if (!slen)
7386 slen = c_strlen (src, 1);
7388 /* Now, we must be passed a constant src ptr parameter. */
7389 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7390 return 0;
7392 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7394 /* We do not support simplification of this case, though we do
7395 support it when expanding trees into RTL. */
7396 /* FIXME: generate a call to __builtin_memset. */
7397 if (tree_int_cst_lt (slen, len))
7398 return 0;
7400 /* OK transform into builtin memcpy. */
7401 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7402 if (!fn)
7403 return 0;
7404 return fold_convert (TREE_TYPE (exp),
7405 build_function_call_expr (fn, arglist));
7408 /* Fold function call to builtin strchr and strrchr.
7409 Return NULL_TREE if no simplification can be made. */
7411 static tree
7412 fold_builtin_strchr (tree exp, bool actually_strrchr)
7414 tree arglist = TREE_OPERAND (exp, 1);
7415 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7416 return 0;
7417 else
7419 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7420 const char *p1;
7422 if (TREE_CODE (s2) != INTEGER_CST)
7423 return 0;
7425 p1 = c_getstr (s1);
7426 if (p1 != NULL)
7428 char c;
7429 const char *r;
7431 if (target_char_cast (s2, &c))
7432 return 0;
7434 r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7436 if (r == NULL)
7437 return fold_convert (TREE_TYPE (s1), integer_zero_node);
7439 /* Return an offset into the constant string argument. */
7440 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7441 s1, fold_convert (TREE_TYPE (s1),
7442 ssize_int (r - p1))));
7445 if (actually_strrchr)
7447 tree fn;
7449 if (!integer_zerop (s2))
7450 return 0;
7452 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7453 if (!fn)
7454 return 0;
7456 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
7457 return build_function_call_expr (fn, arglist);
7460 return 0;
7464 /* Fold function call to builtin memcmp. Return
7465 NULL_TREE if no simplification can be made. */
7467 static tree
7468 fold_builtin_memcmp (tree exp)
7470 tree arglist = TREE_OPERAND (exp, 1);
7471 tree arg1, arg2, len;
7473 if (!validate_arglist (arglist,
7474 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7475 return 0;
7477 arg1 = TREE_VALUE (arglist);
7478 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7479 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7481 /* If the LEN parameter is zero, return zero. */
7482 if (integer_zerop (len))
7484 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7485 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7488 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7489 if (operand_equal_p (arg1, arg2, 0))
7490 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7492 return 0;
7495 /* Fold function call to builtin strcmp. Return
7496 NULL_TREE if no simplification can be made. */
7498 static tree
7499 fold_builtin_strcmp (tree exp)
7501 tree arglist = TREE_OPERAND (exp, 1);
7502 tree arg1, arg2;
7503 const char *p1, *p2;
7505 if (!validate_arglist (arglist,
7506 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7507 return 0;
7509 arg1 = TREE_VALUE (arglist);
7510 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7512 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7513 if (operand_equal_p (arg1, arg2, 0))
7514 return fold_convert (TREE_TYPE (exp), integer_zero_node);
7516 p1 = c_getstr (arg1);
7517 p2 = c_getstr (arg2);
7519 if (p1 && p2)
7521 tree temp;
7522 const int i = strcmp (p1, p2);
7523 if (i < 0)
7524 temp = integer_minus_one_node;
7525 else if (i > 0)
7526 temp = integer_one_node;
7527 else
7528 temp = integer_zero_node;
7529 return fold_convert (TREE_TYPE (exp), temp);
7532 return 0;
7535 /* Fold function call to builtin strncmp. Return
7536 NULL_TREE if no simplification can be made. */
7538 static tree
7539 fold_builtin_strncmp (tree exp)
7541 tree arglist = TREE_OPERAND (exp, 1);
7542 tree arg1, arg2, len;
7543 const char *p1, *p2;
7545 if (!validate_arglist (arglist,
7546 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7547 return 0;
7549 arg1 = TREE_VALUE (arglist);
7550 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7551 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7553 /* If the LEN parameter is zero, return zero. */
7554 if (integer_zerop (len))
7556 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7557 return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7560 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7561 if (operand_equal_p (arg1, arg2, 0))
7562 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7564 p1 = c_getstr (arg1);
7565 p2 = c_getstr (arg2);
7567 if (host_integerp (len, 1) && p1 && p2)
7569 tree temp;
7570 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7571 if (i < 0)
7572 temp = integer_minus_one_node;
7573 else if (i > 0)
7574 temp = integer_one_node;
7575 else
7576 temp = integer_zero_node;
7577 return fold_convert (TREE_TYPE (exp), temp);
7580 return 0;
7583 /* Fold function call to builtin signbit, signbitf or signbitl. Return
7584 NULL_TREE if no simplification can be made. */
7586 static tree
7587 fold_builtin_signbit (tree exp)
7589 tree arglist = TREE_OPERAND (exp, 1);
7590 tree arg, temp;
7592 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7593 return NULL_TREE;
7595 arg = TREE_VALUE (arglist);
7597 /* If ARG is a compile-time constant, determine the result. */
7598 if (TREE_CODE (arg) == REAL_CST
7599 && !TREE_CONSTANT_OVERFLOW (arg))
7601 REAL_VALUE_TYPE c;
7603 c = TREE_REAL_CST (arg);
7604 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7605 return fold_convert (TREE_TYPE (exp), temp);
7608 /* If ARG is non-negative, the result is always zero. */
7609 if (tree_expr_nonnegative_p (arg))
7610 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7612 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
7613 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7614 return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7615 build_real (TREE_TYPE (arg), dconst0)));
7617 return NULL_TREE;
7620 /* Fold function call to builtin copysign, copysignf or copysignl.
7621 Return NULL_TREE if no simplification can be made. */
7623 static tree
7624 fold_builtin_copysign (tree arglist, tree type)
7626 tree arg1, arg2;
7628 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7629 return NULL_TREE;
7631 arg1 = TREE_VALUE (arglist);
7632 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7634 /* copysign(X,X) is X. */
7635 if (operand_equal_p (arg1, arg2, 0))
7636 return fold_convert (type, arg1);
7638 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
7639 if (TREE_CODE (arg1) == REAL_CST
7640 && TREE_CODE (arg2) == REAL_CST
7641 && !TREE_CONSTANT_OVERFLOW (arg1)
7642 && !TREE_CONSTANT_OVERFLOW (arg2))
7644 REAL_VALUE_TYPE c1, c2;
7646 c1 = TREE_REAL_CST (arg1);
7647 c2 = TREE_REAL_CST (arg2);
7648 real_copysign (&c1, &c2);
7649 return build_real (type, c1);
7650 c1.sign = c2.sign;
7653 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7654 Remember to evaluate Y for side-effects. */
7655 if (tree_expr_nonnegative_p (arg2))
7656 return omit_one_operand (type,
7657 fold (build1 (ABS_EXPR, type, arg1)),
7658 arg2);
7660 return NULL_TREE;
7663 /* Fold a call to builtin isascii. */
7665 static tree
7666 fold_builtin_isascii (tree arglist)
7668 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7669 return 0;
7670 else
7672 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7673 tree arg = TREE_VALUE (arglist);
7675 arg = fold (build2 (EQ_EXPR, integer_type_node,
7676 build2 (BIT_AND_EXPR, integer_type_node, arg,
7677 build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7678 ~ (HOST_WIDE_INT) 0)),
7679 integer_zero_node));
7681 if (in_gimple_form && !TREE_CONSTANT (arg))
7682 return NULL_TREE;
7683 else
7684 return arg;
7688 /* Fold a call to builtin toascii. */
7690 static tree
7691 fold_builtin_toascii (tree arglist)
7693 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7694 return 0;
7695 else
7697 /* Transform toascii(c) -> (c & 0x7f). */
7698 tree arg = TREE_VALUE (arglist);
7700 return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7701 build_int_2 (0x7f, 0)));
7705 /* Fold a call to builtin isdigit. */
7707 static tree
7708 fold_builtin_isdigit (tree arglist)
7710 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7711 return 0;
7712 else
7714 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
7715 /* According to the C standard, isdigit is unaffected by locale. */
7716 tree arg = TREE_VALUE (arglist);
7717 arg = fold_convert (unsigned_type_node, arg);
7718 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7719 fold_convert (unsigned_type_node,
7720 build_int_2 (TARGET_DIGIT0, 0)));
7721 arg = build2 (LE_EXPR, integer_type_node, arg,
7722 fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7723 arg = fold (arg);
7724 if (in_gimple_form && !TREE_CONSTANT (arg))
7725 return NULL_TREE;
7726 else
7727 return arg;
7731 /* Fold a call to fabs, fabsf or fabsl. */
7733 static tree
7734 fold_builtin_fabs (tree arglist, tree type)
7736 tree arg;
7738 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7739 return 0;
7741 arg = TREE_VALUE (arglist);
7742 if (TREE_CODE (arg) == REAL_CST)
7743 return fold_abs_const (arg, type);
7744 return fold (build1 (ABS_EXPR, type, arg));
7747 /* Fold a call to abs, labs, llabs or imaxabs. */
7749 static tree
7750 fold_builtin_abs (tree arglist, tree type)
7752 tree arg;
7754 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7755 return 0;
7757 arg = TREE_VALUE (arglist);
7758 if (TREE_CODE (arg) == INTEGER_CST)
7759 return fold_abs_const (arg, type);
7760 return fold (build1 (ABS_EXPR, type, arg));
7763 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7764 EXP is the CALL_EXPR for the call. */
7766 static tree
7767 fold_builtin_classify (tree exp, int builtin_index)
7769 tree fndecl = get_callee_fndecl (exp);
7770 tree arglist = TREE_OPERAND (exp, 1);
7771 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7772 tree arg;
7773 REAL_VALUE_TYPE r;
7775 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7777 /* Check that we have exactly one argument. */
7778 if (arglist == 0)
7780 error ("too few arguments to function `%s'",
7781 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7782 return error_mark_node;
7784 else if (TREE_CHAIN (arglist) != 0)
7786 error ("too many arguments to function `%s'",
7787 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7788 return error_mark_node;
7790 else
7792 error ("non-floating-point argument to function `%s'",
7793 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7794 return error_mark_node;
7798 arg = TREE_VALUE (arglist);
7799 switch (builtin_index)
7801 case BUILT_IN_ISINF:
7802 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7803 return omit_one_operand (type, integer_zero_node, arg);
7805 if (TREE_CODE (arg) == REAL_CST)
7807 r = TREE_REAL_CST (arg);
7808 if (real_isinf (&r))
7809 return real_compare (GT_EXPR, &r, &dconst0)
7810 ? integer_one_node : integer_minus_one_node;
7811 else
7812 return integer_zero_node;
7815 return NULL_TREE;
7817 case BUILT_IN_FINITE:
7818 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7819 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7820 return omit_one_operand (type, integer_zero_node, arg);
7822 if (TREE_CODE (arg) == REAL_CST)
7824 r = TREE_REAL_CST (arg);
7825 return real_isinf (&r) || real_isnan (&r)
7826 ? integer_zero_node : integer_one_node;
7829 return NULL_TREE;
7831 case BUILT_IN_ISNAN:
7832 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7833 return omit_one_operand (type, integer_zero_node, arg);
7835 if (TREE_CODE (arg) == REAL_CST)
7837 r = TREE_REAL_CST (arg);
7838 return real_isnan (&r) ? integer_one_node : integer_zero_node;
7841 arg = builtin_save_expr (arg);
7842 return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7844 default:
7845 abort ();
7849 /* Fold a call to an unordered comparison function such as
7850 __builtin_isgreater(). EXP is the CALL_EXPR for the call.
7851 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7852 the opposite of the desired result. UNORDERED_CODE is used
7853 for modes that can hold NaNs and ORDERED_CODE is used for
7854 the rest. */
7856 static tree
7857 fold_builtin_unordered_cmp (tree exp,
7858 enum tree_code unordered_code,
7859 enum tree_code ordered_code)
7861 tree fndecl = get_callee_fndecl (exp);
7862 tree arglist = TREE_OPERAND (exp, 1);
7863 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7864 enum tree_code code;
7865 tree arg0, arg1;
7867 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7869 enum tree_code code0, code1;
7870 tree type0, type1;
7871 tree cmp_type = 0;
7873 /* Check that we have exactly two arguments. */
7874 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7876 error ("too few arguments to function `%s'",
7877 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7878 return error_mark_node;
7880 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7882 error ("too many arguments to function `%s'",
7883 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7884 return error_mark_node;
7887 arg0 = TREE_VALUE (arglist);
7888 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7890 type0 = TREE_TYPE (arg0);
7891 type1 = TREE_TYPE (arg1);
7893 code0 = TREE_CODE (type0);
7894 code1 = TREE_CODE (type1);
7896 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7897 /* Choose the wider of two real types. */
7898 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7899 ? type0 : type1;
7900 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7901 cmp_type = type0;
7902 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7903 cmp_type = type1;
7904 else
7906 error ("non-floating-point argument to function `%s'",
7907 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7908 return error_mark_node;
7911 arg0 = fold_convert (cmp_type, arg0);
7912 arg1 = fold_convert (cmp_type, arg1);
7914 else
7916 arg0 = TREE_VALUE (arglist);
7917 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7920 if (unordered_code == UNORDERED_EXPR)
7922 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7923 return omit_two_operands (type, integer_zero_node, arg0, arg1);
7924 return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7927 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7928 : ordered_code;
7929 return fold (build1 (TRUTH_NOT_EXPR, type,
7930 fold (build2 (code, type, arg0, arg1))));
7933 /* Used by constant folding to simplify calls to builtin functions. EXP is
7934 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
7935 result of the function call is ignored. This function returns NULL_TREE
7936 if no simplification was possible. */
7938 static tree
7939 fold_builtin_1 (tree exp, bool ignore)
7941 tree fndecl = get_callee_fndecl (exp);
7942 tree arglist = TREE_OPERAND (exp, 1);
7943 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7945 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7946 return 0;
7948 switch (DECL_FUNCTION_CODE (fndecl))
7950 case BUILT_IN_CONSTANT_P:
7951 return fold_builtin_constant_p (arglist);
7953 case BUILT_IN_EXPECT:
7954 return fold_builtin_expect (arglist);
7956 case BUILT_IN_CLASSIFY_TYPE:
7957 return fold_builtin_classify_type (arglist);
7959 case BUILT_IN_STRLEN:
7960 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7962 tree len = c_strlen (TREE_VALUE (arglist), 0);
7963 if (len)
7965 /* Convert from the internal "sizetype" type to "size_t". */
7966 if (size_type_node)
7967 len = fold_convert (size_type_node, len);
7968 return len;
7971 break;
7973 case BUILT_IN_FABS:
7974 case BUILT_IN_FABSF:
7975 case BUILT_IN_FABSL:
7976 return fold_builtin_fabs (arglist, type);
7978 case BUILT_IN_ABS:
7979 case BUILT_IN_LABS:
7980 case BUILT_IN_LLABS:
7981 case BUILT_IN_IMAXABS:
7982 return fold_builtin_abs (arglist, type);
7984 case BUILT_IN_CONJ:
7985 case BUILT_IN_CONJF:
7986 case BUILT_IN_CONJL:
7987 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7988 return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7989 break;
7991 case BUILT_IN_CREAL:
7992 case BUILT_IN_CREALF:
7993 case BUILT_IN_CREALL:
7994 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7995 return non_lvalue (fold (build1 (REALPART_EXPR, type,
7996 TREE_VALUE (arglist))));
7997 break;
7999 case BUILT_IN_CIMAG:
8000 case BUILT_IN_CIMAGF:
8001 case BUILT_IN_CIMAGL:
8002 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8003 return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
8004 TREE_VALUE (arglist))));
8005 break;
8007 case BUILT_IN_CABS:
8008 case BUILT_IN_CABSF:
8009 case BUILT_IN_CABSL:
8010 return fold_builtin_cabs (arglist, type);
8012 case BUILT_IN_SQRT:
8013 case BUILT_IN_SQRTF:
8014 case BUILT_IN_SQRTL:
8015 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8017 enum built_in_function fcode;
8018 tree arg = TREE_VALUE (arglist);
8020 /* Optimize sqrt of constant value. */
8021 if (TREE_CODE (arg) == REAL_CST
8022 && ! TREE_CONSTANT_OVERFLOW (arg))
8024 REAL_VALUE_TYPE r, x;
8026 x = TREE_REAL_CST (arg);
8027 if (real_sqrt (&r, TYPE_MODE (type), &x)
8028 || (!flag_trapping_math && !flag_errno_math))
8029 return build_real (type, r);
8032 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
8033 fcode = builtin_mathfn_code (arg);
8034 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8036 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8037 arg = fold (build2 (MULT_EXPR, type,
8038 TREE_VALUE (TREE_OPERAND (arg, 1)),
8039 build_real (type, dconsthalf)));
8040 arglist = build_tree_list (NULL_TREE, arg);
8041 return build_function_call_expr (expfn, arglist);
8044 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
8045 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
8047 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8049 if (powfn)
8051 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8052 tree tree_root;
8053 /* The inner root was either sqrt or cbrt. */
8054 REAL_VALUE_TYPE dconstroot =
8055 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
8057 /* Adjust for the outer root. */
8058 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8059 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8060 tree_root = build_real (type, dconstroot);
8061 arglist = tree_cons (NULL_TREE, arg0,
8062 build_tree_list (NULL_TREE, tree_root));
8063 return build_function_call_expr (powfn, arglist);
8067 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
8068 if (flag_unsafe_math_optimizations
8069 && (fcode == BUILT_IN_POW
8070 || fcode == BUILT_IN_POWF
8071 || fcode == BUILT_IN_POWL))
8073 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8074 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8075 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
8076 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8077 build_real (type, dconsthalf)));
8078 arglist = tree_cons (NULL_TREE, arg0,
8079 build_tree_list (NULL_TREE, narg1));
8080 return build_function_call_expr (powfn, arglist);
8083 break;
8085 case BUILT_IN_CBRT:
8086 case BUILT_IN_CBRTF:
8087 case BUILT_IN_CBRTL:
8088 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8090 tree arg = TREE_VALUE (arglist);
8091 const enum built_in_function fcode = builtin_mathfn_code (arg);
8093 /* Optimize cbrt of constant value. */
8094 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
8095 return arg;
8097 /* Optimize cbrt(expN(x)) -> expN(x/3). */
8098 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8100 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8101 const REAL_VALUE_TYPE third_trunc =
8102 real_value_truncate (TYPE_MODE (type), dconstthird);
8103 arg = fold (build2 (MULT_EXPR, type,
8104 TREE_VALUE (TREE_OPERAND (arg, 1)),
8105 build_real (type, third_trunc)));
8106 arglist = build_tree_list (NULL_TREE, arg);
8107 return build_function_call_expr (expfn, arglist);
8110 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
8111 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8112 x is negative pow will error but cbrt won't. */
8113 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8115 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8117 if (powfn)
8119 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8120 tree tree_root;
8121 REAL_VALUE_TYPE dconstroot = dconstthird;
8123 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8124 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8125 tree_root = build_real (type, dconstroot);
8126 arglist = tree_cons (NULL_TREE, arg0,
8127 build_tree_list (NULL_TREE, tree_root));
8128 return build_function_call_expr (powfn, arglist);
8133 break;
8135 case BUILT_IN_SIN:
8136 case BUILT_IN_SINF:
8137 case BUILT_IN_SINL:
8138 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8140 tree arg = TREE_VALUE (arglist);
8142 /* Optimize sin(0.0) = 0.0. */
8143 if (real_zerop (arg))
8144 return arg;
8146 break;
8148 case BUILT_IN_COS:
8149 case BUILT_IN_COSF:
8150 case BUILT_IN_COSL:
8151 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8153 tree arg = TREE_VALUE (arglist);
8155 /* Optimize cos(0.0) = 1.0. */
8156 if (real_zerop (arg))
8157 return build_real (type, dconst1);
8159 /* Optimize cos(-x) into cos(x). */
8160 if (TREE_CODE (arg) == NEGATE_EXPR)
8162 tree arglist = build_tree_list (NULL_TREE,
8163 TREE_OPERAND (arg, 0));
8164 return build_function_call_expr (fndecl, arglist);
8167 break;
8169 case BUILT_IN_EXP:
8170 case BUILT_IN_EXPF:
8171 case BUILT_IN_EXPL:
8172 return fold_builtin_exponent (exp, &dconste);
8174 case BUILT_IN_EXP2:
8175 case BUILT_IN_EXP2F:
8176 case BUILT_IN_EXP2L:
8177 return fold_builtin_exponent (exp, &dconst2);
8179 case BUILT_IN_EXP10:
8180 case BUILT_IN_EXP10F:
8181 case BUILT_IN_EXP10L:
8182 case BUILT_IN_POW10:
8183 case BUILT_IN_POW10F:
8184 case BUILT_IN_POW10L:
8185 return fold_builtin_exponent (exp, &dconst10);
8187 case BUILT_IN_LOG:
8188 case BUILT_IN_LOGF:
8189 case BUILT_IN_LOGL:
8190 return fold_builtin_logarithm (exp, &dconste);
8192 case BUILT_IN_LOG2:
8193 case BUILT_IN_LOG2F:
8194 case BUILT_IN_LOG2L:
8195 return fold_builtin_logarithm (exp, &dconst2);
8197 case BUILT_IN_LOG10:
8198 case BUILT_IN_LOG10F:
8199 case BUILT_IN_LOG10L:
8200 return fold_builtin_logarithm (exp, &dconst10);
8202 case BUILT_IN_TAN:
8203 case BUILT_IN_TANF:
8204 case BUILT_IN_TANL:
8205 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8207 enum built_in_function fcode;
8208 tree arg = TREE_VALUE (arglist);
8210 /* Optimize tan(0.0) = 0.0. */
8211 if (real_zerop (arg))
8212 return arg;
8214 /* Optimize tan(atan(x)) = x. */
8215 fcode = builtin_mathfn_code (arg);
8216 if (flag_unsafe_math_optimizations
8217 && (fcode == BUILT_IN_ATAN
8218 || fcode == BUILT_IN_ATANF
8219 || fcode == BUILT_IN_ATANL))
8220 return TREE_VALUE (TREE_OPERAND (arg, 1));
8222 break;
8224 case BUILT_IN_ATAN:
8225 case BUILT_IN_ATANF:
8226 case BUILT_IN_ATANL:
8227 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8229 tree arg = TREE_VALUE (arglist);
8231 /* Optimize atan(0.0) = 0.0. */
8232 if (real_zerop (arg))
8233 return arg;
8235 /* Optimize atan(1.0) = pi/4. */
8236 if (real_onep (arg))
8238 REAL_VALUE_TYPE cst;
8240 real_convert (&cst, TYPE_MODE (type), &dconstpi);
8241 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8242 return build_real (type, cst);
8245 break;
8247 case BUILT_IN_POW:
8248 case BUILT_IN_POWF:
8249 case BUILT_IN_POWL:
8250 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8252 enum built_in_function fcode;
8253 tree arg0 = TREE_VALUE (arglist);
8254 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8256 /* Optimize pow(1.0,y) = 1.0. */
8257 if (real_onep (arg0))
8258 return omit_one_operand (type, build_real (type, dconst1), arg1);
8260 if (TREE_CODE (arg1) == REAL_CST
8261 && ! TREE_CONSTANT_OVERFLOW (arg1))
8263 REAL_VALUE_TYPE c;
8264 c = TREE_REAL_CST (arg1);
8266 /* Optimize pow(x,0.0) = 1.0. */
8267 if (REAL_VALUES_EQUAL (c, dconst0))
8268 return omit_one_operand (type, build_real (type, dconst1),
8269 arg0);
8271 /* Optimize pow(x,1.0) = x. */
8272 if (REAL_VALUES_EQUAL (c, dconst1))
8273 return arg0;
8275 /* Optimize pow(x,-1.0) = 1.0/x. */
8276 if (REAL_VALUES_EQUAL (c, dconstm1))
8277 return fold (build2 (RDIV_EXPR, type,
8278 build_real (type, dconst1), arg0));
8280 /* Optimize pow(x,0.5) = sqrt(x). */
8281 if (flag_unsafe_math_optimizations
8282 && REAL_VALUES_EQUAL (c, dconsthalf))
8284 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8286 if (sqrtfn != NULL_TREE)
8288 tree arglist = build_tree_list (NULL_TREE, arg0);
8289 return build_function_call_expr (sqrtfn, arglist);
8293 /* Attempt to evaluate pow at compile-time. */
8294 if (TREE_CODE (arg0) == REAL_CST
8295 && ! TREE_CONSTANT_OVERFLOW (arg0))
8297 REAL_VALUE_TYPE cint;
8298 HOST_WIDE_INT n;
8300 n = real_to_integer (&c);
8301 real_from_integer (&cint, VOIDmode, n,
8302 n < 0 ? -1 : 0, 0);
8303 if (real_identical (&c, &cint))
8305 REAL_VALUE_TYPE x;
8306 bool inexact;
8308 x = TREE_REAL_CST (arg0);
8309 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8310 if (flag_unsafe_math_optimizations || !inexact)
8311 return build_real (type, x);
8316 /* Optimize pow(expN(x),y) = expN(x*y). */
8317 fcode = builtin_mathfn_code (arg0);
8318 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8320 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8321 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8322 arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8323 arglist = build_tree_list (NULL_TREE, arg);
8324 return build_function_call_expr (expfn, arglist);
8327 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8328 if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8330 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8331 tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8332 build_real (type, dconsthalf)));
8334 arglist = tree_cons (NULL_TREE, narg0,
8335 build_tree_list (NULL_TREE, narg1));
8336 return build_function_call_expr (fndecl, arglist);
8339 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8340 if (flag_unsafe_math_optimizations
8341 && (fcode == BUILT_IN_POW
8342 || fcode == BUILT_IN_POWF
8343 || fcode == BUILT_IN_POWL))
8345 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8346 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8347 tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8348 arglist = tree_cons (NULL_TREE, arg00,
8349 build_tree_list (NULL_TREE, narg1));
8350 return build_function_call_expr (fndecl, arglist);
8353 break;
8355 case BUILT_IN_INF:
8356 case BUILT_IN_INFF:
8357 case BUILT_IN_INFL:
8358 return fold_builtin_inf (type, true);
8360 case BUILT_IN_HUGE_VAL:
8361 case BUILT_IN_HUGE_VALF:
8362 case BUILT_IN_HUGE_VALL:
8363 return fold_builtin_inf (type, false);
8365 case BUILT_IN_NAN:
8366 case BUILT_IN_NANF:
8367 case BUILT_IN_NANL:
8368 return fold_builtin_nan (arglist, type, true);
8370 case BUILT_IN_NANS:
8371 case BUILT_IN_NANSF:
8372 case BUILT_IN_NANSL:
8373 return fold_builtin_nan (arglist, type, false);
8375 case BUILT_IN_FLOOR:
8376 case BUILT_IN_FLOORF:
8377 case BUILT_IN_FLOORL:
8378 return fold_builtin_floor (exp);
8380 case BUILT_IN_CEIL:
8381 case BUILT_IN_CEILF:
8382 case BUILT_IN_CEILL:
8383 return fold_builtin_ceil (exp);
8385 case BUILT_IN_TRUNC:
8386 case BUILT_IN_TRUNCF:
8387 case BUILT_IN_TRUNCL:
8388 return fold_builtin_trunc (exp);
8390 case BUILT_IN_ROUND:
8391 case BUILT_IN_ROUNDF:
8392 case BUILT_IN_ROUNDL:
8393 return fold_builtin_round (exp);
8395 case BUILT_IN_NEARBYINT:
8396 case BUILT_IN_NEARBYINTF:
8397 case BUILT_IN_NEARBYINTL:
8398 case BUILT_IN_RINT:
8399 case BUILT_IN_RINTF:
8400 case BUILT_IN_RINTL:
8401 return fold_trunc_transparent_mathfn (exp);
8403 case BUILT_IN_LROUND:
8404 case BUILT_IN_LROUNDF:
8405 case BUILT_IN_LROUNDL:
8406 case BUILT_IN_LLROUND:
8407 case BUILT_IN_LLROUNDF:
8408 case BUILT_IN_LLROUNDL:
8409 return fold_builtin_lround (exp);
8411 case BUILT_IN_LRINT:
8412 case BUILT_IN_LRINTF:
8413 case BUILT_IN_LRINTL:
8414 case BUILT_IN_LLRINT:
8415 case BUILT_IN_LLRINTF:
8416 case BUILT_IN_LLRINTL:
8417 return fold_fixed_mathfn (exp);
8419 case BUILT_IN_FFS:
8420 case BUILT_IN_FFSL:
8421 case BUILT_IN_FFSLL:
8422 case BUILT_IN_CLZ:
8423 case BUILT_IN_CLZL:
8424 case BUILT_IN_CLZLL:
8425 case BUILT_IN_CTZ:
8426 case BUILT_IN_CTZL:
8427 case BUILT_IN_CTZLL:
8428 case BUILT_IN_POPCOUNT:
8429 case BUILT_IN_POPCOUNTL:
8430 case BUILT_IN_POPCOUNTLL:
8431 case BUILT_IN_PARITY:
8432 case BUILT_IN_PARITYL:
8433 case BUILT_IN_PARITYLL:
8434 return fold_builtin_bitop (exp);
8436 case BUILT_IN_MEMCPY:
8437 return fold_builtin_memcpy (exp);
8439 case BUILT_IN_MEMPCPY:
8440 return fold_builtin_mempcpy (exp);
8442 case BUILT_IN_MEMMOVE:
8443 return fold_builtin_memmove (exp);
8445 case BUILT_IN_STRCPY:
8446 return fold_builtin_strcpy (exp, NULL_TREE);
8448 case BUILT_IN_STRNCPY:
8449 return fold_builtin_strncpy (exp, NULL_TREE);
8451 case BUILT_IN_INDEX:
8452 case BUILT_IN_STRCHR:
8453 return fold_builtin_strchr (exp, false);
8455 case BUILT_IN_RINDEX:
8456 case BUILT_IN_STRRCHR:
8457 return fold_builtin_strchr (exp, true);
8459 case BUILT_IN_MEMCMP:
8460 return fold_builtin_memcmp (exp);
8462 case BUILT_IN_STRCMP:
8463 return fold_builtin_strcmp (exp);
8465 case BUILT_IN_STRNCMP:
8466 return fold_builtin_strncmp (exp);
8468 case BUILT_IN_SIGNBIT:
8469 case BUILT_IN_SIGNBITF:
8470 case BUILT_IN_SIGNBITL:
8471 return fold_builtin_signbit (exp);
8473 case BUILT_IN_ISASCII:
8474 return fold_builtin_isascii (arglist);
8476 case BUILT_IN_TOASCII:
8477 return fold_builtin_toascii (arglist);
8479 case BUILT_IN_ISDIGIT:
8480 return fold_builtin_isdigit (arglist);
8482 case BUILT_IN_COPYSIGN:
8483 case BUILT_IN_COPYSIGNF:
8484 case BUILT_IN_COPYSIGNL:
8485 return fold_builtin_copysign (arglist, type);
8487 case BUILT_IN_FINITE:
8488 case BUILT_IN_FINITEF:
8489 case BUILT_IN_FINITEL:
8490 return fold_builtin_classify (exp, BUILT_IN_FINITE);
8492 case BUILT_IN_ISINF:
8493 case BUILT_IN_ISINFF:
8494 case BUILT_IN_ISINFL:
8495 return fold_builtin_classify (exp, BUILT_IN_ISINF);
8497 case BUILT_IN_ISNAN:
8498 case BUILT_IN_ISNANF:
8499 case BUILT_IN_ISNANL:
8500 return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8502 case BUILT_IN_ISGREATER:
8503 return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8504 case BUILT_IN_ISGREATEREQUAL:
8505 return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8506 case BUILT_IN_ISLESS:
8507 return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8508 case BUILT_IN_ISLESSEQUAL:
8509 return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8510 case BUILT_IN_ISLESSGREATER:
8511 return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8512 case BUILT_IN_ISUNORDERED:
8513 return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8515 case BUILT_IN_FPUTS:
8516 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8518 case BUILT_IN_FPUTS_UNLOCKED:
8519 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8521 default:
8522 break;
8525 return 0;
8528 /* A wrapper function for builtin folding that prevents warnings for
8529 "statement without effect" and the like, caused by removing the
8530 call node earlier than the warning is generated. */
8532 tree
8533 fold_builtin (tree exp, bool ignore)
8535 exp = fold_builtin_1 (exp, ignore);
8536 if (exp)
8538 /* ??? Don't clobber shared nodes such as integer_zero_node. */
8539 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8540 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8541 TREE_NO_WARNING (exp) = 1;
8543 return exp;
8546 /* Conveniently construct a function call expression. */
8548 tree
8549 build_function_call_expr (tree fn, tree arglist)
8551 tree call_expr;
8553 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8554 call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8555 call_expr, arglist, NULL_TREE);
8556 return fold (call_expr);
8559 /* This function validates the types of a function call argument list
8560 represented as a tree chain of parameters against a specified list
8561 of tree_codes. If the last specifier is a 0, that represents an
8562 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8564 static int
8565 validate_arglist (tree arglist, ...)
8567 enum tree_code code;
8568 int res = 0;
8569 va_list ap;
8571 va_start (ap, arglist);
8575 code = va_arg (ap, enum tree_code);
8576 switch (code)
8578 case 0:
8579 /* This signifies an ellipses, any further arguments are all ok. */
8580 res = 1;
8581 goto end;
8582 case VOID_TYPE:
8583 /* This signifies an endlink, if no arguments remain, return
8584 true, otherwise return false. */
8585 res = arglist == 0;
8586 goto end;
8587 default:
8588 /* If no parameters remain or the parameter's code does not
8589 match the specified code, return false. Otherwise continue
8590 checking any remaining arguments. */
8591 if (arglist == 0
8592 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8593 goto end;
8594 break;
8596 arglist = TREE_CHAIN (arglist);
8598 while (1);
8600 /* We need gotos here since we can only have one VA_CLOSE in a
8601 function. */
8602 end: ;
8603 va_end (ap);
8605 return res;
8608 /* Default target-specific builtin expander that does nothing. */
8611 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8612 rtx target ATTRIBUTE_UNUSED,
8613 rtx subtarget ATTRIBUTE_UNUSED,
8614 enum machine_mode mode ATTRIBUTE_UNUSED,
8615 int ignore ATTRIBUTE_UNUSED)
8617 return NULL_RTX;
8620 /* Returns true is EXP represents data that would potentially reside
8621 in a readonly section. */
8623 static bool
8624 readonly_data_expr (tree exp)
8626 STRIP_NOPS (exp);
8628 if (TREE_CODE (exp) != ADDR_EXPR)
8629 return false;
8631 exp = get_base_address (TREE_OPERAND (exp, 0));
8632 if (!exp)
8633 return false;
8635 /* Make sure we call decl_readonly_section only for trees it
8636 can handle (since it returns true for everything it doesn't
8637 understand). */
8638 if (TREE_CODE (exp) == STRING_CST
8639 || TREE_CODE (exp) == CONSTRUCTOR
8640 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8641 return decl_readonly_section (exp, 0);
8642 else
8643 return false;
8646 /* Front-end to the simplify_builtin_XXX routines.
8648 EXP is a call to a builtin function. If possible try to simplify
8649 that into a constant, expression or call to a more efficient
8650 builtin function.
8652 If IGNORE is nonzero, then the result of this builtin function
8653 call is ignored.
8655 If simplification is possible, return the simplified tree, otherwise
8656 return NULL_TREE. */
8658 tree
8659 simplify_builtin (tree exp, int ignore)
8661 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8662 tree arglist = TREE_OPERAND (exp, 1);
8663 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8664 tree val;
8666 switch (fcode)
8668 case BUILT_IN_FPUTS:
8669 val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8670 break;
8671 case BUILT_IN_FPUTS_UNLOCKED:
8672 val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8673 break;
8674 case BUILT_IN_STRSTR:
8675 val = simplify_builtin_strstr (arglist);
8676 break;
8677 case BUILT_IN_STRCAT:
8678 val = simplify_builtin_strcat (arglist);
8679 break;
8680 case BUILT_IN_STRNCAT:
8681 val = simplify_builtin_strncat (arglist);
8682 break;
8683 case BUILT_IN_STRSPN:
8684 val = simplify_builtin_strspn (arglist);
8685 break;
8686 case BUILT_IN_STRCSPN:
8687 val = simplify_builtin_strcspn (arglist);
8688 break;
8689 case BUILT_IN_STRCHR:
8690 case BUILT_IN_INDEX:
8691 val = simplify_builtin_strchr (arglist);
8692 break;
8693 case BUILT_IN_STRRCHR:
8694 case BUILT_IN_RINDEX:
8695 val = simplify_builtin_strrchr (arglist);
8696 break;
8697 case BUILT_IN_STRCPY:
8698 val = fold_builtin_strcpy (exp, NULL_TREE);
8699 break;
8700 case BUILT_IN_STRNCPY:
8701 val = fold_builtin_strncpy (exp, NULL_TREE);
8702 break;
8703 case BUILT_IN_STRCMP:
8704 val = simplify_builtin_strcmp (arglist);
8705 break;
8706 case BUILT_IN_STRNCMP:
8707 val = simplify_builtin_strncmp (arglist);
8708 break;
8709 case BUILT_IN_STRPBRK:
8710 val = simplify_builtin_strpbrk (arglist);
8711 break;
8712 case BUILT_IN_BCMP:
8713 case BUILT_IN_MEMCMP:
8714 val = simplify_builtin_memcmp (arglist);
8715 break;
8716 case BUILT_IN_VA_START:
8717 simplify_builtin_va_start (arglist);
8718 val = NULL_TREE;
8719 break;
8720 case BUILT_IN_SPRINTF:
8721 val = simplify_builtin_sprintf (arglist, ignore);
8722 break;
8723 case BUILT_IN_CONSTANT_P:
8724 val = fold_builtin_constant_p (arglist);
8725 /* Gimplification will pull the CALL_EXPR for the builtin out of
8726 an if condition. When not optimizing, we'll not CSE it back.
8727 To avoid link error types of regressions, return false now. */
8728 if (!val && !optimize)
8729 val = integer_zero_node;
8730 break;
8731 default:
8732 val = NULL_TREE;
8733 break;
8736 if (val)
8737 val = fold_convert (TREE_TYPE (exp), val);
8738 return val;
8741 /* Simplify a call to the strstr builtin.
8743 Return 0 if no simplification was possible, otherwise return the
8744 simplified form of the call as a tree.
8746 The simplified form may be a constant or other expression which
8747 computes the same value, but in a more efficient manner (including
8748 calls to other builtin functions).
8750 The call may contain arguments which need to be evaluated, but
8751 which are not useful to determine the result of the call. In
8752 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8753 COMPOUND_EXPR will be an argument which must be evaluated.
8754 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8755 COMPOUND_EXPR in the chain will contain the tree for the simplified
8756 form of the builtin function call. */
8758 static tree
8759 simplify_builtin_strstr (tree arglist)
8761 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8762 return 0;
8763 else
8765 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8766 tree fn;
8767 const char *p1, *p2;
8769 p2 = c_getstr (s2);
8770 if (p2 == NULL)
8771 return 0;
8773 p1 = c_getstr (s1);
8774 if (p1 != NULL)
8776 const char *r = strstr (p1, p2);
8778 if (r == NULL)
8779 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8781 /* Return an offset into the constant string argument. */
8782 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8783 s1, fold_convert (TREE_TYPE (s1),
8784 ssize_int (r - p1))));
8787 if (p2[0] == '\0')
8788 return s1;
8790 if (p2[1] != '\0')
8791 return 0;
8793 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8794 if (!fn)
8795 return 0;
8797 /* New argument list transforming strstr(s1, s2) to
8798 strchr(s1, s2[0]). */
8799 arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8800 arglist = tree_cons (NULL_TREE, s1, arglist);
8801 return build_function_call_expr (fn, arglist);
8805 /* Simplify a call to the strstr builtin.
8807 Return 0 if no simplification was possible, otherwise return the
8808 simplified form of the call as a tree.
8810 The simplified form may be a constant or other expression which
8811 computes the same value, but in a more efficient manner (including
8812 calls to other builtin functions).
8814 The call may contain arguments which need to be evaluated, but
8815 which are not useful to determine the result of the call. In
8816 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8817 COMPOUND_EXPR will be an argument which must be evaluated.
8818 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8819 COMPOUND_EXPR in the chain will contain the tree for the simplified
8820 form of the builtin function call. */
8822 static tree
8823 simplify_builtin_strchr (tree arglist)
8825 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8826 return 0;
8827 else
8829 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8830 const char *p1;
8832 if (TREE_CODE (s2) != INTEGER_CST)
8833 return 0;
8835 p1 = c_getstr (s1);
8836 if (p1 != NULL)
8838 char c;
8839 const char *r;
8841 if (target_char_cast (s2, &c))
8842 return 0;
8844 r = strchr (p1, c);
8846 if (r == NULL)
8847 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8849 /* Return an offset into the constant string argument. */
8850 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8851 s1, fold_convert (TREE_TYPE (s1),
8852 ssize_int (r - p1))));
8855 /* FIXME: Should use here strchrM optab so that ports can optimize
8856 this. */
8857 return 0;
8861 /* Simplify a call to the strrchr builtin.
8863 Return 0 if no simplification was possible, otherwise return the
8864 simplified form of the call as a tree.
8866 The simplified form may be a constant or other expression which
8867 computes the same value, but in a more efficient manner (including
8868 calls to other builtin functions).
8870 The call may contain arguments which need to be evaluated, but
8871 which are not useful to determine the result of the call. In
8872 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8873 COMPOUND_EXPR will be an argument which must be evaluated.
8874 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8875 COMPOUND_EXPR in the chain will contain the tree for the simplified
8876 form of the builtin function call. */
8878 static tree
8879 simplify_builtin_strrchr (tree arglist)
8881 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8882 return 0;
8883 else
8885 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8886 tree fn;
8887 const char *p1;
8889 if (TREE_CODE (s2) != INTEGER_CST)
8890 return 0;
8892 p1 = c_getstr (s1);
8893 if (p1 != NULL)
8895 char c;
8896 const char *r;
8898 if (target_char_cast (s2, &c))
8899 return 0;
8901 r = strrchr (p1, c);
8903 if (r == NULL)
8904 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8906 /* Return an offset into the constant string argument. */
8907 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8908 s1, fold_convert (TREE_TYPE (s1),
8909 ssize_int (r - p1))));
8912 if (! integer_zerop (s2))
8913 return 0;
8915 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8916 if (!fn)
8917 return 0;
8919 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
8920 return build_function_call_expr (fn, arglist);
8924 /* Simplify a call to the strpbrk builtin.
8926 Return 0 if no simplification was possible, otherwise return the
8927 simplified form of the call as a tree.
8929 The simplified form may be a constant or other expression which
8930 computes the same value, but in a more efficient manner (including
8931 calls to other builtin functions).
8933 The call may contain arguments which need to be evaluated, but
8934 which are not useful to determine the result of the call. In
8935 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8936 COMPOUND_EXPR will be an argument which must be evaluated.
8937 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8938 COMPOUND_EXPR in the chain will contain the tree for the simplified
8939 form of the builtin function call. */
8941 static tree
8942 simplify_builtin_strpbrk (tree arglist)
8944 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8945 return 0;
8946 else
8948 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8949 tree fn;
8950 const char *p1, *p2;
8952 p2 = c_getstr (s2);
8953 if (p2 == NULL)
8954 return 0;
8956 p1 = c_getstr (s1);
8957 if (p1 != NULL)
8959 const char *r = strpbrk (p1, p2);
8961 if (r == NULL)
8962 return fold_convert (TREE_TYPE (s1), integer_zero_node);
8964 /* Return an offset into the constant string argument. */
8965 return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8966 s1, fold_convert (TREE_TYPE (s1),
8967 ssize_int (r - p1))));
8970 if (p2[0] == '\0')
8971 /* strpbrk(x, "") == NULL.
8972 Evaluate and ignore s1 in case it had side-effects. */
8973 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8975 if (p2[1] != '\0')
8976 return 0; /* Really call strpbrk. */
8978 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8979 if (!fn)
8980 return 0;
8982 /* New argument list transforming strpbrk(s1, s2) to
8983 strchr(s1, s2[0]). */
8984 arglist =
8985 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8986 arglist = tree_cons (NULL_TREE, s1, arglist);
8987 return build_function_call_expr (fn, arglist);
8991 /* Simplify a call to the memcmp builtin.
8993 Return 0 if no simplification was possible, otherwise return the
8994 simplified form of the call as a tree.
8996 The simplified form may be a constant or other expression which
8997 computes the same value, but in a more efficient manner (including
8998 calls to other builtin functions).
9000 The call may contain arguments which need to be evaluated, but
9001 which are not useful to determine the result of the call. In
9002 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9003 COMPOUND_EXPR will be an argument which must be evaluated.
9004 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9005 COMPOUND_EXPR in the chain will contain the tree for the simplified
9006 form of the builtin function call. */
9008 static tree
9009 simplify_builtin_memcmp (tree arglist)
9011 tree arg1, arg2, len;
9012 const char *p1, *p2;
9014 if (!validate_arglist (arglist,
9015 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9016 return 0;
9018 arg1 = TREE_VALUE (arglist);
9019 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9020 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9022 /* If the len parameter is zero, return zero. */
9023 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
9024 /* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
9025 return omit_two_operands (integer_type_node, integer_zero_node,
9026 arg1, arg2);
9028 p1 = c_getstr (arg1);
9029 p2 = c_getstr (arg2);
9031 /* If all arguments are constant, and the value of len is not greater
9032 than the lengths of arg1 and arg2, evaluate at compile-time. */
9033 if (host_integerp (len, 1) && p1 && p2
9034 && compare_tree_int (len, strlen (p1) + 1) <= 0
9035 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9037 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9039 return (r < 0
9040 ? integer_minus_one_node
9041 : (r > 0 ? integer_one_node : integer_zero_node));
9044 /* If len parameter is one, return an expression corresponding to
9045 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9046 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9048 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9049 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9050 tree ind1 =
9051 fold (build1 (CONVERT_EXPR, integer_type_node,
9052 build1 (INDIRECT_REF, cst_uchar_node,
9053 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9054 tree ind2 =
9055 fold (build1 (CONVERT_EXPR, integer_type_node,
9056 build1 (INDIRECT_REF, cst_uchar_node,
9057 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9058 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9061 return 0;
9064 /* Simplify a call to the strcmp builtin.
9066 Return 0 if no simplification was possible, otherwise return the
9067 simplified form of the call as a tree.
9069 The simplified form may be a constant or other expression which
9070 computes the same value, but in a more efficient manner (including
9071 calls to other builtin functions).
9073 The call may contain arguments which need to be evaluated, but
9074 which are not useful to determine the result of the call. In
9075 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9076 COMPOUND_EXPR will be an argument which must be evaluated.
9077 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9078 COMPOUND_EXPR in the chain will contain the tree for the simplified
9079 form of the builtin function call. */
9081 static tree
9082 simplify_builtin_strcmp (tree arglist)
9084 tree arg1, arg2;
9085 const char *p1, *p2;
9087 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9088 return 0;
9090 arg1 = TREE_VALUE (arglist);
9091 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9093 /* If both arguments are equal (and not volatile), return zero. */
9094 if (operand_equal_p (arg1, arg2, 0))
9095 return integer_zero_node;
9097 p1 = c_getstr (arg1);
9098 p2 = c_getstr (arg2);
9100 if (p1 && p2)
9102 const int i = strcmp (p1, p2);
9103 return (i < 0
9104 ? integer_minus_one_node
9105 : (i > 0 ? integer_one_node : integer_zero_node));
9108 /* If either arg is "", return an expression corresponding to
9109 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9110 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9112 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9113 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9114 tree ind1 =
9115 fold (build1 (CONVERT_EXPR, integer_type_node,
9116 build1 (INDIRECT_REF, cst_uchar_node,
9117 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9118 tree ind2 =
9119 fold (build1 (CONVERT_EXPR, integer_type_node,
9120 build1 (INDIRECT_REF, cst_uchar_node,
9121 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9122 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9125 return 0;
9128 /* Simplify a call to the strncmp builtin.
9130 Return 0 if no simplification was possible, otherwise return the
9131 simplified form of the call as a tree.
9133 The simplified form may be a constant or other expression which
9134 computes the same value, but in a more efficient manner (including
9135 calls to other builtin functions).
9137 The call may contain arguments which need to be evaluated, but
9138 which are not useful to determine the result of the call. In
9139 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9140 COMPOUND_EXPR will be an argument which must be evaluated.
9141 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9142 COMPOUND_EXPR in the chain will contain the tree for the simplified
9143 form of the builtin function call. */
9145 static tree
9146 simplify_builtin_strncmp (tree arglist)
9148 tree arg1, arg2, arg3;
9149 const char *p1, *p2;
9151 if (!validate_arglist (arglist,
9152 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9153 return 0;
9155 arg1 = TREE_VALUE (arglist);
9156 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9157 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9159 /* If the len parameter is zero, return zero. */
9160 if (integer_zerop (arg3))
9161 /* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
9162 return omit_two_operands (integer_type_node, integer_zero_node,
9163 arg1, arg2);
9165 /* If arg1 and arg2 are equal (and not volatile), return zero. */
9166 if (operand_equal_p (arg1, arg2, 0))
9167 /* Evaluate and ignore arg3 in case it has side-effects. */
9168 return omit_one_operand (integer_type_node, integer_zero_node, arg3);
9170 p1 = c_getstr (arg1);
9171 p2 = c_getstr (arg2);
9173 /* If all arguments are constant, evaluate at compile-time. */
9174 if (host_integerp (arg3, 1) && p1 && p2)
9176 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
9177 return (r < 0
9178 ? integer_minus_one_node
9179 : (r > 0 ? integer_one_node : integer_zero_node));
9182 /* If len == 1 or (either string parameter is "" and (len >= 1)),
9183 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
9184 if (host_integerp (arg3, 1)
9185 && (tree_low_cst (arg3, 1) == 1
9186 || (tree_low_cst (arg3, 1) > 1
9187 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
9189 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9190 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9191 tree ind1 =
9192 fold (build1 (CONVERT_EXPR, integer_type_node,
9193 build1 (INDIRECT_REF, cst_uchar_node,
9194 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9195 tree ind2 =
9196 fold (build1 (CONVERT_EXPR, integer_type_node,
9197 build1 (INDIRECT_REF, cst_uchar_node,
9198 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9199 return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9202 return 0;
9205 /* Simplify a call to the strcat builtin.
9207 Return 0 if no simplification was possible, otherwise return the
9208 simplified form of the call as a tree.
9210 The simplified form may be a constant or other expression which
9211 computes the same value, but in a more efficient manner (including
9212 calls to other builtin functions).
9214 The call may contain arguments which need to be evaluated, but
9215 which are not useful to determine the result of the call. In
9216 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9217 COMPOUND_EXPR will be an argument which must be evaluated.
9218 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9219 COMPOUND_EXPR in the chain will contain the tree for the simplified
9220 form of the builtin function call. */
9222 static tree
9223 simplify_builtin_strcat (tree arglist)
9225 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9226 return 0;
9227 else
9229 tree dst = TREE_VALUE (arglist),
9230 src = TREE_VALUE (TREE_CHAIN (arglist));
9231 const char *p = c_getstr (src);
9233 /* If the string length is zero, return the dst parameter. */
9234 if (p && *p == '\0')
9235 return dst;
9237 return 0;
9241 /* Simplify a call to the strncat builtin.
9243 Return 0 if no simplification was possible, otherwise return the
9244 simplified form of the call as a tree.
9246 The simplified form may be a constant or other expression which
9247 computes the same value, but in a more efficient manner (including
9248 calls to other builtin functions).
9250 The call may contain arguments which need to be evaluated, but
9251 which are not useful to determine the result of the call. In
9252 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9253 COMPOUND_EXPR will be an argument which must be evaluated.
9254 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9255 COMPOUND_EXPR in the chain will contain the tree for the simplified
9256 form of the builtin function call. */
9258 static tree
9259 simplify_builtin_strncat (tree arglist)
9261 if (!validate_arglist (arglist,
9262 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9263 return 0;
9264 else
9266 tree dst = TREE_VALUE (arglist);
9267 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9268 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9269 const char *p = c_getstr (src);
9271 /* If the requested length is zero, or the src parameter string
9272 length is zero, return the dst parameter. */
9273 if (integer_zerop (len) || (p && *p == '\0'))
9274 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9276 /* If the requested len is greater than or equal to the string
9277 length, call strcat. */
9278 if (TREE_CODE (len) == INTEGER_CST && p
9279 && compare_tree_int (len, strlen (p)) >= 0)
9281 tree newarglist
9282 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9283 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9285 /* If the replacement _DECL isn't initialized, don't do the
9286 transformation. */
9287 if (!fn)
9288 return 0;
9290 return build_function_call_expr (fn, newarglist);
9292 return 0;
9296 /* Simplify a call to the strspn builtin.
9298 Return 0 if no simplification was possible, otherwise return the
9299 simplified form of the call as a tree.
9301 The simplified form may be a constant or other expression which
9302 computes the same value, but in a more efficient manner (including
9303 calls to other builtin functions).
9305 The call may contain arguments which need to be evaluated, but
9306 which are not useful to determine the result of the call. In
9307 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9308 COMPOUND_EXPR will be an argument which must be evaluated.
9309 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9310 COMPOUND_EXPR in the chain will contain the tree for the simplified
9311 form of the builtin function call. */
9313 static tree
9314 simplify_builtin_strspn (tree arglist)
9316 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9317 return 0;
9318 else
9320 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9321 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9323 /* If both arguments are constants, evaluate at compile-time. */
9324 if (p1 && p2)
9326 const size_t r = strspn (p1, p2);
9327 return size_int (r);
9330 /* If either argument is "", return 0. */
9331 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9332 /* Evaluate and ignore both arguments in case either one has
9333 side-effects. */
9334 return omit_two_operands (integer_type_node, integer_zero_node,
9335 s1, s2);
9336 return 0;
9340 /* Simplify a call to the strcspn builtin.
9342 Return 0 if no simplification was possible, otherwise return the
9343 simplified form of the call as a tree.
9345 The simplified form may be a constant or other expression which
9346 computes the same value, but in a more efficient manner (including
9347 calls to other builtin functions).
9349 The call may contain arguments which need to be evaluated, but
9350 which are not useful to determine the result of the call. In
9351 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9352 COMPOUND_EXPR will be an argument which must be evaluated.
9353 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9354 COMPOUND_EXPR in the chain will contain the tree for the simplified
9355 form of the builtin function call. */
9357 static tree
9358 simplify_builtin_strcspn (tree arglist)
9360 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9361 return 0;
9362 else
9364 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9365 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9367 /* If both arguments are constants, evaluate at compile-time. */
9368 if (p1 && p2)
9370 const size_t r = strcspn (p1, p2);
9371 return size_int (r);
9374 /* If the first argument is "", return 0. */
9375 if (p1 && *p1 == '\0')
9377 /* Evaluate and ignore argument s2 in case it has
9378 side-effects. */
9379 return omit_one_operand (integer_type_node,
9380 integer_zero_node, s2);
9383 /* If the second argument is "", return __builtin_strlen(s1). */
9384 if (p2 && *p2 == '\0')
9386 tree newarglist = build_tree_list (NULL_TREE, s1),
9387 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9389 /* If the replacement _DECL isn't initialized, don't do the
9390 transformation. */
9391 if (!fn)
9392 return 0;
9394 return build_function_call_expr (fn, newarglist);
9396 return 0;
9400 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9401 by the builtin will be ignored. UNLOCKED is true is true if this
9402 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9403 the known length of the string. Return NULL_TREE if no simplification
9404 was possible. */
9406 tree
9407 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9409 tree fn;
9410 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9411 : implicit_built_in_decls[BUILT_IN_FPUTC];
9412 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9413 : implicit_built_in_decls[BUILT_IN_FWRITE];
9415 /* If the return value is used, or the replacement _DECL isn't
9416 initialized, don't do the transformation. */
9417 if (!ignore || !fn_fputc || !fn_fwrite)
9418 return 0;
9420 /* Verify the arguments in the original call. */
9421 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9422 return 0;
9424 if (! len)
9425 len = c_strlen (TREE_VALUE (arglist), 0);
9427 /* Get the length of the string passed to fputs. If the length
9428 can't be determined, punt. */
9429 if (!len
9430 || TREE_CODE (len) != INTEGER_CST)
9431 return 0;
9433 switch (compare_tree_int (len, 1))
9435 case -1: /* length is 0, delete the call entirely . */
9436 return omit_one_operand (integer_type_node, integer_zero_node,
9437 TREE_VALUE (TREE_CHAIN (arglist)));
9439 case 0: /* length is 1, call fputc. */
9441 const char *p = c_getstr (TREE_VALUE (arglist));
9443 if (p != NULL)
9445 /* New argument list transforming fputs(string, stream) to
9446 fputc(string[0], stream). */
9447 arglist =
9448 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9449 arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9450 fn = fn_fputc;
9451 break;
9454 /* FALLTHROUGH */
9455 case 1: /* length is greater than 1, call fwrite. */
9457 tree string_arg;
9459 /* If optimizing for size keep fputs. */
9460 if (optimize_size)
9461 return 0;
9462 string_arg = TREE_VALUE (arglist);
9463 /* New argument list transforming fputs(string, stream) to
9464 fwrite(string, 1, len, stream). */
9465 arglist = build_tree_list (NULL_TREE,
9466 TREE_VALUE (TREE_CHAIN (arglist)));
9467 arglist = tree_cons (NULL_TREE, len, arglist);
9468 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9469 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9470 fn = fn_fwrite;
9471 break;
9473 default:
9474 abort ();
9477 /* These optimizations are only performed when the result is ignored,
9478 hence there's no need to cast the result to integer_type_node. */
9479 return build_function_call_expr (fn, arglist);
9482 static void
9483 simplify_builtin_va_start (tree arglist)
9485 tree chain = TREE_CHAIN (arglist);
9487 if (TREE_CHAIN (chain))
9488 error ("too many arguments to function `va_start'");
9490 simplify_builtin_next_arg (chain);
9493 static void
9494 simplify_builtin_next_arg (tree arglist)
9496 tree fntype = TREE_TYPE (current_function_decl);
9498 if (TYPE_ARG_TYPES (fntype) == 0
9499 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9500 == void_type_node))
9501 error ("`va_start' used in function with fixed args");
9502 else if (arglist)
9504 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9505 tree arg = TREE_VALUE (arglist);
9507 /* Strip off all nops for the sake of the comparison. This
9508 is not quite the same as STRIP_NOPS. It does more.
9509 We must also strip off INDIRECT_EXPR for C++ reference
9510 parameters. */
9511 while (TREE_CODE (arg) == NOP_EXPR
9512 || TREE_CODE (arg) == CONVERT_EXPR
9513 || TREE_CODE (arg) == NON_LVALUE_EXPR
9514 || TREE_CODE (arg) == INDIRECT_REF)
9515 arg = TREE_OPERAND (arg, 0);
9516 if (arg != last_parm)
9517 warning ("second parameter of `va_start' not last named argument");
9518 TREE_VALUE (arglist) = arg;
9520 else
9521 /* Evidently an out of date version of <stdarg.h>; can't validate
9522 va_start's second argument, but can still work as intended. */
9523 warning ("`__builtin_next_arg' called without an argument");
9527 /* Simplify a call to the sprintf builtin.
9529 Return 0 if no simplification was possible, otherwise return the
9530 simplified form of the call as a tree. If IGNORED is true, it means that
9531 the caller does not use the returned value of the function. */
9533 static tree
9534 simplify_builtin_sprintf (tree arglist, int ignored)
9536 tree call, retval, dest, fmt;
9537 const char *fmt_str = NULL;
9539 /* Verify the required arguments in the original call. We deal with two
9540 types of sprintf() calls: 'sprintf (str, fmt)' and
9541 'sprintf (dest, "%s", orig)'. */
9542 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9543 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9544 VOID_TYPE))
9545 return NULL_TREE;
9547 /* Get the destination string and the format specifier. */
9548 dest = TREE_VALUE (arglist);
9549 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9551 /* Check whether the format is a literal string constant. */
9552 fmt_str = c_getstr (fmt);
9553 if (fmt_str == NULL)
9554 return NULL_TREE;
9556 call = NULL_TREE;
9557 retval = NULL_TREE;
9559 /* If the format doesn't contain % args or %%, use strcpy. */
9560 if (strchr (fmt_str, '%') == NULL)
9562 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9564 if (!fn)
9565 return NULL_TREE;
9567 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9568 'format' is known to contain no % formats. */
9569 arglist = build_tree_list (NULL_TREE, fmt);
9570 arglist = tree_cons (NULL_TREE, dest, arglist);
9571 call = build_function_call_expr (fn, arglist);
9572 if (!ignored)
9573 retval = build_int_2 (strlen (fmt_str), 0);
9576 /* If the format is "%s", use strcpy if the result isn't used. */
9577 else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9579 tree fn, orig;
9580 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9582 if (!fn)
9583 return NULL_TREE;
9585 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9586 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9587 arglist = build_tree_list (NULL_TREE, orig);
9588 arglist = tree_cons (NULL_TREE, dest, arglist);
9589 if (!ignored)
9591 retval = c_strlen (orig, 1);
9592 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9593 return NULL_TREE;
9595 call = build_function_call_expr (fn, arglist);
9598 if (call && retval)
9600 retval = convert
9601 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9602 retval);
9603 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9605 else
9606 return call;